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 bool is_apple = false; 294 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 295 is_apple = true; 296 switch (m_arch.GetTriple().getOS()) 297 { 298 case llvm::Triple::Darwin: 299 case llvm::Triple::MacOSX: 300 case llvm::Triple::IOS: 301 is_apple = true; 302 break; 303 default: 304 break; 305 } 306 307 /* On Apple iOS et al, the frame pointer register is always r7. 308 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 309 */ 310 311 uint32_t fp_regnum = 11; 312 313 if (is_apple) 314 fp_regnum = 7; 315 316 if (m_opcode_mode == eModeThumb) 317 fp_regnum = 7; 318 319 return fp_regnum; 320 } 321 322 uint32_t 323 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 324 { 325 bool is_apple = false; 326 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 327 is_apple = true; 328 switch (m_arch.GetTriple().getOS()) 329 { 330 case llvm::Triple::Darwin: 331 case llvm::Triple::MacOSX: 332 case llvm::Triple::IOS: 333 is_apple = true; 334 break; 335 default: 336 break; 337 } 338 339 /* On Apple iOS et al, the frame pointer register is always r7. 340 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 341 */ 342 343 uint32_t fp_regnum = dwarf_r11; 344 345 if (is_apple) 346 fp_regnum = dwarf_r7; 347 348 if (m_opcode_mode == eModeThumb) 349 fp_regnum = dwarf_r7; 350 351 return fp_regnum; 352 } 353 354 // Push Multiple Registers stores multiple registers to the stack, storing to 355 // consecutive memory locations ending just below the address in SP, and updates 356 // SP to point to the start of the stored data. 357 bool 358 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 359 { 360 #if 0 361 // ARM pseudo code... 362 if (ConditionPassed()) 363 { 364 EncodingSpecificOperations(); 365 NullCheckIfThumbEE(13); 366 address = SP - 4*BitCount(registers); 367 368 for (i = 0 to 14) 369 { 370 if (registers<i> == '1') 371 { 372 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 373 MemA[address,4] = bits(32) UNKNOWN; 374 else 375 MemA[address,4] = R[i]; 376 address = address + 4; 377 } 378 } 379 380 if (registers<15> == '1') // Only possible for encoding A1 or A2 381 MemA[address,4] = PCStoreValue(); 382 383 SP = SP - 4*BitCount(registers); 384 } 385 #endif 386 387 bool conditional = false; 388 bool success = false; 389 if (ConditionPassed(opcode, &conditional)) 390 { 391 const uint32_t addr_byte_size = GetAddressByteSize(); 392 const addr_t sp = ReadCoreReg (SP_REG, &success); 393 if (!success) 394 return false; 395 uint32_t registers = 0; 396 uint32_t Rt; // the source register 397 switch (encoding) { 398 case eEncodingT1: 399 registers = Bits32(opcode, 7, 0); 400 // The M bit represents LR. 401 if (Bit32(opcode, 8)) 402 registers |= (1u << 14); 403 // if BitCount(registers) < 1 then UNPREDICTABLE; 404 if (BitCount(registers) < 1) 405 return false; 406 break; 407 case eEncodingT2: 408 // Ignore bits 15 & 13. 409 registers = Bits32(opcode, 15, 0) & ~0xa000; 410 // if BitCount(registers) < 2 then UNPREDICTABLE; 411 if (BitCount(registers) < 2) 412 return false; 413 break; 414 case eEncodingT3: 415 Rt = Bits32(opcode, 15, 12); 416 // if BadReg(t) then UNPREDICTABLE; 417 if (BadReg(Rt)) 418 return false; 419 registers = (1u << Rt); 420 break; 421 case eEncodingA1: 422 registers = Bits32(opcode, 15, 0); 423 // Instead of return false, let's handle the following case as well, 424 // which amounts to pushing one reg onto the full descending stacks. 425 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 426 break; 427 case eEncodingA2: 428 Rt = Bits32(opcode, 15, 12); 429 // if t == 13 then UNPREDICTABLE; 430 if (Rt == dwarf_sp) 431 return false; 432 registers = (1u << Rt); 433 break; 434 default: 435 return false; 436 } 437 addr_t sp_offset = addr_byte_size * BitCount (registers); 438 addr_t addr = sp - sp_offset; 439 uint32_t i; 440 441 EmulateInstruction::Context context; 442 if (conditional) 443 context.type = EmulateInstruction::eContextRegisterStore; 444 else 445 context.type = EmulateInstruction::eContextPushRegisterOnStack; 446 RegisterInfo reg_info; 447 RegisterInfo sp_reg; 448 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 449 for (i=0; i<15; ++i) 450 { 451 if (BitIsSet (registers, i)) 452 { 453 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 454 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 455 uint32_t reg_value = ReadCoreReg(i, &success); 456 if (!success) 457 return false; 458 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 459 return false; 460 addr += addr_byte_size; 461 } 462 } 463 464 if (BitIsSet (registers, 15)) 465 { 466 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 467 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 468 const uint32_t pc = ReadCoreReg(PC_REG, &success); 469 if (!success) 470 return false; 471 if (!MemAWrite (context, addr, pc, addr_byte_size)) 472 return false; 473 } 474 475 context.type = EmulateInstruction::eContextAdjustStackPointer; 476 context.SetImmediateSigned (-sp_offset); 477 478 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 479 return false; 480 } 481 return true; 482 } 483 484 // Pop Multiple Registers loads multiple registers from the stack, loading from 485 // consecutive memory locations staring at the address in SP, and updates 486 // SP to point just above the loaded data. 487 bool 488 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 489 { 490 #if 0 491 // ARM pseudo code... 492 if (ConditionPassed()) 493 { 494 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 495 address = SP; 496 for i = 0 to 14 497 if registers<i> == '1' then 498 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 499 if registers<15> == '1' then 500 if UnalignedAllowed then 501 LoadWritePC(MemU[address,4]); 502 else 503 LoadWritePC(MemA[address,4]); 504 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 505 if registers<13> == '1' then SP = bits(32) UNKNOWN; 506 } 507 #endif 508 509 bool success = false; 510 511 bool conditional = false; 512 if (ConditionPassed(opcode, &conditional)) 513 { 514 const uint32_t addr_byte_size = GetAddressByteSize(); 515 const addr_t sp = ReadCoreReg (SP_REG, &success); 516 if (!success) 517 return false; 518 uint32_t registers = 0; 519 uint32_t Rt; // the destination register 520 switch (encoding) { 521 case eEncodingT1: 522 registers = Bits32(opcode, 7, 0); 523 // The P bit represents PC. 524 if (Bit32(opcode, 8)) 525 registers |= (1u << 15); 526 // if BitCount(registers) < 1 then UNPREDICTABLE; 527 if (BitCount(registers) < 1) 528 return false; 529 break; 530 case eEncodingT2: 531 // Ignore bit 13. 532 registers = Bits32(opcode, 15, 0) & ~0x2000; 533 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 534 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 535 return false; 536 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 537 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 538 return false; 539 break; 540 case eEncodingT3: 541 Rt = Bits32(opcode, 15, 12); 542 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 543 if (Rt == 13) 544 return false; 545 if (Rt == 15 && InITBlock() && !LastInITBlock()) 546 return false; 547 registers = (1u << Rt); 548 break; 549 case eEncodingA1: 550 registers = Bits32(opcode, 15, 0); 551 // Instead of return false, let's handle the following case as well, 552 // which amounts to popping one reg from the full descending stacks. 553 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 554 555 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 556 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 557 return false; 558 break; 559 case eEncodingA2: 560 Rt = Bits32(opcode, 15, 12); 561 // if t == 13 then UNPREDICTABLE; 562 if (Rt == dwarf_sp) 563 return false; 564 registers = (1u << Rt); 565 break; 566 default: 567 return false; 568 } 569 addr_t sp_offset = addr_byte_size * BitCount (registers); 570 addr_t addr = sp; 571 uint32_t i, data; 572 573 EmulateInstruction::Context context; 574 if (conditional) 575 context.type = EmulateInstruction::eContextRegisterLoad; 576 else 577 context.type = EmulateInstruction::eContextPopRegisterOffStack; 578 579 RegisterInfo sp_reg; 580 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 581 582 for (i=0; i<15; ++i) 583 { 584 if (BitIsSet (registers, i)) 585 { 586 context.SetRegisterPlusOffset (sp_reg, addr - sp); 587 data = MemARead(context, addr, 4, 0, &success); 588 if (!success) 589 return false; 590 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 591 return false; 592 addr += addr_byte_size; 593 } 594 } 595 596 if (BitIsSet (registers, 15)) 597 { 598 context.SetRegisterPlusOffset (sp_reg, addr - sp); 599 data = MemARead(context, addr, 4, 0, &success); 600 if (!success) 601 return false; 602 // In ARMv5T and above, this is an interworking branch. 603 if (!LoadWritePC(context, data)) 604 return false; 605 //addr += addr_byte_size; 606 } 607 608 context.type = EmulateInstruction::eContextAdjustStackPointer; 609 context.SetImmediateSigned (sp_offset); 610 611 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 612 return false; 613 } 614 return true; 615 } 616 617 // Set r7 or ip to point to saved value residing within the stack. 618 // ADD (SP plus immediate) 619 bool 620 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 621 { 622 #if 0 623 // ARM pseudo code... 624 if (ConditionPassed()) 625 { 626 EncodingSpecificOperations(); 627 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 628 if d == 15 then 629 ALUWritePC(result); // setflags is always FALSE here 630 else 631 R[d] = result; 632 if setflags then 633 APSR.N = result<31>; 634 APSR.Z = IsZeroBit(result); 635 APSR.C = carry; 636 APSR.V = overflow; 637 } 638 #endif 639 640 bool success = false; 641 642 if (ConditionPassed(opcode)) 643 { 644 const addr_t sp = ReadCoreReg (SP_REG, &success); 645 if (!success) 646 return false; 647 uint32_t Rd; // the destination register 648 uint32_t imm32; 649 switch (encoding) { 650 case eEncodingT1: 651 Rd = 7; 652 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 653 break; 654 case eEncodingA1: 655 Rd = Bits32(opcode, 15, 12); 656 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 657 break; 658 default: 659 return false; 660 } 661 addr_t sp_offset = imm32; 662 addr_t addr = sp + sp_offset; // a pointer to the stack area 663 664 EmulateInstruction::Context context; 665 context.type = eContextSetFramePointer; 666 RegisterInfo sp_reg; 667 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 668 context.SetRegisterPlusOffset (sp_reg, sp_offset); 669 670 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 671 return false; 672 } 673 return true; 674 } 675 676 // Set r7 or ip to the current stack pointer. 677 // MOV (register) 678 bool 679 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 680 { 681 #if 0 682 // ARM pseudo code... 683 if (ConditionPassed()) 684 { 685 EncodingSpecificOperations(); 686 result = R[m]; 687 if d == 15 then 688 ALUWritePC(result); // setflags is always FALSE here 689 else 690 R[d] = result; 691 if setflags then 692 APSR.N = result<31>; 693 APSR.Z = IsZeroBit(result); 694 // APSR.C unchanged 695 // APSR.V unchanged 696 } 697 #endif 698 699 bool success = false; 700 701 if (ConditionPassed(opcode)) 702 { 703 const addr_t sp = ReadCoreReg (SP_REG, &success); 704 if (!success) 705 return false; 706 uint32_t Rd; // the destination register 707 switch (encoding) { 708 case eEncodingT1: 709 Rd = 7; 710 break; 711 case eEncodingA1: 712 Rd = 12; 713 break; 714 default: 715 return false; 716 } 717 718 EmulateInstruction::Context context; 719 if (Rd == GetFramePointerRegisterNumber()) 720 context.type = EmulateInstruction::eContextSetFramePointer; 721 else 722 context.type = EmulateInstruction::eContextRegisterPlusOffset; 723 RegisterInfo sp_reg; 724 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 725 context.SetRegisterPlusOffset (sp_reg, 0); 726 727 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 728 return false; 729 } 730 return true; 731 } 732 733 // Move from high register (r8-r15) to low register (r0-r7). 734 // MOV (register) 735 bool 736 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 737 { 738 return EmulateMOVRdRm (opcode, encoding); 739 } 740 741 // Move from register to register. 742 // MOV (register) 743 bool 744 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 745 { 746 #if 0 747 // ARM pseudo code... 748 if (ConditionPassed()) 749 { 750 EncodingSpecificOperations(); 751 result = R[m]; 752 if d == 15 then 753 ALUWritePC(result); // setflags is always FALSE here 754 else 755 R[d] = result; 756 if setflags then 757 APSR.N = result<31>; 758 APSR.Z = IsZeroBit(result); 759 // APSR.C unchanged 760 // APSR.V unchanged 761 } 762 #endif 763 764 bool success = false; 765 766 if (ConditionPassed(opcode)) 767 { 768 uint32_t Rm; // the source register 769 uint32_t Rd; // the destination register 770 bool setflags; 771 switch (encoding) { 772 case eEncodingT1: 773 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 774 Rm = Bits32(opcode, 6, 3); 775 setflags = false; 776 if (Rd == 15 && InITBlock() && !LastInITBlock()) 777 return false; 778 break; 779 case eEncodingT2: 780 Rd = Bits32(opcode, 2, 0); 781 Rm = Bits32(opcode, 5, 3); 782 setflags = true; 783 if (InITBlock()) 784 return false; 785 break; 786 case eEncodingT3: 787 Rd = Bits32(opcode, 11, 8); 788 Rm = Bits32(opcode, 3, 0); 789 setflags = BitIsSet(opcode, 20); 790 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 791 if (setflags && (BadReg(Rd) || BadReg(Rm))) 792 return false; 793 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 794 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 795 return false; 796 break; 797 case eEncodingA1: 798 Rd = Bits32(opcode, 15, 12); 799 Rm = Bits32(opcode, 3, 0); 800 setflags = BitIsSet(opcode, 20); 801 802 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 803 if (Rd == 15 && setflags) 804 return EmulateSUBSPcLrEtc (opcode, encoding); 805 break; 806 default: 807 return false; 808 } 809 uint32_t result = ReadCoreReg(Rm, &success); 810 if (!success) 811 return false; 812 813 // The context specifies that Rm is to be moved into Rd. 814 EmulateInstruction::Context context; 815 context.type = EmulateInstruction::eContextRegisterLoad; 816 RegisterInfo dwarf_reg; 817 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 818 context.SetRegister (dwarf_reg); 819 820 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 821 return false; 822 } 823 return true; 824 } 825 826 // Move (immediate) writes an immediate value to the destination register. It 827 // can optionally update the condition flags based on the value. 828 // MOV (immediate) 829 bool 830 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 831 { 832 #if 0 833 // ARM pseudo code... 834 if (ConditionPassed()) 835 { 836 EncodingSpecificOperations(); 837 result = imm32; 838 if d == 15 then // Can only occur for ARM encoding 839 ALUWritePC(result); // setflags is always FALSE here 840 else 841 R[d] = result; 842 if setflags then 843 APSR.N = result<31>; 844 APSR.Z = IsZeroBit(result); 845 APSR.C = carry; 846 // APSR.V unchanged 847 } 848 #endif 849 850 if (ConditionPassed(opcode)) 851 { 852 uint32_t Rd; // the destination register 853 uint32_t imm32; // the immediate value to be written to Rd 854 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 855 // for setflags == false, this value is a don't care 856 // initialized to 0 to silence the static analyzer 857 bool setflags; 858 switch (encoding) { 859 case eEncodingT1: 860 Rd = Bits32(opcode, 10, 8); 861 setflags = !InITBlock(); 862 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 863 carry = APSR_C; 864 865 break; 866 867 case eEncodingT2: 868 Rd = Bits32(opcode, 11, 8); 869 setflags = BitIsSet(opcode, 20); 870 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 871 if (BadReg(Rd)) 872 return false; 873 874 break; 875 876 case eEncodingT3: 877 { 878 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 879 Rd = Bits32 (opcode, 11, 8); 880 setflags = false; 881 uint32_t imm4 = Bits32 (opcode, 19, 16); 882 uint32_t imm3 = Bits32 (opcode, 14, 12); 883 uint32_t i = Bit32 (opcode, 26); 884 uint32_t imm8 = Bits32 (opcode, 7, 0); 885 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 886 887 // if BadReg(d) then UNPREDICTABLE; 888 if (BadReg (Rd)) 889 return false; 890 } 891 break; 892 893 case eEncodingA1: 894 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 895 Rd = Bits32 (opcode, 15, 12); 896 setflags = BitIsSet (opcode, 20); 897 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 898 899 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 900 if ((Rd == 15) && setflags) 901 return EmulateSUBSPcLrEtc (opcode, encoding); 902 903 break; 904 905 case eEncodingA2: 906 { 907 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 908 Rd = Bits32 (opcode, 15, 12); 909 setflags = false; 910 uint32_t imm4 = Bits32 (opcode, 19, 16); 911 uint32_t imm12 = Bits32 (opcode, 11, 0); 912 imm32 = (imm4 << 12) | imm12; 913 914 // if d == 15 then UNPREDICTABLE; 915 if (Rd == 15) 916 return false; 917 } 918 break; 919 920 default: 921 return false; 922 } 923 uint32_t result = imm32; 924 925 // The context specifies that an immediate is to be moved into Rd. 926 EmulateInstruction::Context context; 927 context.type = EmulateInstruction::eContextImmediate; 928 context.SetNoArgs (); 929 930 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 931 return false; 932 } 933 return true; 934 } 935 936 // MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 937 // register. These 32 bits do not depend on whether the source register values are considered to be signed values or 938 // unsigned values. 939 // 940 // Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 941 // limited to only a few forms of the instruction. 942 bool 943 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 944 { 945 #if 0 946 if ConditionPassed() then 947 EncodingSpecificOperations(); 948 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 949 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 950 result = operand1 * operand2; 951 R[d] = result<31:0>; 952 if setflags then 953 APSR.N = result<31>; 954 APSR.Z = IsZeroBit(result); 955 if ArchVersion() == 4 then 956 APSR.C = bit UNKNOWN; 957 // else APSR.C unchanged 958 // APSR.V always unchanged 959 #endif 960 961 if (ConditionPassed(opcode)) 962 { 963 uint32_t d; 964 uint32_t n; 965 uint32_t m; 966 bool setflags; 967 968 // EncodingSpecificOperations(); 969 switch (encoding) 970 { 971 case eEncodingT1: 972 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 973 d = Bits32 (opcode, 2, 0); 974 n = Bits32 (opcode, 5, 3); 975 m = Bits32 (opcode, 2, 0); 976 setflags = !InITBlock(); 977 978 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 979 if ((ArchVersion() < ARMv6) && (d == n)) 980 return false; 981 982 break; 983 984 case eEncodingT2: 985 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 986 d = Bits32 (opcode, 11, 8); 987 n = Bits32 (opcode, 19, 16); 988 m = Bits32 (opcode, 3, 0); 989 setflags = false; 990 991 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 992 if (BadReg (d) || BadReg (n) || BadReg (m)) 993 return false; 994 995 break; 996 997 case eEncodingA1: 998 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 999 d = Bits32 (opcode, 19, 16); 1000 n = Bits32 (opcode, 3, 0); 1001 m = Bits32 (opcode, 11, 8); 1002 setflags = BitIsSet (opcode, 20); 1003 1004 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1005 if ((d == 15) || (n == 15) || (m == 15)) 1006 return false; 1007 1008 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1009 if ((ArchVersion() < ARMv6) && (d == n)) 1010 return false; 1011 1012 break; 1013 1014 default: 1015 return false; 1016 } 1017 1018 bool success = false; 1019 1020 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1021 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1022 if (!success) 1023 return false; 1024 1025 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1026 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1027 if (!success) 1028 return false; 1029 1030 // result = operand1 * operand2; 1031 uint64_t result = operand1 * operand2; 1032 1033 // R[d] = result<31:0>; 1034 RegisterInfo op1_reg; 1035 RegisterInfo op2_reg; 1036 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1037 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1038 1039 EmulateInstruction::Context context; 1040 context.type = eContextArithmetic; 1041 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 1042 1043 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 1044 return false; 1045 1046 // if setflags then 1047 if (setflags) 1048 { 1049 // APSR.N = result<31>; 1050 // APSR.Z = IsZeroBit(result); 1051 m_new_inst_cpsr = m_opcode_cpsr; 1052 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 1053 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1054 if (m_new_inst_cpsr != m_opcode_cpsr) 1055 { 1056 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1057 return false; 1058 } 1059 1060 // if ArchVersion() == 4 then 1061 // APSR.C = bit UNKNOWN; 1062 } 1063 } 1064 return true; 1065 } 1066 1067 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1068 // It can optionally update the condition flags based on the value. 1069 bool 1070 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1071 { 1072 #if 0 1073 // ARM pseudo code... 1074 if (ConditionPassed()) 1075 { 1076 EncodingSpecificOperations(); 1077 result = NOT(imm32); 1078 if d == 15 then // Can only occur for ARM encoding 1079 ALUWritePC(result); // setflags is always FALSE here 1080 else 1081 R[d] = result; 1082 if setflags then 1083 APSR.N = result<31>; 1084 APSR.Z = IsZeroBit(result); 1085 APSR.C = carry; 1086 // APSR.V unchanged 1087 } 1088 #endif 1089 1090 if (ConditionPassed(opcode)) 1091 { 1092 uint32_t Rd; // the destination register 1093 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1094 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1095 bool setflags; 1096 switch (encoding) { 1097 case eEncodingT1: 1098 Rd = Bits32(opcode, 11, 8); 1099 setflags = BitIsSet(opcode, 20); 1100 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1101 break; 1102 case eEncodingA1: 1103 Rd = Bits32(opcode, 15, 12); 1104 setflags = BitIsSet(opcode, 20); 1105 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1106 1107 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1108 if (Rd == 15 && setflags) 1109 return EmulateSUBSPcLrEtc (opcode, encoding); 1110 break; 1111 default: 1112 return false; 1113 } 1114 uint32_t result = ~imm32; 1115 1116 // The context specifies that an immediate is to be moved into Rd. 1117 EmulateInstruction::Context context; 1118 context.type = EmulateInstruction::eContextImmediate; 1119 context.SetNoArgs (); 1120 1121 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1122 return false; 1123 } 1124 return true; 1125 } 1126 1127 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1128 // It can optionally update the condition flags based on the result. 1129 bool 1130 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1131 { 1132 #if 0 1133 // ARM pseudo code... 1134 if (ConditionPassed()) 1135 { 1136 EncodingSpecificOperations(); 1137 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1138 result = NOT(shifted); 1139 if d == 15 then // Can only occur for ARM encoding 1140 ALUWritePC(result); // setflags is always FALSE here 1141 else 1142 R[d] = result; 1143 if setflags then 1144 APSR.N = result<31>; 1145 APSR.Z = IsZeroBit(result); 1146 APSR.C = carry; 1147 // APSR.V unchanged 1148 } 1149 #endif 1150 1151 if (ConditionPassed(opcode)) 1152 { 1153 uint32_t Rm; // the source register 1154 uint32_t Rd; // the destination register 1155 ARM_ShifterType shift_t; 1156 uint32_t shift_n; // the shift applied to the value read from Rm 1157 bool setflags; 1158 uint32_t carry; // the carry bit after the shift operation 1159 switch (encoding) { 1160 case eEncodingT1: 1161 Rd = Bits32(opcode, 2, 0); 1162 Rm = Bits32(opcode, 5, 3); 1163 setflags = !InITBlock(); 1164 shift_t = SRType_LSL; 1165 shift_n = 0; 1166 if (InITBlock()) 1167 return false; 1168 break; 1169 case eEncodingT2: 1170 Rd = Bits32(opcode, 11, 8); 1171 Rm = Bits32(opcode, 3, 0); 1172 setflags = BitIsSet(opcode, 20); 1173 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1174 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1175 if (BadReg(Rd) || BadReg(Rm)) 1176 return false; 1177 break; 1178 case eEncodingA1: 1179 Rd = Bits32(opcode, 15, 12); 1180 Rm = Bits32(opcode, 3, 0); 1181 setflags = BitIsSet(opcode, 20); 1182 shift_n = DecodeImmShiftARM(opcode, shift_t); 1183 break; 1184 default: 1185 return false; 1186 } 1187 bool success = false; 1188 uint32_t value = ReadCoreReg(Rm, &success); 1189 if (!success) 1190 return false; 1191 1192 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1193 if (!success) 1194 return false; 1195 uint32_t result = ~shifted; 1196 1197 // The context specifies that an immediate is to be moved into Rd. 1198 EmulateInstruction::Context context; 1199 context.type = EmulateInstruction::eContextImmediate; 1200 context.SetNoArgs (); 1201 1202 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1203 return false; 1204 } 1205 return true; 1206 } 1207 1208 // PC relative immediate load into register, possibly followed by ADD (SP plus register). 1209 // LDR (literal) 1210 bool 1211 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1212 { 1213 #if 0 1214 // ARM pseudo code... 1215 if (ConditionPassed()) 1216 { 1217 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1218 base = Align(PC,4); 1219 address = if add then (base + imm32) else (base - imm32); 1220 data = MemU[address,4]; 1221 if t == 15 then 1222 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1223 elsif UnalignedSupport() || address<1:0> = '00' then 1224 R[t] = data; 1225 else // Can only apply before ARMv7 1226 if CurrentInstrSet() == InstrSet_ARM then 1227 R[t] = ROR(data, 8*UInt(address<1:0>)); 1228 else 1229 R[t] = bits(32) UNKNOWN; 1230 } 1231 #endif 1232 1233 if (ConditionPassed(opcode)) 1234 { 1235 bool success = false; 1236 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1237 if (!success) 1238 return false; 1239 1240 // PC relative immediate load context 1241 EmulateInstruction::Context context; 1242 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1243 RegisterInfo pc_reg; 1244 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1245 context.SetRegisterPlusOffset (pc_reg, 0); 1246 1247 uint32_t Rt; // the destination register 1248 uint32_t imm32; // immediate offset from the PC 1249 bool add; // +imm32 or -imm32? 1250 addr_t base; // the base address 1251 addr_t address; // the PC relative address 1252 uint32_t data; // the literal data value from the PC relative load 1253 switch (encoding) { 1254 case eEncodingT1: 1255 Rt = Bits32(opcode, 10, 8); 1256 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1257 add = true; 1258 break; 1259 case eEncodingT2: 1260 Rt = Bits32(opcode, 15, 12); 1261 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1262 add = BitIsSet(opcode, 23); 1263 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1264 return false; 1265 break; 1266 default: 1267 return false; 1268 } 1269 1270 base = Align(pc, 4); 1271 if (add) 1272 address = base + imm32; 1273 else 1274 address = base - imm32; 1275 1276 context.SetRegisterPlusOffset(pc_reg, address - base); 1277 data = MemURead(context, address, 4, 0, &success); 1278 if (!success) 1279 return false; 1280 1281 if (Rt == 15) 1282 { 1283 if (Bits32(address, 1, 0) == 0) 1284 { 1285 // In ARMv5T and above, this is an interworking branch. 1286 if (!LoadWritePC(context, data)) 1287 return false; 1288 } 1289 else 1290 return false; 1291 } 1292 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1293 { 1294 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1295 return false; 1296 } 1297 else // We don't handle ARM for now. 1298 return false; 1299 1300 } 1301 return true; 1302 } 1303 1304 // An add operation to adjust the SP. 1305 // ADD (SP plus immediate) 1306 bool 1307 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1308 { 1309 #if 0 1310 // ARM pseudo code... 1311 if (ConditionPassed()) 1312 { 1313 EncodingSpecificOperations(); 1314 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1315 if d == 15 then // Can only occur for ARM encoding 1316 ALUWritePC(result); // setflags is always FALSE here 1317 else 1318 R[d] = result; 1319 if setflags then 1320 APSR.N = result<31>; 1321 APSR.Z = IsZeroBit(result); 1322 APSR.C = carry; 1323 APSR.V = overflow; 1324 } 1325 #endif 1326 1327 bool success = false; 1328 1329 if (ConditionPassed(opcode)) 1330 { 1331 const addr_t sp = ReadCoreReg (SP_REG, &success); 1332 if (!success) 1333 return false; 1334 uint32_t imm32; // the immediate operand 1335 uint32_t d; 1336 //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1 1337 switch (encoding) 1338 { 1339 case eEncodingT1: 1340 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1341 d = Bits32 (opcode, 10, 8); 1342 imm32 = (Bits32 (opcode, 7, 0) << 2); 1343 1344 break; 1345 1346 case eEncodingT2: 1347 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1348 d = 13; 1349 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1350 1351 break; 1352 1353 default: 1354 return false; 1355 } 1356 addr_t sp_offset = imm32; 1357 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1358 1359 EmulateInstruction::Context context; 1360 context.type = EmulateInstruction::eContextAdjustStackPointer; 1361 RegisterInfo sp_reg; 1362 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1363 context.SetRegisterPlusOffset (sp_reg, sp_offset); 1364 1365 if (d == 15) 1366 { 1367 if (!ALUWritePC (context, addr)) 1368 return false; 1369 } 1370 else 1371 { 1372 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr)) 1373 return false; 1374 1375 // Add this back if/when support eEncodingT3 eEncodingA1 1376 //if (setflags) 1377 //{ 1378 // APSR.N = result<31>; 1379 // APSR.Z = IsZeroBit(result); 1380 // APSR.C = carry; 1381 // APSR.V = overflow; 1382 //} 1383 } 1384 } 1385 return true; 1386 } 1387 1388 // An add operation to adjust the SP. 1389 // ADD (SP plus register) 1390 bool 1391 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1392 { 1393 #if 0 1394 // ARM pseudo code... 1395 if (ConditionPassed()) 1396 { 1397 EncodingSpecificOperations(); 1398 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1399 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1400 if d == 15 then 1401 ALUWritePC(result); // setflags is always FALSE here 1402 else 1403 R[d] = result; 1404 if setflags then 1405 APSR.N = result<31>; 1406 APSR.Z = IsZeroBit(result); 1407 APSR.C = carry; 1408 APSR.V = overflow; 1409 } 1410 #endif 1411 1412 bool success = false; 1413 1414 if (ConditionPassed(opcode)) 1415 { 1416 const addr_t sp = ReadCoreReg (SP_REG, &success); 1417 if (!success) 1418 return false; 1419 uint32_t Rm; // the second operand 1420 switch (encoding) { 1421 case eEncodingT2: 1422 Rm = Bits32(opcode, 6, 3); 1423 break; 1424 default: 1425 return false; 1426 } 1427 int32_t reg_value = ReadCoreReg(Rm, &success); 1428 if (!success) 1429 return false; 1430 1431 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1432 1433 EmulateInstruction::Context context; 1434 context.type = eContextArithmetic; 1435 RegisterInfo sp_reg; 1436 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1437 1438 RegisterInfo other_reg; 1439 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1440 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1441 1442 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1443 return false; 1444 } 1445 return true; 1446 } 1447 1448 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1449 // at a PC-relative address, and changes instruction set from ARM to Thumb, or 1450 // from Thumb to ARM. 1451 // BLX (immediate) 1452 bool 1453 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1454 { 1455 #if 0 1456 // ARM pseudo code... 1457 if (ConditionPassed()) 1458 { 1459 EncodingSpecificOperations(); 1460 if CurrentInstrSet() == InstrSet_ARM then 1461 LR = PC - 4; 1462 else 1463 LR = PC<31:1> : '1'; 1464 if targetInstrSet == InstrSet_ARM then 1465 targetAddress = Align(PC,4) + imm32; 1466 else 1467 targetAddress = PC + imm32; 1468 SelectInstrSet(targetInstrSet); 1469 BranchWritePC(targetAddress); 1470 } 1471 #endif 1472 1473 bool success = true; 1474 1475 if (ConditionPassed(opcode)) 1476 { 1477 EmulateInstruction::Context context; 1478 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1479 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1480 if (!success) 1481 return false; 1482 addr_t lr; // next instruction address 1483 addr_t target; // target address 1484 int32_t imm32; // PC-relative offset 1485 switch (encoding) { 1486 case eEncodingT1: 1487 { 1488 lr = pc | 1u; // return address 1489 uint32_t S = Bit32(opcode, 26); 1490 uint32_t imm10 = Bits32(opcode, 25, 16); 1491 uint32_t J1 = Bit32(opcode, 13); 1492 uint32_t J2 = Bit32(opcode, 11); 1493 uint32_t imm11 = Bits32(opcode, 10, 0); 1494 uint32_t I1 = !(J1 ^ S); 1495 uint32_t I2 = !(J2 ^ S); 1496 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1497 imm32 = llvm::SignExtend32<25>(imm25); 1498 target = pc + imm32; 1499 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1500 if (InITBlock() && !LastInITBlock()) 1501 return false; 1502 break; 1503 } 1504 case eEncodingT2: 1505 { 1506 lr = pc | 1u; // return address 1507 uint32_t S = Bit32(opcode, 26); 1508 uint32_t imm10H = Bits32(opcode, 25, 16); 1509 uint32_t J1 = Bit32(opcode, 13); 1510 uint32_t J2 = Bit32(opcode, 11); 1511 uint32_t imm10L = Bits32(opcode, 10, 1); 1512 uint32_t I1 = !(J1 ^ S); 1513 uint32_t I2 = !(J2 ^ S); 1514 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1515 imm32 = llvm::SignExtend32<25>(imm25); 1516 target = Align(pc, 4) + imm32; 1517 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1518 if (InITBlock() && !LastInITBlock()) 1519 return false; 1520 break; 1521 } 1522 case eEncodingA1: 1523 lr = pc - 4; // return address 1524 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1525 target = Align(pc, 4) + imm32; 1526 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1527 break; 1528 case eEncodingA2: 1529 lr = pc - 4; // return address 1530 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1531 target = pc + imm32; 1532 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1533 break; 1534 default: 1535 return false; 1536 } 1537 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1538 return false; 1539 if (!BranchWritePC(context, target)) 1540 return false; 1541 } 1542 return true; 1543 } 1544 1545 // Branch with Link and Exchange (register) calls a subroutine at an address and 1546 // instruction set specified by a register. 1547 // BLX (register) 1548 bool 1549 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1550 { 1551 #if 0 1552 // ARM pseudo code... 1553 if (ConditionPassed()) 1554 { 1555 EncodingSpecificOperations(); 1556 target = R[m]; 1557 if CurrentInstrSet() == InstrSet_ARM then 1558 next_instr_addr = PC - 4; 1559 LR = next_instr_addr; 1560 else 1561 next_instr_addr = PC - 2; 1562 LR = next_instr_addr<31:1> : '1'; 1563 BXWritePC(target); 1564 } 1565 #endif 1566 1567 bool success = false; 1568 1569 if (ConditionPassed(opcode)) 1570 { 1571 EmulateInstruction::Context context; 1572 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1573 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1574 addr_t lr; // next instruction address 1575 if (!success) 1576 return false; 1577 uint32_t Rm; // the register with the target address 1578 switch (encoding) { 1579 case eEncodingT1: 1580 lr = (pc - 2) | 1u; // return address 1581 Rm = Bits32(opcode, 6, 3); 1582 // if m == 15 then UNPREDICTABLE; 1583 if (Rm == 15) 1584 return false; 1585 if (InITBlock() && !LastInITBlock()) 1586 return false; 1587 break; 1588 case eEncodingA1: 1589 lr = pc - 4; // return address 1590 Rm = Bits32(opcode, 3, 0); 1591 // if m == 15 then UNPREDICTABLE; 1592 if (Rm == 15) 1593 return false; 1594 break; 1595 default: 1596 return false; 1597 } 1598 addr_t target = ReadCoreReg (Rm, &success); 1599 if (!success) 1600 return false; 1601 RegisterInfo dwarf_reg; 1602 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1603 context.SetRegister (dwarf_reg); 1604 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1605 return false; 1606 if (!BXWritePC(context, target)) 1607 return false; 1608 } 1609 return true; 1610 } 1611 1612 // Branch and Exchange causes a branch to an address and instruction set specified by a register. 1613 bool 1614 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1615 { 1616 #if 0 1617 // ARM pseudo code... 1618 if (ConditionPassed()) 1619 { 1620 EncodingSpecificOperations(); 1621 BXWritePC(R[m]); 1622 } 1623 #endif 1624 1625 if (ConditionPassed(opcode)) 1626 { 1627 EmulateInstruction::Context context; 1628 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1629 uint32_t Rm; // the register with the target address 1630 switch (encoding) { 1631 case eEncodingT1: 1632 Rm = Bits32(opcode, 6, 3); 1633 if (InITBlock() && !LastInITBlock()) 1634 return false; 1635 break; 1636 case eEncodingA1: 1637 Rm = Bits32(opcode, 3, 0); 1638 break; 1639 default: 1640 return false; 1641 } 1642 bool success = false; 1643 addr_t target = ReadCoreReg (Rm, &success); 1644 if (!success) 1645 return false; 1646 1647 RegisterInfo dwarf_reg; 1648 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1649 context.SetRegister (dwarf_reg); 1650 if (!BXWritePC(context, target)) 1651 return false; 1652 } 1653 return true; 1654 } 1655 1656 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1657 // address and instruction set specified by a register as though it were a BX instruction. 1658 // 1659 // TODO: Emulate Jazelle architecture? 1660 // We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1661 bool 1662 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1663 { 1664 #if 0 1665 // ARM pseudo code... 1666 if (ConditionPassed()) 1667 { 1668 EncodingSpecificOperations(); 1669 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1670 BXWritePC(R[m]); 1671 else 1672 if JazelleAcceptsExecution() then 1673 SwitchToJazelleExecution(); 1674 else 1675 SUBARCHITECTURE_DEFINED handler call; 1676 } 1677 #endif 1678 1679 if (ConditionPassed(opcode)) 1680 { 1681 EmulateInstruction::Context context; 1682 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1683 uint32_t Rm; // the register with the target address 1684 switch (encoding) { 1685 case eEncodingT1: 1686 Rm = Bits32(opcode, 19, 16); 1687 if (BadReg(Rm)) 1688 return false; 1689 if (InITBlock() && !LastInITBlock()) 1690 return false; 1691 break; 1692 case eEncodingA1: 1693 Rm = Bits32(opcode, 3, 0); 1694 if (Rm == 15) 1695 return false; 1696 break; 1697 default: 1698 return false; 1699 } 1700 bool success = false; 1701 addr_t target = ReadCoreReg (Rm, &success); 1702 if (!success) 1703 return false; 1704 1705 RegisterInfo dwarf_reg; 1706 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1707 context.SetRegister (dwarf_reg); 1708 if (!BXWritePC(context, target)) 1709 return false; 1710 } 1711 return true; 1712 } 1713 1714 // Set r7 to point to some ip offset. 1715 // SUB (immediate) 1716 bool 1717 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1718 { 1719 #if 0 1720 // ARM pseudo code... 1721 if (ConditionPassed()) 1722 { 1723 EncodingSpecificOperations(); 1724 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1725 if d == 15 then // Can only occur for ARM encoding 1726 ALUWritePC(result); // setflags is always FALSE here 1727 else 1728 R[d] = result; 1729 if setflags then 1730 APSR.N = result<31>; 1731 APSR.Z = IsZeroBit(result); 1732 APSR.C = carry; 1733 APSR.V = overflow; 1734 } 1735 #endif 1736 1737 if (ConditionPassed(opcode)) 1738 { 1739 bool success = false; 1740 const addr_t ip = ReadCoreReg (12, &success); 1741 if (!success) 1742 return false; 1743 uint32_t imm32; 1744 switch (encoding) { 1745 case eEncodingA1: 1746 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1747 break; 1748 default: 1749 return false; 1750 } 1751 addr_t ip_offset = imm32; 1752 addr_t addr = ip - ip_offset; // the adjusted ip value 1753 1754 EmulateInstruction::Context context; 1755 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1756 RegisterInfo dwarf_reg; 1757 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1758 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1759 1760 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1761 return false; 1762 } 1763 return true; 1764 } 1765 1766 // Set ip to point to some stack offset. 1767 // SUB (SP minus immediate) 1768 bool 1769 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1770 { 1771 #if 0 1772 // ARM pseudo code... 1773 if (ConditionPassed()) 1774 { 1775 EncodingSpecificOperations(); 1776 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1777 if d == 15 then // Can only occur for ARM encoding 1778 ALUWritePC(result); // setflags is always FALSE here 1779 else 1780 R[d] = result; 1781 if setflags then 1782 APSR.N = result<31>; 1783 APSR.Z = IsZeroBit(result); 1784 APSR.C = carry; 1785 APSR.V = overflow; 1786 } 1787 #endif 1788 1789 if (ConditionPassed(opcode)) 1790 { 1791 bool success = false; 1792 const addr_t sp = ReadCoreReg (SP_REG, &success); 1793 if (!success) 1794 return false; 1795 uint32_t imm32; 1796 switch (encoding) { 1797 case eEncodingA1: 1798 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1799 break; 1800 default: 1801 return false; 1802 } 1803 addr_t sp_offset = imm32; 1804 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1805 1806 EmulateInstruction::Context context; 1807 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1808 RegisterInfo dwarf_reg; 1809 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1810 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1811 1812 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1813 return false; 1814 } 1815 return true; 1816 } 1817 1818 // This instruction subtracts an immediate value from the SP value, and writes 1819 // the result to the destination register. 1820 // 1821 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1822 bool 1823 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1824 { 1825 #if 0 1826 // ARM pseudo code... 1827 if (ConditionPassed()) 1828 { 1829 EncodingSpecificOperations(); 1830 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1831 if d == 15 then // Can only occur for ARM encoding 1832 ALUWritePC(result); // setflags is always FALSE here 1833 else 1834 R[d] = result; 1835 if setflags then 1836 APSR.N = result<31>; 1837 APSR.Z = IsZeroBit(result); 1838 APSR.C = carry; 1839 APSR.V = overflow; 1840 } 1841 #endif 1842 1843 bool success = false; 1844 if (ConditionPassed(opcode)) 1845 { 1846 const addr_t sp = ReadCoreReg (SP_REG, &success); 1847 if (!success) 1848 return false; 1849 1850 uint32_t Rd; 1851 bool setflags; 1852 uint32_t imm32; 1853 switch (encoding) { 1854 case eEncodingT1: 1855 Rd = 13; 1856 setflags = false; 1857 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1858 break; 1859 case eEncodingT2: 1860 Rd = Bits32(opcode, 11, 8); 1861 setflags = BitIsSet(opcode, 20); 1862 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1863 if (Rd == 15 && setflags) 1864 return EmulateCMPImm(opcode, eEncodingT2); 1865 if (Rd == 15 && !setflags) 1866 return false; 1867 break; 1868 case eEncodingT3: 1869 Rd = Bits32(opcode, 11, 8); 1870 setflags = false; 1871 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1872 if (Rd == 15) 1873 return false; 1874 break; 1875 case eEncodingA1: 1876 Rd = Bits32(opcode, 15, 12); 1877 setflags = BitIsSet(opcode, 20); 1878 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1879 1880 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1881 if (Rd == 15 && setflags) 1882 return EmulateSUBSPcLrEtc (opcode, encoding); 1883 break; 1884 default: 1885 return false; 1886 } 1887 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1888 1889 EmulateInstruction::Context context; 1890 if (Rd == 13) 1891 { 1892 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1893 // value gets passed down to context.SetImmediateSigned. 1894 context.type = EmulateInstruction::eContextAdjustStackPointer; 1895 context.SetImmediateSigned (-imm64); // the stack pointer offset 1896 } 1897 else 1898 { 1899 context.type = EmulateInstruction::eContextImmediate; 1900 context.SetNoArgs (); 1901 } 1902 1903 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1904 return false; 1905 } 1906 return true; 1907 } 1908 1909 // A store operation to the stack that also updates the SP. 1910 bool 1911 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1912 { 1913 #if 0 1914 // ARM pseudo code... 1915 if (ConditionPassed()) 1916 { 1917 EncodingSpecificOperations(); 1918 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1919 address = if index then offset_addr else R[n]; 1920 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1921 if wback then R[n] = offset_addr; 1922 } 1923 #endif 1924 1925 bool conditional = false; 1926 bool success = false; 1927 if (ConditionPassed(opcode, &conditional)) 1928 { 1929 const uint32_t addr_byte_size = GetAddressByteSize(); 1930 const addr_t sp = ReadCoreReg (SP_REG, &success); 1931 if (!success) 1932 return false; 1933 uint32_t Rt; // the source register 1934 uint32_t imm12; 1935 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1936 1937 bool index; 1938 bool add; 1939 bool wback; 1940 switch (encoding) { 1941 case eEncodingA1: 1942 Rt = Bits32(opcode, 15, 12); 1943 imm12 = Bits32(opcode, 11, 0); 1944 Rn = Bits32 (opcode, 19, 16); 1945 1946 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1947 return false; 1948 1949 index = BitIsSet (opcode, 24); 1950 add = BitIsSet (opcode, 23); 1951 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1952 1953 if (wback && ((Rn == 15) || (Rn == Rt))) 1954 return false; 1955 break; 1956 default: 1957 return false; 1958 } 1959 addr_t offset_addr; 1960 if (add) 1961 offset_addr = sp + imm12; 1962 else 1963 offset_addr = sp - imm12; 1964 1965 addr_t addr; 1966 if (index) 1967 addr = offset_addr; 1968 else 1969 addr = sp; 1970 1971 EmulateInstruction::Context context; 1972 if (conditional) 1973 context.type = EmulateInstruction::eContextRegisterStore; 1974 else 1975 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1976 RegisterInfo sp_reg; 1977 RegisterInfo dwarf_reg; 1978 1979 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1980 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 1981 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 1982 if (Rt != 15) 1983 { 1984 uint32_t reg_value = ReadCoreReg(Rt, &success); 1985 if (!success) 1986 return false; 1987 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1988 return false; 1989 } 1990 else 1991 { 1992 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1993 if (!success) 1994 return false; 1995 if (!MemUWrite (context, addr, pc, addr_byte_size)) 1996 return false; 1997 } 1998 1999 2000 if (wback) 2001 { 2002 context.type = EmulateInstruction::eContextAdjustStackPointer; 2003 context.SetImmediateSigned (addr - sp); 2004 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 2005 return false; 2006 } 2007 } 2008 return true; 2009 } 2010 2011 // Vector Push stores multiple extension registers to the stack. 2012 // It also updates SP to point to the start of the stored data. 2013 bool 2014 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 2015 { 2016 #if 0 2017 // ARM pseudo code... 2018 if (ConditionPassed()) 2019 { 2020 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2021 address = SP - imm32; 2022 SP = SP - imm32; 2023 if single_regs then 2024 for r = 0 to regs-1 2025 MemA[address,4] = S[d+r]; address = address+4; 2026 else 2027 for r = 0 to regs-1 2028 // Store as two word-aligned words in the correct order for current endianness. 2029 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2030 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2031 address = address+8; 2032 } 2033 #endif 2034 2035 bool success = false; 2036 bool conditional = false; 2037 if (ConditionPassed(opcode, &conditional)) 2038 { 2039 const uint32_t addr_byte_size = GetAddressByteSize(); 2040 const addr_t sp = ReadCoreReg (SP_REG, &success); 2041 if (!success) 2042 return false; 2043 bool single_regs; 2044 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2045 uint32_t imm32; // stack offset 2046 uint32_t regs; // number of registers 2047 switch (encoding) { 2048 case eEncodingT1: 2049 case eEncodingA1: 2050 single_regs = false; 2051 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2052 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2053 // If UInt(imm8) is odd, see "FSTMX". 2054 regs = Bits32(opcode, 7, 0) / 2; 2055 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2056 if (regs == 0 || regs > 16 || (d + regs) > 32) 2057 return false; 2058 break; 2059 case eEncodingT2: 2060 case eEncodingA2: 2061 single_regs = true; 2062 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2063 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2064 regs = Bits32(opcode, 7, 0); 2065 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2066 if (regs == 0 || regs > 16 || (d + regs) > 32) 2067 return false; 2068 break; 2069 default: 2070 return false; 2071 } 2072 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2073 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2074 addr_t sp_offset = imm32; 2075 addr_t addr = sp - sp_offset; 2076 uint32_t i; 2077 2078 EmulateInstruction::Context context; 2079 if (conditional) 2080 context.type = EmulateInstruction::eContextRegisterStore; 2081 else 2082 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2083 RegisterInfo dwarf_reg; 2084 RegisterInfo sp_reg; 2085 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2086 for (i=0; i<regs; ++i) 2087 { 2088 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2089 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2090 // uint64_t to accommodate 64-bit registers. 2091 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2092 if (!success) 2093 return false; 2094 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2095 return false; 2096 addr += reg_byte_size; 2097 } 2098 2099 context.type = EmulateInstruction::eContextAdjustStackPointer; 2100 context.SetImmediateSigned (-sp_offset); 2101 2102 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2103 return false; 2104 } 2105 return true; 2106 } 2107 2108 // Vector Pop loads multiple extension registers from the stack. 2109 // It also updates SP to point just above the loaded data. 2110 bool 2111 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2112 { 2113 #if 0 2114 // ARM pseudo code... 2115 if (ConditionPassed()) 2116 { 2117 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2118 address = SP; 2119 SP = SP + imm32; 2120 if single_regs then 2121 for r = 0 to regs-1 2122 S[d+r] = MemA[address,4]; address = address+4; 2123 else 2124 for r = 0 to regs-1 2125 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2126 // Combine the word-aligned words in the correct order for current endianness. 2127 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2128 } 2129 #endif 2130 2131 bool success = false; 2132 bool conditional = false; 2133 if (ConditionPassed(opcode, &conditional)) 2134 { 2135 const uint32_t addr_byte_size = GetAddressByteSize(); 2136 const addr_t sp = ReadCoreReg (SP_REG, &success); 2137 if (!success) 2138 return false; 2139 bool single_regs; 2140 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2141 uint32_t imm32; // stack offset 2142 uint32_t regs; // number of registers 2143 switch (encoding) { 2144 case eEncodingT1: 2145 case eEncodingA1: 2146 single_regs = false; 2147 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2148 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2149 // If UInt(imm8) is odd, see "FLDMX". 2150 regs = Bits32(opcode, 7, 0) / 2; 2151 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2152 if (regs == 0 || regs > 16 || (d + regs) > 32) 2153 return false; 2154 break; 2155 case eEncodingT2: 2156 case eEncodingA2: 2157 single_regs = true; 2158 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2159 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2160 regs = Bits32(opcode, 7, 0); 2161 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2162 if (regs == 0 || regs > 16 || (d + regs) > 32) 2163 return false; 2164 break; 2165 default: 2166 return false; 2167 } 2168 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2169 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2170 addr_t sp_offset = imm32; 2171 addr_t addr = sp; 2172 uint32_t i; 2173 uint64_t data; // uint64_t to accommodate 64-bit registers. 2174 2175 EmulateInstruction::Context context; 2176 if (conditional) 2177 context.type = EmulateInstruction::eContextRegisterLoad; 2178 else 2179 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2180 RegisterInfo dwarf_reg; 2181 RegisterInfo sp_reg; 2182 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2183 for (i=0; i<regs; ++i) 2184 { 2185 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2186 context.SetRegisterPlusOffset (sp_reg, addr - sp); 2187 data = MemARead(context, addr, reg_byte_size, 0, &success); 2188 if (!success) 2189 return false; 2190 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2191 return false; 2192 addr += reg_byte_size; 2193 } 2194 2195 context.type = EmulateInstruction::eContextAdjustStackPointer; 2196 context.SetImmediateSigned (sp_offset); 2197 2198 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2199 return false; 2200 } 2201 return true; 2202 } 2203 2204 // SVC (previously SWI) 2205 bool 2206 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2207 { 2208 #if 0 2209 // ARM pseudo code... 2210 if (ConditionPassed()) 2211 { 2212 EncodingSpecificOperations(); 2213 CallSupervisor(); 2214 } 2215 #endif 2216 2217 bool success = false; 2218 2219 if (ConditionPassed(opcode)) 2220 { 2221 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2222 addr_t lr; // next instruction address 2223 if (!success) 2224 return false; 2225 uint32_t imm32; // the immediate constant 2226 uint32_t mode; // ARM or Thumb mode 2227 switch (encoding) { 2228 case eEncodingT1: 2229 lr = (pc + 2) | 1u; // return address 2230 imm32 = Bits32(opcode, 7, 0); 2231 mode = eModeThumb; 2232 break; 2233 case eEncodingA1: 2234 lr = pc + 4; // return address 2235 imm32 = Bits32(opcode, 23, 0); 2236 mode = eModeARM; 2237 break; 2238 default: 2239 return false; 2240 } 2241 2242 EmulateInstruction::Context context; 2243 context.type = EmulateInstruction::eContextSupervisorCall; 2244 context.SetISAAndImmediate (mode, imm32); 2245 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2246 return false; 2247 } 2248 return true; 2249 } 2250 2251 // If Then makes up to four following instructions (the IT block) conditional. 2252 bool 2253 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2254 { 2255 #if 0 2256 // ARM pseudo code... 2257 EncodingSpecificOperations(); 2258 ITSTATE.IT<7:0> = firstcond:mask; 2259 #endif 2260 2261 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2262 return true; 2263 } 2264 2265 bool 2266 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2267 { 2268 // NOP, nothing to do... 2269 return true; 2270 } 2271 2272 // Branch causes a branch to a target address. 2273 bool 2274 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2275 { 2276 #if 0 2277 // ARM pseudo code... 2278 if (ConditionPassed()) 2279 { 2280 EncodingSpecificOperations(); 2281 BranchWritePC(PC + imm32); 2282 } 2283 #endif 2284 2285 bool success = false; 2286 2287 if (ConditionPassed(opcode)) 2288 { 2289 EmulateInstruction::Context context; 2290 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2291 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2292 if (!success) 2293 return false; 2294 addr_t target; // target address 2295 int32_t imm32; // PC-relative offset 2296 switch (encoding) { 2297 case eEncodingT1: 2298 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2299 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2300 target = pc + imm32; 2301 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2302 break; 2303 case eEncodingT2: 2304 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2305 target = pc + imm32; 2306 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2307 break; 2308 case eEncodingT3: 2309 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2310 { 2311 uint32_t S = Bit32(opcode, 26); 2312 uint32_t imm6 = Bits32(opcode, 21, 16); 2313 uint32_t J1 = Bit32(opcode, 13); 2314 uint32_t J2 = Bit32(opcode, 11); 2315 uint32_t imm11 = Bits32(opcode, 10, 0); 2316 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2317 imm32 = llvm::SignExtend32<21>(imm21); 2318 target = pc + imm32; 2319 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2320 break; 2321 } 2322 case eEncodingT4: 2323 { 2324 uint32_t S = Bit32(opcode, 26); 2325 uint32_t imm10 = Bits32(opcode, 25, 16); 2326 uint32_t J1 = Bit32(opcode, 13); 2327 uint32_t J2 = Bit32(opcode, 11); 2328 uint32_t imm11 = Bits32(opcode, 10, 0); 2329 uint32_t I1 = !(J1 ^ S); 2330 uint32_t I2 = !(J2 ^ S); 2331 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2332 imm32 = llvm::SignExtend32<25>(imm25); 2333 target = pc + imm32; 2334 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2335 break; 2336 } 2337 case eEncodingA1: 2338 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2339 target = pc + imm32; 2340 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2341 break; 2342 default: 2343 return false; 2344 } 2345 if (!BranchWritePC(context, target)) 2346 return false; 2347 } 2348 return true; 2349 } 2350 2351 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2352 // zero and conditionally branch forward a constant value. They do not affect the condition flags. 2353 // CBNZ, CBZ 2354 bool 2355 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2356 { 2357 #if 0 2358 // ARM pseudo code... 2359 EncodingSpecificOperations(); 2360 if nonzero ^ IsZero(R[n]) then 2361 BranchWritePC(PC + imm32); 2362 #endif 2363 2364 bool success = false; 2365 2366 // Read the register value from the operand register Rn. 2367 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2368 if (!success) 2369 return false; 2370 2371 EmulateInstruction::Context context; 2372 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2373 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2374 if (!success) 2375 return false; 2376 2377 addr_t target; // target address 2378 uint32_t imm32; // PC-relative offset to branch forward 2379 bool nonzero; 2380 switch (encoding) { 2381 case eEncodingT1: 2382 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2383 nonzero = BitIsSet(opcode, 11); 2384 target = pc + imm32; 2385 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2386 break; 2387 default: 2388 return false; 2389 } 2390 if (nonzero ^ (reg_val == 0)) 2391 if (!BranchWritePC(context, target)) 2392 return false; 2393 2394 return true; 2395 } 2396 2397 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2398 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2399 // The branch length is twice the value of the byte returned from the table. 2400 // 2401 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2402 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2403 // The branch length is twice the value of the halfword returned from the table. 2404 // TBB, TBH 2405 bool 2406 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2407 { 2408 #if 0 2409 // ARM pseudo code... 2410 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2411 if is_tbh then 2412 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2413 else 2414 halfwords = UInt(MemU[R[n]+R[m], 1]); 2415 BranchWritePC(PC + 2*halfwords); 2416 #endif 2417 2418 bool success = false; 2419 2420 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2421 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2422 bool is_tbh; // true if table branch halfword 2423 switch (encoding) { 2424 case eEncodingT1: 2425 Rn = Bits32(opcode, 19, 16); 2426 Rm = Bits32(opcode, 3, 0); 2427 is_tbh = BitIsSet(opcode, 4); 2428 if (Rn == 13 || BadReg(Rm)) 2429 return false; 2430 if (InITBlock() && !LastInITBlock()) 2431 return false; 2432 break; 2433 default: 2434 return false; 2435 } 2436 2437 // Read the address of the table from the operand register Rn. 2438 // The PC can be used, in which case the table immediately follows this instruction. 2439 uint32_t base = ReadCoreReg(Rm, &success); 2440 if (!success) 2441 return false; 2442 2443 // the table index 2444 uint32_t index = ReadCoreReg(Rm, &success); 2445 if (!success) 2446 return false; 2447 2448 // the offsetted table address 2449 addr_t addr = base + (is_tbh ? index*2 : index); 2450 2451 // PC-relative offset to branch forward 2452 EmulateInstruction::Context context; 2453 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2454 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2455 if (!success) 2456 return false; 2457 2458 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2459 if (!success) 2460 return false; 2461 2462 // target address 2463 addr_t target = pc + offset; 2464 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2465 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2466 2467 if (!BranchWritePC(context, target)) 2468 return false; 2469 2470 return true; 2471 } 2472 2473 // This instruction adds an immediate value to a register value, and writes the result to the destination register. 2474 // It can optionally update the condition flags based on the result. 2475 bool 2476 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2477 { 2478 #if 0 2479 if ConditionPassed() then 2480 EncodingSpecificOperations(); 2481 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2482 R[d] = result; 2483 if setflags then 2484 APSR.N = result<31>; 2485 APSR.Z = IsZeroBit(result); 2486 APSR.C = carry; 2487 APSR.V = overflow; 2488 #endif 2489 2490 bool success = false; 2491 2492 if (ConditionPassed(opcode)) 2493 { 2494 uint32_t d; 2495 uint32_t n; 2496 bool setflags; 2497 uint32_t imm32; 2498 uint32_t carry_out; 2499 2500 //EncodingSpecificOperations(); 2501 switch (encoding) 2502 { 2503 case eEncodingT1: 2504 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2505 d = Bits32 (opcode, 2, 0); 2506 n = Bits32 (opcode, 5, 3); 2507 setflags = !InITBlock(); 2508 imm32 = Bits32 (opcode, 8,6); 2509 2510 break; 2511 2512 case eEncodingT2: 2513 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2514 d = Bits32 (opcode, 10, 8); 2515 n = Bits32 (opcode, 10, 8); 2516 setflags = !InITBlock(); 2517 imm32 = Bits32 (opcode, 7, 0); 2518 2519 break; 2520 2521 case eEncodingT3: 2522 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2523 // if Rn == '1101' then SEE ADD (SP plus immediate); 2524 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2525 d = Bits32 (opcode, 11, 8); 2526 n = Bits32 (opcode, 19, 16); 2527 setflags = BitIsSet (opcode, 20); 2528 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2529 2530 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2531 if (BadReg (d) || (n == 15)) 2532 return false; 2533 2534 break; 2535 2536 case eEncodingT4: 2537 { 2538 // if Rn == '1111' then SEE ADR; 2539 // if Rn == '1101' then SEE ADD (SP plus immediate); 2540 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2541 d = Bits32 (opcode, 11, 8); 2542 n = Bits32 (opcode, 19, 16); 2543 setflags = false; 2544 uint32_t i = Bit32 (opcode, 26); 2545 uint32_t imm3 = Bits32 (opcode, 14, 12); 2546 uint32_t imm8 = Bits32 (opcode, 7, 0); 2547 imm32 = (i << 11) | (imm3 << 8) | imm8; 2548 2549 // if BadReg(d) then UNPREDICTABLE; 2550 if (BadReg (d)) 2551 return false; 2552 2553 break; 2554 } 2555 default: 2556 return false; 2557 } 2558 2559 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2560 if (!success) 2561 return false; 2562 2563 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2564 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2565 2566 RegisterInfo reg_n; 2567 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2568 2569 EmulateInstruction::Context context; 2570 context.type = eContextArithmetic; 2571 context.SetRegisterPlusOffset (reg_n, imm32); 2572 2573 //R[d] = result; 2574 //if setflags then 2575 //APSR.N = result<31>; 2576 //APSR.Z = IsZeroBit(result); 2577 //APSR.C = carry; 2578 //APSR.V = overflow; 2579 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2580 return false; 2581 2582 } 2583 return true; 2584 } 2585 2586 // This instruction adds an immediate value to a register value, and writes the result to the destination 2587 // register. It can optionally update the condition flags based on the result. 2588 bool 2589 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2590 { 2591 #if 0 2592 // ARM pseudo code... 2593 if ConditionPassed() then 2594 EncodingSpecificOperations(); 2595 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2596 if d == 15 then 2597 ALUWritePC(result); // setflags is always FALSE here 2598 else 2599 R[d] = result; 2600 if setflags then 2601 APSR.N = result<31>; 2602 APSR.Z = IsZeroBit(result); 2603 APSR.C = carry; 2604 APSR.V = overflow; 2605 #endif 2606 2607 bool success = false; 2608 2609 if (ConditionPassed(opcode)) 2610 { 2611 uint32_t Rd, Rn; 2612 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2613 bool setflags; 2614 switch (encoding) 2615 { 2616 case eEncodingA1: 2617 Rd = Bits32(opcode, 15, 12); 2618 Rn = Bits32(opcode, 19, 16); 2619 setflags = BitIsSet(opcode, 20); 2620 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2621 break; 2622 default: 2623 return false; 2624 } 2625 2626 // Read the first operand. 2627 uint32_t val1 = ReadCoreReg(Rn, &success); 2628 if (!success) 2629 return false; 2630 2631 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2632 2633 EmulateInstruction::Context context; 2634 context.type = eContextArithmetic; 2635 RegisterInfo dwarf_reg; 2636 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2637 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2638 2639 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2640 return false; 2641 } 2642 return true; 2643 } 2644 2645 // This instruction adds a register value and an optionally-shifted register value, and writes the result 2646 // to the destination register. It can optionally update the condition flags based on the result. 2647 bool 2648 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2649 { 2650 #if 0 2651 // ARM pseudo code... 2652 if ConditionPassed() then 2653 EncodingSpecificOperations(); 2654 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2655 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2656 if d == 15 then 2657 ALUWritePC(result); // setflags is always FALSE here 2658 else 2659 R[d] = result; 2660 if setflags then 2661 APSR.N = result<31>; 2662 APSR.Z = IsZeroBit(result); 2663 APSR.C = carry; 2664 APSR.V = overflow; 2665 #endif 2666 2667 bool success = false; 2668 2669 if (ConditionPassed(opcode)) 2670 { 2671 uint32_t Rd, Rn, Rm; 2672 ARM_ShifterType shift_t; 2673 uint32_t shift_n; // the shift applied to the value read from Rm 2674 bool setflags; 2675 switch (encoding) 2676 { 2677 case eEncodingT1: 2678 Rd = Bits32(opcode, 2, 0); 2679 Rn = Bits32(opcode, 5, 3); 2680 Rm = Bits32(opcode, 8, 6); 2681 setflags = !InITBlock(); 2682 shift_t = SRType_LSL; 2683 shift_n = 0; 2684 break; 2685 case eEncodingT2: 2686 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2687 Rm = Bits32(opcode, 6, 3); 2688 setflags = false; 2689 shift_t = SRType_LSL; 2690 shift_n = 0; 2691 if (Rn == 15 && Rm == 15) 2692 return false; 2693 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2694 return false; 2695 break; 2696 case eEncodingA1: 2697 Rd = Bits32(opcode, 15, 12); 2698 Rn = Bits32(opcode, 19, 16); 2699 Rm = Bits32(opcode, 3, 0); 2700 setflags = BitIsSet(opcode, 20); 2701 shift_n = DecodeImmShiftARM(opcode, shift_t); 2702 break; 2703 default: 2704 return false; 2705 } 2706 2707 // Read the first operand. 2708 uint32_t val1 = ReadCoreReg(Rn, &success); 2709 if (!success) 2710 return false; 2711 2712 // Read the second operand. 2713 uint32_t val2 = ReadCoreReg(Rm, &success); 2714 if (!success) 2715 return false; 2716 2717 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2718 if (!success) 2719 return false; 2720 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2721 2722 EmulateInstruction::Context context; 2723 context.type = eContextArithmetic; 2724 RegisterInfo op1_reg; 2725 RegisterInfo op2_reg; 2726 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2727 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2728 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2729 2730 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2731 return false; 2732 } 2733 return true; 2734 } 2735 2736 // Compare Negative (immediate) adds a register value and an immediate value. 2737 // It updates the condition flags based on the result, and discards the result. 2738 bool 2739 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2740 { 2741 #if 0 2742 // ARM pseudo code... 2743 if ConditionPassed() then 2744 EncodingSpecificOperations(); 2745 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2746 APSR.N = result<31>; 2747 APSR.Z = IsZeroBit(result); 2748 APSR.C = carry; 2749 APSR.V = overflow; 2750 #endif 2751 2752 bool success = false; 2753 2754 uint32_t Rn; // the first operand 2755 uint32_t imm32; // the immediate value to be compared with 2756 switch (encoding) { 2757 case eEncodingT1: 2758 Rn = Bits32(opcode, 19, 16); 2759 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2760 if (Rn == 15) 2761 return false; 2762 break; 2763 case eEncodingA1: 2764 Rn = Bits32(opcode, 19, 16); 2765 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2766 break; 2767 default: 2768 return false; 2769 } 2770 // Read the register value from the operand register Rn. 2771 uint32_t reg_val = ReadCoreReg(Rn, &success); 2772 if (!success) 2773 return false; 2774 2775 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2776 2777 EmulateInstruction::Context context; 2778 context.type = EmulateInstruction::eContextImmediate; 2779 context.SetNoArgs (); 2780 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2781 return false; 2782 2783 return true; 2784 } 2785 2786 // Compare Negative (register) adds a register value and an optionally-shifted register value. 2787 // It updates the condition flags based on the result, and discards the result. 2788 bool 2789 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2790 { 2791 #if 0 2792 // ARM pseudo code... 2793 if ConditionPassed() then 2794 EncodingSpecificOperations(); 2795 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2796 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2797 APSR.N = result<31>; 2798 APSR.Z = IsZeroBit(result); 2799 APSR.C = carry; 2800 APSR.V = overflow; 2801 #endif 2802 2803 bool success = false; 2804 2805 uint32_t Rn; // the first operand 2806 uint32_t Rm; // the second operand 2807 ARM_ShifterType shift_t; 2808 uint32_t shift_n; // the shift applied to the value read from Rm 2809 switch (encoding) { 2810 case eEncodingT1: 2811 Rn = Bits32(opcode, 2, 0); 2812 Rm = Bits32(opcode, 5, 3); 2813 shift_t = SRType_LSL; 2814 shift_n = 0; 2815 break; 2816 case eEncodingT2: 2817 Rn = Bits32(opcode, 19, 16); 2818 Rm = Bits32(opcode, 3, 0); 2819 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2820 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2821 if (Rn == 15 || BadReg(Rm)) 2822 return false; 2823 break; 2824 case eEncodingA1: 2825 Rn = Bits32(opcode, 19, 16); 2826 Rm = Bits32(opcode, 3, 0); 2827 shift_n = DecodeImmShiftARM(opcode, shift_t); 2828 break; 2829 default: 2830 return false; 2831 } 2832 // Read the register value from register Rn. 2833 uint32_t val1 = ReadCoreReg(Rn, &success); 2834 if (!success) 2835 return false; 2836 2837 // Read the register value from register Rm. 2838 uint32_t val2 = ReadCoreReg(Rm, &success); 2839 if (!success) 2840 return false; 2841 2842 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2843 if (!success) 2844 return false; 2845 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2846 2847 EmulateInstruction::Context context; 2848 context.type = EmulateInstruction::eContextImmediate; 2849 context.SetNoArgs(); 2850 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2851 return false; 2852 2853 return true; 2854 } 2855 2856 // Compare (immediate) subtracts an immediate value from a register value. 2857 // It updates the condition flags based on the result, and discards the result. 2858 bool 2859 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2860 { 2861 #if 0 2862 // ARM pseudo code... 2863 if ConditionPassed() then 2864 EncodingSpecificOperations(); 2865 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2866 APSR.N = result<31>; 2867 APSR.Z = IsZeroBit(result); 2868 APSR.C = carry; 2869 APSR.V = overflow; 2870 #endif 2871 2872 bool success = false; 2873 2874 uint32_t Rn; // the first operand 2875 uint32_t imm32; // the immediate value to be compared with 2876 switch (encoding) { 2877 case eEncodingT1: 2878 Rn = Bits32(opcode, 10, 8); 2879 imm32 = Bits32(opcode, 7, 0); 2880 break; 2881 case eEncodingT2: 2882 Rn = Bits32(opcode, 19, 16); 2883 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2884 if (Rn == 15) 2885 return false; 2886 break; 2887 case eEncodingA1: 2888 Rn = Bits32(opcode, 19, 16); 2889 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2890 break; 2891 default: 2892 return false; 2893 } 2894 // Read the register value from the operand register Rn. 2895 uint32_t reg_val = ReadCoreReg(Rn, &success); 2896 if (!success) 2897 return false; 2898 2899 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2900 2901 EmulateInstruction::Context context; 2902 context.type = EmulateInstruction::eContextImmediate; 2903 context.SetNoArgs (); 2904 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2905 return false; 2906 2907 return true; 2908 } 2909 2910 // Compare (register) subtracts an optionally-shifted register value from a register value. 2911 // It updates the condition flags based on the result, and discards the result. 2912 bool 2913 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2914 { 2915 #if 0 2916 // ARM pseudo code... 2917 if ConditionPassed() then 2918 EncodingSpecificOperations(); 2919 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2920 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2921 APSR.N = result<31>; 2922 APSR.Z = IsZeroBit(result); 2923 APSR.C = carry; 2924 APSR.V = overflow; 2925 #endif 2926 2927 bool success = false; 2928 2929 uint32_t Rn; // the first operand 2930 uint32_t Rm; // the second operand 2931 ARM_ShifterType shift_t; 2932 uint32_t shift_n; // the shift applied to the value read from Rm 2933 switch (encoding) { 2934 case eEncodingT1: 2935 Rn = Bits32(opcode, 2, 0); 2936 Rm = Bits32(opcode, 5, 3); 2937 shift_t = SRType_LSL; 2938 shift_n = 0; 2939 break; 2940 case eEncodingT2: 2941 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2942 Rm = Bits32(opcode, 6, 3); 2943 shift_t = SRType_LSL; 2944 shift_n = 0; 2945 if (Rn < 8 && Rm < 8) 2946 return false; 2947 if (Rn == 15 || Rm == 15) 2948 return false; 2949 break; 2950 case eEncodingA1: 2951 Rn = Bits32(opcode, 19, 16); 2952 Rm = Bits32(opcode, 3, 0); 2953 shift_n = DecodeImmShiftARM(opcode, shift_t); 2954 break; 2955 default: 2956 return false; 2957 } 2958 // Read the register value from register Rn. 2959 uint32_t val1 = ReadCoreReg(Rn, &success); 2960 if (!success) 2961 return false; 2962 2963 // Read the register value from register Rm. 2964 uint32_t val2 = ReadCoreReg(Rm, &success); 2965 if (!success) 2966 return false; 2967 2968 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2969 if (!success) 2970 return false; 2971 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 2972 2973 EmulateInstruction::Context context; 2974 context.type = EmulateInstruction::eContextImmediate; 2975 context.SetNoArgs(); 2976 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2977 return false; 2978 2979 return true; 2980 } 2981 2982 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2983 // shifting in copies of its sign bit, and writes the result to the destination register. It can 2984 // optionally update the condition flags based on the result. 2985 bool 2986 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 2987 { 2988 #if 0 2989 // ARM pseudo code... 2990 if ConditionPassed() then 2991 EncodingSpecificOperations(); 2992 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2993 if d == 15 then // Can only occur for ARM encoding 2994 ALUWritePC(result); // setflags is always FALSE here 2995 else 2996 R[d] = result; 2997 if setflags then 2998 APSR.N = result<31>; 2999 APSR.Z = IsZeroBit(result); 3000 APSR.C = carry; 3001 // APSR.V unchanged 3002 #endif 3003 3004 return EmulateShiftImm (opcode, encoding, SRType_ASR); 3005 } 3006 3007 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 3008 // shifting in copies of its sign bit, and writes the result to the destination register. 3009 // The variable number of bits is read from the bottom byte of a register. It can optionally update 3010 // the condition flags based on the result. 3011 bool 3012 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 3013 { 3014 #if 0 3015 // ARM pseudo code... 3016 if ConditionPassed() then 3017 EncodingSpecificOperations(); 3018 shift_n = UInt(R[m]<7:0>); 3019 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3020 R[d] = result; 3021 if setflags then 3022 APSR.N = result<31>; 3023 APSR.Z = IsZeroBit(result); 3024 APSR.C = carry; 3025 // APSR.V unchanged 3026 #endif 3027 3028 return EmulateShiftReg (opcode, encoding, SRType_ASR); 3029 } 3030 3031 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 3032 // shifting in zeros, and writes the result to the destination register. It can optionally 3033 // update the condition flags based on the result. 3034 bool 3035 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 3036 { 3037 #if 0 3038 // ARM pseudo code... 3039 if ConditionPassed() then 3040 EncodingSpecificOperations(); 3041 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3042 if d == 15 then // Can only occur for ARM encoding 3043 ALUWritePC(result); // setflags is always FALSE here 3044 else 3045 R[d] = result; 3046 if setflags then 3047 APSR.N = result<31>; 3048 APSR.Z = IsZeroBit(result); 3049 APSR.C = carry; 3050 // APSR.V unchanged 3051 #endif 3052 3053 return EmulateShiftImm (opcode, encoding, SRType_LSL); 3054 } 3055 3056 // Logical Shift Left (register) shifts a register value left by a variable number of bits, 3057 // shifting in zeros, and writes the result to the destination register. The variable number 3058 // of bits is read from the bottom byte of a register. It can optionally update the condition 3059 // flags based on the result. 3060 bool 3061 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 3062 { 3063 #if 0 3064 // ARM pseudo code... 3065 if ConditionPassed() then 3066 EncodingSpecificOperations(); 3067 shift_n = UInt(R[m]<7:0>); 3068 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3069 R[d] = result; 3070 if setflags then 3071 APSR.N = result<31>; 3072 APSR.Z = IsZeroBit(result); 3073 APSR.C = carry; 3074 // APSR.V unchanged 3075 #endif 3076 3077 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3078 } 3079 3080 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3081 // shifting in zeros, and writes the result to the destination register. It can optionally 3082 // update the condition flags based on the result. 3083 bool 3084 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3085 { 3086 #if 0 3087 // ARM pseudo code... 3088 if ConditionPassed() then 3089 EncodingSpecificOperations(); 3090 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3091 if d == 15 then // Can only occur for ARM encoding 3092 ALUWritePC(result); // setflags is always FALSE here 3093 else 3094 R[d] = result; 3095 if setflags then 3096 APSR.N = result<31>; 3097 APSR.Z = IsZeroBit(result); 3098 APSR.C = carry; 3099 // APSR.V unchanged 3100 #endif 3101 3102 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3103 } 3104 3105 // Logical Shift Right (register) shifts a register value right by a variable number of bits, 3106 // shifting in zeros, and writes the result to the destination register. The variable number 3107 // of bits is read from the bottom byte of a register. It can optionally update the condition 3108 // flags based on the result. 3109 bool 3110 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3111 { 3112 #if 0 3113 // ARM pseudo code... 3114 if ConditionPassed() then 3115 EncodingSpecificOperations(); 3116 shift_n = UInt(R[m]<7:0>); 3117 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3118 R[d] = result; 3119 if setflags then 3120 APSR.N = result<31>; 3121 APSR.Z = IsZeroBit(result); 3122 APSR.C = carry; 3123 // APSR.V unchanged 3124 #endif 3125 3126 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3127 } 3128 3129 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3130 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3131 // It can optionally update the condition flags based on the result. 3132 bool 3133 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3134 { 3135 #if 0 3136 // ARM pseudo code... 3137 if ConditionPassed() then 3138 EncodingSpecificOperations(); 3139 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3140 if d == 15 then // Can only occur for ARM encoding 3141 ALUWritePC(result); // setflags is always FALSE here 3142 else 3143 R[d] = result; 3144 if setflags then 3145 APSR.N = result<31>; 3146 APSR.Z = IsZeroBit(result); 3147 APSR.C = carry; 3148 // APSR.V unchanged 3149 #endif 3150 3151 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3152 } 3153 3154 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3155 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3156 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3157 // flags based on the result. 3158 bool 3159 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3160 { 3161 #if 0 3162 // ARM pseudo code... 3163 if ConditionPassed() then 3164 EncodingSpecificOperations(); 3165 shift_n = UInt(R[m]<7:0>); 3166 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3167 R[d] = result; 3168 if setflags then 3169 APSR.N = result<31>; 3170 APSR.Z = IsZeroBit(result); 3171 APSR.C = carry; 3172 // APSR.V unchanged 3173 #endif 3174 3175 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3176 } 3177 3178 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3179 // with the carry flag shifted into bit [31]. 3180 // 3181 // RRX can optionally update the condition flags based on the result. 3182 // In that case, bit [0] is shifted into the carry flag. 3183 bool 3184 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3185 { 3186 #if 0 3187 // ARM pseudo code... 3188 if ConditionPassed() then 3189 EncodingSpecificOperations(); 3190 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3191 if d == 15 then // Can only occur for ARM encoding 3192 ALUWritePC(result); // setflags is always FALSE here 3193 else 3194 R[d] = result; 3195 if setflags then 3196 APSR.N = result<31>; 3197 APSR.Z = IsZeroBit(result); 3198 APSR.C = carry; 3199 // APSR.V unchanged 3200 #endif 3201 3202 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3203 } 3204 3205 bool 3206 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3207 { 3208 // assert(shift_type == SRType_ASR 3209 // || shift_type == SRType_LSL 3210 // || shift_type == SRType_LSR 3211 // || shift_type == SRType_ROR 3212 // || shift_type == SRType_RRX); 3213 3214 bool success = false; 3215 3216 if (ConditionPassed(opcode)) 3217 { 3218 uint32_t Rd; // the destination register 3219 uint32_t Rm; // the first operand register 3220 uint32_t imm5; // encoding for the shift amount 3221 uint32_t carry; // the carry bit after the shift operation 3222 bool setflags; 3223 3224 // Special case handling! 3225 // A8.6.139 ROR (immediate) -- Encoding T1 3226 ARMEncoding use_encoding = encoding; 3227 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3228 { 3229 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3230 // have the same decoding of bit fields as the other Thumb2 shift operations. 3231 use_encoding = eEncodingT2; 3232 } 3233 3234 switch (use_encoding) { 3235 case eEncodingT1: 3236 // Due to the above special case handling! 3237 if (shift_type == SRType_ROR) 3238 return false; 3239 3240 Rd = Bits32(opcode, 2, 0); 3241 Rm = Bits32(opcode, 5, 3); 3242 setflags = !InITBlock(); 3243 imm5 = Bits32(opcode, 10, 6); 3244 break; 3245 case eEncodingT2: 3246 // A8.6.141 RRX 3247 // There's no imm form of RRX instructions. 3248 if (shift_type == SRType_RRX) 3249 return false; 3250 3251 Rd = Bits32(opcode, 11, 8); 3252 Rm = Bits32(opcode, 3, 0); 3253 setflags = BitIsSet(opcode, 20); 3254 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3255 if (BadReg(Rd) || BadReg(Rm)) 3256 return false; 3257 break; 3258 case eEncodingA1: 3259 Rd = Bits32(opcode, 15, 12); 3260 Rm = Bits32(opcode, 3, 0); 3261 setflags = BitIsSet(opcode, 20); 3262 imm5 = Bits32(opcode, 11, 7); 3263 break; 3264 default: 3265 return false; 3266 } 3267 3268 // A8.6.139 ROR (immediate) 3269 if (shift_type == SRType_ROR && imm5 == 0) 3270 shift_type = SRType_RRX; 3271 3272 // Get the first operand. 3273 uint32_t value = ReadCoreReg (Rm, &success); 3274 if (!success) 3275 return false; 3276 3277 // Decode the shift amount if not RRX. 3278 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3279 3280 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3281 if (!success) 3282 return false; 3283 3284 // The context specifies that an immediate is to be moved into Rd. 3285 EmulateInstruction::Context context; 3286 context.type = EmulateInstruction::eContextImmediate; 3287 context.SetNoArgs (); 3288 3289 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3290 return false; 3291 } 3292 return true; 3293 } 3294 3295 bool 3296 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3297 { 3298 // assert(shift_type == SRType_ASR 3299 // || shift_type == SRType_LSL 3300 // || shift_type == SRType_LSR 3301 // || shift_type == SRType_ROR); 3302 3303 bool success = false; 3304 3305 if (ConditionPassed(opcode)) 3306 { 3307 uint32_t Rd; // the destination register 3308 uint32_t Rn; // the first operand register 3309 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3310 uint32_t carry; // the carry bit after the shift operation 3311 bool setflags; 3312 switch (encoding) { 3313 case eEncodingT1: 3314 Rd = Bits32(opcode, 2, 0); 3315 Rn = Rd; 3316 Rm = Bits32(opcode, 5, 3); 3317 setflags = !InITBlock(); 3318 break; 3319 case eEncodingT2: 3320 Rd = Bits32(opcode, 11, 8); 3321 Rn = Bits32(opcode, 19, 16); 3322 Rm = Bits32(opcode, 3, 0); 3323 setflags = BitIsSet(opcode, 20); 3324 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3325 return false; 3326 break; 3327 case eEncodingA1: 3328 Rd = Bits32(opcode, 15, 12); 3329 Rn = Bits32(opcode, 3, 0); 3330 Rm = Bits32(opcode, 11, 8); 3331 setflags = BitIsSet(opcode, 20); 3332 if (Rd == 15 || Rn == 15 || Rm == 15) 3333 return false; 3334 break; 3335 default: 3336 return false; 3337 } 3338 3339 // Get the first operand. 3340 uint32_t value = ReadCoreReg (Rn, &success); 3341 if (!success) 3342 return false; 3343 // Get the Rm register content. 3344 uint32_t val = ReadCoreReg (Rm, &success); 3345 if (!success) 3346 return false; 3347 3348 // Get the shift amount. 3349 uint32_t amt = Bits32(val, 7, 0); 3350 3351 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3352 if (!success) 3353 return false; 3354 3355 // The context specifies that an immediate is to be moved into Rd. 3356 EmulateInstruction::Context context; 3357 context.type = EmulateInstruction::eContextImmediate; 3358 context.SetNoArgs (); 3359 3360 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3361 return false; 3362 } 3363 return true; 3364 } 3365 3366 // LDM loads multiple registers from consecutive memory locations, using an 3367 // address from a base register. Optionally the address just above the highest of those locations 3368 // can be written back to the base register. 3369 bool 3370 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3371 { 3372 #if 0 3373 // ARM pseudo code... 3374 if ConditionPassed() 3375 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3376 address = R[n]; 3377 3378 for i = 0 to 14 3379 if registers<i> == '1' then 3380 R[i] = MemA[address, 4]; address = address + 4; 3381 if registers<15> == '1' then 3382 LoadWritePC (MemA[address, 4]); 3383 3384 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3385 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3386 3387 #endif 3388 3389 bool success = false; 3390 bool conditional = false; 3391 if (ConditionPassed(opcode, &conditional)) 3392 { 3393 uint32_t n; 3394 uint32_t registers = 0; 3395 bool wback; 3396 const uint32_t addr_byte_size = GetAddressByteSize(); 3397 switch (encoding) 3398 { 3399 case eEncodingT1: 3400 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3401 n = Bits32 (opcode, 10, 8); 3402 registers = Bits32 (opcode, 7, 0); 3403 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3404 wback = BitIsClear (registers, n); 3405 // if BitCount(registers) < 1 then UNPREDICTABLE; 3406 if (BitCount(registers) < 1) 3407 return false; 3408 break; 3409 case eEncodingT2: 3410 // if W == '1' && Rn == '1101' then SEE POP; 3411 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3412 n = Bits32 (opcode, 19, 16); 3413 registers = Bits32 (opcode, 15, 0); 3414 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3415 wback = BitIsSet (opcode, 21); 3416 3417 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3418 if ((n == 15) 3419 || (BitCount (registers) < 2) 3420 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3421 return false; 3422 3423 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3424 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3425 return false; 3426 3427 // if wback && registers<n> == '1' then UNPREDICTABLE; 3428 if (wback 3429 && BitIsSet (registers, n)) 3430 return false; 3431 break; 3432 3433 case eEncodingA1: 3434 n = Bits32 (opcode, 19, 16); 3435 registers = Bits32 (opcode, 15, 0); 3436 wback = BitIsSet (opcode, 21); 3437 if ((n == 15) 3438 || (BitCount (registers) < 1)) 3439 return false; 3440 break; 3441 default: 3442 return false; 3443 } 3444 3445 int32_t offset = 0; 3446 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3447 if (!success) 3448 return false; 3449 3450 EmulateInstruction::Context context; 3451 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3452 RegisterInfo dwarf_reg; 3453 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3454 context.SetRegisterPlusOffset (dwarf_reg, offset); 3455 3456 for (int i = 0; i < 14; ++i) 3457 { 3458 if (BitIsSet (registers, i)) 3459 { 3460 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3461 context.SetRegisterPlusOffset (dwarf_reg, offset); 3462 if (wback && (n == 13)) // Pop Instruction 3463 { 3464 if (conditional) 3465 context.type = EmulateInstruction::eContextRegisterLoad; 3466 else 3467 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3468 } 3469 3470 // R[i] = MemA [address, 4]; address = address + 4; 3471 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3472 if (!success) 3473 return false; 3474 3475 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3476 return false; 3477 3478 offset += addr_byte_size; 3479 } 3480 } 3481 3482 if (BitIsSet (registers, 15)) 3483 { 3484 //LoadWritePC (MemA [address, 4]); 3485 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3486 context.SetRegisterPlusOffset (dwarf_reg, offset); 3487 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3488 if (!success) 3489 return false; 3490 // In ARMv5T and above, this is an interworking branch. 3491 if (!LoadWritePC(context, data)) 3492 return false; 3493 } 3494 3495 if (wback && BitIsClear (registers, n)) 3496 { 3497 // R[n] = R[n] + 4 * BitCount (registers) 3498 int32_t offset = addr_byte_size * BitCount (registers); 3499 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3500 context.SetRegisterPlusOffset (dwarf_reg, offset); 3501 3502 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3503 return false; 3504 } 3505 if (wback && BitIsSet (registers, n)) 3506 // R[n] bits(32) UNKNOWN; 3507 return WriteBits32Unknown (n); 3508 } 3509 return true; 3510 } 3511 3512 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3513 // The consecutive memory locations end at this address and the address just below the lowest of those locations 3514 // can optionally be written back to the base register. 3515 bool 3516 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3517 { 3518 #if 0 3519 // ARM pseudo code... 3520 if ConditionPassed() then 3521 EncodingSpecificOperations(); 3522 address = R[n] - 4*BitCount(registers) + 4; 3523 3524 for i = 0 to 14 3525 if registers<i> == '1' then 3526 R[i] = MemA[address,4]; address = address + 4; 3527 3528 if registers<15> == '1' then 3529 LoadWritePC(MemA[address,4]); 3530 3531 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3532 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3533 #endif 3534 3535 bool success = false; 3536 3537 if (ConditionPassed(opcode)) 3538 { 3539 uint32_t n; 3540 uint32_t registers = 0; 3541 bool wback; 3542 const uint32_t addr_byte_size = GetAddressByteSize(); 3543 3544 // EncodingSpecificOperations(); 3545 switch (encoding) 3546 { 3547 case eEncodingA1: 3548 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3549 n = Bits32 (opcode, 19, 16); 3550 registers = Bits32 (opcode, 15, 0); 3551 wback = BitIsSet (opcode, 21); 3552 3553 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3554 if ((n == 15) || (BitCount (registers) < 1)) 3555 return false; 3556 3557 break; 3558 3559 default: 3560 return false; 3561 } 3562 // address = R[n] - 4*BitCount(registers) + 4; 3563 3564 int32_t offset = 0; 3565 addr_t Rn = ReadCoreReg (n, &success); 3566 3567 if (!success) 3568 return false; 3569 3570 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3571 3572 EmulateInstruction::Context context; 3573 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3574 RegisterInfo dwarf_reg; 3575 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3576 context.SetRegisterPlusOffset (dwarf_reg, offset); 3577 3578 // for i = 0 to 14 3579 for (int i = 0; i < 14; ++i) 3580 { 3581 // if registers<i> == '1' then 3582 if (BitIsSet (registers, i)) 3583 { 3584 // R[i] = MemA[address,4]; address = address + 4; 3585 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3586 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3587 if (!success) 3588 return false; 3589 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3590 return false; 3591 offset += addr_byte_size; 3592 } 3593 } 3594 3595 // if registers<15> == '1' then 3596 // LoadWritePC(MemA[address,4]); 3597 if (BitIsSet (registers, 15)) 3598 { 3599 context.SetRegisterPlusOffset (dwarf_reg, offset); 3600 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3601 if (!success) 3602 return false; 3603 // In ARMv5T and above, this is an interworking branch. 3604 if (!LoadWritePC(context, data)) 3605 return false; 3606 } 3607 3608 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3609 if (wback && BitIsClear (registers, n)) 3610 { 3611 if (!success) 3612 return false; 3613 3614 offset = (addr_byte_size * BitCount (registers)) * -1; 3615 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3616 context.SetImmediateSigned (offset); 3617 addr_t addr = Rn + offset; 3618 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3619 return false; 3620 } 3621 3622 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3623 if (wback && BitIsSet (registers, n)) 3624 return WriteBits32Unknown (n); 3625 } 3626 return true; 3627 } 3628 3629 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3630 // consecutive memory locations end just below this address, and the address of the lowest of those locations can 3631 // be optionally written back to the base register. 3632 bool 3633 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3634 { 3635 #if 0 3636 // ARM pseudo code... 3637 if ConditionPassed() then 3638 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3639 address = R[n] - 4*BitCount(registers); 3640 3641 for i = 0 to 14 3642 if registers<i> == '1' then 3643 R[i] = MemA[address,4]; address = address + 4; 3644 if registers<15> == '1' then 3645 LoadWritePC(MemA[address,4]); 3646 3647 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3648 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3649 #endif 3650 3651 bool success = false; 3652 3653 if (ConditionPassed(opcode)) 3654 { 3655 uint32_t n; 3656 uint32_t registers = 0; 3657 bool wback; 3658 const uint32_t addr_byte_size = GetAddressByteSize(); 3659 switch (encoding) 3660 { 3661 case eEncodingT1: 3662 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3663 n = Bits32 (opcode, 19, 16); 3664 registers = Bits32 (opcode, 15, 0); 3665 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3666 wback = BitIsSet (opcode, 21); 3667 3668 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3669 if ((n == 15) 3670 || (BitCount (registers) < 2) 3671 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3672 return false; 3673 3674 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3675 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3676 return false; 3677 3678 // if wback && registers<n> == '1' then UNPREDICTABLE; 3679 if (wback && BitIsSet (registers, n)) 3680 return false; 3681 3682 break; 3683 3684 case eEncodingA1: 3685 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3686 n = Bits32 (opcode, 19, 16); 3687 registers = Bits32 (opcode, 15, 0); 3688 wback = BitIsSet (opcode, 21); 3689 3690 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3691 if ((n == 15) || (BitCount (registers) < 1)) 3692 return false; 3693 3694 break; 3695 3696 default: 3697 return false; 3698 } 3699 3700 // address = R[n] - 4*BitCount(registers); 3701 3702 int32_t offset = 0; 3703 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3704 3705 if (!success) 3706 return false; 3707 3708 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3709 EmulateInstruction::Context context; 3710 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3711 RegisterInfo dwarf_reg; 3712 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3713 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3714 3715 for (int i = 0; i < 14; ++i) 3716 { 3717 if (BitIsSet (registers, i)) 3718 { 3719 // R[i] = MemA[address,4]; address = address + 4; 3720 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3721 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3722 if (!success) 3723 return false; 3724 3725 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3726 return false; 3727 3728 offset += addr_byte_size; 3729 } 3730 } 3731 3732 // if registers<15> == '1' then 3733 // LoadWritePC(MemA[address,4]); 3734 if (BitIsSet (registers, 15)) 3735 { 3736 context.SetRegisterPlusOffset (dwarf_reg, offset); 3737 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3738 if (!success) 3739 return false; 3740 // In ARMv5T and above, this is an interworking branch. 3741 if (!LoadWritePC(context, data)) 3742 return false; 3743 } 3744 3745 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3746 if (wback && BitIsClear (registers, n)) 3747 { 3748 if (!success) 3749 return false; 3750 3751 offset = (addr_byte_size * BitCount (registers)) * -1; 3752 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3753 context.SetImmediateSigned (offset); 3754 addr_t addr = Rn + offset; 3755 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3756 return false; 3757 } 3758 3759 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3760 if (wback && BitIsSet (registers, n)) 3761 return WriteBits32Unknown (n); 3762 } 3763 return true; 3764 } 3765 3766 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3767 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3768 // optinoally be written back to the base register. 3769 bool 3770 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3771 { 3772 #if 0 3773 if ConditionPassed() then 3774 EncodingSpecificOperations(); 3775 address = R[n] + 4; 3776 3777 for i = 0 to 14 3778 if registers<i> == '1' then 3779 R[i] = MemA[address,4]; address = address + 4; 3780 if registers<15> == '1' then 3781 LoadWritePC(MemA[address,4]); 3782 3783 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3784 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3785 #endif 3786 3787 bool success = false; 3788 3789 if (ConditionPassed(opcode)) 3790 { 3791 uint32_t n; 3792 uint32_t registers = 0; 3793 bool wback; 3794 const uint32_t addr_byte_size = GetAddressByteSize(); 3795 switch (encoding) 3796 { 3797 case eEncodingA1: 3798 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3799 n = Bits32 (opcode, 19, 16); 3800 registers = Bits32 (opcode, 15, 0); 3801 wback = BitIsSet (opcode, 21); 3802 3803 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3804 if ((n == 15) || (BitCount (registers) < 1)) 3805 return false; 3806 3807 break; 3808 default: 3809 return false; 3810 } 3811 // address = R[n] + 4; 3812 3813 int32_t offset = 0; 3814 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3815 3816 if (!success) 3817 return false; 3818 3819 addr_t address = Rn + addr_byte_size; 3820 3821 EmulateInstruction::Context context; 3822 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3823 RegisterInfo dwarf_reg; 3824 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3825 context.SetRegisterPlusOffset (dwarf_reg, offset); 3826 3827 for (int i = 0; i < 14; ++i) 3828 { 3829 if (BitIsSet (registers, i)) 3830 { 3831 // R[i] = MemA[address,4]; address = address + 4; 3832 3833 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3834 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3835 if (!success) 3836 return false; 3837 3838 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3839 return false; 3840 3841 offset += addr_byte_size; 3842 } 3843 } 3844 3845 // if registers<15> == '1' then 3846 // LoadWritePC(MemA[address,4]); 3847 if (BitIsSet (registers, 15)) 3848 { 3849 context.SetRegisterPlusOffset (dwarf_reg, offset); 3850 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3851 if (!success) 3852 return false; 3853 // In ARMv5T and above, this is an interworking branch. 3854 if (!LoadWritePC(context, data)) 3855 return false; 3856 } 3857 3858 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3859 if (wback && BitIsClear (registers, n)) 3860 { 3861 if (!success) 3862 return false; 3863 3864 offset = addr_byte_size * BitCount (registers); 3865 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3866 context.SetImmediateSigned (offset); 3867 addr_t addr = Rn + offset; 3868 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3869 return false; 3870 } 3871 3872 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3873 if (wback && BitIsSet (registers, n)) 3874 return WriteBits32Unknown (n); 3875 } 3876 return true; 3877 } 3878 3879 // Load Register (immediate) calculates an address from a base register value and 3880 // an immediate offset, loads a word from memory, and writes to a register. 3881 // LDR (immediate, Thumb) 3882 bool 3883 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3884 { 3885 #if 0 3886 // ARM pseudo code... 3887 if (ConditionPassed()) 3888 { 3889 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3890 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3891 address = if index then offset_addr else R[n]; 3892 data = MemU[address,4]; 3893 if wback then R[n] = offset_addr; 3894 if t == 15 then 3895 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3896 elsif UnalignedSupport() || address<1:0> = '00' then 3897 R[t] = data; 3898 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3899 } 3900 #endif 3901 3902 bool success = false; 3903 3904 if (ConditionPassed(opcode)) 3905 { 3906 uint32_t Rt; // the destination register 3907 uint32_t Rn; // the base register 3908 uint32_t imm32; // the immediate offset used to form the address 3909 addr_t offset_addr; // the offset address 3910 addr_t address; // the calculated address 3911 uint32_t data; // the literal data value from memory load 3912 bool add, index, wback; 3913 switch (encoding) { 3914 case eEncodingT1: 3915 Rt = Bits32(opcode, 2, 0); 3916 Rn = Bits32(opcode, 5, 3); 3917 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3918 // index = TRUE; add = TRUE; wback = FALSE 3919 add = true; 3920 index = true; 3921 wback = false; 3922 3923 break; 3924 3925 case eEncodingT2: 3926 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3927 Rt = Bits32 (opcode, 10, 8); 3928 Rn = 13; 3929 imm32 = Bits32 (opcode, 7, 0) << 2; 3930 3931 // index = TRUE; add = TRUE; wback = FALSE; 3932 index = true; 3933 add = true; 3934 wback = false; 3935 3936 break; 3937 3938 case eEncodingT3: 3939 // if Rn == '1111' then SEE LDR (literal); 3940 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3941 Rt = Bits32 (opcode, 15, 12); 3942 Rn = Bits32 (opcode, 19, 16); 3943 imm32 = Bits32 (opcode, 11, 0); 3944 3945 // index = TRUE; add = TRUE; wback = FALSE; 3946 index = true; 3947 add = true; 3948 wback = false; 3949 3950 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3951 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3952 return false; 3953 3954 break; 3955 3956 case eEncodingT4: 3957 // if Rn == '1111' then SEE LDR (literal); 3958 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3959 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3960 // if P == '0' && W == '0' then UNDEFINED; 3961 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3962 return false; 3963 3964 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3965 Rt = Bits32 (opcode, 15, 12); 3966 Rn = Bits32 (opcode, 19, 16); 3967 imm32 = Bits32 (opcode, 7, 0); 3968 3969 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3970 index = BitIsSet (opcode, 10); 3971 add = BitIsSet (opcode, 9); 3972 wback = BitIsSet (opcode, 8); 3973 3974 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3975 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3976 return false; 3977 3978 break; 3979 3980 default: 3981 return false; 3982 } 3983 uint32_t base = ReadCoreReg (Rn, &success); 3984 if (!success) 3985 return false; 3986 if (add) 3987 offset_addr = base + imm32; 3988 else 3989 offset_addr = base - imm32; 3990 3991 address = (index ? offset_addr : base); 3992 3993 RegisterInfo base_reg; 3994 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 3995 if (wback) 3996 { 3997 EmulateInstruction::Context ctx; 3998 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 3999 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4000 4001 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 4002 return false; 4003 } 4004 4005 // Prepare to write to the Rt register. 4006 EmulateInstruction::Context context; 4007 context.type = EmulateInstruction::eContextRegisterLoad; 4008 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4009 4010 // Read memory from the address. 4011 data = MemURead(context, address, 4, 0, &success); 4012 if (!success) 4013 return false; 4014 4015 if (Rt == 15) 4016 { 4017 if (Bits32(address, 1, 0) == 0) 4018 { 4019 if (!LoadWritePC(context, data)) 4020 return false; 4021 } 4022 else 4023 return false; 4024 } 4025 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 4026 { 4027 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 4028 return false; 4029 } 4030 else 4031 WriteBits32Unknown (Rt); 4032 } 4033 return true; 4034 } 4035 4036 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 4037 // from a base register. The consecutive memory locations start at this address, and the address just above the last 4038 // of those locations can optionally be written back to the base register. 4039 bool 4040 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 4041 { 4042 #if 0 4043 if ConditionPassed() then 4044 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4045 address = R[n]; 4046 4047 for i = 0 to 14 4048 if registers<i> == '1' then 4049 if i == n && wback && i != LowestSetBit(registers) then 4050 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4051 else 4052 MemA[address,4] = R[i]; 4053 address = address + 4; 4054 4055 if registers<15> == '1' then // Only possible for encoding A1 4056 MemA[address,4] = PCStoreValue(); 4057 if wback then R[n] = R[n] + 4*BitCount(registers); 4058 #endif 4059 4060 bool success = false; 4061 4062 if (ConditionPassed(opcode)) 4063 { 4064 uint32_t n; 4065 uint32_t registers = 0; 4066 bool wback; 4067 const uint32_t addr_byte_size = GetAddressByteSize(); 4068 4069 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4070 switch (encoding) 4071 { 4072 case eEncodingT1: 4073 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4074 n = Bits32 (opcode, 10, 8); 4075 registers = Bits32 (opcode, 7, 0); 4076 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4077 wback = true; 4078 4079 // if BitCount(registers) < 1 then UNPREDICTABLE; 4080 if (BitCount (registers) < 1) 4081 return false; 4082 4083 break; 4084 4085 case eEncodingT2: 4086 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4087 n = Bits32 (opcode, 19, 16); 4088 registers = Bits32 (opcode, 15, 0); 4089 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4090 wback = BitIsSet (opcode, 21); 4091 4092 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4093 if ((n == 15) || (BitCount (registers) < 2)) 4094 return false; 4095 4096 // if wback && registers<n> == '1' then UNPREDICTABLE; 4097 if (wback && BitIsSet (registers, n)) 4098 return false; 4099 4100 break; 4101 4102 case eEncodingA1: 4103 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4104 n = Bits32 (opcode, 19, 16); 4105 registers = Bits32 (opcode, 15, 0); 4106 wback = BitIsSet (opcode, 21); 4107 4108 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4109 if ((n == 15) || (BitCount (registers) < 1)) 4110 return false; 4111 4112 break; 4113 4114 default: 4115 return false; 4116 } 4117 4118 // address = R[n]; 4119 int32_t offset = 0; 4120 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4121 if (!success) 4122 return false; 4123 4124 EmulateInstruction::Context context; 4125 context.type = EmulateInstruction::eContextRegisterStore; 4126 RegisterInfo base_reg; 4127 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4128 4129 // for i = 0 to 14 4130 uint32_t lowest_set_bit = 14; 4131 for (uint32_t i = 0; i < 14; ++i) 4132 { 4133 // if registers<i> == '1' then 4134 if (BitIsSet (registers, i)) 4135 { 4136 if (i < lowest_set_bit) 4137 lowest_set_bit = i; 4138 // if i == n && wback && i != LowestSetBit(registers) then 4139 if ((i == n) && wback && (i != lowest_set_bit)) 4140 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4141 WriteBits32UnknownToMemory (address + offset); 4142 else 4143 { 4144 // MemA[address,4] = R[i]; 4145 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4146 if (!success) 4147 return false; 4148 4149 RegisterInfo data_reg; 4150 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4151 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4152 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4153 return false; 4154 } 4155 4156 // address = address + 4; 4157 offset += addr_byte_size; 4158 } 4159 } 4160 4161 // if registers<15> == '1' then // Only possible for encoding A1 4162 // MemA[address,4] = PCStoreValue(); 4163 if (BitIsSet (registers, 15)) 4164 { 4165 RegisterInfo pc_reg; 4166 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4167 context.SetRegisterPlusOffset (pc_reg, 8); 4168 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4169 if (!success) 4170 return false; 4171 4172 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4173 return false; 4174 } 4175 4176 // if wback then R[n] = R[n] + 4*BitCount(registers); 4177 if (wback) 4178 { 4179 offset = addr_byte_size * BitCount (registers); 4180 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4181 context.SetImmediateSigned (offset); 4182 addr_t data = address + offset; 4183 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4184 return false; 4185 } 4186 } 4187 return true; 4188 } 4189 4190 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4191 // from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4192 // of those locations can optionally be written back to the base register. 4193 bool 4194 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4195 { 4196 #if 0 4197 if ConditionPassed() then 4198 EncodingSpecificOperations(); 4199 address = R[n] - 4*BitCount(registers) + 4; 4200 4201 for i = 0 to 14 4202 if registers<i> == '1' then 4203 if i == n && wback && i != LowestSetBit(registers) then 4204 MemA[address,4] = bits(32) UNKNOWN; 4205 else 4206 MemA[address,4] = R[i]; 4207 address = address + 4; 4208 4209 if registers<15> == '1' then 4210 MemA[address,4] = PCStoreValue(); 4211 4212 if wback then R[n] = R[n] - 4*BitCount(registers); 4213 #endif 4214 4215 bool success = false; 4216 4217 if (ConditionPassed(opcode)) 4218 { 4219 uint32_t n; 4220 uint32_t registers = 0; 4221 bool wback; 4222 const uint32_t addr_byte_size = GetAddressByteSize(); 4223 4224 // EncodingSpecificOperations(); 4225 switch (encoding) 4226 { 4227 case eEncodingA1: 4228 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4229 n = Bits32 (opcode, 19, 16); 4230 registers = Bits32 (opcode, 15, 0); 4231 wback = BitIsSet (opcode, 21); 4232 4233 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4234 if ((n == 15) || (BitCount (registers) < 1)) 4235 return false; 4236 break; 4237 default: 4238 return false; 4239 } 4240 4241 // address = R[n] - 4*BitCount(registers) + 4; 4242 int32_t offset = 0; 4243 addr_t Rn = ReadCoreReg (n, &success); 4244 if (!success) 4245 return false; 4246 4247 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4248 4249 EmulateInstruction::Context context; 4250 context.type = EmulateInstruction::eContextRegisterStore; 4251 RegisterInfo base_reg; 4252 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4253 4254 // for i = 0 to 14 4255 uint32_t lowest_bit_set = 14; 4256 for (uint32_t i = 0; i < 14; ++i) 4257 { 4258 // if registers<i> == '1' then 4259 if (BitIsSet (registers, i)) 4260 { 4261 if (i < lowest_bit_set) 4262 lowest_bit_set = i; 4263 //if i == n && wback && i != LowestSetBit(registers) then 4264 if ((i == n) && wback && (i != lowest_bit_set)) 4265 // MemA[address,4] = bits(32) UNKNOWN; 4266 WriteBits32UnknownToMemory (address + offset); 4267 else 4268 { 4269 // MemA[address,4] = R[i]; 4270 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4271 if (!success) 4272 return false; 4273 4274 RegisterInfo data_reg; 4275 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4276 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4277 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4278 return false; 4279 } 4280 4281 // address = address + 4; 4282 offset += addr_byte_size; 4283 } 4284 } 4285 4286 // if registers<15> == '1' then 4287 // MemA[address,4] = PCStoreValue(); 4288 if (BitIsSet (registers, 15)) 4289 { 4290 RegisterInfo pc_reg; 4291 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4292 context.SetRegisterPlusOffset (pc_reg, 8); 4293 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4294 if (!success) 4295 return false; 4296 4297 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4298 return false; 4299 } 4300 4301 // if wback then R[n] = R[n] - 4*BitCount(registers); 4302 if (wback) 4303 { 4304 offset = (addr_byte_size * BitCount (registers)) * -1; 4305 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4306 context.SetImmediateSigned (offset); 4307 addr_t data = Rn + offset; 4308 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4309 return false; 4310 } 4311 } 4312 return true; 4313 } 4314 4315 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4316 // from a base register. The consecutive memory locations end just below this address, and the address of the first of 4317 // those locations can optionally be written back to the base register. 4318 bool 4319 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4320 { 4321 #if 0 4322 if ConditionPassed() then 4323 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4324 address = R[n] - 4*BitCount(registers); 4325 4326 for i = 0 to 14 4327 if registers<i> == '1' then 4328 if i == n && wback && i != LowestSetBit(registers) then 4329 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4330 else 4331 MemA[address,4] = R[i]; 4332 address = address + 4; 4333 4334 if registers<15> == '1' then // Only possible for encoding A1 4335 MemA[address,4] = PCStoreValue(); 4336 4337 if wback then R[n] = R[n] - 4*BitCount(registers); 4338 #endif 4339 4340 4341 bool success = false; 4342 4343 if (ConditionPassed(opcode)) 4344 { 4345 uint32_t n; 4346 uint32_t registers = 0; 4347 bool wback; 4348 const uint32_t addr_byte_size = GetAddressByteSize(); 4349 4350 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4351 switch (encoding) 4352 { 4353 case eEncodingT1: 4354 // if W == '1' && Rn == '1101' then SEE PUSH; 4355 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4356 { 4357 // See PUSH 4358 } 4359 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4360 n = Bits32 (opcode, 19, 16); 4361 registers = Bits32 (opcode, 15, 0); 4362 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4363 wback = BitIsSet (opcode, 21); 4364 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4365 if ((n == 15) || BitCount (registers) < 2) 4366 return false; 4367 // if wback && registers<n> == '1' then UNPREDICTABLE; 4368 if (wback && BitIsSet (registers, n)) 4369 return false; 4370 break; 4371 4372 case eEncodingA1: 4373 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH; 4374 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4375 { 4376 // See Push 4377 } 4378 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4379 n = Bits32 (opcode, 19, 16); 4380 registers = Bits32 (opcode, 15, 0); 4381 wback = BitIsSet (opcode, 21); 4382 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4383 if ((n == 15) || BitCount (registers) < 1) 4384 return false; 4385 break; 4386 4387 default: 4388 return false; 4389 } 4390 4391 // address = R[n] - 4*BitCount(registers); 4392 4393 int32_t offset = 0; 4394 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4395 if (!success) 4396 return false; 4397 4398 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4399 4400 EmulateInstruction::Context context; 4401 context.type = EmulateInstruction::eContextRegisterStore; 4402 RegisterInfo base_reg; 4403 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4404 4405 // for i = 0 to 14 4406 uint32_t lowest_set_bit = 14; 4407 for (uint32_t i = 0; i < 14; ++i) 4408 { 4409 // if registers<i> == '1' then 4410 if (BitIsSet (registers, i)) 4411 { 4412 if (i < lowest_set_bit) 4413 lowest_set_bit = i; 4414 // if i == n && wback && i != LowestSetBit(registers) then 4415 if ((i == n) && wback && (i != lowest_set_bit)) 4416 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4417 WriteBits32UnknownToMemory (address + offset); 4418 else 4419 { 4420 // MemA[address,4] = R[i]; 4421 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4422 if (!success) 4423 return false; 4424 4425 RegisterInfo data_reg; 4426 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4427 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4428 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4429 return false; 4430 } 4431 4432 // address = address + 4; 4433 offset += addr_byte_size; 4434 } 4435 } 4436 4437 // if registers<15> == '1' then // Only possible for encoding A1 4438 // MemA[address,4] = PCStoreValue(); 4439 if (BitIsSet (registers, 15)) 4440 { 4441 RegisterInfo pc_reg; 4442 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4443 context.SetRegisterPlusOffset (pc_reg, 8); 4444 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4445 if (!success) 4446 return false; 4447 4448 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4449 return false; 4450 } 4451 4452 // if wback then R[n] = R[n] - 4*BitCount(registers); 4453 if (wback) 4454 { 4455 offset = (addr_byte_size * BitCount (registers)) * -1; 4456 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4457 context.SetImmediateSigned (offset); 4458 addr_t data = Rn + offset; 4459 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4460 return false; 4461 } 4462 } 4463 return true; 4464 } 4465 4466 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4467 // from a base register. The consecutive memory locations start just above this address, and the address of the last 4468 // of those locations can optionally be written back to the base register. 4469 bool 4470 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4471 { 4472 #if 0 4473 if ConditionPassed() then 4474 EncodingSpecificOperations(); 4475 address = R[n] + 4; 4476 4477 for i = 0 to 14 4478 if registers<i> == '1' then 4479 if i == n && wback && i != LowestSetBit(registers) then 4480 MemA[address,4] = bits(32) UNKNOWN; 4481 else 4482 MemA[address,4] = R[i]; 4483 address = address + 4; 4484 4485 if registers<15> == '1' then 4486 MemA[address,4] = PCStoreValue(); 4487 4488 if wback then R[n] = R[n] + 4*BitCount(registers); 4489 #endif 4490 4491 bool success = false; 4492 4493 if (ConditionPassed(opcode)) 4494 { 4495 uint32_t n; 4496 uint32_t registers = 0; 4497 bool wback; 4498 const uint32_t addr_byte_size = GetAddressByteSize(); 4499 4500 // EncodingSpecificOperations(); 4501 switch (encoding) 4502 { 4503 case eEncodingA1: 4504 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4505 n = Bits32 (opcode, 19, 16); 4506 registers = Bits32 (opcode, 15, 0); 4507 wback = BitIsSet (opcode, 21); 4508 4509 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4510 if ((n == 15) && (BitCount (registers) < 1)) 4511 return false; 4512 break; 4513 default: 4514 return false; 4515 } 4516 // address = R[n] + 4; 4517 4518 int32_t offset = 0; 4519 addr_t Rn = ReadCoreReg (n, &success); 4520 if (!success) 4521 return false; 4522 4523 addr_t address = Rn + addr_byte_size; 4524 4525 EmulateInstruction::Context context; 4526 context.type = EmulateInstruction::eContextRegisterStore; 4527 RegisterInfo base_reg; 4528 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4529 4530 uint32_t lowest_set_bit = 14; 4531 // for i = 0 to 14 4532 for (uint32_t i = 0; i < 14; ++i) 4533 { 4534 // if registers<i> == '1' then 4535 if (BitIsSet (registers, i)) 4536 { 4537 if (i < lowest_set_bit) 4538 lowest_set_bit = i; 4539 // if i == n && wback && i != LowestSetBit(registers) then 4540 if ((i == n) && wback && (i != lowest_set_bit)) 4541 // MemA[address,4] = bits(32) UNKNOWN; 4542 WriteBits32UnknownToMemory (address + offset); 4543 // else 4544 else 4545 { 4546 // MemA[address,4] = R[i]; 4547 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4548 if (!success) 4549 return false; 4550 4551 RegisterInfo data_reg; 4552 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4553 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4554 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4555 return false; 4556 } 4557 4558 // address = address + 4; 4559 offset += addr_byte_size; 4560 } 4561 } 4562 4563 // if registers<15> == '1' then 4564 // MemA[address,4] = PCStoreValue(); 4565 if (BitIsSet (registers, 15)) 4566 { 4567 RegisterInfo pc_reg; 4568 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4569 context.SetRegisterPlusOffset (pc_reg, 8); 4570 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4571 if (!success) 4572 return false; 4573 4574 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4575 return false; 4576 } 4577 4578 // if wback then R[n] = R[n] + 4*BitCount(registers); 4579 if (wback) 4580 { 4581 offset = addr_byte_size * BitCount (registers); 4582 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4583 context.SetImmediateSigned (offset); 4584 addr_t data = Rn + offset; 4585 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4586 return false; 4587 } 4588 } 4589 return true; 4590 } 4591 4592 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word 4593 // from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4594 bool 4595 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4596 { 4597 #if 0 4598 if ConditionPassed() then 4599 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4600 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4601 address = if index then offset_addr else R[n]; 4602 if UnalignedSupport() || address<1:0> == '00' then 4603 MemU[address,4] = R[t]; 4604 else // Can only occur before ARMv7 4605 MemU[address,4] = bits(32) UNKNOWN; 4606 if wback then R[n] = offset_addr; 4607 #endif 4608 4609 bool success = false; 4610 4611 if (ConditionPassed(opcode)) 4612 { 4613 const uint32_t addr_byte_size = GetAddressByteSize(); 4614 4615 uint32_t t; 4616 uint32_t n; 4617 uint32_t imm32; 4618 bool index; 4619 bool add; 4620 bool wback; 4621 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4622 switch (encoding) 4623 { 4624 case eEncodingT1: 4625 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4626 t = Bits32 (opcode, 2, 0); 4627 n = Bits32 (opcode, 5, 3); 4628 imm32 = Bits32 (opcode, 10, 6) << 2; 4629 4630 // index = TRUE; add = TRUE; wback = FALSE; 4631 index = true; 4632 add = false; 4633 wback = false; 4634 break; 4635 4636 case eEncodingT2: 4637 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4638 t = Bits32 (opcode, 10, 8); 4639 n = 13; 4640 imm32 = Bits32 (opcode, 7, 0) << 2; 4641 4642 // index = TRUE; add = TRUE; wback = FALSE; 4643 index = true; 4644 add = true; 4645 wback = false; 4646 break; 4647 4648 case eEncodingT3: 4649 // if Rn == '1111' then UNDEFINED; 4650 if (Bits32 (opcode, 19, 16) == 15) 4651 return false; 4652 4653 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4654 t = Bits32 (opcode, 15, 12); 4655 n = Bits32 (opcode, 19, 16); 4656 imm32 = Bits32 (opcode, 11, 0); 4657 4658 // index = TRUE; add = TRUE; wback = FALSE; 4659 index = true; 4660 add = true; 4661 wback = false; 4662 4663 // if t == 15 then UNPREDICTABLE; 4664 if (t == 15) 4665 return false; 4666 break; 4667 4668 case eEncodingT4: 4669 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4670 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4671 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4672 if ((Bits32 (opcode, 19, 16) == 15) 4673 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4674 return false; 4675 4676 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4677 t = Bits32 (opcode, 15, 12); 4678 n = Bits32 (opcode, 19, 16); 4679 imm32 = Bits32 (opcode, 7, 0); 4680 4681 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4682 index = BitIsSet (opcode, 10); 4683 add = BitIsSet (opcode, 9); 4684 wback = BitIsSet (opcode, 8); 4685 4686 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4687 if ((t == 15) || (wback && (n == t))) 4688 return false; 4689 break; 4690 4691 default: 4692 return false; 4693 } 4694 4695 addr_t offset_addr; 4696 addr_t address; 4697 4698 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4699 uint32_t base_address = ReadCoreReg (n, &success); 4700 if (!success) 4701 return false; 4702 4703 if (add) 4704 offset_addr = base_address + imm32; 4705 else 4706 offset_addr = base_address - imm32; 4707 4708 // address = if index then offset_addr else R[n]; 4709 if (index) 4710 address = offset_addr; 4711 else 4712 address = base_address; 4713 4714 EmulateInstruction::Context context; 4715 context.type = eContextRegisterStore; 4716 RegisterInfo base_reg; 4717 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4718 4719 // if UnalignedSupport() || address<1:0> == '00' then 4720 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4721 { 4722 // MemU[address,4] = R[t]; 4723 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4724 if (!success) 4725 return false; 4726 4727 RegisterInfo data_reg; 4728 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4729 int32_t offset = address - base_address; 4730 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4731 if (!MemUWrite (context, address, data, addr_byte_size)) 4732 return false; 4733 } 4734 else 4735 { 4736 // MemU[address,4] = bits(32) UNKNOWN; 4737 WriteBits32UnknownToMemory (address); 4738 } 4739 4740 // if wback then R[n] = offset_addr; 4741 if (wback) 4742 { 4743 context.type = eContextRegisterLoad; 4744 context.SetAddress (offset_addr); 4745 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4746 return false; 4747 } 4748 } 4749 return true; 4750 } 4751 4752 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4753 // word from a register to memory. The offset register value can optionally be shifted. 4754 bool 4755 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4756 { 4757 #if 0 4758 if ConditionPassed() then 4759 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4760 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4761 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4762 address = if index then offset_addr else R[n]; 4763 if t == 15 then // Only possible for encoding A1 4764 data = PCStoreValue(); 4765 else 4766 data = R[t]; 4767 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4768 MemU[address,4] = data; 4769 else // Can only occur before ARMv7 4770 MemU[address,4] = bits(32) UNKNOWN; 4771 if wback then R[n] = offset_addr; 4772 #endif 4773 4774 bool success = false; 4775 4776 if (ConditionPassed(opcode)) 4777 { 4778 const uint32_t addr_byte_size = GetAddressByteSize(); 4779 4780 uint32_t t; 4781 uint32_t n; 4782 uint32_t m; 4783 ARM_ShifterType shift_t; 4784 uint32_t shift_n; 4785 bool index; 4786 bool add; 4787 bool wback; 4788 4789 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4790 switch (encoding) 4791 { 4792 case eEncodingT1: 4793 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4794 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4795 t = Bits32 (opcode, 2, 0); 4796 n = Bits32 (opcode, 5, 3); 4797 m = Bits32 (opcode, 8, 6); 4798 4799 // index = TRUE; add = TRUE; wback = FALSE; 4800 index = true; 4801 add = true; 4802 wback = false; 4803 4804 // (shift_t, shift_n) = (SRType_LSL, 0); 4805 shift_t = SRType_LSL; 4806 shift_n = 0; 4807 break; 4808 4809 case eEncodingT2: 4810 // if Rn == '1111' then UNDEFINED; 4811 if (Bits32 (opcode, 19, 16) == 15) 4812 return false; 4813 4814 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4815 t = Bits32 (opcode, 15, 12); 4816 n = Bits32 (opcode, 19, 16); 4817 m = Bits32 (opcode, 3, 0); 4818 4819 // index = TRUE; add = TRUE; wback = FALSE; 4820 index = true; 4821 add = true; 4822 wback = false; 4823 4824 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4825 shift_t = SRType_LSL; 4826 shift_n = Bits32 (opcode, 5, 4); 4827 4828 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4829 if ((t == 15) || (BadReg (m))) 4830 return false; 4831 break; 4832 4833 case eEncodingA1: 4834 { 4835 // if P == '0' && W == '1' then SEE STRT; 4836 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4837 t = Bits32 (opcode, 15, 12); 4838 n = Bits32 (opcode, 19, 16); 4839 m = Bits32 (opcode, 3, 0); 4840 4841 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4842 index = BitIsSet (opcode, 24); 4843 add = BitIsSet (opcode, 23); 4844 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4845 4846 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4847 uint32_t typ = Bits32 (opcode, 6, 5); 4848 uint32_t imm5 = Bits32 (opcode, 11, 7); 4849 shift_n = DecodeImmShift(typ, imm5, shift_t); 4850 4851 // if m == 15 then UNPREDICTABLE; 4852 if (m == 15) 4853 return false; 4854 4855 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4856 if (wback && ((n == 15) || (n == t))) 4857 return false; 4858 4859 break; 4860 } 4861 default: 4862 return false; 4863 } 4864 4865 addr_t offset_addr; 4866 addr_t address; 4867 int32_t offset = 0; 4868 4869 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4870 if (!success) 4871 return false; 4872 4873 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4874 if (!success) 4875 return false; 4876 4877 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4878 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4879 if (!success) 4880 return false; 4881 4882 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4883 if (add) 4884 offset_addr = base_address + offset; 4885 else 4886 offset_addr = base_address - offset; 4887 4888 // address = if index then offset_addr else R[n]; 4889 if (index) 4890 address = offset_addr; 4891 else 4892 address = base_address; 4893 4894 uint32_t data; 4895 // if t == 15 then // Only possible for encoding A1 4896 if (t == 15) 4897 // data = PCStoreValue(); 4898 data = ReadCoreReg (PC_REG, &success); 4899 else 4900 // data = R[t]; 4901 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4902 4903 if (!success) 4904 return false; 4905 4906 EmulateInstruction::Context context; 4907 context.type = eContextRegisterStore; 4908 4909 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4910 if (UnalignedSupport () 4911 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4912 || CurrentInstrSet() == eModeARM) 4913 { 4914 // MemU[address,4] = data; 4915 4916 RegisterInfo base_reg; 4917 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4918 4919 RegisterInfo data_reg; 4920 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4921 4922 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4923 if (!MemUWrite (context, address, data, addr_byte_size)) 4924 return false; 4925 4926 } 4927 else 4928 // MemU[address,4] = bits(32) UNKNOWN; 4929 WriteBits32UnknownToMemory (address); 4930 4931 // if wback then R[n] = offset_addr; 4932 if (wback) 4933 { 4934 context.type = eContextRegisterLoad; 4935 context.SetAddress (offset_addr); 4936 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4937 return false; 4938 } 4939 4940 } 4941 return true; 4942 } 4943 4944 bool 4945 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 4946 { 4947 #if 0 4948 if ConditionPassed() then 4949 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4950 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4951 address = if index then offset_addr else R[n]; 4952 MemU[address,1] = R[t]<7:0>; 4953 if wback then R[n] = offset_addr; 4954 #endif 4955 4956 4957 bool success = false; 4958 4959 if (ConditionPassed(opcode)) 4960 { 4961 uint32_t t; 4962 uint32_t n; 4963 uint32_t imm32; 4964 bool index; 4965 bool add; 4966 bool wback; 4967 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4968 switch (encoding) 4969 { 4970 case eEncodingT1: 4971 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4972 t = Bits32 (opcode, 2, 0); 4973 n = Bits32 (opcode, 5, 3); 4974 imm32 = Bits32 (opcode, 10, 6); 4975 4976 // index = TRUE; add = TRUE; wback = FALSE; 4977 index = true; 4978 add = true; 4979 wback = false; 4980 break; 4981 4982 case eEncodingT2: 4983 // if Rn == '1111' then UNDEFINED; 4984 if (Bits32 (opcode, 19, 16) == 15) 4985 return false; 4986 4987 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4988 t = Bits32 (opcode, 15, 12); 4989 n = Bits32 (opcode, 19, 16); 4990 imm32 = Bits32 (opcode, 11, 0); 4991 4992 // index = TRUE; add = TRUE; wback = FALSE; 4993 index = true; 4994 add = true; 4995 wback = false; 4996 4997 // if BadReg(t) then UNPREDICTABLE; 4998 if (BadReg (t)) 4999 return false; 5000 break; 5001 5002 case eEncodingT3: 5003 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5004 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5005 if (Bits32 (opcode, 19, 16) == 15) 5006 return false; 5007 5008 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5009 t = Bits32 (opcode, 15, 12); 5010 n = Bits32 (opcode, 19, 16); 5011 imm32 = Bits32 (opcode, 7, 0); 5012 5013 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5014 index = BitIsSet (opcode, 10); 5015 add = BitIsSet (opcode, 9); 5016 wback = BitIsSet (opcode, 8); 5017 5018 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5019 if ((BadReg (t)) || (wback && (n == t))) 5020 return false; 5021 break; 5022 5023 default: 5024 return false; 5025 } 5026 5027 addr_t offset_addr; 5028 addr_t address; 5029 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5030 if (!success) 5031 return false; 5032 5033 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5034 if (add) 5035 offset_addr = base_address + imm32; 5036 else 5037 offset_addr = base_address - imm32; 5038 5039 // address = if index then offset_addr else R[n]; 5040 if (index) 5041 address = offset_addr; 5042 else 5043 address = base_address; 5044 5045 // MemU[address,1] = R[t]<7:0> 5046 RegisterInfo base_reg; 5047 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5048 5049 RegisterInfo data_reg; 5050 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5051 5052 EmulateInstruction::Context context; 5053 context.type = eContextRegisterStore; 5054 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5055 5056 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5057 if (!success) 5058 return false; 5059 5060 data = Bits32 (data, 7, 0); 5061 5062 if (!MemUWrite (context, address, data, 1)) 5063 return false; 5064 5065 // if wback then R[n] = offset_addr; 5066 if (wback) 5067 { 5068 context.type = eContextRegisterLoad; 5069 context.SetAddress (offset_addr); 5070 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5071 return false; 5072 } 5073 5074 } 5075 5076 return true; 5077 } 5078 5079 // STRH (register) calculates an address from a base register value and an offset register value, and stores a 5080 // halfword from a register to memory. The offset register value can be shifted left by 0, 1, 2, or 3 bits. 5081 bool 5082 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5083 { 5084 #if 0 5085 if ConditionPassed() then 5086 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5087 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5088 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5089 address = if index then offset_addr else R[n]; 5090 if UnalignedSupport() || address<0> == '0' then 5091 MemU[address,2] = R[t]<15:0>; 5092 else // Can only occur before ARMv7 5093 MemU[address,2] = bits(16) UNKNOWN; 5094 if wback then R[n] = offset_addr; 5095 #endif 5096 5097 bool success = false; 5098 5099 if (ConditionPassed(opcode)) 5100 { 5101 uint32_t t; 5102 uint32_t n; 5103 uint32_t m; 5104 bool index; 5105 bool add; 5106 bool wback; 5107 ARM_ShifterType shift_t; 5108 uint32_t shift_n; 5109 5110 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5111 switch (encoding) 5112 { 5113 case eEncodingT1: 5114 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5115 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5116 t = Bits32 (opcode, 2, 0); 5117 n = Bits32 (opcode, 5, 3); 5118 m = Bits32 (opcode, 8, 6); 5119 5120 // index = TRUE; add = TRUE; wback = FALSE; 5121 index = true; 5122 add = true; 5123 wback = false; 5124 5125 // (shift_t, shift_n) = (SRType_LSL, 0); 5126 shift_t = SRType_LSL; 5127 shift_n = 0; 5128 5129 break; 5130 5131 case eEncodingT2: 5132 // if Rn == '1111' then UNDEFINED; 5133 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5134 t = Bits32 (opcode, 15, 12); 5135 n = Bits32 (opcode, 19, 16); 5136 m = Bits32 (opcode, 3, 0); 5137 if (n == 15) 5138 return false; 5139 5140 // index = TRUE; add = TRUE; wback = FALSE; 5141 index = true; 5142 add = true; 5143 wback = false; 5144 5145 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5146 shift_t = SRType_LSL; 5147 shift_n = Bits32 (opcode, 5, 4); 5148 5149 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5150 if (BadReg (t) || BadReg (m)) 5151 return false; 5152 5153 break; 5154 5155 case eEncodingA1: 5156 // if P == '0' && W == '1' then SEE STRHT; 5157 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5158 t = Bits32 (opcode, 15, 12); 5159 n = Bits32 (opcode, 19, 16); 5160 m = Bits32 (opcode, 3, 0); 5161 5162 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5163 index = BitIsSet (opcode, 24); 5164 add = BitIsSet (opcode, 23); 5165 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5166 5167 // (shift_t, shift_n) = (SRType_LSL, 0); 5168 shift_t = SRType_LSL; 5169 shift_n = 0; 5170 5171 // if t == 15 || m == 15 then UNPREDICTABLE; 5172 if ((t == 15) || (m == 15)) 5173 return false; 5174 5175 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5176 if (wback && ((n == 15) || (n == t))) 5177 return false; 5178 5179 break; 5180 5181 default: 5182 return false; 5183 } 5184 5185 uint32_t Rm = ReadCoreReg (m, &success); 5186 if (!success) 5187 return false; 5188 5189 uint32_t Rn = ReadCoreReg (n, &success); 5190 if (!success) 5191 return false; 5192 5193 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5194 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5195 if (!success) 5196 return false; 5197 5198 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5199 addr_t offset_addr; 5200 if (add) 5201 offset_addr = Rn + offset; 5202 else 5203 offset_addr = Rn - offset; 5204 5205 // address = if index then offset_addr else R[n]; 5206 addr_t address; 5207 if (index) 5208 address = offset_addr; 5209 else 5210 address = Rn; 5211 5212 EmulateInstruction::Context context; 5213 context.type = eContextRegisterStore; 5214 RegisterInfo base_reg; 5215 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5216 RegisterInfo offset_reg; 5217 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5218 5219 // if UnalignedSupport() || address<0> == '0' then 5220 if (UnalignedSupport() || BitIsClear (address, 0)) 5221 { 5222 // MemU[address,2] = R[t]<15:0>; 5223 uint32_t Rt = ReadCoreReg (t, &success); 5224 if (!success) 5225 return false; 5226 5227 EmulateInstruction::Context context; 5228 context.type = eContextRegisterStore; 5229 RegisterInfo base_reg; 5230 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5231 RegisterInfo offset_reg; 5232 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5233 RegisterInfo data_reg; 5234 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5235 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5236 5237 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5238 return false; 5239 } 5240 else // Can only occur before ARMv7 5241 { 5242 // MemU[address,2] = bits(16) UNKNOWN; 5243 } 5244 5245 // if wback then R[n] = offset_addr; 5246 if (wback) 5247 { 5248 context.type = eContextAdjustBaseRegister; 5249 context.SetAddress (offset_addr); 5250 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5251 return false; 5252 } 5253 } 5254 5255 return true; 5256 } 5257 5258 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5259 // and writes the result to the destination register. It can optionally update the condition flags 5260 // based on the result. 5261 bool 5262 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5263 { 5264 #if 0 5265 // ARM pseudo code... 5266 if ConditionPassed() then 5267 EncodingSpecificOperations(); 5268 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5269 if d == 15 then // Can only occur for ARM encoding 5270 ALUWritePC(result); // setflags is always FALSE here 5271 else 5272 R[d] = result; 5273 if setflags then 5274 APSR.N = result<31>; 5275 APSR.Z = IsZeroBit(result); 5276 APSR.C = carry; 5277 APSR.V = overflow; 5278 #endif 5279 5280 bool success = false; 5281 5282 if (ConditionPassed(opcode)) 5283 { 5284 uint32_t Rd, Rn; 5285 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5286 bool setflags; 5287 switch (encoding) 5288 { 5289 case eEncodingT1: 5290 Rd = Bits32(opcode, 11, 8); 5291 Rn = Bits32(opcode, 19, 16); 5292 setflags = BitIsSet(opcode, 20); 5293 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5294 if (BadReg(Rd) || BadReg(Rn)) 5295 return false; 5296 break; 5297 case eEncodingA1: 5298 Rd = Bits32(opcode, 15, 12); 5299 Rn = Bits32(opcode, 19, 16); 5300 setflags = BitIsSet(opcode, 20); 5301 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5302 5303 if (Rd == 15 && setflags) 5304 return EmulateSUBSPcLrEtc (opcode, encoding); 5305 break; 5306 default: 5307 return false; 5308 } 5309 5310 // Read the first operand. 5311 int32_t val1 = ReadCoreReg(Rn, &success); 5312 if (!success) 5313 return false; 5314 5315 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5316 5317 EmulateInstruction::Context context; 5318 context.type = EmulateInstruction::eContextImmediate; 5319 context.SetNoArgs (); 5320 5321 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5322 return false; 5323 } 5324 return true; 5325 } 5326 5327 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5328 // register value, and writes the result to the destination register. It can optionally update the 5329 // condition flags based on the result. 5330 bool 5331 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5332 { 5333 #if 0 5334 // ARM pseudo code... 5335 if ConditionPassed() then 5336 EncodingSpecificOperations(); 5337 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5338 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5339 if d == 15 then // Can only occur for ARM encoding 5340 ALUWritePC(result); // setflags is always FALSE here 5341 else 5342 R[d] = result; 5343 if setflags then 5344 APSR.N = result<31>; 5345 APSR.Z = IsZeroBit(result); 5346 APSR.C = carry; 5347 APSR.V = overflow; 5348 #endif 5349 5350 bool success = false; 5351 5352 if (ConditionPassed(opcode)) 5353 { 5354 uint32_t Rd, Rn, Rm; 5355 ARM_ShifterType shift_t; 5356 uint32_t shift_n; // the shift applied to the value read from Rm 5357 bool setflags; 5358 switch (encoding) 5359 { 5360 case eEncodingT1: 5361 Rd = Rn = Bits32(opcode, 2, 0); 5362 Rm = Bits32(opcode, 5, 3); 5363 setflags = !InITBlock(); 5364 shift_t = SRType_LSL; 5365 shift_n = 0; 5366 break; 5367 case eEncodingT2: 5368 Rd = Bits32(opcode, 11, 8); 5369 Rn = Bits32(opcode, 19, 16); 5370 Rm = Bits32(opcode, 3, 0); 5371 setflags = BitIsSet(opcode, 20); 5372 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5373 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5374 return false; 5375 break; 5376 case eEncodingA1: 5377 Rd = Bits32(opcode, 15, 12); 5378 Rn = Bits32(opcode, 19, 16); 5379 Rm = Bits32(opcode, 3, 0); 5380 setflags = BitIsSet(opcode, 20); 5381 shift_n = DecodeImmShiftARM(opcode, shift_t); 5382 5383 if (Rd == 15 && setflags) 5384 return EmulateSUBSPcLrEtc (opcode, encoding); 5385 break; 5386 default: 5387 return false; 5388 } 5389 5390 // Read the first operand. 5391 int32_t val1 = ReadCoreReg(Rn, &success); 5392 if (!success) 5393 return false; 5394 5395 // Read the second operand. 5396 int32_t val2 = ReadCoreReg(Rm, &success); 5397 if (!success) 5398 return false; 5399 5400 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5401 if (!success) 5402 return false; 5403 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5404 5405 EmulateInstruction::Context context; 5406 context.type = EmulateInstruction::eContextImmediate; 5407 context.SetNoArgs (); 5408 5409 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5410 return false; 5411 } 5412 return true; 5413 } 5414 5415 // This instruction adds an immediate value to the PC value to form a PC-relative address, 5416 // and writes the result to the destination register. 5417 bool 5418 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5419 { 5420 #if 0 5421 // ARM pseudo code... 5422 if ConditionPassed() then 5423 EncodingSpecificOperations(); 5424 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5425 if d == 15 then // Can only occur for ARM encodings 5426 ALUWritePC(result); 5427 else 5428 R[d] = result; 5429 #endif 5430 5431 bool success = false; 5432 5433 if (ConditionPassed(opcode)) 5434 { 5435 uint32_t Rd; 5436 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5437 bool add; 5438 switch (encoding) 5439 { 5440 case eEncodingT1: 5441 Rd = Bits32(opcode, 10, 8); 5442 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5443 add = true; 5444 break; 5445 case eEncodingT2: 5446 case eEncodingT3: 5447 Rd = Bits32(opcode, 11, 8); 5448 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5449 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5450 if (BadReg(Rd)) 5451 return false; 5452 break; 5453 case eEncodingA1: 5454 case eEncodingA2: 5455 Rd = Bits32(opcode, 15, 12); 5456 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5457 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5458 break; 5459 default: 5460 return false; 5461 } 5462 5463 // Read the PC value. 5464 uint32_t pc = ReadCoreReg(PC_REG, &success); 5465 if (!success) 5466 return false; 5467 5468 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5469 5470 EmulateInstruction::Context context; 5471 context.type = EmulateInstruction::eContextImmediate; 5472 context.SetNoArgs (); 5473 5474 if (!WriteCoreReg(context, result, Rd)) 5475 return false; 5476 } 5477 return true; 5478 } 5479 5480 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5481 // to the destination register. It can optionally update the condition flags based on the result. 5482 bool 5483 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5484 { 5485 #if 0 5486 // ARM pseudo code... 5487 if ConditionPassed() then 5488 EncodingSpecificOperations(); 5489 result = R[n] AND imm32; 5490 if d == 15 then // Can only occur for ARM encoding 5491 ALUWritePC(result); // setflags is always FALSE here 5492 else 5493 R[d] = result; 5494 if setflags then 5495 APSR.N = result<31>; 5496 APSR.Z = IsZeroBit(result); 5497 APSR.C = carry; 5498 // APSR.V unchanged 5499 #endif 5500 5501 bool success = false; 5502 5503 if (ConditionPassed(opcode)) 5504 { 5505 uint32_t Rd, Rn; 5506 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5507 bool setflags; 5508 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5509 switch (encoding) 5510 { 5511 case eEncodingT1: 5512 Rd = Bits32(opcode, 11, 8); 5513 Rn = Bits32(opcode, 19, 16); 5514 setflags = BitIsSet(opcode, 20); 5515 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5516 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5517 if (Rd == 15 && setflags) 5518 return EmulateTSTImm(opcode, eEncodingT1); 5519 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5520 return false; 5521 break; 5522 case eEncodingA1: 5523 Rd = Bits32(opcode, 15, 12); 5524 Rn = Bits32(opcode, 19, 16); 5525 setflags = BitIsSet(opcode, 20); 5526 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5527 5528 if (Rd == 15 && setflags) 5529 return EmulateSUBSPcLrEtc (opcode, encoding); 5530 break; 5531 default: 5532 return false; 5533 } 5534 5535 // Read the first operand. 5536 uint32_t val1 = ReadCoreReg(Rn, &success); 5537 if (!success) 5538 return false; 5539 5540 uint32_t result = val1 & imm32; 5541 5542 EmulateInstruction::Context context; 5543 context.type = EmulateInstruction::eContextImmediate; 5544 context.SetNoArgs (); 5545 5546 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5547 return false; 5548 } 5549 return true; 5550 } 5551 5552 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5553 // and writes the result to the destination register. It can optionally update the condition flags 5554 // based on the result. 5555 bool 5556 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5557 { 5558 #if 0 5559 // ARM pseudo code... 5560 if ConditionPassed() then 5561 EncodingSpecificOperations(); 5562 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5563 result = R[n] AND shifted; 5564 if d == 15 then // Can only occur for ARM encoding 5565 ALUWritePC(result); // setflags is always FALSE here 5566 else 5567 R[d] = result; 5568 if setflags then 5569 APSR.N = result<31>; 5570 APSR.Z = IsZeroBit(result); 5571 APSR.C = carry; 5572 // APSR.V unchanged 5573 #endif 5574 5575 bool success = false; 5576 5577 if (ConditionPassed(opcode)) 5578 { 5579 uint32_t Rd, Rn, Rm; 5580 ARM_ShifterType shift_t; 5581 uint32_t shift_n; // the shift applied to the value read from Rm 5582 bool setflags; 5583 uint32_t carry; 5584 switch (encoding) 5585 { 5586 case eEncodingT1: 5587 Rd = Rn = Bits32(opcode, 2, 0); 5588 Rm = Bits32(opcode, 5, 3); 5589 setflags = !InITBlock(); 5590 shift_t = SRType_LSL; 5591 shift_n = 0; 5592 break; 5593 case eEncodingT2: 5594 Rd = Bits32(opcode, 11, 8); 5595 Rn = Bits32(opcode, 19, 16); 5596 Rm = Bits32(opcode, 3, 0); 5597 setflags = BitIsSet(opcode, 20); 5598 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5599 // if Rd == '1111' && S == '1' then SEE TST (register); 5600 if (Rd == 15 && setflags) 5601 return EmulateTSTReg(opcode, eEncodingT2); 5602 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5603 return false; 5604 break; 5605 case eEncodingA1: 5606 Rd = Bits32(opcode, 15, 12); 5607 Rn = Bits32(opcode, 19, 16); 5608 Rm = Bits32(opcode, 3, 0); 5609 setflags = BitIsSet(opcode, 20); 5610 shift_n = DecodeImmShiftARM(opcode, shift_t); 5611 5612 if (Rd == 15 && setflags) 5613 return EmulateSUBSPcLrEtc (opcode, encoding); 5614 break; 5615 default: 5616 return false; 5617 } 5618 5619 // Read the first operand. 5620 uint32_t val1 = ReadCoreReg(Rn, &success); 5621 if (!success) 5622 return false; 5623 5624 // Read the second operand. 5625 uint32_t val2 = ReadCoreReg(Rm, &success); 5626 if (!success) 5627 return false; 5628 5629 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5630 if (!success) 5631 return false; 5632 uint32_t result = val1 & shifted; 5633 5634 EmulateInstruction::Context context; 5635 context.type = EmulateInstruction::eContextImmediate; 5636 context.SetNoArgs (); 5637 5638 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5639 return false; 5640 } 5641 return true; 5642 } 5643 5644 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5645 // immediate value, and writes the result to the destination register. It can optionally update the 5646 // condition flags based on the result. 5647 bool 5648 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5649 { 5650 #if 0 5651 // ARM pseudo code... 5652 if ConditionPassed() then 5653 EncodingSpecificOperations(); 5654 result = R[n] AND NOT(imm32); 5655 if d == 15 then // Can only occur for ARM encoding 5656 ALUWritePC(result); // setflags is always FALSE here 5657 else 5658 R[d] = result; 5659 if setflags then 5660 APSR.N = result<31>; 5661 APSR.Z = IsZeroBit(result); 5662 APSR.C = carry; 5663 // APSR.V unchanged 5664 #endif 5665 5666 bool success = false; 5667 5668 if (ConditionPassed(opcode)) 5669 { 5670 uint32_t Rd, Rn; 5671 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5672 bool setflags; 5673 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5674 switch (encoding) 5675 { 5676 case eEncodingT1: 5677 Rd = Bits32(opcode, 11, 8); 5678 Rn = Bits32(opcode, 19, 16); 5679 setflags = BitIsSet(opcode, 20); 5680 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5681 if (BadReg(Rd) || BadReg(Rn)) 5682 return false; 5683 break; 5684 case eEncodingA1: 5685 Rd = Bits32(opcode, 15, 12); 5686 Rn = Bits32(opcode, 19, 16); 5687 setflags = BitIsSet(opcode, 20); 5688 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5689 5690 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5691 if (Rd == 15 && setflags) 5692 return EmulateSUBSPcLrEtc (opcode, encoding); 5693 break; 5694 default: 5695 return false; 5696 } 5697 5698 // Read the first operand. 5699 uint32_t val1 = ReadCoreReg(Rn, &success); 5700 if (!success) 5701 return false; 5702 5703 uint32_t result = val1 & ~imm32; 5704 5705 EmulateInstruction::Context context; 5706 context.type = EmulateInstruction::eContextImmediate; 5707 context.SetNoArgs (); 5708 5709 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5710 return false; 5711 } 5712 return true; 5713 } 5714 5715 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5716 // optionally-shifted register value, and writes the result to the destination register. 5717 // It can optionally update the condition flags based on the result. 5718 bool 5719 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5720 { 5721 #if 0 5722 // ARM pseudo code... 5723 if ConditionPassed() then 5724 EncodingSpecificOperations(); 5725 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5726 result = R[n] AND NOT(shifted); 5727 if d == 15 then // Can only occur for ARM encoding 5728 ALUWritePC(result); // setflags is always FALSE here 5729 else 5730 R[d] = result; 5731 if setflags then 5732 APSR.N = result<31>; 5733 APSR.Z = IsZeroBit(result); 5734 APSR.C = carry; 5735 // APSR.V unchanged 5736 #endif 5737 5738 bool success = false; 5739 5740 if (ConditionPassed(opcode)) 5741 { 5742 uint32_t Rd, Rn, Rm; 5743 ARM_ShifterType shift_t; 5744 uint32_t shift_n; // the shift applied to the value read from Rm 5745 bool setflags; 5746 uint32_t carry; 5747 switch (encoding) 5748 { 5749 case eEncodingT1: 5750 Rd = Rn = Bits32(opcode, 2, 0); 5751 Rm = Bits32(opcode, 5, 3); 5752 setflags = !InITBlock(); 5753 shift_t = SRType_LSL; 5754 shift_n = 0; 5755 break; 5756 case eEncodingT2: 5757 Rd = Bits32(opcode, 11, 8); 5758 Rn = Bits32(opcode, 19, 16); 5759 Rm = Bits32(opcode, 3, 0); 5760 setflags = BitIsSet(opcode, 20); 5761 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5762 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5763 return false; 5764 break; 5765 case eEncodingA1: 5766 Rd = Bits32(opcode, 15, 12); 5767 Rn = Bits32(opcode, 19, 16); 5768 Rm = Bits32(opcode, 3, 0); 5769 setflags = BitIsSet(opcode, 20); 5770 shift_n = DecodeImmShiftARM(opcode, shift_t); 5771 5772 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5773 if (Rd == 15 && setflags) 5774 return EmulateSUBSPcLrEtc (opcode, encoding); 5775 break; 5776 default: 5777 return false; 5778 } 5779 5780 // Read the first operand. 5781 uint32_t val1 = ReadCoreReg(Rn, &success); 5782 if (!success) 5783 return false; 5784 5785 // Read the second operand. 5786 uint32_t val2 = ReadCoreReg(Rm, &success); 5787 if (!success) 5788 return false; 5789 5790 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5791 if (!success) 5792 return false; 5793 uint32_t result = val1 & ~shifted; 5794 5795 EmulateInstruction::Context context; 5796 context.type = EmulateInstruction::eContextImmediate; 5797 context.SetNoArgs (); 5798 5799 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5800 return false; 5801 } 5802 return true; 5803 } 5804 5805 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5806 // from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5807 bool 5808 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5809 { 5810 #if 0 5811 if ConditionPassed() then 5812 EncodingSpecificOperations(); 5813 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5814 address = if index then offset_addr else R[n]; 5815 data = MemU[address,4]; 5816 if wback then R[n] = offset_addr; 5817 if t == 15 then 5818 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5819 elsif UnalignedSupport() || address<1:0> = '00' then 5820 R[t] = data; 5821 else // Can only apply before ARMv7 5822 R[t] = ROR(data, 8*UInt(address<1:0>)); 5823 #endif 5824 5825 bool success = false; 5826 5827 if (ConditionPassed(opcode)) 5828 { 5829 const uint32_t addr_byte_size = GetAddressByteSize(); 5830 5831 uint32_t t; 5832 uint32_t n; 5833 uint32_t imm32; 5834 bool index; 5835 bool add; 5836 bool wback; 5837 5838 switch (encoding) 5839 { 5840 case eEncodingA1: 5841 // if Rn == '1111' then SEE LDR (literal); 5842 // if P == '0' && W == '1' then SEE LDRT; 5843 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5844 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5845 t = Bits32 (opcode, 15, 12); 5846 n = Bits32 (opcode, 19, 16); 5847 imm32 = Bits32 (opcode, 11, 0); 5848 5849 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5850 index = BitIsSet (opcode, 24); 5851 add = BitIsSet (opcode, 23); 5852 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5853 5854 // if wback && n == t then UNPREDICTABLE; 5855 if (wback && (n == t)) 5856 return false; 5857 5858 break; 5859 5860 default: 5861 return false; 5862 } 5863 5864 addr_t address; 5865 addr_t offset_addr; 5866 addr_t base_address = ReadCoreReg (n, &success); 5867 if (!success) 5868 return false; 5869 5870 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5871 if (add) 5872 offset_addr = base_address + imm32; 5873 else 5874 offset_addr = base_address - imm32; 5875 5876 // address = if index then offset_addr else R[n]; 5877 if (index) 5878 address = offset_addr; 5879 else 5880 address = base_address; 5881 5882 // data = MemU[address,4]; 5883 5884 RegisterInfo base_reg; 5885 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5886 5887 EmulateInstruction::Context context; 5888 context.type = eContextRegisterLoad; 5889 context.SetRegisterPlusOffset (base_reg, address - base_address); 5890 5891 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5892 if (!success) 5893 return false; 5894 5895 // if wback then R[n] = offset_addr; 5896 if (wback) 5897 { 5898 context.type = eContextAdjustBaseRegister; 5899 context.SetAddress (offset_addr); 5900 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5901 return false; 5902 } 5903 5904 // if t == 15 then 5905 if (t == 15) 5906 { 5907 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5908 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5909 { 5910 // LoadWritePC (data); 5911 context.type = eContextRegisterLoad; 5912 context.SetRegisterPlusOffset (base_reg, address - base_address); 5913 LoadWritePC (context, data); 5914 } 5915 else 5916 return false; 5917 } 5918 // elsif UnalignedSupport() || address<1:0> = '00' then 5919 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5920 { 5921 // R[t] = data; 5922 context.type = eContextRegisterLoad; 5923 context.SetRegisterPlusOffset (base_reg, address - base_address); 5924 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5925 return false; 5926 } 5927 // else // Can only apply before ARMv7 5928 else 5929 { 5930 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5931 data = ROR (data, Bits32 (address, 1, 0), &success); 5932 if (!success) 5933 return false; 5934 context.type = eContextRegisterLoad; 5935 context.SetImmediate (data); 5936 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5937 return false; 5938 } 5939 5940 } 5941 return true; 5942 } 5943 5944 // LDR (register) calculates an address from a base register value and an offset register value, loads a word 5945 // from memory, and writes it to a register. The offset register value can optionally be shifted. 5946 bool 5947 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5948 { 5949 #if 0 5950 if ConditionPassed() then 5951 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5952 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5953 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5954 address = if index then offset_addr else R[n]; 5955 data = MemU[address,4]; 5956 if wback then R[n] = offset_addr; 5957 if t == 15 then 5958 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5959 elsif UnalignedSupport() || address<1:0> = '00' then 5960 R[t] = data; 5961 else // Can only apply before ARMv7 5962 if CurrentInstrSet() == InstrSet_ARM then 5963 R[t] = ROR(data, 8*UInt(address<1:0>)); 5964 else 5965 R[t] = bits(32) UNKNOWN; 5966 #endif 5967 5968 bool success = false; 5969 5970 if (ConditionPassed(opcode)) 5971 { 5972 const uint32_t addr_byte_size = GetAddressByteSize(); 5973 5974 uint32_t t; 5975 uint32_t n; 5976 uint32_t m; 5977 bool index; 5978 bool add; 5979 bool wback; 5980 ARM_ShifterType shift_t; 5981 uint32_t shift_n; 5982 5983 switch (encoding) 5984 { 5985 case eEncodingT1: 5986 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5987 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5988 t = Bits32 (opcode, 2, 0); 5989 n = Bits32 (opcode, 5, 3); 5990 m = Bits32 (opcode, 8, 6); 5991 5992 // index = TRUE; add = TRUE; wback = FALSE; 5993 index = true; 5994 add = true; 5995 wback = false; 5996 5997 // (shift_t, shift_n) = (SRType_LSL, 0); 5998 shift_t = SRType_LSL; 5999 shift_n = 0; 6000 6001 break; 6002 6003 case eEncodingT2: 6004 // if Rn == '1111' then SEE LDR (literal); 6005 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6006 t = Bits32 (opcode, 15, 12); 6007 n = Bits32 (opcode, 19, 16); 6008 m = Bits32 (opcode, 3, 0); 6009 6010 // index = TRUE; add = TRUE; wback = FALSE; 6011 index = true; 6012 add = true; 6013 wback = false; 6014 6015 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6016 shift_t = SRType_LSL; 6017 shift_n = Bits32 (opcode, 5, 4); 6018 6019 // if BadReg(m) then UNPREDICTABLE; 6020 if (BadReg (m)) 6021 return false; 6022 6023 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6024 if ((t == 15) && InITBlock() && !LastInITBlock()) 6025 return false; 6026 6027 break; 6028 6029 case eEncodingA1: 6030 { 6031 // if P == '0' && W == '1' then SEE LDRT; 6032 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6033 t = Bits32 (opcode, 15, 12); 6034 n = Bits32 (opcode, 19, 16); 6035 m = Bits32 (opcode, 3, 0); 6036 6037 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6038 index = BitIsSet (opcode, 24); 6039 add = BitIsSet (opcode, 23); 6040 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6041 6042 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6043 uint32_t type = Bits32 (opcode, 6, 5); 6044 uint32_t imm5 = Bits32 (opcode, 11, 7); 6045 shift_n = DecodeImmShift (type, imm5, shift_t); 6046 6047 // if m == 15 then UNPREDICTABLE; 6048 if (m == 15) 6049 return false; 6050 6051 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6052 if (wback && ((n == 15) || (n == t))) 6053 return false; 6054 } 6055 break; 6056 6057 6058 default: 6059 return false; 6060 } 6061 6062 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6063 if (!success) 6064 return false; 6065 6066 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6067 if (!success) 6068 return false; 6069 6070 addr_t offset_addr; 6071 addr_t address; 6072 6073 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6074 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6075 if (!success) 6076 return false; 6077 6078 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6079 if (add) 6080 offset_addr = Rn + offset; 6081 else 6082 offset_addr = Rn - offset; 6083 6084 // address = if index then offset_addr else R[n]; 6085 if (index) 6086 address = offset_addr; 6087 else 6088 address = Rn; 6089 6090 // data = MemU[address,4]; 6091 RegisterInfo base_reg; 6092 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6093 6094 EmulateInstruction::Context context; 6095 context.type = eContextRegisterLoad; 6096 context.SetRegisterPlusOffset (base_reg, address - Rn); 6097 6098 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6099 if (!success) 6100 return false; 6101 6102 // if wback then R[n] = offset_addr; 6103 if (wback) 6104 { 6105 context.type = eContextAdjustBaseRegister; 6106 context.SetAddress (offset_addr); 6107 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6108 return false; 6109 } 6110 6111 // if t == 15 then 6112 if (t == 15) 6113 { 6114 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6115 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6116 { 6117 context.type = eContextRegisterLoad; 6118 context.SetRegisterPlusOffset (base_reg, address - Rn); 6119 LoadWritePC (context, data); 6120 } 6121 else 6122 return false; 6123 } 6124 // elsif UnalignedSupport() || address<1:0> = '00' then 6125 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6126 { 6127 // R[t] = data; 6128 context.type = eContextRegisterLoad; 6129 context.SetRegisterPlusOffset (base_reg, address - Rn); 6130 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6131 return false; 6132 } 6133 else // Can only apply before ARMv7 6134 { 6135 // if CurrentInstrSet() == InstrSet_ARM then 6136 if (CurrentInstrSet () == eModeARM) 6137 { 6138 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6139 data = ROR (data, Bits32 (address, 1, 0), &success); 6140 if (!success) 6141 return false; 6142 context.type = eContextRegisterLoad; 6143 context.SetImmediate (data); 6144 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6145 return false; 6146 } 6147 else 6148 { 6149 // R[t] = bits(32) UNKNOWN; 6150 WriteBits32Unknown (t); 6151 } 6152 } 6153 } 6154 return true; 6155 } 6156 6157 // LDRB (immediate, Thumb) 6158 bool 6159 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6160 { 6161 #if 0 6162 if ConditionPassed() then 6163 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6164 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6165 address = if index then offset_addr else R[n]; 6166 R[t] = ZeroExtend(MemU[address,1], 32); 6167 if wback then R[n] = offset_addr; 6168 #endif 6169 6170 bool success = false; 6171 6172 if (ConditionPassed(opcode)) 6173 { 6174 uint32_t t; 6175 uint32_t n; 6176 uint32_t imm32; 6177 bool index; 6178 bool add; 6179 bool wback; 6180 6181 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6182 switch (encoding) 6183 { 6184 case eEncodingT1: 6185 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6186 t = Bits32 (opcode, 2, 0); 6187 n = Bits32 (opcode, 5, 3); 6188 imm32 = Bits32 (opcode, 10, 6); 6189 6190 // index = TRUE; add = TRUE; wback = FALSE; 6191 index = true; 6192 add = true; 6193 wback= false; 6194 6195 break; 6196 6197 case eEncodingT2: 6198 // if Rt == '1111' then SEE PLD; 6199 // if Rn == '1111' then SEE LDRB (literal); 6200 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6201 t = Bits32 (opcode, 15, 12); 6202 n = Bits32 (opcode, 19, 16); 6203 imm32 = Bits32 (opcode, 11, 0); 6204 6205 // index = TRUE; add = TRUE; wback = FALSE; 6206 index = true; 6207 add = true; 6208 wback = false; 6209 6210 // if t == 13 then UNPREDICTABLE; 6211 if (t == 13) 6212 return false; 6213 6214 break; 6215 6216 case eEncodingT3: 6217 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6218 // if Rn == '1111' then SEE LDRB (literal); 6219 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6220 // if P == '0' && W == '0' then UNDEFINED; 6221 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6222 return false; 6223 6224 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6225 t = Bits32 (opcode, 15, 12); 6226 n = Bits32 (opcode, 19, 16); 6227 imm32 = Bits32 (opcode, 7, 0); 6228 6229 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6230 index = BitIsSet (opcode, 10); 6231 add = BitIsSet (opcode, 9); 6232 wback = BitIsSet (opcode, 8); 6233 6234 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6235 if (BadReg (t) || (wback && (n == t))) 6236 return false; 6237 6238 break; 6239 6240 default: 6241 return false; 6242 } 6243 6244 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6245 if (!success) 6246 return false; 6247 6248 addr_t address; 6249 addr_t offset_addr; 6250 6251 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6252 if (add) 6253 offset_addr = Rn + imm32; 6254 else 6255 offset_addr = Rn - imm32; 6256 6257 // address = if index then offset_addr else R[n]; 6258 if (index) 6259 address = offset_addr; 6260 else 6261 address = Rn; 6262 6263 // R[t] = ZeroExtend(MemU[address,1], 32); 6264 RegisterInfo base_reg; 6265 RegisterInfo data_reg; 6266 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6267 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6268 6269 EmulateInstruction::Context context; 6270 context.type = eContextRegisterLoad; 6271 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6272 6273 uint64_t data = MemURead (context, address, 1, 0, &success); 6274 if (!success) 6275 return false; 6276 6277 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6278 return false; 6279 6280 // if wback then R[n] = offset_addr; 6281 if (wback) 6282 { 6283 context.type = eContextAdjustBaseRegister; 6284 context.SetAddress (offset_addr); 6285 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6286 return false; 6287 } 6288 } 6289 return true; 6290 } 6291 6292 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6293 // zero-extends it to form a 32-bit word and writes it to a register. 6294 bool 6295 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6296 { 6297 #if 0 6298 if ConditionPassed() then 6299 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6300 base = Align(PC,4); 6301 address = if add then (base + imm32) else (base - imm32); 6302 R[t] = ZeroExtend(MemU[address,1], 32); 6303 #endif 6304 6305 bool success = false; 6306 6307 if (ConditionPassed(opcode)) 6308 { 6309 uint32_t t; 6310 uint32_t imm32; 6311 bool add; 6312 switch (encoding) 6313 { 6314 case eEncodingT1: 6315 // if Rt == '1111' then SEE PLD; 6316 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6317 t = Bits32 (opcode, 15, 12); 6318 imm32 = Bits32 (opcode, 11, 0); 6319 add = BitIsSet (opcode, 23); 6320 6321 // if t == 13 then UNPREDICTABLE; 6322 if (t == 13) 6323 return false; 6324 6325 break; 6326 6327 case eEncodingA1: 6328 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6329 t = Bits32 (opcode, 15, 12); 6330 imm32 = Bits32 (opcode, 11, 0); 6331 add = BitIsSet (opcode, 23); 6332 6333 // if t == 15 then UNPREDICTABLE; 6334 if (t == 15) 6335 return false; 6336 break; 6337 6338 default: 6339 return false; 6340 } 6341 6342 // base = Align(PC,4); 6343 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6344 if (!success) 6345 return false; 6346 6347 uint32_t base = AlignPC (pc_val); 6348 6349 addr_t address; 6350 // address = if add then (base + imm32) else (base - imm32); 6351 if (add) 6352 address = base + imm32; 6353 else 6354 address = base - imm32; 6355 6356 // R[t] = ZeroExtend(MemU[address,1], 32); 6357 EmulateInstruction::Context context; 6358 context.type = eContextRelativeBranchImmediate; 6359 context.SetImmediate (address - base); 6360 6361 uint64_t data = MemURead (context, address, 1, 0, &success); 6362 if (!success) 6363 return false; 6364 6365 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6366 return false; 6367 } 6368 return true; 6369 } 6370 6371 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6372 // memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6373 // optionally be shifted. 6374 bool 6375 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6376 { 6377 #if 0 6378 if ConditionPassed() then 6379 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6380 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6381 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6382 address = if index then offset_addr else R[n]; 6383 R[t] = ZeroExtend(MemU[address,1],32); 6384 if wback then R[n] = offset_addr; 6385 #endif 6386 6387 bool success = false; 6388 6389 if (ConditionPassed(opcode)) 6390 { 6391 uint32_t t; 6392 uint32_t n; 6393 uint32_t m; 6394 bool index; 6395 bool add; 6396 bool wback; 6397 ARM_ShifterType shift_t; 6398 uint32_t shift_n; 6399 6400 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6401 switch (encoding) 6402 { 6403 case eEncodingT1: 6404 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6405 t = Bits32 (opcode, 2, 0); 6406 n = Bits32 (opcode, 5, 3); 6407 m = Bits32 (opcode, 8, 6); 6408 6409 // index = TRUE; add = TRUE; wback = FALSE; 6410 index = true; 6411 add = true; 6412 wback = false; 6413 6414 // (shift_t, shift_n) = (SRType_LSL, 0); 6415 shift_t = SRType_LSL; 6416 shift_n = 0; 6417 break; 6418 6419 case eEncodingT2: 6420 // if Rt == '1111' then SEE PLD; 6421 // if Rn == '1111' then SEE LDRB (literal); 6422 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6423 t = Bits32 (opcode, 15, 12); 6424 n = Bits32 (opcode, 19, 16); 6425 m = Bits32 (opcode, 3, 0); 6426 6427 // index = TRUE; add = TRUE; wback = FALSE; 6428 index = true; 6429 add = true; 6430 wback = false; 6431 6432 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6433 shift_t = SRType_LSL; 6434 shift_n = Bits32 (opcode, 5, 4); 6435 6436 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6437 if ((t == 13) || BadReg (m)) 6438 return false; 6439 break; 6440 6441 case eEncodingA1: 6442 { 6443 // if P == '0' && W == '1' then SEE LDRBT; 6444 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6445 t = Bits32 (opcode, 15, 12); 6446 n = Bits32 (opcode, 19, 16); 6447 m = Bits32 (opcode, 3, 0); 6448 6449 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6450 index = BitIsSet (opcode, 24); 6451 add = BitIsSet (opcode, 23); 6452 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6453 6454 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6455 uint32_t type = Bits32 (opcode, 6, 5); 6456 uint32_t imm5 = Bits32 (opcode, 11, 7); 6457 shift_n = DecodeImmShift (type, imm5, shift_t); 6458 6459 // if t == 15 || m == 15 then UNPREDICTABLE; 6460 if ((t == 15) || (m == 15)) 6461 return false; 6462 6463 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6464 if (wback && ((n == 15) || (n == t))) 6465 return false; 6466 } 6467 break; 6468 6469 default: 6470 return false; 6471 } 6472 6473 addr_t offset_addr; 6474 addr_t address; 6475 6476 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6477 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6478 if (!success) 6479 return false; 6480 6481 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6482 if (!success) 6483 return false; 6484 6485 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6486 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6487 if (!success) 6488 return false; 6489 6490 if (add) 6491 offset_addr = Rn + offset; 6492 else 6493 offset_addr = Rn - offset; 6494 6495 // address = if index then offset_addr else R[n]; 6496 if (index) 6497 address = offset_addr; 6498 else 6499 address = Rn; 6500 6501 // R[t] = ZeroExtend(MemU[address,1],32); 6502 RegisterInfo base_reg; 6503 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6504 6505 EmulateInstruction::Context context; 6506 context.type = eContextRegisterLoad; 6507 context.SetRegisterPlusOffset (base_reg, address - Rn); 6508 6509 uint64_t data = MemURead (context, address, 1, 0, &success); 6510 if (!success) 6511 return false; 6512 6513 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6514 return false; 6515 6516 // if wback then R[n] = offset_addr; 6517 if (wback) 6518 { 6519 context.type = eContextAdjustBaseRegister; 6520 context.SetAddress (offset_addr); 6521 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6522 return false; 6523 } 6524 } 6525 return true; 6526 } 6527 6528 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6529 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6530 // post-indexed, or pre-indexed addressing. 6531 bool 6532 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6533 { 6534 #if 0 6535 if ConditionPassed() then 6536 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6537 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6538 address = if index then offset_addr else R[n]; 6539 data = MemU[address,2]; 6540 if wback then R[n] = offset_addr; 6541 if UnalignedSupport() || address<0> = '0' then 6542 R[t] = ZeroExtend(data, 32); 6543 else // Can only apply before ARMv7 6544 R[t] = bits(32) UNKNOWN; 6545 #endif 6546 6547 6548 bool success = false; 6549 6550 if (ConditionPassed(opcode)) 6551 { 6552 uint32_t t; 6553 uint32_t n; 6554 uint32_t imm32; 6555 bool index; 6556 bool add; 6557 bool wback; 6558 6559 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6560 switch (encoding) 6561 { 6562 case eEncodingT1: 6563 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6564 t = Bits32 (opcode, 2, 0); 6565 n = Bits32 (opcode, 5, 3); 6566 imm32 = Bits32 (opcode, 10, 6) << 1; 6567 6568 // index = TRUE; add = TRUE; wback = FALSE; 6569 index = true; 6570 add = true; 6571 wback = false; 6572 6573 break; 6574 6575 case eEncodingT2: 6576 // if Rt == '1111' then SEE "Unallocated memory hints"; 6577 // if Rn == '1111' then SEE LDRH (literal); 6578 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6579 t = Bits32 (opcode, 15, 12); 6580 n = Bits32 (opcode, 19, 16); 6581 imm32 = Bits32 (opcode, 11, 0); 6582 6583 // index = TRUE; add = TRUE; wback = FALSE; 6584 index = true; 6585 add = true; 6586 wback = false; 6587 6588 // if t == 13 then UNPREDICTABLE; 6589 if (t == 13) 6590 return false; 6591 break; 6592 6593 case eEncodingT3: 6594 // if Rn == '1111' then SEE LDRH (literal); 6595 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6596 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6597 // if P == '0' && W == '0' then UNDEFINED; 6598 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6599 return false; 6600 6601 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6602 t = Bits32 (opcode, 15, 12); 6603 n = Bits32 (opcode, 19, 16); 6604 imm32 = Bits32 (opcode, 7, 0); 6605 6606 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6607 index = BitIsSet (opcode, 10); 6608 add = BitIsSet (opcode, 9); 6609 wback = BitIsSet (opcode, 8); 6610 6611 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6612 if (BadReg (t) || (wback && (n == t))) 6613 return false; 6614 break; 6615 6616 default: 6617 return false; 6618 } 6619 6620 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6621 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6622 if (!success) 6623 return false; 6624 6625 addr_t offset_addr; 6626 addr_t address; 6627 6628 if (add) 6629 offset_addr = Rn + imm32; 6630 else 6631 offset_addr = Rn - imm32; 6632 6633 // address = if index then offset_addr else R[n]; 6634 if (index) 6635 address = offset_addr; 6636 else 6637 address = Rn; 6638 6639 // data = MemU[address,2]; 6640 RegisterInfo base_reg; 6641 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6642 6643 EmulateInstruction::Context context; 6644 context.type = eContextRegisterLoad; 6645 context.SetRegisterPlusOffset (base_reg, address - Rn); 6646 6647 uint64_t data = MemURead (context, address, 2, 0, &success); 6648 if (!success) 6649 return false; 6650 6651 // if wback then R[n] = offset_addr; 6652 if (wback) 6653 { 6654 context.type = eContextAdjustBaseRegister; 6655 context.SetAddress (offset_addr); 6656 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6657 return false; 6658 } 6659 6660 // if UnalignedSupport() || address<0> = '0' then 6661 if (UnalignedSupport () || BitIsClear (address, 0)) 6662 { 6663 // R[t] = ZeroExtend(data, 32); 6664 context.type = eContextRegisterLoad; 6665 context.SetRegisterPlusOffset (base_reg, address - Rn); 6666 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6667 return false; 6668 } 6669 else // Can only apply before ARMv7 6670 { 6671 // R[t] = bits(32) UNKNOWN; 6672 WriteBits32Unknown (t); 6673 } 6674 } 6675 return true; 6676 } 6677 6678 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6679 // zero-extends it to form a 32-bit word, and writes it to a register. 6680 bool 6681 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6682 { 6683 #if 0 6684 if ConditionPassed() then 6685 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6686 base = Align(PC,4); 6687 address = if add then (base + imm32) else (base - imm32); 6688 data = MemU[address,2]; 6689 if UnalignedSupport() || address<0> = '0' then 6690 R[t] = ZeroExtend(data, 32); 6691 else // Can only apply before ARMv7 6692 R[t] = bits(32) UNKNOWN; 6693 #endif 6694 6695 bool success = false; 6696 6697 if (ConditionPassed(opcode)) 6698 { 6699 uint32_t t; 6700 uint32_t imm32; 6701 bool add; 6702 6703 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6704 switch (encoding) 6705 { 6706 case eEncodingT1: 6707 // if Rt == '1111' then SEE "Unallocated memory hints"; 6708 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6709 t = Bits32 (opcode, 15, 12); 6710 imm32 = Bits32 (opcode, 11, 0); 6711 add = BitIsSet (opcode, 23); 6712 6713 // if t == 13 then UNPREDICTABLE; 6714 if (t == 13) 6715 return false; 6716 6717 break; 6718 6719 case eEncodingA1: 6720 { 6721 uint32_t imm4H = Bits32 (opcode, 11, 8); 6722 uint32_t imm4L = Bits32 (opcode, 3, 0); 6723 6724 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6725 t = Bits32 (opcode, 15, 12); 6726 imm32 = (imm4H << 4) | imm4L; 6727 add = BitIsSet (opcode, 23); 6728 6729 // if t == 15 then UNPREDICTABLE; 6730 if (t == 15) 6731 return false; 6732 break; 6733 } 6734 6735 default: 6736 return false; 6737 } 6738 6739 // base = Align(PC,4); 6740 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6741 if (!success) 6742 return false; 6743 6744 addr_t base = AlignPC (pc_value); 6745 addr_t address; 6746 6747 // address = if add then (base + imm32) else (base - imm32); 6748 if (add) 6749 address = base + imm32; 6750 else 6751 address = base - imm32; 6752 6753 // data = MemU[address,2]; 6754 RegisterInfo base_reg; 6755 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6756 6757 EmulateInstruction::Context context; 6758 context.type = eContextRegisterLoad; 6759 context.SetRegisterPlusOffset (base_reg, address - base); 6760 6761 uint64_t data = MemURead (context, address, 2, 0, &success); 6762 if (!success) 6763 return false; 6764 6765 6766 // if UnalignedSupport() || address<0> = '0' then 6767 if (UnalignedSupport () || BitIsClear (address, 0)) 6768 { 6769 // R[t] = ZeroExtend(data, 32); 6770 context.type = eContextRegisterLoad; 6771 context.SetRegisterPlusOffset (base_reg, address - base); 6772 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6773 return false; 6774 6775 } 6776 else // Can only apply before ARMv7 6777 { 6778 // R[t] = bits(32) UNKNOWN; 6779 WriteBits32Unknown (t); 6780 } 6781 } 6782 return true; 6783 } 6784 6785 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6786 // from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6787 // be shifted left by 0, 1, 2, or 3 bits. 6788 bool 6789 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6790 { 6791 #if 0 6792 if ConditionPassed() then 6793 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6794 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6795 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6796 address = if index then offset_addr else R[n]; 6797 data = MemU[address,2]; 6798 if wback then R[n] = offset_addr; 6799 if UnalignedSupport() || address<0> = '0' then 6800 R[t] = ZeroExtend(data, 32); 6801 else // Can only apply before ARMv7 6802 R[t] = bits(32) UNKNOWN; 6803 #endif 6804 6805 bool success = false; 6806 6807 if (ConditionPassed(opcode)) 6808 { 6809 uint32_t t; 6810 uint32_t n; 6811 uint32_t m; 6812 bool index; 6813 bool add; 6814 bool wback; 6815 ARM_ShifterType shift_t; 6816 uint32_t shift_n; 6817 6818 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6819 switch (encoding) 6820 { 6821 case eEncodingT1: 6822 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6823 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6824 t = Bits32 (opcode, 2, 0); 6825 n = Bits32 (opcode, 5, 3); 6826 m = Bits32 (opcode, 8, 6); 6827 6828 // index = TRUE; add = TRUE; wback = FALSE; 6829 index = true; 6830 add = true; 6831 wback = false; 6832 6833 // (shift_t, shift_n) = (SRType_LSL, 0); 6834 shift_t = SRType_LSL; 6835 shift_n = 0; 6836 6837 break; 6838 6839 case eEncodingT2: 6840 // if Rn == '1111' then SEE LDRH (literal); 6841 // if Rt == '1111' then SEE "Unallocated memory hints"; 6842 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6843 t = Bits32 (opcode, 15, 12); 6844 n = Bits32 (opcode, 19, 16); 6845 m = Bits32 (opcode, 3, 0); 6846 6847 // index = TRUE; add = TRUE; wback = FALSE; 6848 index = true; 6849 add = true; 6850 wback = false; 6851 6852 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6853 shift_t = SRType_LSL; 6854 shift_n = Bits32 (opcode, 5, 4); 6855 6856 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6857 if ((t == 13) || BadReg (m)) 6858 return false; 6859 break; 6860 6861 case eEncodingA1: 6862 // if P == '0' && W == '1' then SEE LDRHT; 6863 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6864 t = Bits32 (opcode, 15, 12); 6865 n = Bits32 (opcode, 19, 16); 6866 m = Bits32 (opcode, 3, 0); 6867 6868 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6869 index = BitIsSet (opcode, 24); 6870 add = BitIsSet (opcode, 23); 6871 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6872 6873 // (shift_t, shift_n) = (SRType_LSL, 0); 6874 shift_t = SRType_LSL; 6875 shift_n = 0; 6876 6877 // if t == 15 || m == 15 then UNPREDICTABLE; 6878 if ((t == 15) || (m == 15)) 6879 return false; 6880 6881 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6882 if (wback && ((n == 15) || (n == t))) 6883 return false; 6884 6885 break; 6886 6887 default: 6888 return false; 6889 } 6890 6891 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6892 6893 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6894 if (!success) 6895 return false; 6896 6897 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6898 if (!success) 6899 return false; 6900 6901 addr_t offset_addr; 6902 addr_t address; 6903 6904 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6905 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6906 if (!success) 6907 return false; 6908 6909 if (add) 6910 offset_addr = Rn + offset; 6911 else 6912 offset_addr = Rn - offset; 6913 6914 // address = if index then offset_addr else R[n]; 6915 if (index) 6916 address = offset_addr; 6917 else 6918 address = Rn; 6919 6920 // data = MemU[address,2]; 6921 RegisterInfo base_reg; 6922 RegisterInfo offset_reg; 6923 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6924 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 6925 6926 EmulateInstruction::Context context; 6927 context.type = eContextRegisterLoad; 6928 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6929 uint64_t data = MemURead (context, address, 2, 0, &success); 6930 if (!success) 6931 return false; 6932 6933 // if wback then R[n] = offset_addr; 6934 if (wback) 6935 { 6936 context.type = eContextAdjustBaseRegister; 6937 context.SetAddress (offset_addr); 6938 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6939 return false; 6940 } 6941 6942 // if UnalignedSupport() || address<0> = '0' then 6943 if (UnalignedSupport() || BitIsClear (address, 0)) 6944 { 6945 // R[t] = ZeroExtend(data, 32); 6946 context.type = eContextRegisterLoad; 6947 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6948 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6949 return false; 6950 } 6951 else // Can only apply before ARMv7 6952 { 6953 // R[t] = bits(32) UNKNOWN; 6954 WriteBits32Unknown (t); 6955 } 6956 } 6957 return true; 6958 } 6959 6960 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6961 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6962 // or pre-indexed addressing. 6963 bool 6964 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6965 { 6966 #if 0 6967 if ConditionPassed() then 6968 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6969 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6970 address = if index then offset_addr else R[n]; 6971 R[t] = SignExtend(MemU[address,1], 32); 6972 if wback then R[n] = offset_addr; 6973 #endif 6974 6975 bool success = false; 6976 6977 if (ConditionPassed(opcode)) 6978 { 6979 uint32_t t; 6980 uint32_t n; 6981 uint32_t imm32; 6982 bool index; 6983 bool add; 6984 bool wback; 6985 6986 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6987 switch (encoding) 6988 { 6989 case eEncodingT1: 6990 // if Rt == '1111' then SEE PLI; 6991 // if Rn == '1111' then SEE LDRSB (literal); 6992 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6993 t = Bits32 (opcode, 15, 12); 6994 n = Bits32 (opcode, 19, 16); 6995 imm32 = Bits32 (opcode, 11, 0); 6996 6997 // index = TRUE; add = TRUE; wback = FALSE; 6998 index = true; 6999 add = true; 7000 wback = false; 7001 7002 // if t == 13 then UNPREDICTABLE; 7003 if (t == 13) 7004 return false; 7005 7006 break; 7007 7008 case eEncodingT2: 7009 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7010 // if Rn == '1111' then SEE LDRSB (literal); 7011 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7012 // if P == '0' && W == '0' then UNDEFINED; 7013 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7014 return false; 7015 7016 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7017 t = Bits32 (opcode, 15, 12); 7018 n = Bits32 (opcode, 19, 16); 7019 imm32 = Bits32 (opcode, 7, 0); 7020 7021 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7022 index = BitIsSet (opcode, 10); 7023 add = BitIsSet (opcode, 9); 7024 wback = BitIsSet (opcode, 8); 7025 7026 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7027 if (((t == 13) || ((t == 15) 7028 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 7029 || (wback && (n == t))) 7030 return false; 7031 7032 break; 7033 7034 case eEncodingA1: 7035 { 7036 // if Rn == '1111' then SEE LDRSB (literal); 7037 // if P == '0' && W == '1' then SEE LDRSBT; 7038 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7039 t = Bits32 (opcode, 15, 12); 7040 n = Bits32 (opcode, 19, 16); 7041 7042 uint32_t imm4H = Bits32 (opcode, 11, 8); 7043 uint32_t imm4L = Bits32 (opcode, 3, 0); 7044 imm32 = (imm4H << 4) | imm4L; 7045 7046 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7047 index = BitIsSet (opcode, 24); 7048 add = BitIsSet (opcode, 23); 7049 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7050 7051 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7052 if ((t == 15) || (wback && (n == t))) 7053 return false; 7054 7055 break; 7056 } 7057 7058 default: 7059 return false; 7060 } 7061 7062 uint64_t Rn = ReadCoreReg (n, &success); 7063 if (!success) 7064 return false; 7065 7066 addr_t offset_addr; 7067 addr_t address; 7068 7069 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7070 if (add) 7071 offset_addr = Rn + imm32; 7072 else 7073 offset_addr = Rn - imm32; 7074 7075 // address = if index then offset_addr else R[n]; 7076 if (index) 7077 address = offset_addr; 7078 else 7079 address = Rn; 7080 7081 // R[t] = SignExtend(MemU[address,1], 32); 7082 RegisterInfo base_reg; 7083 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7084 7085 EmulateInstruction::Context context; 7086 context.type = eContextRegisterLoad; 7087 context.SetRegisterPlusOffset (base_reg, address - Rn); 7088 7089 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7090 if (!success) 7091 return false; 7092 7093 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7094 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7095 return false; 7096 7097 // if wback then R[n] = offset_addr; 7098 if (wback) 7099 { 7100 context.type = eContextAdjustBaseRegister; 7101 context.SetAddress (offset_addr); 7102 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7103 return false; 7104 } 7105 } 7106 7107 return true; 7108 } 7109 7110 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7111 // sign-extends it to form a 32-bit word, and writes tit to a register. 7112 bool 7113 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7114 { 7115 #if 0 7116 if ConditionPassed() then 7117 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7118 base = Align(PC,4); 7119 address = if add then (base + imm32) else (base - imm32); 7120 R[t] = SignExtend(MemU[address,1], 32); 7121 #endif 7122 7123 bool success = false; 7124 7125 if (ConditionPassed(opcode)) 7126 { 7127 uint32_t t; 7128 uint32_t imm32; 7129 bool add; 7130 7131 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7132 switch (encoding) 7133 { 7134 case eEncodingT1: 7135 // if Rt == '1111' then SEE PLI; 7136 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7137 t = Bits32 (opcode, 15, 12); 7138 imm32 = Bits32 (opcode, 11, 0); 7139 add = BitIsSet (opcode, 23); 7140 7141 // if t == 13 then UNPREDICTABLE; 7142 if (t == 13) 7143 return false; 7144 7145 break; 7146 7147 case eEncodingA1: 7148 { 7149 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7150 t = Bits32 (opcode, 15, 12); 7151 uint32_t imm4H = Bits32 (opcode, 11, 8); 7152 uint32_t imm4L = Bits32 (opcode, 3, 0); 7153 imm32 = (imm4H << 4) | imm4L; 7154 add = BitIsSet (opcode, 23); 7155 7156 // if t == 15 then UNPREDICTABLE; 7157 if (t == 15) 7158 return false; 7159 7160 break; 7161 } 7162 7163 default: 7164 return false; 7165 } 7166 7167 // base = Align(PC,4); 7168 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7169 if (!success) 7170 return false; 7171 uint64_t base = AlignPC (pc_value); 7172 7173 // address = if add then (base + imm32) else (base - imm32); 7174 addr_t address; 7175 if (add) 7176 address = base + imm32; 7177 else 7178 address = base - imm32; 7179 7180 // R[t] = SignExtend(MemU[address,1], 32); 7181 RegisterInfo base_reg; 7182 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7183 7184 EmulateInstruction::Context context; 7185 context.type = eContextRegisterLoad; 7186 context.SetRegisterPlusOffset (base_reg, address - base); 7187 7188 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7189 if (!success) 7190 return false; 7191 7192 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7193 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7194 return false; 7195 } 7196 return true; 7197 } 7198 7199 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7200 // memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7201 // shifted left by 0, 1, 2, or 3 bits. 7202 bool 7203 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7204 { 7205 #if 0 7206 if ConditionPassed() then 7207 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7208 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7209 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7210 address = if index then offset_addr else R[n]; 7211 R[t] = SignExtend(MemU[address,1], 32); 7212 if wback then R[n] = offset_addr; 7213 #endif 7214 7215 bool success = false; 7216 7217 if (ConditionPassed(opcode)) 7218 { 7219 uint32_t t; 7220 uint32_t n; 7221 uint32_t m; 7222 bool index; 7223 bool add; 7224 bool wback; 7225 ARM_ShifterType shift_t; 7226 uint32_t shift_n; 7227 7228 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7229 switch (encoding) 7230 { 7231 case eEncodingT1: 7232 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7233 t = Bits32 (opcode, 2, 0); 7234 n = Bits32 (opcode, 5, 3); 7235 m = Bits32 (opcode, 8, 6); 7236 7237 // index = TRUE; add = TRUE; wback = FALSE; 7238 index = true; 7239 add = true; 7240 wback = false; 7241 7242 // (shift_t, shift_n) = (SRType_LSL, 0); 7243 shift_t = SRType_LSL; 7244 shift_n = 0; 7245 7246 break; 7247 7248 case eEncodingT2: 7249 // if Rt == '1111' then SEE PLI; 7250 // if Rn == '1111' then SEE LDRSB (literal); 7251 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7252 t = Bits32 (opcode, 15, 12); 7253 n = Bits32 (opcode, 19, 16); 7254 m = Bits32 (opcode, 3, 0); 7255 7256 // index = TRUE; add = TRUE; wback = FALSE; 7257 index = true; 7258 add = true; 7259 wback = false; 7260 7261 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7262 shift_t = SRType_LSL; 7263 shift_n = Bits32 (opcode, 5, 4); 7264 7265 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7266 if ((t == 13) || BadReg (m)) 7267 return false; 7268 break; 7269 7270 case eEncodingA1: 7271 // if P == '0' && W == '1' then SEE LDRSBT; 7272 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7273 t = Bits32 (opcode, 15, 12); 7274 n = Bits32 (opcode, 19, 16); 7275 m = Bits32 (opcode, 3, 0); 7276 7277 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7278 index = BitIsSet (opcode, 24); 7279 add = BitIsSet (opcode, 23); 7280 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7281 7282 // (shift_t, shift_n) = (SRType_LSL, 0); 7283 shift_t = SRType_LSL; 7284 shift_n = 0; 7285 7286 // if t == 15 || m == 15 then UNPREDICTABLE; 7287 if ((t == 15) || (m == 15)) 7288 return false; 7289 7290 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7291 if (wback && ((n == 15) || (n == t))) 7292 return false; 7293 break; 7294 7295 default: 7296 return false; 7297 } 7298 7299 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7300 if (!success) 7301 return false; 7302 7303 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7304 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7305 if (!success) 7306 return false; 7307 7308 addr_t offset_addr; 7309 addr_t address; 7310 7311 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7312 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7313 if (!success) 7314 return false; 7315 7316 if (add) 7317 offset_addr = Rn + offset; 7318 else 7319 offset_addr = Rn - offset; 7320 7321 // address = if index then offset_addr else R[n]; 7322 if (index) 7323 address = offset_addr; 7324 else 7325 address = Rn; 7326 7327 // R[t] = SignExtend(MemU[address,1], 32); 7328 RegisterInfo base_reg; 7329 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7330 RegisterInfo offset_reg; 7331 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7332 7333 EmulateInstruction::Context context; 7334 context.type = eContextRegisterLoad; 7335 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7336 7337 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7338 if (!success) 7339 return false; 7340 7341 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7342 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7343 return false; 7344 7345 // if wback then R[n] = offset_addr; 7346 if (wback) 7347 { 7348 context.type = eContextAdjustBaseRegister; 7349 context.SetAddress (offset_addr); 7350 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7351 return false; 7352 } 7353 } 7354 return true; 7355 } 7356 7357 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7358 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7359 // pre-indexed addressing. 7360 bool 7361 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7362 { 7363 #if 0 7364 if ConditionPassed() then 7365 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7366 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7367 address = if index then offset_addr else R[n]; 7368 data = MemU[address,2]; 7369 if wback then R[n] = offset_addr; 7370 if UnalignedSupport() || address<0> = '0' then 7371 R[t] = SignExtend(data, 32); 7372 else // Can only apply before ARMv7 7373 R[t] = bits(32) UNKNOWN; 7374 #endif 7375 7376 bool success = false; 7377 7378 if (ConditionPassed(opcode)) 7379 { 7380 uint32_t t; 7381 uint32_t n; 7382 uint32_t imm32; 7383 bool index; 7384 bool add; 7385 bool wback; 7386 7387 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7388 switch (encoding) 7389 { 7390 case eEncodingT1: 7391 // if Rn == '1111' then SEE LDRSH (literal); 7392 // if Rt == '1111' then SEE "Unallocated memory hints"; 7393 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7394 t = Bits32 (opcode, 15, 12); 7395 n = Bits32 (opcode, 19, 16); 7396 imm32 = Bits32 (opcode, 11, 0); 7397 7398 // index = TRUE; add = TRUE; wback = FALSE; 7399 index = true; 7400 add = true; 7401 wback = false; 7402 7403 // if t == 13 then UNPREDICTABLE; 7404 if (t == 13) 7405 return false; 7406 7407 break; 7408 7409 case eEncodingT2: 7410 // if Rn == '1111' then SEE LDRSH (literal); 7411 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7412 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7413 // if P == '0' && W == '0' then UNDEFINED; 7414 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7415 return false; 7416 7417 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7418 t = Bits32 (opcode, 15, 12); 7419 n = Bits32 (opcode, 19, 16); 7420 imm32 = Bits32 (opcode, 7, 0); 7421 7422 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7423 index = BitIsSet (opcode, 10); 7424 add = BitIsSet (opcode, 9); 7425 wback = BitIsSet (opcode, 8); 7426 7427 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7428 if (BadReg (t) || (wback && (n == t))) 7429 return false; 7430 7431 break; 7432 7433 case eEncodingA1: 7434 { 7435 // if Rn == '1111' then SEE LDRSH (literal); 7436 // if P == '0' && W == '1' then SEE LDRSHT; 7437 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7438 t = Bits32 (opcode, 15, 12); 7439 n = Bits32 (opcode, 19, 16); 7440 uint32_t imm4H = Bits32 (opcode, 11,8); 7441 uint32_t imm4L = Bits32 (opcode, 3, 0); 7442 imm32 = (imm4H << 4) | imm4L; 7443 7444 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7445 index = BitIsSet (opcode, 24); 7446 add = BitIsSet (opcode, 23); 7447 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7448 7449 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7450 if ((t == 15) || (wback && (n == t))) 7451 return false; 7452 7453 break; 7454 } 7455 7456 default: 7457 return false; 7458 } 7459 7460 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7461 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7462 if (!success) 7463 return false; 7464 7465 addr_t offset_addr; 7466 if (add) 7467 offset_addr = Rn + imm32; 7468 else 7469 offset_addr = Rn - imm32; 7470 7471 // address = if index then offset_addr else R[n]; 7472 addr_t address; 7473 if (index) 7474 address = offset_addr; 7475 else 7476 address = Rn; 7477 7478 // data = MemU[address,2]; 7479 RegisterInfo base_reg; 7480 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7481 7482 EmulateInstruction::Context context; 7483 context.type = eContextRegisterLoad; 7484 context.SetRegisterPlusOffset (base_reg, address - Rn); 7485 7486 uint64_t data = MemURead (context, address, 2, 0, &success); 7487 if (!success) 7488 return false; 7489 7490 // if wback then R[n] = offset_addr; 7491 if (wback) 7492 { 7493 context.type = eContextAdjustBaseRegister; 7494 context.SetAddress (offset_addr); 7495 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7496 return false; 7497 } 7498 7499 // if UnalignedSupport() || address<0> = '0' then 7500 if (UnalignedSupport() || BitIsClear (address, 0)) 7501 { 7502 // R[t] = SignExtend(data, 32); 7503 int64_t signed_data = llvm::SignExtend64<16>(data); 7504 context.type = eContextRegisterLoad; 7505 context.SetRegisterPlusOffset (base_reg, address - Rn); 7506 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7507 return false; 7508 } 7509 else // Can only apply before ARMv7 7510 { 7511 // R[t] = bits(32) UNKNOWN; 7512 WriteBits32Unknown (t); 7513 } 7514 } 7515 return true; 7516 } 7517 7518 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7519 // sign-extends it to from a 32-bit word, and writes it to a register. 7520 bool 7521 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7522 { 7523 #if 0 7524 if ConditionPassed() then 7525 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7526 base = Align(PC,4); 7527 address = if add then (base + imm32) else (base - imm32); 7528 data = MemU[address,2]; 7529 if UnalignedSupport() || address<0> = '0' then 7530 R[t] = SignExtend(data, 32); 7531 else // Can only apply before ARMv7 7532 R[t] = bits(32) UNKNOWN; 7533 #endif 7534 7535 bool success = false; 7536 7537 if (ConditionPassed(opcode)) 7538 { 7539 uint32_t t; 7540 uint32_t imm32; 7541 bool add; 7542 7543 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7544 switch (encoding) 7545 { 7546 case eEncodingT1: 7547 // if Rt == '1111' then SEE "Unallocated memory hints"; 7548 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7549 t = Bits32 (opcode, 15, 12); 7550 imm32 = Bits32 (opcode, 11, 0); 7551 add = BitIsSet (opcode, 23); 7552 7553 // if t == 13 then UNPREDICTABLE; 7554 if (t == 13) 7555 return false; 7556 7557 break; 7558 7559 case eEncodingA1: 7560 { 7561 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7562 t = Bits32 (opcode, 15, 12); 7563 uint32_t imm4H = Bits32 (opcode, 11, 8); 7564 uint32_t imm4L = Bits32 (opcode, 3, 0); 7565 imm32 = (imm4H << 4) | imm4L; 7566 add = BitIsSet (opcode, 23); 7567 7568 // if t == 15 then UNPREDICTABLE; 7569 if (t == 15) 7570 return false; 7571 7572 break; 7573 } 7574 default: 7575 return false; 7576 } 7577 7578 // base = Align(PC,4); 7579 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7580 if (!success) 7581 return false; 7582 7583 uint64_t base = AlignPC (pc_value); 7584 7585 addr_t address; 7586 // address = if add then (base + imm32) else (base - imm32); 7587 if (add) 7588 address = base + imm32; 7589 else 7590 address = base - imm32; 7591 7592 // data = MemU[address,2]; 7593 RegisterInfo base_reg; 7594 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7595 7596 EmulateInstruction::Context context; 7597 context.type = eContextRegisterLoad; 7598 context.SetRegisterPlusOffset (base_reg, imm32); 7599 7600 uint64_t data = MemURead (context, address, 2, 0, &success); 7601 if (!success) 7602 return false; 7603 7604 // if UnalignedSupport() || address<0> = '0' then 7605 if (UnalignedSupport() || BitIsClear (address, 0)) 7606 { 7607 // R[t] = SignExtend(data, 32); 7608 int64_t signed_data = llvm::SignExtend64<16>(data); 7609 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7610 return false; 7611 } 7612 else // Can only apply before ARMv7 7613 { 7614 // R[t] = bits(32) UNKNOWN; 7615 WriteBits32Unknown (t); 7616 } 7617 } 7618 return true; 7619 } 7620 7621 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7622 // from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7623 // shifted left by 0, 1, 2, or 3 bits. 7624 bool 7625 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7626 { 7627 #if 0 7628 if ConditionPassed() then 7629 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7630 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7631 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7632 address = if index then offset_addr else R[n]; 7633 data = MemU[address,2]; 7634 if wback then R[n] = offset_addr; 7635 if UnalignedSupport() || address<0> = '0' then 7636 R[t] = SignExtend(data, 32); 7637 else // Can only apply before ARMv7 7638 R[t] = bits(32) UNKNOWN; 7639 #endif 7640 7641 bool success = false; 7642 7643 if (ConditionPassed(opcode)) 7644 { 7645 uint32_t t; 7646 uint32_t n; 7647 uint32_t m; 7648 bool index; 7649 bool add; 7650 bool wback; 7651 ARM_ShifterType shift_t; 7652 uint32_t shift_n; 7653 7654 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7655 switch (encoding) 7656 { 7657 case eEncodingT1: 7658 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7659 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7660 t = Bits32 (opcode, 2, 0); 7661 n = Bits32 (opcode, 5, 3); 7662 m = Bits32 (opcode, 8, 6); 7663 7664 // index = TRUE; add = TRUE; wback = FALSE; 7665 index = true; 7666 add = true; 7667 wback = false; 7668 7669 // (shift_t, shift_n) = (SRType_LSL, 0); 7670 shift_t = SRType_LSL; 7671 shift_n = 0; 7672 7673 break; 7674 7675 case eEncodingT2: 7676 // if Rn == '1111' then SEE LDRSH (literal); 7677 // if Rt == '1111' then SEE "Unallocated memory hints"; 7678 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7679 t = Bits32 (opcode, 15, 12); 7680 n = Bits32 (opcode, 19, 16); 7681 m = Bits32 (opcode, 3, 0); 7682 7683 // index = TRUE; add = TRUE; wback = FALSE; 7684 index = true; 7685 add = true; 7686 wback = false; 7687 7688 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7689 shift_t = SRType_LSL; 7690 shift_n = Bits32 (opcode, 5, 4); 7691 7692 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7693 if ((t == 13) || BadReg (m)) 7694 return false; 7695 7696 break; 7697 7698 case eEncodingA1: 7699 // if P == '0' && W == '1' then SEE LDRSHT; 7700 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7701 t = Bits32 (opcode, 15, 12); 7702 n = Bits32 (opcode, 19, 16); 7703 m = Bits32 (opcode, 3, 0); 7704 7705 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7706 index = BitIsSet (opcode, 24); 7707 add = BitIsSet (opcode, 23); 7708 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7709 7710 // (shift_t, shift_n) = (SRType_LSL, 0); 7711 shift_t = SRType_LSL; 7712 shift_n = 0; 7713 7714 // if t == 15 || m == 15 then UNPREDICTABLE; 7715 if ((t == 15) || (m == 15)) 7716 return false; 7717 7718 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7719 if (wback && ((n == 15) || (n == t))) 7720 return false; 7721 7722 break; 7723 7724 default: 7725 return false; 7726 } 7727 7728 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7729 if (!success) 7730 return false; 7731 7732 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7733 if (!success) 7734 return false; 7735 7736 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7737 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7738 if (!success) 7739 return false; 7740 7741 addr_t offset_addr; 7742 addr_t address; 7743 7744 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7745 if (add) 7746 offset_addr = Rn + offset; 7747 else 7748 offset_addr = Rn - offset; 7749 7750 // address = if index then offset_addr else R[n]; 7751 if (index) 7752 address = offset_addr; 7753 else 7754 address = Rn; 7755 7756 // data = MemU[address,2]; 7757 RegisterInfo base_reg; 7758 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7759 7760 RegisterInfo offset_reg; 7761 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7762 7763 EmulateInstruction::Context context; 7764 context.type = eContextRegisterLoad; 7765 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7766 7767 uint64_t data = MemURead (context, address, 2, 0, &success); 7768 if (!success) 7769 return false; 7770 7771 // if wback then R[n] = offset_addr; 7772 if (wback) 7773 { 7774 context.type = eContextAdjustBaseRegister; 7775 context.SetAddress (offset_addr); 7776 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7777 return false; 7778 } 7779 7780 // if UnalignedSupport() || address<0> = '0' then 7781 if (UnalignedSupport() || BitIsClear (address, 0)) 7782 { 7783 // R[t] = SignExtend(data, 32); 7784 context.type = eContextRegisterLoad; 7785 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7786 7787 int64_t signed_data = llvm::SignExtend64<16>(data); 7788 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7789 return false; 7790 } 7791 else // Can only apply before ARMv7 7792 { 7793 // R[t] = bits(32) UNKNOWN; 7794 WriteBits32Unknown (t); 7795 } 7796 } 7797 return true; 7798 } 7799 7800 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7801 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7802 bool 7803 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7804 { 7805 #if 0 7806 if ConditionPassed() then 7807 EncodingSpecificOperations(); 7808 rotated = ROR(R[m], rotation); 7809 R[d] = SignExtend(rotated<7:0>, 32); 7810 #endif 7811 7812 bool success = false; 7813 7814 if (ConditionPassed(opcode)) 7815 { 7816 uint32_t d; 7817 uint32_t m; 7818 uint32_t rotation; 7819 7820 // EncodingSpecificOperations(); 7821 switch (encoding) 7822 { 7823 case eEncodingT1: 7824 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7825 d = Bits32 (opcode, 2, 0); 7826 m = Bits32 (opcode, 5, 3); 7827 rotation = 0; 7828 7829 break; 7830 7831 case eEncodingT2: 7832 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7833 d = Bits32 (opcode, 11, 8); 7834 m = Bits32 (opcode, 3, 0); 7835 rotation = Bits32 (opcode, 5, 4) << 3; 7836 7837 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7838 if (BadReg (d) || BadReg (m)) 7839 return false; 7840 7841 break; 7842 7843 case eEncodingA1: 7844 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7845 d = Bits32 (opcode, 15, 12); 7846 m = Bits32 (opcode, 3, 0); 7847 rotation = Bits32 (opcode, 11, 10) << 3; 7848 7849 // if d == 15 || m == 15 then UNPREDICTABLE; 7850 if ((d == 15) || (m == 15)) 7851 return false; 7852 7853 break; 7854 7855 default: 7856 return false; 7857 } 7858 7859 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7860 if (!success) 7861 return false; 7862 7863 // rotated = ROR(R[m], rotation); 7864 uint64_t rotated = ROR (Rm, rotation, &success); 7865 if (!success) 7866 return false; 7867 7868 // R[d] = SignExtend(rotated<7:0>, 32); 7869 int64_t data = llvm::SignExtend64<8>(rotated); 7870 7871 RegisterInfo source_reg; 7872 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7873 7874 EmulateInstruction::Context context; 7875 context.type = eContextRegisterLoad; 7876 context.SetRegister (source_reg); 7877 7878 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7879 return false; 7880 } 7881 return true; 7882 } 7883 7884 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7885 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7886 bool 7887 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7888 { 7889 #if 0 7890 if ConditionPassed() then 7891 EncodingSpecificOperations(); 7892 rotated = ROR(R[m], rotation); 7893 R[d] = SignExtend(rotated<15:0>, 32); 7894 #endif 7895 7896 bool success = false; 7897 7898 if (ConditionPassed(opcode)) 7899 { 7900 uint32_t d; 7901 uint32_t m; 7902 uint32_t rotation; 7903 7904 // EncodingSpecificOperations(); 7905 switch (encoding) 7906 { 7907 case eEncodingT1: 7908 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7909 d = Bits32 (opcode, 2, 0); 7910 m = Bits32 (opcode, 5, 3); 7911 rotation = 0; 7912 7913 break; 7914 7915 case eEncodingT2: 7916 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7917 d = Bits32 (opcode, 11, 8); 7918 m = Bits32 (opcode, 3, 0); 7919 rotation = Bits32 (opcode, 5, 4) << 3; 7920 7921 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7922 if (BadReg (d) || BadReg (m)) 7923 return false; 7924 7925 break; 7926 7927 case eEncodingA1: 7928 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7929 d = Bits32 (opcode, 15, 12); 7930 m = Bits32 (opcode, 3, 0); 7931 rotation = Bits32 (opcode, 11, 10) << 3; 7932 7933 // if d == 15 || m == 15 then UNPREDICTABLE; 7934 if ((d == 15) || (m == 15)) 7935 return false; 7936 7937 break; 7938 7939 default: 7940 return false; 7941 } 7942 7943 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7944 if (!success) 7945 return false; 7946 7947 // rotated = ROR(R[m], rotation); 7948 uint64_t rotated = ROR (Rm, rotation, &success); 7949 if (!success) 7950 return false; 7951 7952 // R[d] = SignExtend(rotated<15:0>, 32); 7953 RegisterInfo source_reg; 7954 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7955 7956 EmulateInstruction::Context context; 7957 context.type = eContextRegisterLoad; 7958 context.SetRegister (source_reg); 7959 7960 int64_t data = llvm::SignExtend64<16> (rotated); 7961 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7962 return false; 7963 } 7964 7965 return true; 7966 } 7967 7968 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 7969 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7970 bool 7971 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 7972 { 7973 #if 0 7974 if ConditionPassed() then 7975 EncodingSpecificOperations(); 7976 rotated = ROR(R[m], rotation); 7977 R[d] = ZeroExtend(rotated<7:0>, 32); 7978 #endif 7979 7980 bool success = false; 7981 7982 if (ConditionPassed(opcode)) 7983 { 7984 uint32_t d; 7985 uint32_t m; 7986 uint32_t rotation; 7987 7988 // EncodingSpecificOperations(); 7989 switch (encoding) 7990 { 7991 case eEncodingT1: 7992 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7993 d = Bits32 (opcode, 2, 0); 7994 m = Bits32 (opcode, 5, 3); 7995 rotation = 0; 7996 7997 break; 7998 7999 case eEncodingT2: 8000 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8001 d = Bits32 (opcode, 11, 8); 8002 m = Bits32 (opcode, 3, 0); 8003 rotation = Bits32 (opcode, 5, 4) << 3; 8004 8005 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8006 if (BadReg (d) || BadReg (m)) 8007 return false; 8008 8009 break; 8010 8011 case eEncodingA1: 8012 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8013 d = Bits32 (opcode, 15, 12); 8014 m = Bits32 (opcode, 3, 0); 8015 rotation = Bits32 (opcode, 11, 10) << 3; 8016 8017 // if d == 15 || m == 15 then UNPREDICTABLE; 8018 if ((d == 15) || (m == 15)) 8019 return false; 8020 8021 break; 8022 8023 default: 8024 return false; 8025 } 8026 8027 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8028 if (!success) 8029 return false; 8030 8031 // rotated = ROR(R[m], rotation); 8032 uint64_t rotated = ROR (Rm, rotation, &success); 8033 if (!success) 8034 return false; 8035 8036 // R[d] = ZeroExtend(rotated<7:0>, 32); 8037 RegisterInfo source_reg; 8038 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8039 8040 EmulateInstruction::Context context; 8041 context.type = eContextRegisterLoad; 8042 context.SetRegister (source_reg); 8043 8044 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 8045 return false; 8046 } 8047 return true; 8048 } 8049 8050 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 8051 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 8052 bool 8053 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 8054 { 8055 #if 0 8056 if ConditionPassed() then 8057 EncodingSpecificOperations(); 8058 rotated = ROR(R[m], rotation); 8059 R[d] = ZeroExtend(rotated<15:0>, 32); 8060 #endif 8061 8062 bool success = false; 8063 8064 if (ConditionPassed(opcode)) 8065 { 8066 uint32_t d; 8067 uint32_t m; 8068 uint32_t rotation; 8069 8070 switch (encoding) 8071 { 8072 case eEncodingT1: 8073 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8074 d = Bits32 (opcode, 2, 0); 8075 m = Bits32 (opcode, 5, 3); 8076 rotation = 0; 8077 8078 break; 8079 8080 case eEncodingT2: 8081 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8082 d = Bits32 (opcode, 11, 8); 8083 m = Bits32 (opcode, 3, 0); 8084 rotation = Bits32 (opcode, 5, 4) << 3; 8085 8086 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8087 if (BadReg (d) || BadReg (m)) 8088 return false; 8089 8090 break; 8091 8092 case eEncodingA1: 8093 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8094 d = Bits32 (opcode, 15, 12); 8095 m = Bits32 (opcode, 3, 0); 8096 rotation = Bits32 (opcode, 11, 10) << 3; 8097 8098 // if d == 15 || m == 15 then UNPREDICTABLE; 8099 if ((d == 15) || (m == 15)) 8100 return false; 8101 8102 break; 8103 8104 default: 8105 return false; 8106 } 8107 8108 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8109 if (!success) 8110 return false; 8111 8112 // rotated = ROR(R[m], rotation); 8113 uint64_t rotated = ROR (Rm, rotation, &success); 8114 if (!success) 8115 return false; 8116 8117 // R[d] = ZeroExtend(rotated<15:0>, 32); 8118 RegisterInfo source_reg; 8119 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8120 8121 EmulateInstruction::Context context; 8122 context.type = eContextRegisterLoad; 8123 context.SetRegister (source_reg); 8124 8125 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8126 return false; 8127 } 8128 return true; 8129 } 8130 8131 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8132 // word respectively. 8133 bool 8134 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8135 { 8136 #if 0 8137 if ConditionPassed() then 8138 EncodingSpecificOperations(); 8139 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8140 UNPREDICTABLE; 8141 else 8142 address = if increment then R[n] else R[n]-8; 8143 if wordhigher then address = address+4; 8144 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8145 BranchWritePC(MemA[address,4]); 8146 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8147 #endif 8148 8149 bool success = false; 8150 8151 if (ConditionPassed(opcode)) 8152 { 8153 uint32_t n; 8154 bool wback; 8155 bool increment; 8156 bool wordhigher; 8157 8158 // EncodingSpecificOperations(); 8159 switch (encoding) 8160 { 8161 case eEncodingT1: 8162 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8163 n = Bits32 (opcode, 19, 16); 8164 wback = BitIsSet (opcode, 21); 8165 increment = false; 8166 wordhigher = false; 8167 8168 // if n == 15 then UNPREDICTABLE; 8169 if (n == 15) 8170 return false; 8171 8172 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8173 if (InITBlock() && !LastInITBlock()) 8174 return false; 8175 8176 break; 8177 8178 case eEncodingT2: 8179 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8180 n = Bits32 (opcode, 19, 16); 8181 wback = BitIsSet (opcode, 21); 8182 increment = true; 8183 wordhigher = false; 8184 8185 // if n == 15 then UNPREDICTABLE; 8186 if (n == 15) 8187 return false; 8188 8189 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8190 if (InITBlock() && !LastInITBlock()) 8191 return false; 8192 8193 break; 8194 8195 case eEncodingA1: 8196 // n = UInt(Rn); 8197 n = Bits32 (opcode, 19, 16); 8198 8199 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8200 wback = BitIsSet (opcode, 21); 8201 increment = BitIsSet (opcode, 23); 8202 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8203 8204 // if n == 15 then UNPREDICTABLE; 8205 if (n == 15) 8206 return false; 8207 8208 break; 8209 8210 default: 8211 return false; 8212 } 8213 8214 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8215 if (!CurrentModeIsPrivileged ()) 8216 // UNPREDICTABLE; 8217 return false; 8218 else 8219 { 8220 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8221 if (!success) 8222 return false; 8223 8224 addr_t address; 8225 // address = if increment then R[n] else R[n]-8; 8226 if (increment) 8227 address = Rn; 8228 else 8229 address = Rn - 8; 8230 8231 // if wordhigher then address = address+4; 8232 if (wordhigher) 8233 address = address + 4; 8234 8235 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8236 RegisterInfo base_reg; 8237 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8238 8239 EmulateInstruction::Context context; 8240 context.type = eContextReturnFromException; 8241 context.SetRegisterPlusOffset (base_reg, address - Rn); 8242 8243 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8244 if (!success) 8245 return false; 8246 8247 CPSRWriteByInstr (data, 15, true); 8248 8249 // BranchWritePC(MemA[address,4]); 8250 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8251 if (!success) 8252 return false; 8253 8254 BranchWritePC (context, data2); 8255 8256 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8257 if (wback) 8258 { 8259 context.type = eContextAdjustBaseRegister; 8260 if (increment) 8261 { 8262 context.SetOffset (8); 8263 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8264 return false; 8265 } 8266 else 8267 { 8268 context.SetOffset (-8); 8269 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8270 return false; 8271 } 8272 } // if wback 8273 } 8274 } // if ConditionPassed() 8275 return true; 8276 } 8277 8278 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8279 // and writes the result to the destination register. It can optionally update the condition flags based on 8280 // the result. 8281 bool 8282 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8283 { 8284 #if 0 8285 // ARM pseudo code... 8286 if ConditionPassed() then 8287 EncodingSpecificOperations(); 8288 result = R[n] EOR imm32; 8289 if d == 15 then // Can only occur for ARM encoding 8290 ALUWritePC(result); // setflags is always FALSE here 8291 else 8292 R[d] = result; 8293 if setflags then 8294 APSR.N = result<31>; 8295 APSR.Z = IsZeroBit(result); 8296 APSR.C = carry; 8297 // APSR.V unchanged 8298 #endif 8299 8300 bool success = false; 8301 8302 if (ConditionPassed(opcode)) 8303 { 8304 uint32_t Rd, Rn; 8305 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8306 bool setflags; 8307 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8308 switch (encoding) 8309 { 8310 case eEncodingT1: 8311 Rd = Bits32(opcode, 11, 8); 8312 Rn = Bits32(opcode, 19, 16); 8313 setflags = BitIsSet(opcode, 20); 8314 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8315 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8316 if (Rd == 15 && setflags) 8317 return EmulateTEQImm (opcode, eEncodingT1); 8318 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8319 return false; 8320 break; 8321 case eEncodingA1: 8322 Rd = Bits32(opcode, 15, 12); 8323 Rn = Bits32(opcode, 19, 16); 8324 setflags = BitIsSet(opcode, 20); 8325 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8326 8327 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8328 if (Rd == 15 && setflags) 8329 return EmulateSUBSPcLrEtc (opcode, encoding); 8330 break; 8331 default: 8332 return false; 8333 } 8334 8335 // Read the first operand. 8336 uint32_t val1 = ReadCoreReg(Rn, &success); 8337 if (!success) 8338 return false; 8339 8340 uint32_t result = val1 ^ imm32; 8341 8342 EmulateInstruction::Context context; 8343 context.type = EmulateInstruction::eContextImmediate; 8344 context.SetNoArgs (); 8345 8346 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8347 return false; 8348 } 8349 return true; 8350 } 8351 8352 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8353 // optionally-shifted register value, and writes the result to the destination register. 8354 // It can optionally update the condition flags based on the result. 8355 bool 8356 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8357 { 8358 #if 0 8359 // ARM pseudo code... 8360 if ConditionPassed() then 8361 EncodingSpecificOperations(); 8362 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8363 result = R[n] EOR shifted; 8364 if d == 15 then // Can only occur for ARM encoding 8365 ALUWritePC(result); // setflags is always FALSE here 8366 else 8367 R[d] = result; 8368 if setflags then 8369 APSR.N = result<31>; 8370 APSR.Z = IsZeroBit(result); 8371 APSR.C = carry; 8372 // APSR.V unchanged 8373 #endif 8374 8375 bool success = false; 8376 8377 if (ConditionPassed(opcode)) 8378 { 8379 uint32_t Rd, Rn, Rm; 8380 ARM_ShifterType shift_t; 8381 uint32_t shift_n; // the shift applied to the value read from Rm 8382 bool setflags; 8383 uint32_t carry; 8384 switch (encoding) 8385 { 8386 case eEncodingT1: 8387 Rd = Rn = Bits32(opcode, 2, 0); 8388 Rm = Bits32(opcode, 5, 3); 8389 setflags = !InITBlock(); 8390 shift_t = SRType_LSL; 8391 shift_n = 0; 8392 break; 8393 case eEncodingT2: 8394 Rd = Bits32(opcode, 11, 8); 8395 Rn = Bits32(opcode, 19, 16); 8396 Rm = Bits32(opcode, 3, 0); 8397 setflags = BitIsSet(opcode, 20); 8398 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8399 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8400 if (Rd == 15 && setflags) 8401 return EmulateTEQReg (opcode, eEncodingT1); 8402 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8403 return false; 8404 break; 8405 case eEncodingA1: 8406 Rd = Bits32(opcode, 15, 12); 8407 Rn = Bits32(opcode, 19, 16); 8408 Rm = Bits32(opcode, 3, 0); 8409 setflags = BitIsSet(opcode, 20); 8410 shift_n = DecodeImmShiftARM(opcode, shift_t); 8411 8412 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8413 if (Rd == 15 && setflags) 8414 return EmulateSUBSPcLrEtc (opcode, encoding); 8415 break; 8416 default: 8417 return false; 8418 } 8419 8420 // Read the first operand. 8421 uint32_t val1 = ReadCoreReg(Rn, &success); 8422 if (!success) 8423 return false; 8424 8425 // Read the second operand. 8426 uint32_t val2 = ReadCoreReg(Rm, &success); 8427 if (!success) 8428 return false; 8429 8430 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8431 if (!success) 8432 return false; 8433 uint32_t result = val1 ^ shifted; 8434 8435 EmulateInstruction::Context context; 8436 context.type = EmulateInstruction::eContextImmediate; 8437 context.SetNoArgs (); 8438 8439 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8440 return false; 8441 } 8442 return true; 8443 } 8444 8445 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8446 // writes the result to the destination register. It can optionally update the condition flags based 8447 // on the result. 8448 bool 8449 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8450 { 8451 #if 0 8452 // ARM pseudo code... 8453 if ConditionPassed() then 8454 EncodingSpecificOperations(); 8455 result = R[n] OR imm32; 8456 if d == 15 then // Can only occur for ARM encoding 8457 ALUWritePC(result); // setflags is always FALSE here 8458 else 8459 R[d] = result; 8460 if setflags then 8461 APSR.N = result<31>; 8462 APSR.Z = IsZeroBit(result); 8463 APSR.C = carry; 8464 // APSR.V unchanged 8465 #endif 8466 8467 bool success = false; 8468 8469 if (ConditionPassed(opcode)) 8470 { 8471 uint32_t Rd, Rn; 8472 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8473 bool setflags; 8474 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8475 switch (encoding) 8476 { 8477 case eEncodingT1: 8478 Rd = Bits32(opcode, 11, 8); 8479 Rn = Bits32(opcode, 19, 16); 8480 setflags = BitIsSet(opcode, 20); 8481 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8482 // if Rn == '1111' then SEE MOV (immediate); 8483 if (Rn == 15) 8484 return EmulateMOVRdImm (opcode, eEncodingT2); 8485 if (BadReg(Rd) || Rn == 13) 8486 return false; 8487 break; 8488 case eEncodingA1: 8489 Rd = Bits32(opcode, 15, 12); 8490 Rn = Bits32(opcode, 19, 16); 8491 setflags = BitIsSet(opcode, 20); 8492 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8493 8494 if (Rd == 15 && setflags) 8495 return EmulateSUBSPcLrEtc (opcode, encoding); 8496 break; 8497 default: 8498 return false; 8499 } 8500 8501 // Read the first operand. 8502 uint32_t val1 = ReadCoreReg(Rn, &success); 8503 if (!success) 8504 return false; 8505 8506 uint32_t result = val1 | imm32; 8507 8508 EmulateInstruction::Context context; 8509 context.type = EmulateInstruction::eContextImmediate; 8510 context.SetNoArgs (); 8511 8512 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8513 return false; 8514 } 8515 return true; 8516 } 8517 8518 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8519 // value, and writes the result to the destination register. It can optionally update the condition flags based 8520 // on the result. 8521 bool 8522 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8523 { 8524 #if 0 8525 // ARM pseudo code... 8526 if ConditionPassed() then 8527 EncodingSpecificOperations(); 8528 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8529 result = R[n] OR shifted; 8530 if d == 15 then // Can only occur for ARM encoding 8531 ALUWritePC(result); // setflags is always FALSE here 8532 else 8533 R[d] = result; 8534 if setflags then 8535 APSR.N = result<31>; 8536 APSR.Z = IsZeroBit(result); 8537 APSR.C = carry; 8538 // APSR.V unchanged 8539 #endif 8540 8541 bool success = false; 8542 8543 if (ConditionPassed(opcode)) 8544 { 8545 uint32_t Rd, Rn, Rm; 8546 ARM_ShifterType shift_t; 8547 uint32_t shift_n; // the shift applied to the value read from Rm 8548 bool setflags; 8549 uint32_t carry; 8550 switch (encoding) 8551 { 8552 case eEncodingT1: 8553 Rd = Rn = Bits32(opcode, 2, 0); 8554 Rm = Bits32(opcode, 5, 3); 8555 setflags = !InITBlock(); 8556 shift_t = SRType_LSL; 8557 shift_n = 0; 8558 break; 8559 case eEncodingT2: 8560 Rd = Bits32(opcode, 11, 8); 8561 Rn = Bits32(opcode, 19, 16); 8562 Rm = Bits32(opcode, 3, 0); 8563 setflags = BitIsSet(opcode, 20); 8564 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8565 // if Rn == '1111' then SEE MOV (register); 8566 if (Rn == 15) 8567 return EmulateMOVRdRm (opcode, eEncodingT3); 8568 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8569 return false; 8570 break; 8571 case eEncodingA1: 8572 Rd = Bits32(opcode, 15, 12); 8573 Rn = Bits32(opcode, 19, 16); 8574 Rm = Bits32(opcode, 3, 0); 8575 setflags = BitIsSet(opcode, 20); 8576 shift_n = DecodeImmShiftARM(opcode, shift_t); 8577 8578 if (Rd == 15 && setflags) 8579 return EmulateSUBSPcLrEtc (opcode, encoding); 8580 break; 8581 default: 8582 return false; 8583 } 8584 8585 // Read the first operand. 8586 uint32_t val1 = ReadCoreReg(Rn, &success); 8587 if (!success) 8588 return false; 8589 8590 // Read the second operand. 8591 uint32_t val2 = ReadCoreReg(Rm, &success); 8592 if (!success) 8593 return false; 8594 8595 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8596 if (!success) 8597 return false; 8598 uint32_t result = val1 | shifted; 8599 8600 EmulateInstruction::Context context; 8601 context.type = EmulateInstruction::eContextImmediate; 8602 context.SetNoArgs (); 8603 8604 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8605 return false; 8606 } 8607 return true; 8608 } 8609 8610 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8611 // the destination register. It can optionally update the condition flags based on the result. 8612 bool 8613 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8614 { 8615 #if 0 8616 // ARM pseudo code... 8617 if ConditionPassed() then 8618 EncodingSpecificOperations(); 8619 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8620 if d == 15 then // Can only occur for ARM encoding 8621 ALUWritePC(result); // setflags is always FALSE here 8622 else 8623 R[d] = result; 8624 if setflags then 8625 APSR.N = result<31>; 8626 APSR.Z = IsZeroBit(result); 8627 APSR.C = carry; 8628 APSR.V = overflow; 8629 #endif 8630 8631 bool success = false; 8632 8633 uint32_t Rd; // the destination register 8634 uint32_t Rn; // the first operand 8635 bool setflags; 8636 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8637 switch (encoding) { 8638 case eEncodingT1: 8639 Rd = Bits32(opcode, 2, 0); 8640 Rn = Bits32(opcode, 5, 3); 8641 setflags = !InITBlock(); 8642 imm32 = 0; 8643 break; 8644 case eEncodingT2: 8645 Rd = Bits32(opcode, 11, 8); 8646 Rn = Bits32(opcode, 19, 16); 8647 setflags = BitIsSet(opcode, 20); 8648 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8649 if (BadReg(Rd) || BadReg(Rn)) 8650 return false; 8651 break; 8652 case eEncodingA1: 8653 Rd = Bits32(opcode, 15, 12); 8654 Rn = Bits32(opcode, 19, 16); 8655 setflags = BitIsSet(opcode, 20); 8656 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8657 8658 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8659 if (Rd == 15 && setflags) 8660 return EmulateSUBSPcLrEtc (opcode, encoding); 8661 break; 8662 default: 8663 return false; 8664 } 8665 // Read the register value from the operand register Rn. 8666 uint32_t reg_val = ReadCoreReg(Rn, &success); 8667 if (!success) 8668 return false; 8669 8670 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8671 8672 EmulateInstruction::Context context; 8673 context.type = EmulateInstruction::eContextImmediate; 8674 context.SetNoArgs (); 8675 8676 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8677 return false; 8678 8679 return true; 8680 } 8681 8682 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8683 // result to the destination register. It can optionally update the condition flags based on the result. 8684 bool 8685 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8686 { 8687 #if 0 8688 // ARM pseudo code... 8689 if ConditionPassed() then 8690 EncodingSpecificOperations(); 8691 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8692 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8693 if d == 15 then // Can only occur for ARM encoding 8694 ALUWritePC(result); // setflags is always FALSE here 8695 else 8696 R[d] = result; 8697 if setflags then 8698 APSR.N = result<31>; 8699 APSR.Z = IsZeroBit(result); 8700 APSR.C = carry; 8701 APSR.V = overflow; 8702 #endif 8703 8704 bool success = false; 8705 8706 uint32_t Rd; // the destination register 8707 uint32_t Rn; // the first operand 8708 uint32_t Rm; // the second operand 8709 bool setflags; 8710 ARM_ShifterType shift_t; 8711 uint32_t shift_n; // the shift applied to the value read from Rm 8712 switch (encoding) { 8713 case eEncodingT1: 8714 Rd = Bits32(opcode, 11, 8); 8715 Rn = Bits32(opcode, 19, 16); 8716 Rm = Bits32(opcode, 3, 0); 8717 setflags = BitIsSet(opcode, 20); 8718 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8719 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8720 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8721 return false; 8722 break; 8723 case eEncodingA1: 8724 Rd = Bits32(opcode, 15, 12); 8725 Rn = Bits32(opcode, 19, 16); 8726 Rm = Bits32(opcode, 3, 0); 8727 setflags = BitIsSet(opcode, 20); 8728 shift_n = DecodeImmShiftARM(opcode, shift_t); 8729 8730 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8731 if (Rd == 15 && setflags) 8732 return EmulateSUBSPcLrEtc (opcode, encoding); 8733 break; 8734 default: 8735 return false; 8736 } 8737 // Read the register value from register Rn. 8738 uint32_t val1 = ReadCoreReg(Rn, &success); 8739 if (!success) 8740 return false; 8741 8742 // Read the register value from register Rm. 8743 uint32_t val2 = ReadCoreReg(Rm, &success); 8744 if (!success) 8745 return false; 8746 8747 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8748 if (!success) 8749 return false; 8750 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8751 8752 EmulateInstruction::Context context; 8753 context.type = EmulateInstruction::eContextImmediate; 8754 context.SetNoArgs(); 8755 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8756 return false; 8757 8758 return true; 8759 } 8760 8761 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8762 // an immediate value, and writes the result to the destination register. It can optionally update the condition 8763 // flags based on the result. 8764 bool 8765 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8766 { 8767 #if 0 8768 // ARM pseudo code... 8769 if ConditionPassed() then 8770 EncodingSpecificOperations(); 8771 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8772 if d == 15 then 8773 ALUWritePC(result); // setflags is always FALSE here 8774 else 8775 R[d] = result; 8776 if setflags then 8777 APSR.N = result<31>; 8778 APSR.Z = IsZeroBit(result); 8779 APSR.C = carry; 8780 APSR.V = overflow; 8781 #endif 8782 8783 bool success = false; 8784 8785 uint32_t Rd; // the destination register 8786 uint32_t Rn; // the first operand 8787 bool setflags; 8788 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8789 switch (encoding) { 8790 case eEncodingA1: 8791 Rd = Bits32(opcode, 15, 12); 8792 Rn = Bits32(opcode, 19, 16); 8793 setflags = BitIsSet(opcode, 20); 8794 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8795 8796 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8797 if (Rd == 15 && setflags) 8798 return EmulateSUBSPcLrEtc (opcode, encoding); 8799 break; 8800 default: 8801 return false; 8802 } 8803 // Read the register value from the operand register Rn. 8804 uint32_t reg_val = ReadCoreReg(Rn, &success); 8805 if (!success) 8806 return false; 8807 8808 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8809 8810 EmulateInstruction::Context context; 8811 context.type = EmulateInstruction::eContextImmediate; 8812 context.SetNoArgs (); 8813 8814 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8815 return false; 8816 8817 return true; 8818 } 8819 8820 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8821 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8822 // condition flags based on the result. 8823 bool 8824 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8825 { 8826 #if 0 8827 // ARM pseudo code... 8828 if ConditionPassed() then 8829 EncodingSpecificOperations(); 8830 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8831 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8832 if d == 15 then 8833 ALUWritePC(result); // setflags is always FALSE here 8834 else 8835 R[d] = result; 8836 if setflags then 8837 APSR.N = result<31>; 8838 APSR.Z = IsZeroBit(result); 8839 APSR.C = carry; 8840 APSR.V = overflow; 8841 #endif 8842 8843 bool success = false; 8844 8845 uint32_t Rd; // the destination register 8846 uint32_t Rn; // the first operand 8847 uint32_t Rm; // the second operand 8848 bool setflags; 8849 ARM_ShifterType shift_t; 8850 uint32_t shift_n; // the shift applied to the value read from Rm 8851 switch (encoding) { 8852 case eEncodingA1: 8853 Rd = Bits32(opcode, 15, 12); 8854 Rn = Bits32(opcode, 19, 16); 8855 Rm = Bits32(opcode, 3, 0); 8856 setflags = BitIsSet(opcode, 20); 8857 shift_n = DecodeImmShiftARM(opcode, shift_t); 8858 8859 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8860 if (Rd == 15 && setflags) 8861 return EmulateSUBSPcLrEtc (opcode, encoding); 8862 break; 8863 default: 8864 return false; 8865 } 8866 // Read the register value from register Rn. 8867 uint32_t val1 = ReadCoreReg(Rn, &success); 8868 if (!success) 8869 return false; 8870 8871 // Read the register value from register Rm. 8872 uint32_t val2 = ReadCoreReg(Rm, &success); 8873 if (!success) 8874 return false; 8875 8876 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8877 if (!success) 8878 return false; 8879 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8880 8881 EmulateInstruction::Context context; 8882 context.type = EmulateInstruction::eContextImmediate; 8883 context.SetNoArgs(); 8884 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8885 return false; 8886 8887 return true; 8888 } 8889 8890 // Subtract with Carry (immediate) subtracts an immediate value and the value of 8891 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8892 // It can optionally update the condition flags based on the result. 8893 bool 8894 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8895 { 8896 #if 0 8897 // ARM pseudo code... 8898 if ConditionPassed() then 8899 EncodingSpecificOperations(); 8900 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8901 if d == 15 then // Can only occur for ARM encoding 8902 ALUWritePC(result); // setflags is always FALSE here 8903 else 8904 R[d] = result; 8905 if setflags then 8906 APSR.N = result<31>; 8907 APSR.Z = IsZeroBit(result); 8908 APSR.C = carry; 8909 APSR.V = overflow; 8910 #endif 8911 8912 bool success = false; 8913 8914 uint32_t Rd; // the destination register 8915 uint32_t Rn; // the first operand 8916 bool setflags; 8917 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8918 switch (encoding) { 8919 case eEncodingT1: 8920 Rd = Bits32(opcode, 11, 8); 8921 Rn = Bits32(opcode, 19, 16); 8922 setflags = BitIsSet(opcode, 20); 8923 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8924 if (BadReg(Rd) || BadReg(Rn)) 8925 return false; 8926 break; 8927 case eEncodingA1: 8928 Rd = Bits32(opcode, 15, 12); 8929 Rn = Bits32(opcode, 19, 16); 8930 setflags = BitIsSet(opcode, 20); 8931 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8932 8933 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8934 if (Rd == 15 && setflags) 8935 return EmulateSUBSPcLrEtc (opcode, encoding); 8936 break; 8937 default: 8938 return false; 8939 } 8940 // Read the register value from the operand register Rn. 8941 uint32_t reg_val = ReadCoreReg(Rn, &success); 8942 if (!success) 8943 return false; 8944 8945 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 8946 8947 EmulateInstruction::Context context; 8948 context.type = EmulateInstruction::eContextImmediate; 8949 context.SetNoArgs (); 8950 8951 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8952 return false; 8953 8954 return true; 8955 } 8956 8957 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 8958 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8959 // It can optionally update the condition flags based on the result. 8960 bool 8961 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 8962 { 8963 #if 0 8964 // ARM pseudo code... 8965 if ConditionPassed() then 8966 EncodingSpecificOperations(); 8967 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8968 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 8969 if d == 15 then // Can only occur for ARM encoding 8970 ALUWritePC(result); // setflags is always FALSE here 8971 else 8972 R[d] = result; 8973 if setflags then 8974 APSR.N = result<31>; 8975 APSR.Z = IsZeroBit(result); 8976 APSR.C = carry; 8977 APSR.V = overflow; 8978 #endif 8979 8980 bool success = false; 8981 8982 uint32_t Rd; // the destination register 8983 uint32_t Rn; // the first operand 8984 uint32_t Rm; // the second operand 8985 bool setflags; 8986 ARM_ShifterType shift_t; 8987 uint32_t shift_n; // the shift applied to the value read from Rm 8988 switch (encoding) { 8989 case eEncodingT1: 8990 Rd = Rn = Bits32(opcode, 2, 0); 8991 Rm = Bits32(opcode, 5, 3); 8992 setflags = !InITBlock(); 8993 shift_t = SRType_LSL; 8994 shift_n = 0; 8995 break; 8996 case eEncodingT2: 8997 Rd = Bits32(opcode, 11, 8); 8998 Rn = Bits32(opcode, 19, 16); 8999 Rm = Bits32(opcode, 3, 0); 9000 setflags = BitIsSet(opcode, 20); 9001 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9002 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9003 return false; 9004 break; 9005 case eEncodingA1: 9006 Rd = Bits32(opcode, 15, 12); 9007 Rn = Bits32(opcode, 19, 16); 9008 Rm = Bits32(opcode, 3, 0); 9009 setflags = BitIsSet(opcode, 20); 9010 shift_n = DecodeImmShiftARM(opcode, shift_t); 9011 9012 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9013 if (Rd == 15 && setflags) 9014 return EmulateSUBSPcLrEtc (opcode, encoding); 9015 break; 9016 default: 9017 return false; 9018 } 9019 // Read the register value from register Rn. 9020 uint32_t val1 = ReadCoreReg(Rn, &success); 9021 if (!success) 9022 return false; 9023 9024 // Read the register value from register Rm. 9025 uint32_t val2 = ReadCoreReg(Rm, &success); 9026 if (!success) 9027 return false; 9028 9029 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9030 if (!success) 9031 return false; 9032 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9033 9034 EmulateInstruction::Context context; 9035 context.type = EmulateInstruction::eContextImmediate; 9036 context.SetNoArgs(); 9037 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9038 return false; 9039 9040 return true; 9041 } 9042 9043 // This instruction subtracts an immediate value from a register value, and writes the result 9044 // to the destination register. It can optionally update the condition flags based on the result. 9045 bool 9046 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9047 { 9048 #if 0 9049 // ARM pseudo code... 9050 if ConditionPassed() then 9051 EncodingSpecificOperations(); 9052 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9053 R[d] = result; 9054 if setflags then 9055 APSR.N = result<31>; 9056 APSR.Z = IsZeroBit(result); 9057 APSR.C = carry; 9058 APSR.V = overflow; 9059 #endif 9060 9061 bool success = false; 9062 9063 uint32_t Rd; // the destination register 9064 uint32_t Rn; // the first operand 9065 bool setflags; 9066 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9067 switch (encoding) { 9068 case eEncodingT1: 9069 Rd = Bits32(opcode, 2, 0); 9070 Rn = Bits32(opcode, 5, 3); 9071 setflags = !InITBlock(); 9072 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9073 break; 9074 case eEncodingT2: 9075 Rd = Rn = Bits32(opcode, 10, 8); 9076 setflags = !InITBlock(); 9077 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9078 break; 9079 case eEncodingT3: 9080 Rd = Bits32(opcode, 11, 8); 9081 Rn = Bits32(opcode, 19, 16); 9082 setflags = BitIsSet(opcode, 20); 9083 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9084 9085 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9086 if (Rd == 15 && setflags) 9087 return EmulateCMPImm (opcode, eEncodingT2); 9088 9089 // if Rn == '1101' then SEE SUB (SP minus immediate); 9090 if (Rn == 13) 9091 return EmulateSUBSPImm (opcode, eEncodingT2); 9092 9093 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9094 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9095 return false; 9096 break; 9097 case eEncodingT4: 9098 Rd = Bits32(opcode, 11, 8); 9099 Rn = Bits32(opcode, 19, 16); 9100 setflags = BitIsSet(opcode, 20); 9101 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9102 9103 // if Rn == '1111' then SEE ADR; 9104 if (Rn == 15) 9105 return EmulateADR (opcode, eEncodingT2); 9106 9107 // if Rn == '1101' then SEE SUB (SP minus immediate); 9108 if (Rn == 13) 9109 return EmulateSUBSPImm (opcode, eEncodingT3); 9110 9111 if (BadReg(Rd)) 9112 return false; 9113 break; 9114 default: 9115 return false; 9116 } 9117 // Read the register value from the operand register Rn. 9118 uint32_t reg_val = ReadCoreReg(Rn, &success); 9119 if (!success) 9120 return false; 9121 9122 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9123 9124 EmulateInstruction::Context context; 9125 context.type = EmulateInstruction::eContextImmediate; 9126 context.SetNoArgs (); 9127 9128 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9129 return false; 9130 9131 return true; 9132 } 9133 9134 // This instruction subtracts an immediate value from a register value, and writes the result 9135 // to the destination register. It can optionally update the condition flags based on the result. 9136 bool 9137 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9138 { 9139 #if 0 9140 // ARM pseudo code... 9141 if ConditionPassed() then 9142 EncodingSpecificOperations(); 9143 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9144 if d == 15 then 9145 ALUWritePC(result); // setflags is always FALSE here 9146 else 9147 R[d] = result; 9148 if setflags then 9149 APSR.N = result<31>; 9150 APSR.Z = IsZeroBit(result); 9151 APSR.C = carry; 9152 APSR.V = overflow; 9153 #endif 9154 9155 bool success = false; 9156 9157 uint32_t Rd; // the destination register 9158 uint32_t Rn; // the first operand 9159 bool setflags; 9160 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9161 switch (encoding) { 9162 case eEncodingA1: 9163 Rd = Bits32(opcode, 15, 12); 9164 Rn = Bits32(opcode, 19, 16); 9165 setflags = BitIsSet(opcode, 20); 9166 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9167 9168 // if Rn == '1111' && S == '0' then SEE ADR; 9169 if (Rn == 15 && !setflags) 9170 return EmulateADR (opcode, eEncodingA2); 9171 9172 // if Rn == '1101' then SEE SUB (SP minus immediate); 9173 if (Rn == 13) 9174 return EmulateSUBSPImm (opcode, eEncodingA1); 9175 9176 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9177 if (Rd == 15 && setflags) 9178 return EmulateSUBSPcLrEtc (opcode, encoding); 9179 break; 9180 default: 9181 return false; 9182 } 9183 // Read the register value from the operand register Rn. 9184 uint32_t reg_val = ReadCoreReg(Rn, &success); 9185 if (!success) 9186 return false; 9187 9188 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9189 9190 EmulateInstruction::Context context; 9191 context.type = EmulateInstruction::eContextImmediate; 9192 context.SetNoArgs (); 9193 9194 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9195 return false; 9196 9197 return true; 9198 } 9199 9200 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9201 // immediate value. It updates the condition flags based on the result, and discards the result. 9202 bool 9203 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9204 { 9205 #if 0 9206 // ARM pseudo code... 9207 if ConditionPassed() then 9208 EncodingSpecificOperations(); 9209 result = R[n] EOR imm32; 9210 APSR.N = result<31>; 9211 APSR.Z = IsZeroBit(result); 9212 APSR.C = carry; 9213 // APSR.V unchanged 9214 #endif 9215 9216 bool success = false; 9217 9218 if (ConditionPassed(opcode)) 9219 { 9220 uint32_t Rn; 9221 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9222 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9223 switch (encoding) 9224 { 9225 case eEncodingT1: 9226 Rn = Bits32(opcode, 19, 16); 9227 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9228 if (BadReg(Rn)) 9229 return false; 9230 break; 9231 case eEncodingA1: 9232 Rn = Bits32(opcode, 19, 16); 9233 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9234 break; 9235 default: 9236 return false; 9237 } 9238 9239 // Read the first operand. 9240 uint32_t val1 = ReadCoreReg(Rn, &success); 9241 if (!success) 9242 return false; 9243 9244 uint32_t result = val1 ^ imm32; 9245 9246 EmulateInstruction::Context context; 9247 context.type = EmulateInstruction::eContextImmediate; 9248 context.SetNoArgs (); 9249 9250 if (!WriteFlags(context, result, carry)) 9251 return false; 9252 } 9253 return true; 9254 } 9255 9256 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9257 // optionally-shifted register value. It updates the condition flags based on the result, and discards 9258 // the result. 9259 bool 9260 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9261 { 9262 #if 0 9263 // ARM pseudo code... 9264 if ConditionPassed() then 9265 EncodingSpecificOperations(); 9266 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9267 result = R[n] EOR shifted; 9268 APSR.N = result<31>; 9269 APSR.Z = IsZeroBit(result); 9270 APSR.C = carry; 9271 // APSR.V unchanged 9272 #endif 9273 9274 bool success = false; 9275 9276 if (ConditionPassed(opcode)) 9277 { 9278 uint32_t Rn, Rm; 9279 ARM_ShifterType shift_t; 9280 uint32_t shift_n; // the shift applied to the value read from Rm 9281 uint32_t carry; 9282 switch (encoding) 9283 { 9284 case eEncodingT1: 9285 Rn = Bits32(opcode, 19, 16); 9286 Rm = Bits32(opcode, 3, 0); 9287 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9288 if (BadReg(Rn) || BadReg(Rm)) 9289 return false; 9290 break; 9291 case eEncodingA1: 9292 Rn = Bits32(opcode, 19, 16); 9293 Rm = Bits32(opcode, 3, 0); 9294 shift_n = DecodeImmShiftARM(opcode, shift_t); 9295 break; 9296 default: 9297 return false; 9298 } 9299 9300 // Read the first operand. 9301 uint32_t val1 = ReadCoreReg(Rn, &success); 9302 if (!success) 9303 return false; 9304 9305 // Read the second operand. 9306 uint32_t val2 = ReadCoreReg(Rm, &success); 9307 if (!success) 9308 return false; 9309 9310 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9311 if (!success) 9312 return false; 9313 uint32_t result = val1 ^ shifted; 9314 9315 EmulateInstruction::Context context; 9316 context.type = EmulateInstruction::eContextImmediate; 9317 context.SetNoArgs (); 9318 9319 if (!WriteFlags(context, result, carry)) 9320 return false; 9321 } 9322 return true; 9323 } 9324 9325 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9326 // It updates the condition flags based on the result, and discards the result. 9327 bool 9328 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9329 { 9330 #if 0 9331 // ARM pseudo code... 9332 if ConditionPassed() then 9333 EncodingSpecificOperations(); 9334 result = R[n] AND imm32; 9335 APSR.N = result<31>; 9336 APSR.Z = IsZeroBit(result); 9337 APSR.C = carry; 9338 // APSR.V unchanged 9339 #endif 9340 9341 bool success = false; 9342 9343 if (ConditionPassed(opcode)) 9344 { 9345 uint32_t Rn; 9346 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9347 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9348 switch (encoding) 9349 { 9350 case eEncodingT1: 9351 Rn = Bits32(opcode, 19, 16); 9352 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9353 if (BadReg(Rn)) 9354 return false; 9355 break; 9356 case eEncodingA1: 9357 Rn = Bits32(opcode, 19, 16); 9358 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9359 break; 9360 default: 9361 return false; 9362 } 9363 9364 // Read the first operand. 9365 uint32_t val1 = ReadCoreReg(Rn, &success); 9366 if (!success) 9367 return false; 9368 9369 uint32_t result = val1 & imm32; 9370 9371 EmulateInstruction::Context context; 9372 context.type = EmulateInstruction::eContextImmediate; 9373 context.SetNoArgs (); 9374 9375 if (!WriteFlags(context, result, carry)) 9376 return false; 9377 } 9378 return true; 9379 } 9380 9381 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9382 // It updates the condition flags based on the result, and discards the result. 9383 bool 9384 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9385 { 9386 #if 0 9387 // ARM pseudo code... 9388 if ConditionPassed() then 9389 EncodingSpecificOperations(); 9390 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9391 result = R[n] AND shifted; 9392 APSR.N = result<31>; 9393 APSR.Z = IsZeroBit(result); 9394 APSR.C = carry; 9395 // APSR.V unchanged 9396 #endif 9397 9398 bool success = false; 9399 9400 if (ConditionPassed(opcode)) 9401 { 9402 uint32_t Rn, Rm; 9403 ARM_ShifterType shift_t; 9404 uint32_t shift_n; // the shift applied to the value read from Rm 9405 uint32_t carry; 9406 switch (encoding) 9407 { 9408 case eEncodingT1: 9409 Rn = Bits32(opcode, 2, 0); 9410 Rm = Bits32(opcode, 5, 3); 9411 shift_t = SRType_LSL; 9412 shift_n = 0; 9413 break; 9414 case eEncodingT2: 9415 Rn = Bits32(opcode, 19, 16); 9416 Rm = Bits32(opcode, 3, 0); 9417 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9418 if (BadReg(Rn) || BadReg(Rm)) 9419 return false; 9420 break; 9421 case eEncodingA1: 9422 Rn = Bits32(opcode, 19, 16); 9423 Rm = Bits32(opcode, 3, 0); 9424 shift_n = DecodeImmShiftARM(opcode, shift_t); 9425 break; 9426 default: 9427 return false; 9428 } 9429 9430 // Read the first operand. 9431 uint32_t val1 = ReadCoreReg(Rn, &success); 9432 if (!success) 9433 return false; 9434 9435 // Read the second operand. 9436 uint32_t val2 = ReadCoreReg(Rm, &success); 9437 if (!success) 9438 return false; 9439 9440 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9441 if (!success) 9442 return false; 9443 uint32_t result = val1 & shifted; 9444 9445 EmulateInstruction::Context context; 9446 context.type = EmulateInstruction::eContextImmediate; 9447 context.SetNoArgs (); 9448 9449 if (!WriteFlags(context, result, carry)) 9450 return false; 9451 } 9452 return true; 9453 } 9454 9455 // A8.6.216 SUB (SP minus register) 9456 bool 9457 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9458 { 9459 #if 0 9460 if ConditionPassed() then 9461 EncodingSpecificOperations(); 9462 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9463 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9464 if d == 15 then // Can only occur for ARM encoding 9465 ALUWritePC(result); // setflags is always FALSE here 9466 else 9467 R[d] = result; 9468 if setflags then 9469 APSR.N = result<31>; 9470 APSR.Z = IsZeroBit(result); 9471 APSR.C = carry; 9472 APSR.V = overflow; 9473 #endif 9474 9475 bool success = false; 9476 9477 if (ConditionPassed(opcode)) 9478 { 9479 uint32_t d; 9480 uint32_t m; 9481 bool setflags; 9482 ARM_ShifterType shift_t; 9483 uint32_t shift_n; 9484 9485 switch (encoding) 9486 { 9487 case eEncodingT1: 9488 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9489 d = Bits32 (opcode, 11, 8); 9490 m = Bits32 (opcode, 3, 0); 9491 setflags = BitIsSet (opcode, 20); 9492 9493 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9494 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9495 9496 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9497 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9498 return false; 9499 9500 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9501 if ((d == 15) || BadReg (m)) 9502 return false; 9503 break; 9504 9505 case eEncodingA1: 9506 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9507 d = Bits32 (opcode, 15, 12); 9508 m = Bits32 (opcode, 3, 0); 9509 setflags = BitIsSet (opcode, 20); 9510 9511 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9512 if (d == 15 && setflags) 9513 EmulateSUBSPcLrEtc (opcode, encoding); 9514 9515 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9516 shift_n = DecodeImmShiftARM (opcode, shift_t); 9517 break; 9518 9519 default: 9520 return false; 9521 } 9522 9523 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9524 uint32_t Rm = ReadCoreReg (m, &success); 9525 if (!success) 9526 return false; 9527 9528 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9529 if (!success) 9530 return false; 9531 9532 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9533 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9534 if (!success) 9535 return false; 9536 9537 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9538 9539 EmulateInstruction::Context context; 9540 context.type = eContextArithmetic; 9541 RegisterInfo sp_reg; 9542 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9543 RegisterInfo dwarf_reg; 9544 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9545 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9546 9547 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9548 return false; 9549 } 9550 return true; 9551 } 9552 9553 9554 // A8.6.7 ADD (register-shifted register) 9555 bool 9556 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9557 { 9558 #if 0 9559 if ConditionPassed() then 9560 EncodingSpecificOperations(); 9561 shift_n = UInt(R[s]<7:0>); 9562 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9563 (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9564 R[d] = result; 9565 if setflags then 9566 APSR.N = result<31>; 9567 APSR.Z = IsZeroBit(result); 9568 APSR.C = carry; 9569 APSR.V = overflow; 9570 #endif 9571 9572 bool success = false; 9573 9574 if (ConditionPassed(opcode)) 9575 { 9576 uint32_t d; 9577 uint32_t n; 9578 uint32_t m; 9579 uint32_t s; 9580 bool setflags; 9581 ARM_ShifterType shift_t; 9582 9583 switch (encoding) 9584 { 9585 case eEncodingA1: 9586 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9587 d = Bits32 (opcode, 15, 12); 9588 n = Bits32 (opcode, 19, 16); 9589 m = Bits32 (opcode, 3, 0); 9590 s = Bits32 (opcode, 11, 8); 9591 9592 // setflags = (S == �1�); shift_t = DecodeRegShift(type); 9593 setflags = BitIsSet (opcode, 20); 9594 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9595 9596 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9597 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9598 return false; 9599 break; 9600 9601 default: 9602 return false; 9603 } 9604 9605 // shift_n = UInt(R[s]<7:0>); 9606 uint32_t Rs = ReadCoreReg (s, &success); 9607 if (!success) 9608 return false; 9609 9610 uint32_t shift_n = Bits32 (Rs, 7, 0); 9611 9612 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9613 uint32_t Rm = ReadCoreReg (m, &success); 9614 if (!success) 9615 return false; 9616 9617 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9618 if (!success) 9619 return false; 9620 9621 // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9622 uint32_t Rn = ReadCoreReg (n, &success); 9623 if (!success) 9624 return false; 9625 9626 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9627 9628 // R[d] = result; 9629 EmulateInstruction::Context context; 9630 context.type = eContextArithmetic; 9631 RegisterInfo reg_n; 9632 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9633 RegisterInfo reg_m; 9634 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9635 9636 context.SetRegisterRegisterOperands (reg_n, reg_m); 9637 9638 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9639 return false; 9640 9641 // if setflags then 9642 // APSR.N = result<31>; 9643 // APSR.Z = IsZeroBit(result); 9644 // APSR.C = carry; 9645 // APSR.V = overflow; 9646 if (setflags) 9647 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9648 } 9649 return true; 9650 } 9651 9652 // A8.6.213 SUB (register) 9653 bool 9654 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9655 { 9656 #if 0 9657 if ConditionPassed() then 9658 EncodingSpecificOperations(); 9659 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9660 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9661 if d == 15 then // Can only occur for ARM encoding 9662 ALUWritePC(result); // setflags is always FALSE here 9663 else 9664 R[d] = result; 9665 if setflags then 9666 APSR.N = result<31>; 9667 APSR.Z = IsZeroBit(result); 9668 APSR.C = carry; 9669 APSR.V = overflow; 9670 #endif 9671 9672 bool success = false; 9673 9674 if (ConditionPassed(opcode)) 9675 { 9676 uint32_t d; 9677 uint32_t n; 9678 uint32_t m; 9679 bool setflags; 9680 ARM_ShifterType shift_t; 9681 uint32_t shift_n; 9682 9683 switch (encoding) 9684 { 9685 case eEncodingT1: 9686 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9687 d = Bits32 (opcode, 2, 0); 9688 n = Bits32 (opcode, 5, 3); 9689 m = Bits32 (opcode, 8, 6); 9690 setflags = !InITBlock(); 9691 9692 // (shift_t, shift_n) = (SRType_LSL, 0); 9693 shift_t = SRType_LSL; 9694 shift_n = 0; 9695 9696 break; 9697 9698 case eEncodingT2: 9699 // if Rd == �1111� && S == �1� then SEE CMP (register); 9700 // if Rn == �1101� then SEE SUB (SP minus register); 9701 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9702 d = Bits32 (opcode, 11, 8); 9703 n = Bits32 (opcode, 19, 16); 9704 m = Bits32 (opcode, 3, 0); 9705 setflags = BitIsSet (opcode, 20); 9706 9707 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9708 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9709 9710 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9711 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9712 return false; 9713 9714 break; 9715 9716 case eEncodingA1: 9717 // if Rn == �1101� then SEE SUB (SP minus register); 9718 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9719 d = Bits32 (opcode, 15, 12); 9720 n = Bits32 (opcode, 19, 16); 9721 m = Bits32 (opcode, 3, 0); 9722 setflags = BitIsSet (opcode, 20); 9723 9724 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9725 if ((d == 15) && setflags) 9726 EmulateSUBSPcLrEtc (opcode, encoding); 9727 9728 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9729 shift_n = DecodeImmShiftARM (opcode, shift_t); 9730 9731 break; 9732 9733 default: 9734 return false; 9735 } 9736 9737 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9738 uint32_t Rm = ReadCoreReg (m, &success); 9739 if (!success) 9740 return false; 9741 9742 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9743 if (!success) 9744 return false; 9745 9746 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9747 uint32_t Rn = ReadCoreReg (n, &success); 9748 if (!success) 9749 return false; 9750 9751 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9752 9753 // if d == 15 then // Can only occur for ARM encoding 9754 // ALUWritePC(result); // setflags is always FALSE here 9755 // else 9756 // R[d] = result; 9757 // if setflags then 9758 // APSR.N = result<31>; 9759 // APSR.Z = IsZeroBit(result); 9760 // APSR.C = carry; 9761 // APSR.V = overflow; 9762 9763 EmulateInstruction::Context context; 9764 context.type = eContextArithmetic; 9765 RegisterInfo reg_n; 9766 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9767 RegisterInfo reg_m; 9768 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9769 context.SetRegisterRegisterOperands (reg_n, reg_m); 9770 9771 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9772 return false; 9773 } 9774 return true; 9775 } 9776 9777 // A8.6.202 STREX 9778 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9779 // word from a register to memory if the executing processor has exclusive access to the memory addressed. 9780 bool 9781 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9782 { 9783 #if 0 9784 if ConditionPassed() then 9785 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9786 address = R[n] + imm32; 9787 if ExclusiveMonitorsPass(address,4) then 9788 MemA[address,4] = R[t]; 9789 R[d] = 0; 9790 else 9791 R[d] = 1; 9792 #endif 9793 9794 bool success = false; 9795 9796 if (ConditionPassed(opcode)) 9797 { 9798 uint32_t d; 9799 uint32_t t; 9800 uint32_t n; 9801 uint32_t imm32; 9802 const uint32_t addr_byte_size = GetAddressByteSize(); 9803 9804 switch (encoding) 9805 { 9806 case eEncodingT1: 9807 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 9808 d = Bits32 (opcode, 11, 8); 9809 t = Bits32 (opcode, 15, 12); 9810 n = Bits32 (opcode, 19, 16); 9811 imm32 = Bits32 (opcode, 7, 0) << 2; 9812 9813 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9814 if (BadReg (d) || BadReg (t) || (n == 15)) 9815 return false; 9816 9817 // if d == n || d == t then UNPREDICTABLE; 9818 if ((d == n) || (d == t)) 9819 return false; 9820 9821 break; 9822 9823 case eEncodingA1: 9824 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9825 d = Bits32 (opcode, 15, 12); 9826 t = Bits32 (opcode, 3, 0); 9827 n = Bits32 (opcode, 19, 16); 9828 imm32 = 0; 9829 9830 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9831 if ((d == 15) || (t == 15) || (n == 15)) 9832 return false; 9833 9834 // if d == n || d == t then UNPREDICTABLE; 9835 if ((d == n) || (d == t)) 9836 return false; 9837 9838 break; 9839 9840 default: 9841 return false; 9842 } 9843 9844 // address = R[n] + imm32; 9845 uint32_t Rn = ReadCoreReg (n, &success); 9846 if (!success) 9847 return false; 9848 9849 addr_t address = Rn + imm32; 9850 9851 RegisterInfo base_reg; 9852 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9853 RegisterInfo data_reg; 9854 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9855 EmulateInstruction::Context context; 9856 context.type = eContextRegisterStore; 9857 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9858 9859 // if ExclusiveMonitorsPass(address,4) then 9860 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9861 // always return true. 9862 if (true) 9863 { 9864 // MemA[address,4] = R[t]; 9865 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9866 if (!success) 9867 return false; 9868 9869 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9870 return false; 9871 9872 // R[d] = 0; 9873 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9874 return false; 9875 } 9876 else 9877 { 9878 // R[d] = 1; 9879 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9880 return false; 9881 } 9882 } 9883 return true; 9884 } 9885 9886 // A8.6.197 STRB (immediate, ARM) 9887 bool 9888 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9889 { 9890 #if 0 9891 if ConditionPassed() then 9892 EncodingSpecificOperations(); 9893 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9894 address = if index then offset_addr else R[n]; 9895 MemU[address,1] = R[t]<7:0>; 9896 if wback then R[n] = offset_addr; 9897 #endif 9898 9899 bool success = false; 9900 9901 if (ConditionPassed(opcode)) 9902 { 9903 uint32_t t; 9904 uint32_t n; 9905 uint32_t imm32; 9906 bool index; 9907 bool add; 9908 bool wback; 9909 9910 switch (encoding) 9911 { 9912 case eEncodingA1: 9913 // if P == �0� && W == �1� then SEE STRBT; 9914 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9915 t = Bits32 (opcode, 15, 12); 9916 n = Bits32 (opcode, 19, 16); 9917 imm32 = Bits32 (opcode, 11, 0); 9918 9919 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9920 index = BitIsSet (opcode, 24); 9921 add = BitIsSet (opcode, 23); 9922 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9923 9924 // if t == 15 then UNPREDICTABLE; 9925 if (t == 15) 9926 return false; 9927 9928 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9929 if (wback && ((n == 15) || (n == t))) 9930 return false; 9931 9932 break; 9933 9934 default: 9935 return false; 9936 } 9937 9938 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9939 uint32_t Rn = ReadCoreReg (n, &success); 9940 if (!success) 9941 return false; 9942 9943 addr_t offset_addr; 9944 if (add) 9945 offset_addr = Rn + imm32; 9946 else 9947 offset_addr = Rn - imm32; 9948 9949 // address = if index then offset_addr else R[n]; 9950 addr_t address; 9951 if (index) 9952 address = offset_addr; 9953 else 9954 address = Rn; 9955 9956 // MemU[address,1] = R[t]<7:0>; 9957 uint32_t Rt = ReadCoreReg (t, &success); 9958 if (!success) 9959 return false; 9960 9961 RegisterInfo base_reg; 9962 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9963 RegisterInfo data_reg; 9964 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9965 EmulateInstruction::Context context; 9966 context.type = eContextRegisterStore; 9967 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9968 9969 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 9970 return false; 9971 9972 // if wback then R[n] = offset_addr; 9973 if (wback) 9974 { 9975 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9976 return false; 9977 } 9978 } 9979 return true; 9980 } 9981 9982 // A8.6.194 STR (immediate, ARM) 9983 bool 9984 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9985 { 9986 #if 0 9987 if ConditionPassed() then 9988 EncodingSpecificOperations(); 9989 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9990 address = if index then offset_addr else R[n]; 9991 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9992 if wback then R[n] = offset_addr; 9993 #endif 9994 9995 bool success = false; 9996 9997 if (ConditionPassed(opcode)) 9998 { 9999 uint32_t t; 10000 uint32_t n; 10001 uint32_t imm32; 10002 bool index; 10003 bool add; 10004 bool wback; 10005 10006 const uint32_t addr_byte_size = GetAddressByteSize(); 10007 10008 switch (encoding) 10009 { 10010 case eEncodingA1: 10011 // if P == �0� && W == �1� then SEE STRT; 10012 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH; 10013 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10014 t = Bits32 (opcode, 15, 12); 10015 n = Bits32 (opcode, 19, 16); 10016 imm32 = Bits32 (opcode, 11, 0); 10017 10018 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10019 index = BitIsSet (opcode, 24); 10020 add = BitIsSet (opcode, 23); 10021 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10022 10023 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10024 if (wback && ((n == 15) || (n == t))) 10025 return false; 10026 10027 break; 10028 10029 default: 10030 return false; 10031 } 10032 10033 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10034 uint32_t Rn = ReadCoreReg (n, &success); 10035 if (!success) 10036 return false; 10037 10038 addr_t offset_addr; 10039 if (add) 10040 offset_addr = Rn + imm32; 10041 else 10042 offset_addr = Rn - imm32; 10043 10044 // address = if index then offset_addr else R[n]; 10045 addr_t address; 10046 if (index) 10047 address = offset_addr; 10048 else 10049 address = Rn; 10050 10051 RegisterInfo base_reg; 10052 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10053 RegisterInfo data_reg; 10054 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10055 EmulateInstruction::Context context; 10056 context.type = eContextRegisterStore; 10057 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10058 10059 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10060 uint32_t Rt = ReadCoreReg (t, &success); 10061 if (!success) 10062 return false; 10063 10064 if (t == 15) 10065 { 10066 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10067 if (!success) 10068 return false; 10069 10070 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10071 return false; 10072 } 10073 else 10074 { 10075 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10076 return false; 10077 } 10078 10079 // if wback then R[n] = offset_addr; 10080 if (wback) 10081 { 10082 context.type = eContextAdjustBaseRegister; 10083 context.SetImmediate (offset_addr); 10084 10085 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10086 return false; 10087 } 10088 } 10089 return true; 10090 } 10091 10092 // A8.6.66 LDRD (immediate) 10093 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10094 // words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10095 bool 10096 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10097 { 10098 #if 0 10099 if ConditionPassed() then 10100 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10101 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10102 address = if index then offset_addr else R[n]; 10103 R[t] = MemA[address,4]; 10104 R[t2] = MemA[address+4,4]; 10105 if wback then R[n] = offset_addr; 10106 #endif 10107 10108 bool success = false; 10109 10110 if (ConditionPassed(opcode)) 10111 { 10112 uint32_t t; 10113 uint32_t t2; 10114 uint32_t n; 10115 uint32_t imm32; 10116 bool index; 10117 bool add; 10118 bool wback; 10119 10120 switch (encoding) 10121 { 10122 case eEncodingT1: 10123 //if P == �0� && W == �0� then SEE �Related encodings�; 10124 //if Rn == �1111� then SEE LDRD (literal); 10125 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10126 t = Bits32 (opcode, 15, 12); 10127 t2 = Bits32 (opcode, 11, 8); 10128 n = Bits32 (opcode, 19, 16); 10129 imm32 = Bits32 (opcode, 7, 0) << 2; 10130 10131 //index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10132 index = BitIsSet (opcode, 24); 10133 add = BitIsSet (opcode, 23); 10134 wback = BitIsSet (opcode, 21); 10135 10136 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10137 if (wback && ((n == t) || (n == t2))) 10138 return false; 10139 10140 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10141 if (BadReg (t) || BadReg (t2) || (t == t2)) 10142 return false; 10143 10144 break; 10145 10146 case eEncodingA1: 10147 //if Rn == �1111� then SEE LDRD (literal); 10148 //if Rt<0> == �1� then UNPREDICTABLE; 10149 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10150 t = Bits32 (opcode, 15, 12); 10151 if (BitIsSet (t, 0)) 10152 return false; 10153 t2 = t + 1; 10154 n = Bits32 (opcode, 19, 16); 10155 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10156 10157 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10158 index = BitIsSet (opcode, 24); 10159 add = BitIsSet (opcode, 23); 10160 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10161 10162 //if P == �0� && W == �1� then UNPREDICTABLE; 10163 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10164 return false; 10165 10166 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10167 if (wback && ((n == t) || (n == t2))) 10168 return false; 10169 10170 //if t2 == 15 then UNPREDICTABLE; 10171 if (t2 == 15) 10172 return false; 10173 10174 break; 10175 10176 default: 10177 return false; 10178 } 10179 10180 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10181 uint32_t Rn = ReadCoreReg (n, &success); 10182 if (!success) 10183 return false; 10184 10185 addr_t offset_addr; 10186 if (add) 10187 offset_addr = Rn + imm32; 10188 else 10189 offset_addr = Rn - imm32; 10190 10191 //address = if index then offset_addr else R[n]; 10192 addr_t address; 10193 if (index) 10194 address = offset_addr; 10195 else 10196 address = Rn; 10197 10198 //R[t] = MemA[address,4]; 10199 RegisterInfo base_reg; 10200 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10201 10202 EmulateInstruction::Context context; 10203 context.type = eContextRegisterLoad; 10204 context.SetRegisterPlusOffset (base_reg, address - Rn); 10205 10206 const uint32_t addr_byte_size = GetAddressByteSize(); 10207 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10208 if (!success) 10209 return false; 10210 10211 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10212 return false; 10213 10214 //R[t2] = MemA[address+4,4]; 10215 10216 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10217 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10218 if (!success) 10219 return false; 10220 10221 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10222 return false; 10223 10224 //if wback then R[n] = offset_addr; 10225 if (wback) 10226 { 10227 context.type = eContextAdjustBaseRegister; 10228 context.SetAddress (offset_addr); 10229 10230 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10231 return false; 10232 } 10233 } 10234 return true; 10235 } 10236 10237 // A8.6.68 LDRD (register) 10238 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10239 // words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10240 bool 10241 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10242 { 10243 #if 0 10244 if ConditionPassed() then 10245 EncodingSpecificOperations(); 10246 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10247 address = if index then offset_addr else R[n]; 10248 R[t] = MemA[address,4]; 10249 R[t2] = MemA[address+4,4]; 10250 if wback then R[n] = offset_addr; 10251 #endif 10252 10253 bool success = false; 10254 10255 if (ConditionPassed(opcode)) 10256 { 10257 uint32_t t; 10258 uint32_t t2; 10259 uint32_t n; 10260 uint32_t m; 10261 bool index; 10262 bool add; 10263 bool wback; 10264 10265 switch (encoding) 10266 { 10267 case eEncodingA1: 10268 // if Rt<0> == �1� then UNPREDICTABLE; 10269 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10270 t = Bits32 (opcode, 15, 12); 10271 if (BitIsSet (t, 0)) 10272 return false; 10273 t2 = t + 1; 10274 n = Bits32 (opcode, 19, 16); 10275 m = Bits32 (opcode, 3, 0); 10276 10277 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10278 index = BitIsSet (opcode, 24); 10279 add = BitIsSet (opcode, 23); 10280 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10281 10282 // if P == �0� && W == �1� then UNPREDICTABLE; 10283 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10284 return false; 10285 10286 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10287 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10288 return false; 10289 10290 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10291 if (wback && ((n == 15) || (n == t) || (n == t2))) 10292 return false; 10293 10294 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10295 if ((ArchVersion() < 6) && wback && (m == n)) 10296 return false; 10297 break; 10298 10299 default: 10300 return false; 10301 } 10302 10303 uint32_t Rn = ReadCoreReg (n, &success); 10304 if (!success) 10305 return false; 10306 RegisterInfo base_reg; 10307 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10308 10309 uint32_t Rm = ReadCoreReg (m, &success); 10310 if (!success) 10311 return false; 10312 RegisterInfo offset_reg; 10313 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10314 10315 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10316 addr_t offset_addr; 10317 if (add) 10318 offset_addr = Rn + Rm; 10319 else 10320 offset_addr = Rn - Rm; 10321 10322 // address = if index then offset_addr else R[n]; 10323 addr_t address; 10324 if (index) 10325 address = offset_addr; 10326 else 10327 address = Rn; 10328 10329 EmulateInstruction::Context context; 10330 context.type = eContextRegisterLoad; 10331 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10332 10333 // R[t] = MemA[address,4]; 10334 const uint32_t addr_byte_size = GetAddressByteSize(); 10335 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10336 if (!success) 10337 return false; 10338 10339 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10340 return false; 10341 10342 // R[t2] = MemA[address+4,4]; 10343 10344 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10345 if (!success) 10346 return false; 10347 10348 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10349 return false; 10350 10351 // if wback then R[n] = offset_addr; 10352 if (wback) 10353 { 10354 context.type = eContextAdjustBaseRegister; 10355 context.SetAddress (offset_addr); 10356 10357 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10358 return false; 10359 } 10360 } 10361 return true; 10362 } 10363 10364 // A8.6.200 STRD (immediate) 10365 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10366 // stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10367 bool 10368 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10369 { 10370 #if 0 10371 if ConditionPassed() then 10372 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10373 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10374 address = if index then offset_addr else R[n]; 10375 MemA[address,4] = R[t]; 10376 MemA[address+4,4] = R[t2]; 10377 if wback then R[n] = offset_addr; 10378 #endif 10379 10380 bool success = false; 10381 10382 if (ConditionPassed(opcode)) 10383 { 10384 uint32_t t; 10385 uint32_t t2; 10386 uint32_t n; 10387 uint32_t imm32; 10388 bool index; 10389 bool add; 10390 bool wback; 10391 10392 switch (encoding) 10393 { 10394 case eEncodingT1: 10395 // if P == �0� && W == �0� then SEE �Related encodings�; 10396 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10397 t = Bits32 (opcode, 15, 12); 10398 t2 = Bits32 (opcode, 11, 8); 10399 n = Bits32 (opcode, 19, 16); 10400 imm32 = Bits32 (opcode, 7, 0) << 2; 10401 10402 // index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10403 index = BitIsSet (opcode, 24); 10404 add = BitIsSet (opcode, 23); 10405 wback = BitIsSet (opcode, 21); 10406 10407 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10408 if (wback && ((n == t) || (n == t2))) 10409 return false; 10410 10411 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10412 if ((n == 15) || BadReg (t) || BadReg (t2)) 10413 return false; 10414 10415 break; 10416 10417 case eEncodingA1: 10418 // if Rt<0> == �1� then UNPREDICTABLE; 10419 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10420 t = Bits32 (opcode, 15, 12); 10421 if (BitIsSet (t, 0)) 10422 return false; 10423 10424 t2 = t + 1; 10425 n = Bits32 (opcode, 19, 16); 10426 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10427 10428 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10429 index = BitIsSet (opcode, 24); 10430 add = BitIsSet (opcode, 23); 10431 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10432 10433 // if P == �0� && W == �1� then UNPREDICTABLE; 10434 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10435 return false; 10436 10437 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10438 if (wback && ((n == 15) || (n == t) || (n == t2))) 10439 return false; 10440 10441 // if t2 == 15 then UNPREDICTABLE; 10442 if (t2 == 15) 10443 return false; 10444 10445 break; 10446 10447 default: 10448 return false; 10449 } 10450 10451 RegisterInfo base_reg; 10452 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10453 10454 uint32_t Rn = ReadCoreReg (n, &success); 10455 if (!success) 10456 return false; 10457 10458 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10459 addr_t offset_addr; 10460 if (add) 10461 offset_addr = Rn + imm32; 10462 else 10463 offset_addr = Rn - imm32; 10464 10465 //address = if index then offset_addr else R[n]; 10466 addr_t address; 10467 if (index) 10468 address = offset_addr; 10469 else 10470 address = Rn; 10471 10472 //MemA[address,4] = R[t]; 10473 RegisterInfo data_reg; 10474 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10475 10476 uint32_t data = ReadCoreReg (t, &success); 10477 if (!success) 10478 return false; 10479 10480 EmulateInstruction::Context context; 10481 context.type = eContextRegisterStore; 10482 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10483 10484 const uint32_t addr_byte_size = GetAddressByteSize(); 10485 10486 if (!MemAWrite (context, address, data, addr_byte_size)) 10487 return false; 10488 10489 //MemA[address+4,4] = R[t2]; 10490 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10491 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10492 10493 data = ReadCoreReg (t2, &success); 10494 if (!success) 10495 return false; 10496 10497 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10498 return false; 10499 10500 //if wback then R[n] = offset_addr; 10501 if (wback) 10502 { 10503 context.type = eContextAdjustBaseRegister; 10504 context.SetAddress (offset_addr); 10505 10506 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10507 return false; 10508 } 10509 } 10510 return true; 10511 } 10512 10513 10514 // A8.6.201 STRD (register) 10515 bool 10516 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10517 { 10518 #if 0 10519 if ConditionPassed() then 10520 EncodingSpecificOperations(); 10521 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10522 address = if index then offset_addr else R[n]; 10523 MemA[address,4] = R[t]; 10524 MemA[address+4,4] = R[t2]; 10525 if wback then R[n] = offset_addr; 10526 #endif 10527 10528 bool success = false; 10529 10530 if (ConditionPassed(opcode)) 10531 { 10532 uint32_t t; 10533 uint32_t t2; 10534 uint32_t n; 10535 uint32_t m; 10536 bool index; 10537 bool add; 10538 bool wback; 10539 10540 switch (encoding) 10541 { 10542 case eEncodingA1: 10543 // if Rt<0> == �1� then UNPREDICTABLE; 10544 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10545 t = Bits32 (opcode, 15, 12); 10546 if (BitIsSet (t, 0)) 10547 return false; 10548 10549 t2 = t+1; 10550 n = Bits32 (opcode, 19, 16); 10551 m = Bits32 (opcode, 3, 0); 10552 10553 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10554 index = BitIsSet (opcode, 24); 10555 add = BitIsSet (opcode, 23); 10556 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10557 10558 // if P == �0� && W == �1� then UNPREDICTABLE; 10559 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10560 return false; 10561 10562 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10563 if ((t2 == 15) || (m == 15)) 10564 return false; 10565 10566 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10567 if (wback && ((n == 15) || (n == t) || (n == t2))) 10568 return false; 10569 10570 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10571 if ((ArchVersion() < 6) && wback && (m == n)) 10572 return false; 10573 10574 break; 10575 10576 default: 10577 return false; 10578 } 10579 10580 RegisterInfo base_reg; 10581 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10582 RegisterInfo offset_reg; 10583 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10584 RegisterInfo data_reg; 10585 10586 uint32_t Rn = ReadCoreReg (n, &success); 10587 if (!success) 10588 return false; 10589 10590 uint32_t Rm = ReadCoreReg (m, &success); 10591 if (!success) 10592 return false; 10593 10594 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10595 addr_t offset_addr; 10596 if (add) 10597 offset_addr = Rn + Rm; 10598 else 10599 offset_addr = Rn - Rm; 10600 10601 // address = if index then offset_addr else R[n]; 10602 addr_t address; 10603 if (index) 10604 address = offset_addr; 10605 else 10606 address = Rn; 10607 // MemA[address,4] = R[t]; 10608 uint32_t Rt = ReadCoreReg (t, &success); 10609 if (!success) 10610 return false; 10611 10612 EmulateInstruction::Context context; 10613 context.type = eContextRegisterStore; 10614 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10615 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10616 10617 const uint32_t addr_byte_size = GetAddressByteSize(); 10618 10619 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10620 return false; 10621 10622 // MemA[address+4,4] = R[t2]; 10623 uint32_t Rt2 = ReadCoreReg (t2, &success); 10624 if (!success) 10625 return false; 10626 10627 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10628 10629 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10630 10631 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10632 return false; 10633 10634 // if wback then R[n] = offset_addr; 10635 if (wback) 10636 { 10637 context.type = eContextAdjustBaseRegister; 10638 context.SetAddress (offset_addr); 10639 10640 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10641 return false; 10642 10643 } 10644 } 10645 return true; 10646 } 10647 10648 // A8.6.319 VLDM 10649 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10650 // an ARM core register. 10651 bool 10652 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10653 { 10654 #if 0 10655 if ConditionPassed() then 10656 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10657 address = if add then R[n] else R[n]-imm32; 10658 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10659 for r = 0 to regs-1 10660 if single_regs then 10661 S[d+r] = MemA[address,4]; address = address+4; 10662 else 10663 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10664 // Combine the word-aligned words in the correct order for current endianness. 10665 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10666 #endif 10667 10668 bool success = false; 10669 10670 if (ConditionPassed(opcode)) 10671 { 10672 bool single_regs; 10673 bool add; 10674 bool wback; 10675 uint32_t d; 10676 uint32_t n; 10677 uint32_t imm32; 10678 uint32_t regs; 10679 10680 switch (encoding) 10681 { 10682 case eEncodingT1: 10683 case eEncodingA1: 10684 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10685 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10686 // if P == �1� && W == �0� then SEE VLDR; 10687 // if P == U && W == �1� then UNDEFINED; 10688 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10689 return false; 10690 10691 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10692 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10693 single_regs = false; 10694 add = BitIsSet (opcode, 23); 10695 wback = BitIsSet (opcode, 21); 10696 10697 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10698 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10699 n = Bits32 (opcode, 19, 16); 10700 imm32 = Bits32 (opcode, 7, 0) << 2; 10701 10702 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�. 10703 regs = Bits32 (opcode, 7, 0) / 2; 10704 10705 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10706 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10707 return false; 10708 10709 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10710 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10711 return false; 10712 10713 break; 10714 10715 case eEncodingT2: 10716 case eEncodingA2: 10717 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10718 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10719 // if P == �1� && W == �0� then SEE VLDR; 10720 // if P == U && W == �1� then UNDEFINED; 10721 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10722 return false; 10723 10724 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10725 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10726 single_regs = true; 10727 add = BitIsSet (opcode, 23); 10728 wback = BitIsSet (opcode, 21); 10729 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10730 n = Bits32 (opcode, 19, 16); 10731 10732 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10733 imm32 = Bits32 (opcode, 7, 0) << 2; 10734 regs = Bits32 (opcode, 7, 0); 10735 10736 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10737 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10738 return false; 10739 10740 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10741 if ((regs == 0) || ((d + regs) > 32)) 10742 return false; 10743 break; 10744 10745 default: 10746 return false; 10747 } 10748 10749 RegisterInfo base_reg; 10750 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10751 10752 uint32_t Rn = ReadCoreReg (n, &success); 10753 if (!success) 10754 return false; 10755 10756 // address = if add then R[n] else R[n]-imm32; 10757 addr_t address; 10758 if (add) 10759 address = Rn; 10760 else 10761 address = Rn - imm32; 10762 10763 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10764 EmulateInstruction::Context context; 10765 10766 if (wback) 10767 { 10768 uint32_t value; 10769 if (add) 10770 value = Rn + imm32; 10771 else 10772 value = Rn - imm32; 10773 10774 context.type = eContextAdjustBaseRegister; 10775 context.SetImmediateSigned (value - Rn); 10776 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10777 return false; 10778 10779 } 10780 10781 const uint32_t addr_byte_size = GetAddressByteSize(); 10782 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10783 10784 context.type = eContextRegisterLoad; 10785 10786 // for r = 0 to regs-1 10787 for (uint32_t r = 0; r < regs; ++r) 10788 { 10789 if (single_regs) 10790 { 10791 // S[d+r] = MemA[address,4]; address = address+4; 10792 context.SetRegisterPlusOffset (base_reg, address - Rn); 10793 10794 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10795 if (!success) 10796 return false; 10797 10798 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10799 return false; 10800 10801 address = address + 4; 10802 } 10803 else 10804 { 10805 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10806 context.SetRegisterPlusOffset (base_reg, address - Rn); 10807 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10808 if (!success) 10809 return false; 10810 10811 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10812 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10813 if (!success) 10814 return false; 10815 10816 address = address + 8; 10817 // // Combine the word-aligned words in the correct order for current endianness. 10818 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10819 uint64_t data; 10820 if (GetByteOrder() == eByteOrderBig) 10821 { 10822 data = word1; 10823 data = (data << 32) | word2; 10824 } 10825 else 10826 { 10827 data = word2; 10828 data = (data << 32) | word1; 10829 } 10830 10831 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10832 return false; 10833 } 10834 } 10835 } 10836 return true; 10837 } 10838 10839 // A8.6.399 VSTM 10840 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10841 // ARM core register. 10842 bool 10843 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10844 { 10845 #if 0 10846 if ConditionPassed() then 10847 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10848 address = if add then R[n] else R[n]-imm32; 10849 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10850 for r = 0 to regs-1 10851 if single_regs then 10852 MemA[address,4] = S[d+r]; address = address+4; 10853 else 10854 // Store as two word-aligned words in the correct order for current endianness. 10855 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10856 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10857 address = address+8; 10858 #endif 10859 10860 bool success = false; 10861 10862 if (ConditionPassed (opcode)) 10863 { 10864 bool single_regs; 10865 bool add; 10866 bool wback; 10867 uint32_t d; 10868 uint32_t n; 10869 uint32_t imm32; 10870 uint32_t regs; 10871 10872 switch (encoding) 10873 { 10874 case eEncodingT1: 10875 case eEncodingA1: 10876 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10877 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10878 // if P == �1� && W == �0� then SEE VSTR; 10879 // if P == U && W == �1� then UNDEFINED; 10880 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10881 return false; 10882 10883 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10884 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10885 single_regs = false; 10886 add = BitIsSet (opcode, 23); 10887 wback = BitIsSet (opcode, 21); 10888 10889 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10890 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10891 n = Bits32 (opcode, 19, 16); 10892 imm32 = Bits32 (opcode, 7, 0) << 2; 10893 10894 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�. 10895 regs = Bits32 (opcode, 7, 0) / 2; 10896 10897 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10898 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10899 return false; 10900 10901 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10902 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10903 return false; 10904 10905 break; 10906 10907 case eEncodingT2: 10908 case eEncodingA2: 10909 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10910 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10911 // if P == �1� && W == �0� then SEE VSTR; 10912 // if P == U && W == �1� then UNDEFINED; 10913 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10914 return false; 10915 10916 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10917 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10918 single_regs = true; 10919 add = BitIsSet (opcode, 23); 10920 wback = BitIsSet (opcode, 21); 10921 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10922 n = Bits32 (opcode, 19, 16); 10923 10924 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10925 imm32 = Bits32 (opcode, 7, 0) << 2; 10926 regs = Bits32 (opcode, 7, 0); 10927 10928 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10929 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 10930 return false; 10931 10932 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10933 if ((regs == 0) || ((d + regs) > 32)) 10934 return false; 10935 10936 break; 10937 10938 default: 10939 return false; 10940 } 10941 10942 RegisterInfo base_reg; 10943 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10944 10945 uint32_t Rn = ReadCoreReg (n, &success); 10946 if (!success) 10947 return false; 10948 10949 // address = if add then R[n] else R[n]-imm32; 10950 addr_t address; 10951 if (add) 10952 address = Rn; 10953 else 10954 address = Rn - imm32; 10955 10956 EmulateInstruction::Context context; 10957 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10958 if (wback) 10959 { 10960 uint32_t value; 10961 if (add) 10962 value = Rn + imm32; 10963 else 10964 value = Rn - imm32; 10965 10966 context.type = eContextAdjustBaseRegister; 10967 context.SetRegisterPlusOffset (base_reg, value - Rn); 10968 10969 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10970 return false; 10971 } 10972 10973 const uint32_t addr_byte_size = GetAddressByteSize(); 10974 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10975 10976 context.type = eContextRegisterStore; 10977 // for r = 0 to regs-1 10978 for (uint32_t r = 0; r < regs; ++r) 10979 { 10980 10981 if (single_regs) 10982 { 10983 // MemA[address,4] = S[d+r]; address = address+4; 10984 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10985 if (!success) 10986 return false; 10987 10988 RegisterInfo data_reg; 10989 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10990 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10991 if (!MemAWrite (context, address, data, addr_byte_size)) 10992 return false; 10993 10994 address = address + 4; 10995 } 10996 else 10997 { 10998 // // Store as two word-aligned words in the correct order for current endianness. 10999 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11000 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11001 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11002 if (!success) 11003 return false; 11004 11005 RegisterInfo data_reg; 11006 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11007 11008 if (GetByteOrder() == eByteOrderBig) 11009 { 11010 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11011 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11012 return false; 11013 11014 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11015 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 11016 return false; 11017 } 11018 else 11019 { 11020 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11021 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11022 return false; 11023 11024 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11025 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11026 return false; 11027 } 11028 // address = address+8; 11029 address = address + 8; 11030 } 11031 } 11032 } 11033 return true; 11034 } 11035 11036 // A8.6.320 11037 // This instruction loads a single extension register from memory, using an address from an ARM core register, with 11038 // an optional offset. 11039 bool 11040 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 11041 { 11042 #if 0 11043 if ConditionPassed() then 11044 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11045 base = if n == 15 then Align(PC,4) else R[n]; 11046 address = if add then (base + imm32) else (base - imm32); 11047 if single_reg then 11048 S[d] = MemA[address,4]; 11049 else 11050 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11051 // Combine the word-aligned words in the correct order for current endianness. 11052 D[d] = if BigEndian() then word1:word2 else word2:word1; 11053 #endif 11054 11055 bool success = false; 11056 11057 if (ConditionPassed (opcode)) 11058 { 11059 bool single_reg; 11060 bool add; 11061 uint32_t imm32; 11062 uint32_t d; 11063 uint32_t n; 11064 11065 switch (encoding) 11066 { 11067 case eEncodingT1: 11068 case eEncodingA1: 11069 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11070 single_reg = false; 11071 add = BitIsSet (opcode, 23); 11072 imm32 = Bits32 (opcode, 7, 0) << 2; 11073 11074 // d = UInt(D:Vd); n = UInt(Rn); 11075 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11076 n = Bits32 (opcode, 19, 16); 11077 11078 break; 11079 11080 case eEncodingT2: 11081 case eEncodingA2: 11082 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11083 single_reg = true; 11084 add = BitIsSet (opcode, 23); 11085 imm32 = Bits32 (opcode, 7, 0) << 2; 11086 11087 // d = UInt(Vd:D); n = UInt(Rn); 11088 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11089 n = Bits32 (opcode, 19, 16); 11090 11091 break; 11092 11093 default: 11094 return false; 11095 } 11096 RegisterInfo base_reg; 11097 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11098 11099 uint32_t Rn = ReadCoreReg (n, &success); 11100 if (!success) 11101 return false; 11102 11103 // base = if n == 15 then Align(PC,4) else R[n]; 11104 uint32_t base; 11105 if (n == 15) 11106 base = AlignPC (Rn); 11107 else 11108 base = Rn; 11109 11110 // address = if add then (base + imm32) else (base - imm32); 11111 addr_t address; 11112 if (add) 11113 address = base + imm32; 11114 else 11115 address = base - imm32; 11116 11117 const uint32_t addr_byte_size = GetAddressByteSize(); 11118 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11119 11120 EmulateInstruction::Context context; 11121 context.type = eContextRegisterLoad; 11122 context.SetRegisterPlusOffset (base_reg, address - base); 11123 11124 if (single_reg) 11125 { 11126 // S[d] = MemA[address,4]; 11127 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11128 if (!success) 11129 return false; 11130 11131 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11132 return false; 11133 } 11134 else 11135 { 11136 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11137 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11138 if (!success) 11139 return false; 11140 11141 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11142 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11143 if (!success) 11144 return false; 11145 // // Combine the word-aligned words in the correct order for current endianness. 11146 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11147 uint64_t data64; 11148 if (GetByteOrder() == eByteOrderBig) 11149 { 11150 data64 = word1; 11151 data64 = (data64 << 32) | word2; 11152 } 11153 else 11154 { 11155 data64 = word2; 11156 data64 = (data64 << 32) | word1; 11157 } 11158 11159 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11160 return false; 11161 } 11162 } 11163 return true; 11164 } 11165 11166 // A8.6.400 VSTR 11167 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11168 // optional offset. 11169 bool 11170 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11171 { 11172 #if 0 11173 if ConditionPassed() then 11174 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11175 address = if add then (R[n] + imm32) else (R[n] - imm32); 11176 if single_reg then 11177 MemA[address,4] = S[d]; 11178 else 11179 // Store as two word-aligned words in the correct order for current endianness. 11180 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11181 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11182 #endif 11183 11184 bool success = false; 11185 11186 if (ConditionPassed (opcode)) 11187 { 11188 bool single_reg; 11189 bool add; 11190 uint32_t imm32; 11191 uint32_t d; 11192 uint32_t n; 11193 11194 switch (encoding) 11195 { 11196 case eEncodingT1: 11197 case eEncodingA1: 11198 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11199 single_reg = false; 11200 add = BitIsSet (opcode, 23); 11201 imm32 = Bits32 (opcode, 7, 0) << 2; 11202 11203 // d = UInt(D:Vd); n = UInt(Rn); 11204 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11205 n = Bits32 (opcode, 19, 16); 11206 11207 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11208 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11209 return false; 11210 11211 break; 11212 11213 case eEncodingT2: 11214 case eEncodingA2: 11215 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11216 single_reg = true; 11217 add = BitIsSet (opcode, 23); 11218 imm32 = Bits32 (opcode, 7, 0) << 2; 11219 11220 // d = UInt(Vd:D); n = UInt(Rn); 11221 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11222 n = Bits32 (opcode, 19, 16); 11223 11224 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11225 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11226 return false; 11227 11228 break; 11229 11230 default: 11231 return false; 11232 } 11233 11234 RegisterInfo base_reg; 11235 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11236 11237 uint32_t Rn = ReadCoreReg (n, &success); 11238 if (!success) 11239 return false; 11240 11241 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11242 addr_t address; 11243 if (add) 11244 address = Rn + imm32; 11245 else 11246 address = Rn - imm32; 11247 11248 const uint32_t addr_byte_size = GetAddressByteSize(); 11249 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11250 11251 RegisterInfo data_reg; 11252 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11253 EmulateInstruction::Context context; 11254 context.type = eContextRegisterStore; 11255 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11256 11257 if (single_reg) 11258 { 11259 // MemA[address,4] = S[d]; 11260 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11261 if (!success) 11262 return false; 11263 11264 if (!MemAWrite (context, address, data, addr_byte_size)) 11265 return false; 11266 } 11267 else 11268 { 11269 // // Store as two word-aligned words in the correct order for current endianness. 11270 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11271 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11272 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11273 if (!success) 11274 return false; 11275 11276 if (GetByteOrder() == eByteOrderBig) 11277 { 11278 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11279 return false; 11280 11281 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11282 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11283 return false; 11284 } 11285 else 11286 { 11287 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11288 return false; 11289 11290 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11291 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11292 return false; 11293 } 11294 } 11295 } 11296 return true; 11297 } 11298 11299 // A8.6.307 VLDI1 (multiple single elements) 11300 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11301 // element of each register is loaded. 11302 bool 11303 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11304 { 11305 #if 0 11306 if ConditionPassed() then 11307 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11308 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11309 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11310 for r = 0 to regs-1 11311 for e = 0 to elements-1 11312 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11313 address = address + ebytes; 11314 #endif 11315 11316 bool success = false; 11317 11318 if (ConditionPassed (opcode)) 11319 { 11320 uint32_t regs; 11321 uint32_t alignment; 11322 uint32_t ebytes; 11323 uint32_t esize; 11324 uint32_t elements; 11325 uint32_t d; 11326 uint32_t n; 11327 uint32_t m; 11328 bool wback; 11329 bool register_index; 11330 11331 switch (encoding) 11332 { 11333 case eEncodingT1: 11334 case eEncodingA1: 11335 { 11336 // case type of 11337 // when �0111� 11338 // regs = 1; if align<1> == �1� then UNDEFINED; 11339 // when �1010� 11340 // regs = 2; if align == �11� then UNDEFINED; 11341 // when �0110� 11342 // regs = 3; if align<1> == �1� then UNDEFINED; 11343 // when �0010� 11344 // regs = 4; 11345 // otherwise 11346 // SEE �Related encodings�; 11347 uint32_t type = Bits32 (opcode, 11, 8); 11348 uint32_t align = Bits32 (opcode, 5, 4); 11349 if (type == 7) // '0111' 11350 { 11351 regs = 1; 11352 if (BitIsSet (align, 1)) 11353 return false; 11354 } 11355 else if (type == 10) // '1010' 11356 { 11357 regs = 2; 11358 if (align == 3) 11359 return false; 11360 11361 } 11362 else if (type == 6) // '0110' 11363 { 11364 regs = 3; 11365 if (BitIsSet (align, 1)) 11366 return false; 11367 } 11368 else if (type == 2) // '0010' 11369 { 11370 regs = 4; 11371 } 11372 else 11373 return false; 11374 11375 // alignment = if align == �00� then 1 else 4 << UInt(align); 11376 if (align == 0) 11377 alignment = 1; 11378 else 11379 alignment = 4 << align; 11380 11381 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11382 ebytes = 1 << Bits32 (opcode, 7, 6); 11383 esize = 8 * ebytes; 11384 elements = 8 / ebytes; 11385 11386 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11387 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11388 n = Bits32 (opcode, 19, 15); 11389 m = Bits32 (opcode, 3, 0); 11390 11391 // wback = (m != 15); register_index = (m != 15 && m != 13); 11392 wback = (m != 15); 11393 register_index = ((m != 15) && (m != 13)); 11394 11395 // if d+regs > 32 then UNPREDICTABLE; 11396 if ((d + regs) > 32) 11397 return false; 11398 } 11399 break; 11400 11401 default: 11402 return false; 11403 } 11404 11405 RegisterInfo base_reg; 11406 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11407 11408 uint32_t Rn = ReadCoreReg (n, &success); 11409 if (!success) 11410 return false; 11411 11412 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11413 addr_t address = Rn; 11414 if ((address % alignment) != 0) 11415 return false; 11416 11417 EmulateInstruction::Context context; 11418 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11419 if (wback) 11420 { 11421 uint32_t Rm = ReadCoreReg (m, &success); 11422 if (!success) 11423 return false; 11424 11425 uint32_t offset; 11426 if (register_index) 11427 offset = Rm; 11428 else 11429 offset = 8 * regs; 11430 11431 uint32_t value = Rn + offset; 11432 context.type = eContextAdjustBaseRegister; 11433 context.SetRegisterPlusOffset (base_reg, offset); 11434 11435 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11436 return false; 11437 11438 } 11439 11440 // for r = 0 to regs-1 11441 for (uint32_t r = 0; r < regs; ++r) 11442 { 11443 // for e = 0 to elements-1 11444 uint64_t assembled_data = 0; 11445 for (uint32_t e = 0; e < elements; ++e) 11446 { 11447 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11448 context.type = eContextRegisterLoad; 11449 context.SetRegisterPlusOffset (base_reg, address - Rn); 11450 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11451 if (!success) 11452 return false; 11453 11454 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11455 11456 // address = address + ebytes; 11457 address = address + ebytes; 11458 } 11459 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11460 return false; 11461 } 11462 } 11463 return true; 11464 } 11465 11466 // A8.6.308 VLD1 (single element to one lane) 11467 // 11468 bool 11469 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11470 { 11471 #if 0 11472 if ConditionPassed() then 11473 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11474 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11475 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11476 Elem[D[d],index,esize] = MemU[address,ebytes]; 11477 #endif 11478 11479 bool success = false; 11480 11481 if (ConditionPassed (opcode)) 11482 { 11483 uint32_t ebytes; 11484 uint32_t esize; 11485 uint32_t index; 11486 uint32_t alignment; 11487 uint32_t d; 11488 uint32_t n; 11489 uint32_t m; 11490 bool wback; 11491 bool register_index; 11492 11493 switch (encoding) 11494 { 11495 case eEncodingT1: 11496 case eEncodingA1: 11497 { 11498 uint32_t size = Bits32 (opcode, 11, 10); 11499 uint32_t index_align = Bits32 (opcode, 7, 4); 11500 // if size == �11� then SEE VLD1 (single element to all lanes); 11501 if (size == 3) 11502 return EmulateVLD1SingleAll (opcode, encoding); 11503 // case size of 11504 if (size == 0) // when '00' 11505 { 11506 // if index_align<0> != �0� then UNDEFINED; 11507 if (BitIsClear (index_align, 0)) 11508 return false; 11509 11510 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11511 ebytes = 1; 11512 esize = 8; 11513 index = Bits32 (index_align, 3, 1); 11514 alignment = 1; 11515 } 11516 else if (size == 1) // when �01� 11517 { 11518 // if index_align<1> != �0� then UNDEFINED; 11519 if (BitIsClear (index_align, 1)) 11520 return false; 11521 11522 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11523 ebytes = 2; 11524 esize = 16; 11525 index = Bits32 (index_align, 3, 2); 11526 11527 // alignment = if index_align<0> == �0� then 1 else 2; 11528 if (BitIsClear (index_align, 0)) 11529 alignment = 1; 11530 else 11531 alignment = 2; 11532 } 11533 else if (size == 2) // when �10� 11534 { 11535 // if index_align<2> != �0� then UNDEFINED; 11536 if (BitIsClear (index_align, 2)) 11537 return false; 11538 11539 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11540 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11541 return false; 11542 11543 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11544 ebytes = 4; 11545 esize = 32; 11546 index = Bit32 (index_align, 3); 11547 11548 // alignment = if index_align<1:0> == �00� then 1 else 4; 11549 if (Bits32 (index_align, 1, 0) == 0) 11550 alignment = 1; 11551 else 11552 alignment = 4; 11553 } 11554 else 11555 { 11556 return false; 11557 } 11558 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11559 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11560 n = Bits32 (opcode, 19, 16); 11561 m = Bits32 (opcode, 3, 0); 11562 11563 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11564 wback = (m != 15); 11565 register_index = ((m != 15) && (m != 13)); 11566 11567 if (n == 15) 11568 return false; 11569 11570 } 11571 break; 11572 11573 default: 11574 return false; 11575 } 11576 11577 RegisterInfo base_reg; 11578 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11579 11580 uint32_t Rn = ReadCoreReg (n, &success); 11581 if (!success) 11582 return false; 11583 11584 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11585 addr_t address = Rn; 11586 if ((address % alignment) != 0) 11587 return false; 11588 11589 EmulateInstruction::Context context; 11590 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11591 if (wback) 11592 { 11593 uint32_t Rm = ReadCoreReg (m, &success); 11594 if (!success) 11595 return false; 11596 11597 uint32_t offset; 11598 if (register_index) 11599 offset = Rm; 11600 else 11601 offset = ebytes; 11602 11603 uint32_t value = Rn + offset; 11604 11605 context.type = eContextAdjustBaseRegister; 11606 context.SetRegisterPlusOffset (base_reg, offset); 11607 11608 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11609 return false; 11610 } 11611 11612 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11613 uint32_t element = MemURead (context, address, esize, 0, &success); 11614 if (!success) 11615 return false; 11616 11617 element = element << (index * esize); 11618 11619 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11620 if (!success) 11621 return false; 11622 11623 uint64_t all_ones = -1; 11624 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11625 // at element & to the right of element. 11626 if (index > 0) 11627 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11628 // now mask should be 0's where element goes & 1's 11629 // everywhere else. 11630 11631 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11632 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11633 11634 context.type = eContextRegisterLoad; 11635 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11636 return false; 11637 } 11638 return true; 11639 } 11640 11641 // A8.6.391 VST1 (multiple single elements) 11642 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without 11643 // interleaving. Every element of each register is stored. 11644 bool 11645 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11646 { 11647 #if 0 11648 if ConditionPassed() then 11649 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11650 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11651 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11652 for r = 0 to regs-1 11653 for e = 0 to elements-1 11654 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11655 address = address + ebytes; 11656 #endif 11657 11658 bool success = false; 11659 11660 if (ConditionPassed (opcode)) 11661 { 11662 uint32_t regs; 11663 uint32_t alignment; 11664 uint32_t ebytes; 11665 uint32_t esize; 11666 uint32_t elements; 11667 uint32_t d; 11668 uint32_t n; 11669 uint32_t m; 11670 bool wback; 11671 bool register_index; 11672 11673 switch (encoding) 11674 { 11675 case eEncodingT1: 11676 case eEncodingA1: 11677 { 11678 uint32_t type = Bits32 (opcode, 11, 8); 11679 uint32_t align = Bits32 (opcode, 5, 4); 11680 11681 // case type of 11682 if (type == 7) // when �0111� 11683 { 11684 // regs = 1; if align<1> == �1� then UNDEFINED; 11685 regs = 1; 11686 if (BitIsSet (align, 1)) 11687 return false; 11688 } 11689 else if (type == 10) // when �1010� 11690 { 11691 // regs = 2; if align == �11� then UNDEFINED; 11692 regs = 2; 11693 if (align == 3) 11694 return false; 11695 } 11696 else if (type == 6) // when �0110� 11697 { 11698 // regs = 3; if align<1> == �1� then UNDEFINED; 11699 regs = 3; 11700 if (BitIsSet (align, 1)) 11701 return false; 11702 } 11703 else if (type == 2) // when �0010� 11704 // regs = 4; 11705 regs = 4; 11706 else // otherwise 11707 // SEE �Related encodings�; 11708 return false; 11709 11710 // alignment = if align == �00� then 1 else 4 << UInt(align); 11711 if (align == 0) 11712 alignment = 1; 11713 else 11714 alignment = 4 << align; 11715 11716 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11717 ebytes = 1 << Bits32 (opcode,7, 6); 11718 esize = 8 * ebytes; 11719 elements = 8 / ebytes; 11720 11721 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11722 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11723 n = Bits32 (opcode, 19, 16); 11724 m = Bits32 (opcode, 3, 0); 11725 11726 // wback = (m != 15); register_index = (m != 15 && m != 13); 11727 wback = (m != 15); 11728 register_index = ((m != 15) && (m != 13)); 11729 11730 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11731 if ((d + regs) > 32) 11732 return false; 11733 11734 if (n == 15) 11735 return false; 11736 11737 } 11738 break; 11739 11740 default: 11741 return false; 11742 } 11743 11744 RegisterInfo base_reg; 11745 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11746 11747 uint32_t Rn = ReadCoreReg (n, &success); 11748 if (!success) 11749 return false; 11750 11751 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11752 addr_t address = Rn; 11753 if ((address % alignment) != 0) 11754 return false; 11755 11756 EmulateInstruction::Context context; 11757 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11758 if (wback) 11759 { 11760 uint32_t Rm = ReadCoreReg (m, &success); 11761 if (!success) 11762 return false; 11763 11764 uint32_t offset; 11765 if (register_index) 11766 offset = Rm; 11767 else 11768 offset = 8 * regs; 11769 11770 context.type = eContextAdjustBaseRegister; 11771 context.SetRegisterPlusOffset (base_reg, offset); 11772 11773 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11774 return false; 11775 } 11776 11777 RegisterInfo data_reg; 11778 context.type = eContextRegisterStore; 11779 // for r = 0 to regs-1 11780 for (uint32_t r = 0; r < regs; ++r) 11781 { 11782 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11783 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11784 if (!success) 11785 return false; 11786 11787 // for e = 0 to elements-1 11788 for (uint32_t e = 0; e < elements; ++e) 11789 { 11790 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11791 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11792 11793 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11794 if (!MemUWrite (context, address, word, ebytes)) 11795 return false; 11796 11797 // address = address + ebytes; 11798 address = address + ebytes; 11799 } 11800 } 11801 } 11802 return true; 11803 } 11804 11805 // A8.6.392 VST1 (single element from one lane) 11806 // This instruction stores one element to memory from one element of a register. 11807 bool 11808 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11809 { 11810 #if 0 11811 if ConditionPassed() then 11812 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11813 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11814 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11815 MemU[address,ebytes] = Elem[D[d],index,esize]; 11816 #endif 11817 11818 bool success = false; 11819 11820 if (ConditionPassed (opcode)) 11821 { 11822 uint32_t ebytes; 11823 uint32_t esize; 11824 uint32_t index; 11825 uint32_t alignment; 11826 uint32_t d; 11827 uint32_t n; 11828 uint32_t m; 11829 bool wback; 11830 bool register_index; 11831 11832 switch (encoding) 11833 { 11834 case eEncodingT1: 11835 case eEncodingA1: 11836 { 11837 uint32_t size = Bits32 (opcode, 11, 10); 11838 uint32_t index_align = Bits32 (opcode, 7, 4); 11839 11840 // if size == �11� then UNDEFINED; 11841 if (size == 3) 11842 return false; 11843 11844 // case size of 11845 if (size == 0) // when �00� 11846 { 11847 // if index_align<0> != �0� then UNDEFINED; 11848 if (BitIsClear (index_align, 0)) 11849 return false; 11850 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11851 ebytes = 1; 11852 esize = 8; 11853 index = Bits32 (index_align, 3, 1); 11854 alignment = 1; 11855 } 11856 else if (size == 1) // when �01� 11857 { 11858 // if index_align<1> != �0� then UNDEFINED; 11859 if (BitIsClear (index_align, 1)) 11860 return false; 11861 11862 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11863 ebytes = 2; 11864 esize = 16; 11865 index = Bits32 (index_align, 3, 2); 11866 11867 // alignment = if index_align<0> == �0� then 1 else 2; 11868 if (BitIsClear (index_align, 0)) 11869 alignment = 1; 11870 else 11871 alignment = 2; 11872 } 11873 else if (size == 2) // when �10� 11874 { 11875 // if index_align<2> != �0� then UNDEFINED; 11876 if (BitIsClear (index_align, 2)) 11877 return false; 11878 11879 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11880 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11881 return false; 11882 11883 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11884 ebytes = 4; 11885 esize = 32; 11886 index = Bit32 (index_align, 3); 11887 11888 // alignment = if index_align<1:0> == �00� then 1 else 4; 11889 if (Bits32 (index_align, 1, 0) == 0) 11890 alignment = 1; 11891 else 11892 alignment = 4; 11893 } 11894 else 11895 { 11896 return false; 11897 } 11898 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11899 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11900 n = Bits32 (opcode, 19, 16); 11901 m = Bits32 (opcode, 3, 0); 11902 11903 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11904 wback = (m != 15); 11905 register_index = ((m != 15) && (m != 13)); 11906 11907 if (n == 15) 11908 return false; 11909 } 11910 break; 11911 11912 default: 11913 return false; 11914 } 11915 11916 RegisterInfo base_reg; 11917 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11918 11919 uint32_t Rn = ReadCoreReg (n, &success); 11920 if (!success) 11921 return false; 11922 11923 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11924 addr_t address = Rn; 11925 if ((address % alignment) != 0) 11926 return false; 11927 11928 EmulateInstruction::Context context; 11929 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11930 if (wback) 11931 { 11932 uint32_t Rm = ReadCoreReg (m, &success); 11933 if (!success) 11934 return false; 11935 11936 uint32_t offset; 11937 if (register_index) 11938 offset = Rm; 11939 else 11940 offset = ebytes; 11941 11942 context.type = eContextAdjustBaseRegister; 11943 context.SetRegisterPlusOffset (base_reg, offset); 11944 11945 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11946 return false; 11947 } 11948 11949 // MemU[address,ebytes] = Elem[D[d],index,esize]; 11950 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11951 if (!success) 11952 return false; 11953 11954 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 11955 11956 RegisterInfo data_reg; 11957 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 11958 context.type = eContextRegisterStore; 11959 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11960 11961 if (!MemUWrite (context, address, word, ebytes)) 11962 return false; 11963 } 11964 return true; 11965 } 11966 11967 // A8.6.309 VLD1 (single element to all lanes) 11968 // This instruction loads one element from memory into every element of one or two vectors. 11969 bool 11970 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 11971 { 11972 #if 0 11973 if ConditionPassed() then 11974 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11975 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11976 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11977 replicated_element = Replicate(MemU[address,ebytes], elements); 11978 for r = 0 to regs-1 11979 D[d+r] = replicated_element; 11980 #endif 11981 11982 bool success = false; 11983 11984 if (ConditionPassed (opcode)) 11985 { 11986 uint32_t ebytes; 11987 uint32_t elements; 11988 uint32_t regs; 11989 uint32_t alignment; 11990 uint32_t d; 11991 uint32_t n; 11992 uint32_t m; 11993 bool wback; 11994 bool register_index; 11995 11996 switch (encoding) 11997 { 11998 case eEncodingT1: 11999 case eEncodingA1: 12000 { 12001 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED; 12002 uint32_t size = Bits32 (opcode, 7, 6); 12003 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 12004 return false; 12005 12006 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2; 12007 ebytes = 1 << size; 12008 elements = 8 / ebytes; 12009 if (BitIsClear (opcode, 5)) 12010 regs = 1; 12011 else 12012 regs = 2; 12013 12014 //alignment = if a == �0� then 1 else ebytes; 12015 if (BitIsClear (opcode, 4)) 12016 alignment = 1; 12017 else 12018 alignment = ebytes; 12019 12020 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12021 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12022 n = Bits32 (opcode, 19, 16); 12023 m = Bits32 (opcode, 3, 0); 12024 12025 //wback = (m != 15); register_index = (m != 15 && m != 13); 12026 wback = (m != 15); 12027 register_index = ((m != 15) && (m != 13)); 12028 12029 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12030 if ((d + regs) > 32) 12031 return false; 12032 12033 if (n == 15) 12034 return false; 12035 } 12036 break; 12037 12038 default: 12039 return false; 12040 } 12041 12042 RegisterInfo base_reg; 12043 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12044 12045 uint32_t Rn = ReadCoreReg (n, &success); 12046 if (!success) 12047 return false; 12048 12049 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12050 addr_t address = Rn; 12051 if ((address % alignment) != 0) 12052 return false; 12053 12054 EmulateInstruction::Context context; 12055 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12056 if (wback) 12057 { 12058 uint32_t Rm = ReadCoreReg (m, &success); 12059 if (!success) 12060 return false; 12061 12062 uint32_t offset; 12063 if (register_index) 12064 offset = Rm; 12065 else 12066 offset = ebytes; 12067 12068 context.type = eContextAdjustBaseRegister; 12069 context.SetRegisterPlusOffset (base_reg, offset); 12070 12071 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12072 return false; 12073 } 12074 12075 // replicated_element = Replicate(MemU[address,ebytes], elements); 12076 12077 context.type = eContextRegisterLoad; 12078 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12079 if (!success) 12080 return false; 12081 12082 uint64_t replicated_element = 0; 12083 uint32_t esize = ebytes * 8; 12084 for (uint32_t e = 0; e < elements; ++e) 12085 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12086 12087 // for r = 0 to regs-1 12088 for (uint32_t r = 0; r < regs; ++r) 12089 { 12090 // D[d+r] = replicated_element; 12091 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12092 return false; 12093 } 12094 } 12095 return true; 12096 } 12097 12098 // B6.2.13 SUBS PC, LR and related instructions 12099 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12100 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12101 bool 12102 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12103 { 12104 #if 0 12105 if ConditionPassed() then 12106 EncodingSpecificOperations(); 12107 if CurrentInstrSet() == InstrSet_ThumbEE then 12108 UNPREDICTABLE; 12109 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12110 case opcode of 12111 when �0000� result = R[n] AND operand2; // AND 12112 when �0001� result = R[n] EOR operand2; // EOR 12113 when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12114 when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12115 when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12116 when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12117 when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12118 when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12119 when �1100� result = R[n] OR operand2; // ORR 12120 when �1101� result = operand2; // MOV 12121 when �1110� result = R[n] AND NOT(operand2); // BIC 12122 when �1111� result = NOT(operand2); // MVN 12123 CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12124 BranchWritePC(result); 12125 #endif 12126 12127 bool success = false; 12128 12129 if (ConditionPassed (opcode)) 12130 { 12131 uint32_t n; 12132 uint32_t m; 12133 uint32_t imm32; 12134 bool register_form; 12135 ARM_ShifterType shift_t; 12136 uint32_t shift_n; 12137 uint32_t code; 12138 12139 switch (encoding) 12140 { 12141 case eEncodingT1: 12142 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12143 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB 12144 n = 14; 12145 imm32 = Bits32 (opcode, 7, 0); 12146 register_form = false; 12147 code = 2; 12148 12149 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12150 if (InITBlock() && !LastInITBlock()) 12151 return false; 12152 12153 break; 12154 12155 case eEncodingA1: 12156 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12157 n = Bits32 (opcode, 19, 16); 12158 imm32 = ARMExpandImm (opcode); 12159 register_form = false; 12160 code = Bits32 (opcode, 24, 21); 12161 12162 break; 12163 12164 case eEncodingA2: 12165 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12166 n = Bits32 (opcode, 19, 16); 12167 m = Bits32 (opcode, 3, 0); 12168 register_form = true; 12169 12170 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12171 shift_n = DecodeImmShiftARM (opcode, shift_t); 12172 12173 break; 12174 12175 default: 12176 return false; 12177 } 12178 12179 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12180 uint32_t operand2; 12181 if (register_form) 12182 { 12183 uint32_t Rm = ReadCoreReg (m, &success); 12184 if (!success) 12185 return false; 12186 12187 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12188 if (!success) 12189 return false; 12190 } 12191 else 12192 { 12193 operand2 = imm32; 12194 } 12195 12196 uint32_t Rn = ReadCoreReg (n, &success); 12197 if (!success) 12198 return false; 12199 12200 AddWithCarryResult result; 12201 12202 // case opcode of 12203 switch (code) 12204 { 12205 case 0: // when �0000� 12206 // result = R[n] AND operand2; // AND 12207 result.result = Rn & operand2; 12208 break; 12209 12210 case 1: // when �0001� 12211 // result = R[n] EOR operand2; // EOR 12212 result.result = Rn ^ operand2; 12213 break; 12214 12215 case 2: // when �0010� 12216 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12217 result = AddWithCarry (Rn, ~(operand2), 1); 12218 break; 12219 12220 case 3: // when �0011� 12221 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12222 result = AddWithCarry (~(Rn), operand2, 1); 12223 break; 12224 12225 case 4: // when �0100� 12226 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12227 result = AddWithCarry (Rn, operand2, 0); 12228 break; 12229 12230 case 5: // when �0101� 12231 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12232 result = AddWithCarry (Rn, operand2, APSR_C); 12233 break; 12234 12235 case 6: // when �0110� 12236 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12237 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12238 break; 12239 12240 case 7: // when �0111� 12241 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12242 result = AddWithCarry (~(Rn), operand2, APSR_C); 12243 break; 12244 12245 case 10: // when �1100� 12246 // result = R[n] OR operand2; // ORR 12247 result.result = Rn | operand2; 12248 break; 12249 12250 case 11: // when �1101� 12251 // result = operand2; // MOV 12252 result.result = operand2; 12253 break; 12254 12255 case 12: // when �1110� 12256 // result = R[n] AND NOT(operand2); // BIC 12257 result.result = Rn & ~(operand2); 12258 break; 12259 12260 case 15: // when �1111� 12261 // result = NOT(operand2); // MVN 12262 result.result = ~(operand2); 12263 break; 12264 12265 default: 12266 return false; 12267 } 12268 // CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12269 12270 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12271 // the best. 12272 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12273 if (!success) 12274 return false; 12275 12276 CPSRWriteByInstr (spsr, 15, true); 12277 12278 // BranchWritePC(result); 12279 EmulateInstruction::Context context; 12280 context.type = eContextAdjustPC; 12281 context.SetImmediate (result.result); 12282 12283 BranchWritePC (context, result.result); 12284 } 12285 return true; 12286 } 12287 12288 EmulateInstructionARM::ARMOpcode* 12289 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12290 { 12291 static ARMOpcode 12292 g_arm_opcodes[] = 12293 { 12294 //---------------------------------------------------------------------- 12295 // Prologue instructions 12296 //---------------------------------------------------------------------- 12297 12298 // push register(s) 12299 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12300 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12301 12302 // set r7 to point to a stack offset 12303 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12304 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12305 // copy the stack pointer to ip 12306 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12307 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12308 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12309 12310 // adjust the stack pointer 12311 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12312 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12313 12314 // push one register 12315 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12316 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12317 12318 // vector push consecutive extension register(s) 12319 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12320 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12321 12322 //---------------------------------------------------------------------- 12323 // Epilogue instructions 12324 //---------------------------------------------------------------------- 12325 12326 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12327 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12328 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12329 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12330 12331 //---------------------------------------------------------------------- 12332 // Supervisor Call (previously Software Interrupt) 12333 //---------------------------------------------------------------------- 12334 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12335 12336 //---------------------------------------------------------------------- 12337 // Branch instructions 12338 //---------------------------------------------------------------------- 12339 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12340 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 12341 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12342 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12343 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12344 // for example, "bx lr" 12345 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12346 // bxj 12347 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12348 12349 //---------------------------------------------------------------------- 12350 // Data-processing instructions 12351 //---------------------------------------------------------------------- 12352 // adc (immediate) 12353 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12354 // adc (register) 12355 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12356 // add (immediate) 12357 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12358 // add (register) 12359 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12360 // add (register-shifted register) 12361 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12362 // adr 12363 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12364 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12365 // and (immediate) 12366 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12367 // and (register) 12368 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12369 // bic (immediate) 12370 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12371 // bic (register) 12372 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12373 // eor (immediate) 12374 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12375 // eor (register) 12376 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12377 // orr (immediate) 12378 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12379 // orr (register) 12380 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12381 // rsb (immediate) 12382 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12383 // rsb (register) 12384 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12385 // rsc (immediate) 12386 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12387 // rsc (register) 12388 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12389 // sbc (immediate) 12390 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12391 // sbc (register) 12392 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12393 // sub (immediate, ARM) 12394 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12395 // sub (sp minus immediate) 12396 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12397 // sub (register) 12398 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12399 // teq (immediate) 12400 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12401 // teq (register) 12402 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12403 // tst (immediate) 12404 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12405 // tst (register) 12406 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12407 12408 // mov (immediate) 12409 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12410 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12411 // mov (register) 12412 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12413 // mvn (immediate) 12414 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12415 // mvn (register) 12416 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12417 // cmn (immediate) 12418 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12419 // cmn (register) 12420 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12421 // cmp (immediate) 12422 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12423 // cmp (register) 12424 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12425 // asr (immediate) 12426 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12427 // asr (register) 12428 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12429 // lsl (immediate) 12430 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12431 // lsl (register) 12432 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12433 // lsr (immediate) 12434 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12435 // lsr (register) 12436 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12437 // rrx is a special case encoding of ror (immediate) 12438 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12439 // ror (immediate) 12440 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12441 // ror (register) 12442 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12443 // mul 12444 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12445 12446 // subs pc, lr and related instructions 12447 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12448 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12449 12450 //---------------------------------------------------------------------- 12451 // Load instructions 12452 //---------------------------------------------------------------------- 12453 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12454 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12455 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12456 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12457 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12458 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12459 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12460 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12461 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12462 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12463 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12464 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12465 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12466 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12467 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12468 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12469 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12470 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12471 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12472 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12473 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12474 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12475 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12476 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12477 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12478 12479 //---------------------------------------------------------------------- 12480 // Store instructions 12481 //---------------------------------------------------------------------- 12482 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12483 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12484 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12485 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12486 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12487 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12488 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12489 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12490 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12491 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12492 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12493 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12494 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12495 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12496 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12497 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12498 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12499 12500 //---------------------------------------------------------------------- 12501 // Other instructions 12502 //---------------------------------------------------------------------- 12503 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12504 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12505 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12506 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12507 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12508 12509 }; 12510 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 12511 12512 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12513 { 12514 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12515 (g_arm_opcodes[i].variants & arm_isa) != 0) 12516 return &g_arm_opcodes[i]; 12517 } 12518 return NULL; 12519 } 12520 12521 12522 EmulateInstructionARM::ARMOpcode* 12523 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12524 { 12525 12526 static ARMOpcode 12527 g_thumb_opcodes[] = 12528 { 12529 //---------------------------------------------------------------------- 12530 // Prologue instructions 12531 //---------------------------------------------------------------------- 12532 12533 // push register(s) 12534 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12535 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12536 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12537 12538 // set r7 to point to a stack offset 12539 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12540 // copy the stack pointer to r7 12541 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12542 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12543 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12544 12545 // PC-relative load into register (see also EmulateADDSPRm) 12546 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12547 12548 // adjust the stack pointer 12549 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12550 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12551 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12552 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12553 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12554 12555 // vector push consecutive extension register(s) 12556 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12557 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12558 12559 //---------------------------------------------------------------------- 12560 // Epilogue instructions 12561 //---------------------------------------------------------------------- 12562 12563 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12564 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12565 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12566 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12567 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12568 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12569 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12570 12571 //---------------------------------------------------------------------- 12572 // Supervisor Call (previously Software Interrupt) 12573 //---------------------------------------------------------------------- 12574 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12575 12576 //---------------------------------------------------------------------- 12577 // If Then makes up to four following instructions conditional. 12578 //---------------------------------------------------------------------- 12579 // The next 5 opcode _must_ come before the if then instruction 12580 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12581 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12582 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12583 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12584 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12585 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12586 12587 //---------------------------------------------------------------------- 12588 // Branch instructions 12589 //---------------------------------------------------------------------- 12590 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12591 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12592 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12593 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12594 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12595 // J1 == J2 == 1 12596 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12597 // J1 == J2 == 1 12598 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12599 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12600 // for example, "bx lr" 12601 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12602 // bxj 12603 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12604 // compare and branch 12605 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12606 // table branch byte 12607 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12608 // table branch halfword 12609 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12610 12611 //---------------------------------------------------------------------- 12612 // Data-processing instructions 12613 //---------------------------------------------------------------------- 12614 // adc (immediate) 12615 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12616 // adc (register) 12617 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12618 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12619 // add (register) 12620 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12621 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12622 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12623 // adr 12624 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12625 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12626 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12627 // and (immediate) 12628 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12629 // and (register) 12630 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12631 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12632 // bic (immediate) 12633 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12634 // bic (register) 12635 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12636 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12637 // eor (immediate) 12638 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12639 // eor (register) 12640 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12641 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12642 // orr (immediate) 12643 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12644 // orr (register) 12645 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12646 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12647 // rsb (immediate) 12648 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12649 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12650 // rsb (register) 12651 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12652 // sbc (immediate) 12653 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12654 // sbc (register) 12655 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12656 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12657 // add (immediate, Thumb) 12658 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12659 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12660 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12661 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12662 // sub (immediate, Thumb) 12663 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12664 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12665 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12666 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12667 // sub (sp minus immediate) 12668 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12669 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12670 // sub (register) 12671 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12672 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12673 // teq (immediate) 12674 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12675 // teq (register) 12676 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12677 // tst (immediate) 12678 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12679 // tst (register) 12680 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12681 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12682 12683 12684 // move from high register to high register 12685 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12686 // move from low register to low register 12687 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12688 // mov{s}<c>.w <Rd>, <Rm> 12689 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12690 // move immediate 12691 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12692 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12693 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12694 // mvn (immediate) 12695 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12696 // mvn (register) 12697 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12698 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12699 // cmn (immediate) 12700 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12701 // cmn (register) 12702 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12703 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12704 // cmp (immediate) 12705 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12706 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12707 // cmp (register) (Rn and Rm both from r0-r7) 12708 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12709 // cmp (register) (Rn and Rm not both from r0-r7) 12710 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12711 // asr (immediate) 12712 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12713 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12714 // asr (register) 12715 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12716 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12717 // lsl (immediate) 12718 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12719 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12720 // lsl (register) 12721 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12722 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12723 // lsr (immediate) 12724 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12725 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12726 // lsr (register) 12727 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12728 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12729 // rrx is a special case encoding of ror (immediate) 12730 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12731 // ror (immediate) 12732 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12733 // ror (register) 12734 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12735 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12736 // mul 12737 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12738 // mul 12739 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12740 12741 // subs pc, lr and related instructions 12742 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12743 12744 //---------------------------------------------------------------------- 12745 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12746 // otherwise the wrong instructions will be selected. 12747 //---------------------------------------------------------------------- 12748 12749 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12750 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12751 12752 //---------------------------------------------------------------------- 12753 // Load instructions 12754 //---------------------------------------------------------------------- 12755 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12756 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12757 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12758 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12759 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12760 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12761 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12762 // Thumb2 PC-relative load into register 12763 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12764 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12765 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12766 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12767 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12768 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12769 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12770 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12771 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12772 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12773 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12774 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12775 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12776 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12777 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12778 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12779 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12780 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12781 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12782 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12783 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12784 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12785 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12786 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12787 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12788 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12789 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12790 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12791 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12792 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12793 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12794 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12795 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12796 12797 //---------------------------------------------------------------------- 12798 // Store instructions 12799 //---------------------------------------------------------------------- 12800 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12801 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12802 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12803 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12804 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12805 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12806 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12807 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12808 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12809 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12810 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12811 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12812 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12813 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12814 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12815 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12816 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12817 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12818 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12819 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12820 { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12821 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12822 12823 //---------------------------------------------------------------------- 12824 // Other instructions 12825 //---------------------------------------------------------------------- 12826 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12827 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12828 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12829 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12830 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12831 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12832 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12833 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12834 }; 12835 12836 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 12837 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12838 { 12839 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12840 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12841 return &g_thumb_opcodes[i]; 12842 } 12843 return NULL; 12844 } 12845 12846 bool 12847 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12848 { 12849 m_arch = arch; 12850 m_arm_isa = 0; 12851 const char *arch_cstr = arch.GetArchitectureName (); 12852 if (arch_cstr) 12853 { 12854 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12855 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12856 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12857 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12858 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12859 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12860 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12861 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12862 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12863 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12864 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12865 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12866 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12867 } 12868 return m_arm_isa != 0; 12869 } 12870 12871 bool 12872 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12873 { 12874 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12875 { 12876 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12877 m_opcode_mode = eModeThumb; 12878 else 12879 { 12880 AddressClass addr_class = inst_addr.GetAddressClass(); 12881 12882 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 12883 m_opcode_mode = eModeARM; 12884 else if (addr_class == eAddressClassCodeAlternateISA) 12885 m_opcode_mode = eModeThumb; 12886 else 12887 return false; 12888 } 12889 if (m_opcode_mode == eModeThumb) 12890 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 12891 else 12892 m_opcode_cpsr = CPSR_MODE_USR; 12893 return true; 12894 } 12895 return false; 12896 } 12897 12898 bool 12899 EmulateInstructionARM::ReadInstruction () 12900 { 12901 bool success = false; 12902 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 12903 if (success) 12904 { 12905 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 12906 if (success) 12907 { 12908 Context read_inst_context; 12909 read_inst_context.type = eContextReadOpcode; 12910 read_inst_context.SetNoArgs (); 12911 12912 if (m_opcode_cpsr & MASK_CPSR_T) 12913 { 12914 m_opcode_mode = eModeThumb; 12915 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 12916 12917 if (success) 12918 { 12919 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 12920 { 12921 m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder()); 12922 } 12923 else 12924 { 12925 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder()); 12926 } 12927 } 12928 } 12929 else 12930 { 12931 m_opcode_mode = eModeARM; 12932 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder()); 12933 } 12934 } 12935 } 12936 if (!success) 12937 { 12938 m_opcode_mode = eModeInvalid; 12939 m_addr = LLDB_INVALID_ADDRESS; 12940 } 12941 return success; 12942 } 12943 12944 uint32_t 12945 EmulateInstructionARM::ArchVersion () 12946 { 12947 return m_arm_isa; 12948 } 12949 12950 bool 12951 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) 12952 { 12953 // If we are ignoring conditions, then always return true. 12954 // this allows us to iterate over disassembly code and still 12955 // emulate an instruction even if we don't have all the right 12956 // bits set in the CPSR register... 12957 if (m_ignore_conditions) 12958 return true; 12959 12960 if (is_conditional) 12961 *is_conditional = true; 12962 12963 const uint32_t cond = CurrentCond (opcode); 12964 12965 if (cond == UINT32_MAX) 12966 return false; 12967 12968 bool result = false; 12969 switch (UnsignedBits(cond, 3, 1)) 12970 { 12971 case 0: 12972 if (m_opcode_cpsr == 0) 12973 result = true; 12974 else 12975 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 12976 break; 12977 case 1: 12978 if (m_opcode_cpsr == 0) 12979 result = true; 12980 else 12981 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 12982 break; 12983 case 2: 12984 if (m_opcode_cpsr == 0) 12985 result = true; 12986 else 12987 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 12988 break; 12989 case 3: 12990 if (m_opcode_cpsr == 0) 12991 result = true; 12992 else 12993 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 12994 break; 12995 case 4: 12996 if (m_opcode_cpsr == 0) 12997 result = true; 12998 else 12999 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13000 break; 13001 case 5: 13002 if (m_opcode_cpsr == 0) 13003 result = true; 13004 else 13005 { 13006 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13007 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13008 result = n == v; 13009 } 13010 break; 13011 case 6: 13012 if (m_opcode_cpsr == 0) 13013 result = true; 13014 else 13015 { 13016 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13017 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13018 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13019 } 13020 break; 13021 case 7: 13022 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13023 // opcodes different meanings, but always means execution happens. 13024 if (is_conditional) 13025 *is_conditional = false; 13026 result = true; 13027 break; 13028 } 13029 13030 if (cond & 1) 13031 result = !result; 13032 return result; 13033 } 13034 13035 uint32_t 13036 EmulateInstructionARM::CurrentCond (const uint32_t opcode) 13037 { 13038 switch (m_opcode_mode) 13039 { 13040 case eModeInvalid: 13041 break; 13042 13043 case eModeARM: 13044 return UnsignedBits(opcode, 31, 28); 13045 13046 case eModeThumb: 13047 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13048 // 'cond' field of the encoding. 13049 { 13050 const uint32_t byte_size = m_opcode.GetByteSize(); 13051 if (byte_size == 2) 13052 { 13053 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 13054 return Bits32(opcode, 11, 7); 13055 } 13056 else if (byte_size == 4) 13057 { 13058 if (Bits32(opcode, 31, 27) == 0x1e && 13059 Bits32(opcode, 15, 14) == 0x02 && 13060 Bits32(opcode, 12, 12) == 0x00 && 13061 Bits32(opcode, 25, 22) <= 0x0d) 13062 { 13063 return Bits32(opcode, 25, 22); 13064 } 13065 } 13066 else 13067 // We have an invalid thumb instruction, let's bail out. 13068 break; 13069 13070 return m_it_session.GetCond(); 13071 } 13072 } 13073 return UINT32_MAX; // Return invalid value 13074 } 13075 13076 bool 13077 EmulateInstructionARM::InITBlock() 13078 { 13079 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13080 } 13081 13082 bool 13083 EmulateInstructionARM::LastInITBlock() 13084 { 13085 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13086 } 13087 13088 bool 13089 EmulateInstructionARM::BadMode (uint32_t mode) 13090 { 13091 13092 switch (mode) 13093 { 13094 case 16: return false; // '10000' 13095 case 17: return false; // '10001' 13096 case 18: return false; // '10010' 13097 case 19: return false; // '10011' 13098 case 22: return false; // '10110' 13099 case 23: return false; // '10111' 13100 case 27: return false; // '11011' 13101 case 31: return false; // '11111' 13102 default: return true; 13103 } 13104 return true; 13105 } 13106 13107 bool 13108 EmulateInstructionARM::CurrentModeIsPrivileged () 13109 { 13110 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13111 13112 if (BadMode (mode)) 13113 return false; 13114 13115 if (mode == 16) 13116 return false; 13117 13118 return true; 13119 } 13120 13121 void 13122 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13123 { 13124 bool privileged = CurrentModeIsPrivileged(); 13125 13126 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13127 13128 if (BitIsSet (bytemask, 3)) 13129 { 13130 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13131 if (affect_execstate) 13132 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13133 } 13134 13135 if (BitIsSet (bytemask, 2)) 13136 { 13137 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13138 } 13139 13140 if (BitIsSet (bytemask, 1)) 13141 { 13142 if (affect_execstate) 13143 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13144 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13145 if (privileged) 13146 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13147 } 13148 13149 if (BitIsSet (bytemask, 0)) 13150 { 13151 if (privileged) 13152 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13153 if (affect_execstate) 13154 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13155 if (privileged) 13156 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13157 } 13158 13159 m_opcode_cpsr = tmp_cpsr; 13160 } 13161 13162 13163 bool 13164 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13165 { 13166 addr_t target; 13167 13168 // Check the current instruction set. 13169 if (CurrentInstrSet() == eModeARM) 13170 target = addr & 0xfffffffc; 13171 else 13172 target = addr & 0xfffffffe; 13173 13174 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13175 return false; 13176 13177 return true; 13178 } 13179 13180 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13181 bool 13182 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13183 { 13184 addr_t target; 13185 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13186 // we want to record it and issue a WriteRegister callback so the clients 13187 // can track the mode changes accordingly. 13188 bool cpsr_changed = false; 13189 13190 if (BitIsSet(addr, 0)) 13191 { 13192 if (CurrentInstrSet() != eModeThumb) 13193 { 13194 SelectInstrSet(eModeThumb); 13195 cpsr_changed = true; 13196 } 13197 target = addr & 0xfffffffe; 13198 context.SetISA (eModeThumb); 13199 } 13200 else if (BitIsClear(addr, 1)) 13201 { 13202 if (CurrentInstrSet() != eModeARM) 13203 { 13204 SelectInstrSet(eModeARM); 13205 cpsr_changed = true; 13206 } 13207 target = addr & 0xfffffffc; 13208 context.SetISA (eModeARM); 13209 } 13210 else 13211 return false; // address<1:0> == '10' => UNPREDICTABLE 13212 13213 if (cpsr_changed) 13214 { 13215 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13216 return false; 13217 } 13218 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13219 return false; 13220 13221 return true; 13222 } 13223 13224 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13225 bool 13226 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13227 { 13228 if (ArchVersion() >= ARMv5T) 13229 return BXWritePC(context, addr); 13230 else 13231 return BranchWritePC((const Context)context, addr); 13232 } 13233 13234 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13235 bool 13236 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13237 { 13238 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13239 return BXWritePC(context, addr); 13240 else 13241 return BranchWritePC((const Context)context, addr); 13242 } 13243 13244 EmulateInstructionARM::Mode 13245 EmulateInstructionARM::CurrentInstrSet () 13246 { 13247 return m_opcode_mode; 13248 } 13249 13250 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13251 // ReadInstruction() is performed. This function has a side effect of updating 13252 // the m_new_inst_cpsr member variable if necessary. 13253 bool 13254 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13255 { 13256 m_new_inst_cpsr = m_opcode_cpsr; 13257 switch (arm_or_thumb) 13258 { 13259 default: 13260 return false; 13261 case eModeARM: 13262 // Clear the T bit. 13263 m_new_inst_cpsr &= ~MASK_CPSR_T; 13264 break; 13265 case eModeThumb: 13266 // Set the T bit. 13267 m_new_inst_cpsr |= MASK_CPSR_T; 13268 break; 13269 } 13270 return true; 13271 } 13272 13273 // This function returns TRUE if the processor currently provides support for 13274 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13275 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13276 bool 13277 EmulateInstructionARM::UnalignedSupport() 13278 { 13279 return (ArchVersion() >= ARMv7); 13280 } 13281 13282 // The main addition and subtraction instructions can produce status information 13283 // about both unsigned carry and signed overflow conditions. This status 13284 // information can be used to synthesize multi-word additions and subtractions. 13285 EmulateInstructionARM::AddWithCarryResult 13286 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13287 { 13288 uint32_t result; 13289 uint8_t carry_out; 13290 uint8_t overflow; 13291 13292 uint64_t unsigned_sum = x + y + carry_in; 13293 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13294 13295 result = UnsignedBits(unsigned_sum, 31, 0); 13296 // carry_out = (result == unsigned_sum ? 0 : 1); 13297 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13298 13299 if (carry_in) 13300 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13301 else 13302 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13303 13304 AddWithCarryResult res = { result, carry_out, overflow }; 13305 return res; 13306 } 13307 13308 uint32_t 13309 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13310 { 13311 lldb::RegisterKind reg_kind; 13312 uint32_t reg_num; 13313 switch (num) 13314 { 13315 case SP_REG: 13316 reg_kind = eRegisterKindGeneric; 13317 reg_num = LLDB_REGNUM_GENERIC_SP; 13318 break; 13319 case LR_REG: 13320 reg_kind = eRegisterKindGeneric; 13321 reg_num = LLDB_REGNUM_GENERIC_RA; 13322 break; 13323 case PC_REG: 13324 reg_kind = eRegisterKindGeneric; 13325 reg_num = LLDB_REGNUM_GENERIC_PC; 13326 break; 13327 default: 13328 if (num < SP_REG) 13329 { 13330 reg_kind = eRegisterKindDWARF; 13331 reg_num = dwarf_r0 + num; 13332 } 13333 else 13334 { 13335 //assert(0 && "Invalid register number"); 13336 *success = false; 13337 return UINT32_MAX; 13338 } 13339 break; 13340 } 13341 13342 // Read our register. 13343 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13344 13345 // When executing an ARM instruction , PC reads as the address of the current 13346 // instruction plus 8. 13347 // When executing a Thumb instruction , PC reads as the address of the current 13348 // instruction plus 4. 13349 if (num == 15) 13350 { 13351 if (CurrentInstrSet() == eModeARM) 13352 val += 8; 13353 else 13354 val += 4; 13355 } 13356 13357 return val; 13358 } 13359 13360 // Write the result to the ARM core register Rd, and optionally update the 13361 // condition flags based on the result. 13362 // 13363 // This helper method tries to encapsulate the following pseudocode from the 13364 // ARM Architecture Reference Manual: 13365 // 13366 // if d == 15 then // Can only occur for encoding A1 13367 // ALUWritePC(result); // setflags is always FALSE here 13368 // else 13369 // R[d] = result; 13370 // if setflags then 13371 // APSR.N = result<31>; 13372 // APSR.Z = IsZeroBit(result); 13373 // APSR.C = carry; 13374 // // APSR.V unchanged 13375 // 13376 // In the above case, the API client does not pass in the overflow arg, which 13377 // defaults to ~0u. 13378 bool 13379 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13380 const uint32_t result, 13381 const uint32_t Rd, 13382 bool setflags, 13383 const uint32_t carry, 13384 const uint32_t overflow) 13385 { 13386 if (Rd == 15) 13387 { 13388 if (!ALUWritePC (context, result)) 13389 return false; 13390 } 13391 else 13392 { 13393 lldb::RegisterKind reg_kind; 13394 uint32_t reg_num; 13395 switch (Rd) 13396 { 13397 case SP_REG: 13398 reg_kind = eRegisterKindGeneric; 13399 reg_num = LLDB_REGNUM_GENERIC_SP; 13400 break; 13401 case LR_REG: 13402 reg_kind = eRegisterKindGeneric; 13403 reg_num = LLDB_REGNUM_GENERIC_RA; 13404 break; 13405 default: 13406 reg_kind = eRegisterKindDWARF; 13407 reg_num = dwarf_r0 + Rd; 13408 } 13409 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13410 return false; 13411 if (setflags) 13412 return WriteFlags (context, result, carry, overflow); 13413 } 13414 return true; 13415 } 13416 13417 // This helper method tries to encapsulate the following pseudocode from the 13418 // ARM Architecture Reference Manual: 13419 // 13420 // APSR.N = result<31>; 13421 // APSR.Z = IsZeroBit(result); 13422 // APSR.C = carry; 13423 // APSR.V = overflow 13424 // 13425 // Default arguments can be specified for carry and overflow parameters, which means 13426 // not to update the respective flags. 13427 bool 13428 EmulateInstructionARM::WriteFlags (Context &context, 13429 const uint32_t result, 13430 const uint32_t carry, 13431 const uint32_t overflow) 13432 { 13433 m_new_inst_cpsr = m_opcode_cpsr; 13434 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13435 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13436 if (carry != ~0u) 13437 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13438 if (overflow != ~0u) 13439 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13440 if (m_new_inst_cpsr != m_opcode_cpsr) 13441 { 13442 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13443 return false; 13444 } 13445 return true; 13446 } 13447 13448 bool 13449 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13450 { 13451 // Advance the ITSTATE bits to their values for the next instruction. 13452 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13453 m_it_session.ITAdvance(); 13454 13455 ARMOpcode *opcode_data = NULL; 13456 13457 if (m_opcode_mode == eModeThumb) 13458 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13459 else if (m_opcode_mode == eModeARM) 13460 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13461 13462 if (opcode_data == NULL) 13463 return false; 13464 13465 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13466 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13467 13468 bool success = false; 13469 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13470 { 13471 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13472 dwarf_cpsr, 13473 0, 13474 &success); 13475 } 13476 13477 // Only return false if we are unable to read the CPSR if we care about conditions 13478 if (success == false && m_ignore_conditions == false) 13479 return false; 13480 13481 uint32_t orig_pc_value = 0; 13482 if (auto_advance_pc) 13483 { 13484 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13485 if (!success) 13486 return false; 13487 } 13488 13489 // Call the Emulate... function. 13490 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13491 if (!success) 13492 return false; 13493 13494 if (auto_advance_pc) 13495 { 13496 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13497 if (!success) 13498 return false; 13499 13500 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13501 { 13502 if (opcode_data->size == eSize32) 13503 after_pc_value += 4; 13504 else if (opcode_data->size == eSize16) 13505 after_pc_value += 2; 13506 13507 EmulateInstruction::Context context; 13508 context.type = eContextAdvancePC; 13509 context.SetNoArgs(); 13510 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13511 return false; 13512 13513 } 13514 } 13515 return true; 13516 } 13517 13518 bool 13519 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13520 { 13521 if (!test_data) 13522 { 13523 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13524 return false; 13525 } 13526 13527 static ConstString opcode_key ("opcode"); 13528 static ConstString before_key ("before_state"); 13529 static ConstString after_key ("after_state"); 13530 13531 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13532 13533 uint32_t test_opcode; 13534 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13535 { 13536 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13537 return false; 13538 } 13539 test_opcode = value_sp->GetUInt64Value (); 13540 13541 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13542 { 13543 m_opcode_mode = eModeARM; 13544 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13545 } 13546 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13547 { 13548 m_opcode_mode = eModeThumb; 13549 if (test_opcode < 0x10000) 13550 m_opcode.SetOpcode16 (test_opcode, GetByteOrder()); 13551 else 13552 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13553 13554 } 13555 else 13556 { 13557 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13558 return false; 13559 } 13560 13561 EmulationStateARM before_state; 13562 EmulationStateARM after_state; 13563 13564 value_sp = test_data->GetValueForKey (before_key); 13565 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13566 { 13567 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13568 return false; 13569 } 13570 13571 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13572 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13573 { 13574 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13575 return false; 13576 } 13577 13578 value_sp = test_data->GetValueForKey (after_key); 13579 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13580 { 13581 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13582 return false; 13583 } 13584 13585 state_dictionary = value_sp->GetAsDictionary (); 13586 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13587 { 13588 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13589 return false; 13590 } 13591 13592 SetBaton ((void *) &before_state); 13593 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13594 &EmulationStateARM::WritePseudoMemory, 13595 &EmulationStateARM::ReadPseudoRegister, 13596 &EmulationStateARM::WritePseudoRegister); 13597 13598 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13599 if (!success) 13600 { 13601 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13602 return false; 13603 } 13604 13605 success = before_state.CompareState (after_state); 13606 if (!success) 13607 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13608 13609 return success; 13610 } 13611 // 13612 // 13613 //const char * 13614 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13615 //{ 13616 // if (reg_kind == eRegisterKindGeneric) 13617 // { 13618 // switch (reg_num) 13619 // { 13620 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 13621 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 13622 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 13623 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 13624 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13625 // default: return NULL; 13626 // } 13627 // } 13628 // else if (reg_kind == eRegisterKindDWARF) 13629 // { 13630 // return GetARMDWARFRegisterName (reg_num); 13631 // } 13632 // return NULL; 13633 //} 13634 // 13635 bool 13636 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13637 { 13638 unwind_plan.Clear(); 13639 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13640 13641 UnwindPlan::RowSP row(new UnwindPlan::Row); 13642 13643 // Our previous Call Frame Address is the stack pointer 13644 row->SetCFARegister (dwarf_sp); 13645 13646 // Our previous PC is in the LR 13647 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true); 13648 unwind_plan.AppendRow (row); 13649 13650 // All other registers are the same. 13651 13652 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13653 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 13654 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 13655 return true; 13656 } 13657