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 #if 0 // unreachable because if true 9877 else 9878 { 9879 // R[d] = 1; 9880 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9881 return false; 9882 } 9883 #endif // unreachable because if true 9884 } 9885 return true; 9886 } 9887 9888 // A8.6.197 STRB (immediate, ARM) 9889 bool 9890 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9891 { 9892 #if 0 9893 if ConditionPassed() then 9894 EncodingSpecificOperations(); 9895 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9896 address = if index then offset_addr else R[n]; 9897 MemU[address,1] = R[t]<7:0>; 9898 if wback then R[n] = offset_addr; 9899 #endif 9900 9901 bool success = false; 9902 9903 if (ConditionPassed(opcode)) 9904 { 9905 uint32_t t; 9906 uint32_t n; 9907 uint32_t imm32; 9908 bool index; 9909 bool add; 9910 bool wback; 9911 9912 switch (encoding) 9913 { 9914 case eEncodingA1: 9915 // if P == �0� && W == �1� then SEE STRBT; 9916 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9917 t = Bits32 (opcode, 15, 12); 9918 n = Bits32 (opcode, 19, 16); 9919 imm32 = Bits32 (opcode, 11, 0); 9920 9921 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9922 index = BitIsSet (opcode, 24); 9923 add = BitIsSet (opcode, 23); 9924 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9925 9926 // if t == 15 then UNPREDICTABLE; 9927 if (t == 15) 9928 return false; 9929 9930 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9931 if (wback && ((n == 15) || (n == t))) 9932 return false; 9933 9934 break; 9935 9936 default: 9937 return false; 9938 } 9939 9940 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9941 uint32_t Rn = ReadCoreReg (n, &success); 9942 if (!success) 9943 return false; 9944 9945 addr_t offset_addr; 9946 if (add) 9947 offset_addr = Rn + imm32; 9948 else 9949 offset_addr = Rn - imm32; 9950 9951 // address = if index then offset_addr else R[n]; 9952 addr_t address; 9953 if (index) 9954 address = offset_addr; 9955 else 9956 address = Rn; 9957 9958 // MemU[address,1] = R[t]<7:0>; 9959 uint32_t Rt = ReadCoreReg (t, &success); 9960 if (!success) 9961 return false; 9962 9963 RegisterInfo base_reg; 9964 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9965 RegisterInfo data_reg; 9966 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9967 EmulateInstruction::Context context; 9968 context.type = eContextRegisterStore; 9969 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9970 9971 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 9972 return false; 9973 9974 // if wback then R[n] = offset_addr; 9975 if (wback) 9976 { 9977 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9978 return false; 9979 } 9980 } 9981 return true; 9982 } 9983 9984 // A8.6.194 STR (immediate, ARM) 9985 bool 9986 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9987 { 9988 #if 0 9989 if ConditionPassed() then 9990 EncodingSpecificOperations(); 9991 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9992 address = if index then offset_addr else R[n]; 9993 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9994 if wback then R[n] = offset_addr; 9995 #endif 9996 9997 bool success = false; 9998 9999 if (ConditionPassed(opcode)) 10000 { 10001 uint32_t t; 10002 uint32_t n; 10003 uint32_t imm32; 10004 bool index; 10005 bool add; 10006 bool wback; 10007 10008 const uint32_t addr_byte_size = GetAddressByteSize(); 10009 10010 switch (encoding) 10011 { 10012 case eEncodingA1: 10013 // if P == �0� && W == �1� then SEE STRT; 10014 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH; 10015 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10016 t = Bits32 (opcode, 15, 12); 10017 n = Bits32 (opcode, 19, 16); 10018 imm32 = Bits32 (opcode, 11, 0); 10019 10020 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10021 index = BitIsSet (opcode, 24); 10022 add = BitIsSet (opcode, 23); 10023 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10024 10025 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10026 if (wback && ((n == 15) || (n == t))) 10027 return false; 10028 10029 break; 10030 10031 default: 10032 return false; 10033 } 10034 10035 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10036 uint32_t Rn = ReadCoreReg (n, &success); 10037 if (!success) 10038 return false; 10039 10040 addr_t offset_addr; 10041 if (add) 10042 offset_addr = Rn + imm32; 10043 else 10044 offset_addr = Rn - imm32; 10045 10046 // address = if index then offset_addr else R[n]; 10047 addr_t address; 10048 if (index) 10049 address = offset_addr; 10050 else 10051 address = Rn; 10052 10053 RegisterInfo base_reg; 10054 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10055 RegisterInfo data_reg; 10056 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10057 EmulateInstruction::Context context; 10058 context.type = eContextRegisterStore; 10059 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10060 10061 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10062 uint32_t Rt = ReadCoreReg (t, &success); 10063 if (!success) 10064 return false; 10065 10066 if (t == 15) 10067 { 10068 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10069 if (!success) 10070 return false; 10071 10072 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10073 return false; 10074 } 10075 else 10076 { 10077 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10078 return false; 10079 } 10080 10081 // if wback then R[n] = offset_addr; 10082 if (wback) 10083 { 10084 context.type = eContextAdjustBaseRegister; 10085 context.SetImmediate (offset_addr); 10086 10087 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10088 return false; 10089 } 10090 } 10091 return true; 10092 } 10093 10094 // A8.6.66 LDRD (immediate) 10095 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10096 // words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10097 bool 10098 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10099 { 10100 #if 0 10101 if ConditionPassed() then 10102 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10103 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10104 address = if index then offset_addr else R[n]; 10105 R[t] = MemA[address,4]; 10106 R[t2] = MemA[address+4,4]; 10107 if wback then R[n] = offset_addr; 10108 #endif 10109 10110 bool success = false; 10111 10112 if (ConditionPassed(opcode)) 10113 { 10114 uint32_t t; 10115 uint32_t t2; 10116 uint32_t n; 10117 uint32_t imm32; 10118 bool index; 10119 bool add; 10120 bool wback; 10121 10122 switch (encoding) 10123 { 10124 case eEncodingT1: 10125 //if P == �0� && W == �0� then SEE �Related encodings�; 10126 //if Rn == �1111� then SEE LDRD (literal); 10127 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10128 t = Bits32 (opcode, 15, 12); 10129 t2 = Bits32 (opcode, 11, 8); 10130 n = Bits32 (opcode, 19, 16); 10131 imm32 = Bits32 (opcode, 7, 0) << 2; 10132 10133 //index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10134 index = BitIsSet (opcode, 24); 10135 add = BitIsSet (opcode, 23); 10136 wback = BitIsSet (opcode, 21); 10137 10138 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10139 if (wback && ((n == t) || (n == t2))) 10140 return false; 10141 10142 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10143 if (BadReg (t) || BadReg (t2) || (t == t2)) 10144 return false; 10145 10146 break; 10147 10148 case eEncodingA1: 10149 //if Rn == �1111� then SEE LDRD (literal); 10150 //if Rt<0> == �1� then UNPREDICTABLE; 10151 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10152 t = Bits32 (opcode, 15, 12); 10153 if (BitIsSet (t, 0)) 10154 return false; 10155 t2 = t + 1; 10156 n = Bits32 (opcode, 19, 16); 10157 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10158 10159 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10160 index = BitIsSet (opcode, 24); 10161 add = BitIsSet (opcode, 23); 10162 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10163 10164 //if P == �0� && W == �1� then UNPREDICTABLE; 10165 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10166 return false; 10167 10168 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10169 if (wback && ((n == t) || (n == t2))) 10170 return false; 10171 10172 //if t2 == 15 then UNPREDICTABLE; 10173 if (t2 == 15) 10174 return false; 10175 10176 break; 10177 10178 default: 10179 return false; 10180 } 10181 10182 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10183 uint32_t Rn = ReadCoreReg (n, &success); 10184 if (!success) 10185 return false; 10186 10187 addr_t offset_addr; 10188 if (add) 10189 offset_addr = Rn + imm32; 10190 else 10191 offset_addr = Rn - imm32; 10192 10193 //address = if index then offset_addr else R[n]; 10194 addr_t address; 10195 if (index) 10196 address = offset_addr; 10197 else 10198 address = Rn; 10199 10200 //R[t] = MemA[address,4]; 10201 RegisterInfo base_reg; 10202 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10203 10204 EmulateInstruction::Context context; 10205 context.type = eContextRegisterLoad; 10206 context.SetRegisterPlusOffset (base_reg, address - Rn); 10207 10208 const uint32_t addr_byte_size = GetAddressByteSize(); 10209 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10210 if (!success) 10211 return false; 10212 10213 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10214 return false; 10215 10216 //R[t2] = MemA[address+4,4]; 10217 10218 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10219 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10220 if (!success) 10221 return false; 10222 10223 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10224 return false; 10225 10226 //if wback then R[n] = offset_addr; 10227 if (wback) 10228 { 10229 context.type = eContextAdjustBaseRegister; 10230 context.SetAddress (offset_addr); 10231 10232 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10233 return false; 10234 } 10235 } 10236 return true; 10237 } 10238 10239 // A8.6.68 LDRD (register) 10240 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10241 // words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10242 bool 10243 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10244 { 10245 #if 0 10246 if ConditionPassed() then 10247 EncodingSpecificOperations(); 10248 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10249 address = if index then offset_addr else R[n]; 10250 R[t] = MemA[address,4]; 10251 R[t2] = MemA[address+4,4]; 10252 if wback then R[n] = offset_addr; 10253 #endif 10254 10255 bool success = false; 10256 10257 if (ConditionPassed(opcode)) 10258 { 10259 uint32_t t; 10260 uint32_t t2; 10261 uint32_t n; 10262 uint32_t m; 10263 bool index; 10264 bool add; 10265 bool wback; 10266 10267 switch (encoding) 10268 { 10269 case eEncodingA1: 10270 // if Rt<0> == �1� then UNPREDICTABLE; 10271 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10272 t = Bits32 (opcode, 15, 12); 10273 if (BitIsSet (t, 0)) 10274 return false; 10275 t2 = t + 1; 10276 n = Bits32 (opcode, 19, 16); 10277 m = Bits32 (opcode, 3, 0); 10278 10279 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10280 index = BitIsSet (opcode, 24); 10281 add = BitIsSet (opcode, 23); 10282 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10283 10284 // if P == �0� && W == �1� then UNPREDICTABLE; 10285 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10286 return false; 10287 10288 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10289 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10290 return false; 10291 10292 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10293 if (wback && ((n == 15) || (n == t) || (n == t2))) 10294 return false; 10295 10296 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10297 if ((ArchVersion() < 6) && wback && (m == n)) 10298 return false; 10299 break; 10300 10301 default: 10302 return false; 10303 } 10304 10305 uint32_t Rn = ReadCoreReg (n, &success); 10306 if (!success) 10307 return false; 10308 RegisterInfo base_reg; 10309 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10310 10311 uint32_t Rm = ReadCoreReg (m, &success); 10312 if (!success) 10313 return false; 10314 RegisterInfo offset_reg; 10315 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10316 10317 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10318 addr_t offset_addr; 10319 if (add) 10320 offset_addr = Rn + Rm; 10321 else 10322 offset_addr = Rn - Rm; 10323 10324 // address = if index then offset_addr else R[n]; 10325 addr_t address; 10326 if (index) 10327 address = offset_addr; 10328 else 10329 address = Rn; 10330 10331 EmulateInstruction::Context context; 10332 context.type = eContextRegisterLoad; 10333 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10334 10335 // R[t] = MemA[address,4]; 10336 const uint32_t addr_byte_size = GetAddressByteSize(); 10337 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10338 if (!success) 10339 return false; 10340 10341 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10342 return false; 10343 10344 // R[t2] = MemA[address+4,4]; 10345 10346 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10347 if (!success) 10348 return false; 10349 10350 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10351 return false; 10352 10353 // if wback then R[n] = offset_addr; 10354 if (wback) 10355 { 10356 context.type = eContextAdjustBaseRegister; 10357 context.SetAddress (offset_addr); 10358 10359 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10360 return false; 10361 } 10362 } 10363 return true; 10364 } 10365 10366 // A8.6.200 STRD (immediate) 10367 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10368 // stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10369 bool 10370 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10371 { 10372 #if 0 10373 if ConditionPassed() then 10374 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10375 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10376 address = if index then offset_addr else R[n]; 10377 MemA[address,4] = R[t]; 10378 MemA[address+4,4] = R[t2]; 10379 if wback then R[n] = offset_addr; 10380 #endif 10381 10382 bool success = false; 10383 10384 if (ConditionPassed(opcode)) 10385 { 10386 uint32_t t; 10387 uint32_t t2; 10388 uint32_t n; 10389 uint32_t imm32; 10390 bool index; 10391 bool add; 10392 bool wback; 10393 10394 switch (encoding) 10395 { 10396 case eEncodingT1: 10397 // if P == �0� && W == �0� then SEE �Related encodings�; 10398 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10399 t = Bits32 (opcode, 15, 12); 10400 t2 = Bits32 (opcode, 11, 8); 10401 n = Bits32 (opcode, 19, 16); 10402 imm32 = Bits32 (opcode, 7, 0) << 2; 10403 10404 // index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10405 index = BitIsSet (opcode, 24); 10406 add = BitIsSet (opcode, 23); 10407 wback = BitIsSet (opcode, 21); 10408 10409 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10410 if (wback && ((n == t) || (n == t2))) 10411 return false; 10412 10413 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10414 if ((n == 15) || BadReg (t) || BadReg (t2)) 10415 return false; 10416 10417 break; 10418 10419 case eEncodingA1: 10420 // if Rt<0> == �1� then UNPREDICTABLE; 10421 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10422 t = Bits32 (opcode, 15, 12); 10423 if (BitIsSet (t, 0)) 10424 return false; 10425 10426 t2 = t + 1; 10427 n = Bits32 (opcode, 19, 16); 10428 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10429 10430 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10431 index = BitIsSet (opcode, 24); 10432 add = BitIsSet (opcode, 23); 10433 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10434 10435 // if P == �0� && W == �1� then UNPREDICTABLE; 10436 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10437 return false; 10438 10439 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10440 if (wback && ((n == 15) || (n == t) || (n == t2))) 10441 return false; 10442 10443 // if t2 == 15 then UNPREDICTABLE; 10444 if (t2 == 15) 10445 return false; 10446 10447 break; 10448 10449 default: 10450 return false; 10451 } 10452 10453 RegisterInfo base_reg; 10454 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10455 10456 uint32_t Rn = ReadCoreReg (n, &success); 10457 if (!success) 10458 return false; 10459 10460 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10461 addr_t offset_addr; 10462 if (add) 10463 offset_addr = Rn + imm32; 10464 else 10465 offset_addr = Rn - imm32; 10466 10467 //address = if index then offset_addr else R[n]; 10468 addr_t address; 10469 if (index) 10470 address = offset_addr; 10471 else 10472 address = Rn; 10473 10474 //MemA[address,4] = R[t]; 10475 RegisterInfo data_reg; 10476 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10477 10478 uint32_t data = ReadCoreReg (t, &success); 10479 if (!success) 10480 return false; 10481 10482 EmulateInstruction::Context context; 10483 context.type = eContextRegisterStore; 10484 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10485 10486 const uint32_t addr_byte_size = GetAddressByteSize(); 10487 10488 if (!MemAWrite (context, address, data, addr_byte_size)) 10489 return false; 10490 10491 //MemA[address+4,4] = R[t2]; 10492 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10493 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10494 10495 data = ReadCoreReg (t2, &success); 10496 if (!success) 10497 return false; 10498 10499 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10500 return false; 10501 10502 //if wback then R[n] = offset_addr; 10503 if (wback) 10504 { 10505 context.type = eContextAdjustBaseRegister; 10506 context.SetAddress (offset_addr); 10507 10508 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10509 return false; 10510 } 10511 } 10512 return true; 10513 } 10514 10515 10516 // A8.6.201 STRD (register) 10517 bool 10518 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10519 { 10520 #if 0 10521 if ConditionPassed() then 10522 EncodingSpecificOperations(); 10523 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10524 address = if index then offset_addr else R[n]; 10525 MemA[address,4] = R[t]; 10526 MemA[address+4,4] = R[t2]; 10527 if wback then R[n] = offset_addr; 10528 #endif 10529 10530 bool success = false; 10531 10532 if (ConditionPassed(opcode)) 10533 { 10534 uint32_t t; 10535 uint32_t t2; 10536 uint32_t n; 10537 uint32_t m; 10538 bool index; 10539 bool add; 10540 bool wback; 10541 10542 switch (encoding) 10543 { 10544 case eEncodingA1: 10545 // if Rt<0> == �1� then UNPREDICTABLE; 10546 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10547 t = Bits32 (opcode, 15, 12); 10548 if (BitIsSet (t, 0)) 10549 return false; 10550 10551 t2 = t+1; 10552 n = Bits32 (opcode, 19, 16); 10553 m = Bits32 (opcode, 3, 0); 10554 10555 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10556 index = BitIsSet (opcode, 24); 10557 add = BitIsSet (opcode, 23); 10558 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10559 10560 // if P == �0� && W == �1� then UNPREDICTABLE; 10561 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10562 return false; 10563 10564 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10565 if ((t2 == 15) || (m == 15)) 10566 return false; 10567 10568 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10569 if (wback && ((n == 15) || (n == t) || (n == t2))) 10570 return false; 10571 10572 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10573 if ((ArchVersion() < 6) && wback && (m == n)) 10574 return false; 10575 10576 break; 10577 10578 default: 10579 return false; 10580 } 10581 10582 RegisterInfo base_reg; 10583 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10584 RegisterInfo offset_reg; 10585 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10586 RegisterInfo data_reg; 10587 10588 uint32_t Rn = ReadCoreReg (n, &success); 10589 if (!success) 10590 return false; 10591 10592 uint32_t Rm = ReadCoreReg (m, &success); 10593 if (!success) 10594 return false; 10595 10596 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10597 addr_t offset_addr; 10598 if (add) 10599 offset_addr = Rn + Rm; 10600 else 10601 offset_addr = Rn - Rm; 10602 10603 // address = if index then offset_addr else R[n]; 10604 addr_t address; 10605 if (index) 10606 address = offset_addr; 10607 else 10608 address = Rn; 10609 // MemA[address,4] = R[t]; 10610 uint32_t Rt = ReadCoreReg (t, &success); 10611 if (!success) 10612 return false; 10613 10614 EmulateInstruction::Context context; 10615 context.type = eContextRegisterStore; 10616 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10617 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10618 10619 const uint32_t addr_byte_size = GetAddressByteSize(); 10620 10621 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10622 return false; 10623 10624 // MemA[address+4,4] = R[t2]; 10625 uint32_t Rt2 = ReadCoreReg (t2, &success); 10626 if (!success) 10627 return false; 10628 10629 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10630 10631 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10632 10633 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10634 return false; 10635 10636 // if wback then R[n] = offset_addr; 10637 if (wback) 10638 { 10639 context.type = eContextAdjustBaseRegister; 10640 context.SetAddress (offset_addr); 10641 10642 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10643 return false; 10644 10645 } 10646 } 10647 return true; 10648 } 10649 10650 // A8.6.319 VLDM 10651 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10652 // an ARM core register. 10653 bool 10654 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10655 { 10656 #if 0 10657 if ConditionPassed() then 10658 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10659 address = if add then R[n] else R[n]-imm32; 10660 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10661 for r = 0 to regs-1 10662 if single_regs then 10663 S[d+r] = MemA[address,4]; address = address+4; 10664 else 10665 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10666 // Combine the word-aligned words in the correct order for current endianness. 10667 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10668 #endif 10669 10670 bool success = false; 10671 10672 if (ConditionPassed(opcode)) 10673 { 10674 bool single_regs; 10675 bool add; 10676 bool wback; 10677 uint32_t d; 10678 uint32_t n; 10679 uint32_t imm32; 10680 uint32_t regs; 10681 10682 switch (encoding) 10683 { 10684 case eEncodingT1: 10685 case eEncodingA1: 10686 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10687 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10688 // if P == �1� && W == �0� then SEE VLDR; 10689 // if P == U && W == �1� then UNDEFINED; 10690 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10691 return false; 10692 10693 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10694 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10695 single_regs = false; 10696 add = BitIsSet (opcode, 23); 10697 wback = BitIsSet (opcode, 21); 10698 10699 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10700 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10701 n = Bits32 (opcode, 19, 16); 10702 imm32 = Bits32 (opcode, 7, 0) << 2; 10703 10704 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�. 10705 regs = Bits32 (opcode, 7, 0) / 2; 10706 10707 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10708 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10709 return false; 10710 10711 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10712 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10713 return false; 10714 10715 break; 10716 10717 case eEncodingT2: 10718 case eEncodingA2: 10719 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10720 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10721 // if P == �1� && W == �0� then SEE VLDR; 10722 // if P == U && W == �1� then UNDEFINED; 10723 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10724 return false; 10725 10726 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10727 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10728 single_regs = true; 10729 add = BitIsSet (opcode, 23); 10730 wback = BitIsSet (opcode, 21); 10731 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10732 n = Bits32 (opcode, 19, 16); 10733 10734 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10735 imm32 = Bits32 (opcode, 7, 0) << 2; 10736 regs = Bits32 (opcode, 7, 0); 10737 10738 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10739 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10740 return false; 10741 10742 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10743 if ((regs == 0) || ((d + regs) > 32)) 10744 return false; 10745 break; 10746 10747 default: 10748 return false; 10749 } 10750 10751 RegisterInfo base_reg; 10752 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10753 10754 uint32_t Rn = ReadCoreReg (n, &success); 10755 if (!success) 10756 return false; 10757 10758 // address = if add then R[n] else R[n]-imm32; 10759 addr_t address; 10760 if (add) 10761 address = Rn; 10762 else 10763 address = Rn - imm32; 10764 10765 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10766 EmulateInstruction::Context context; 10767 10768 if (wback) 10769 { 10770 uint32_t value; 10771 if (add) 10772 value = Rn + imm32; 10773 else 10774 value = Rn - imm32; 10775 10776 context.type = eContextAdjustBaseRegister; 10777 context.SetImmediateSigned (value - Rn); 10778 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10779 return false; 10780 10781 } 10782 10783 const uint32_t addr_byte_size = GetAddressByteSize(); 10784 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10785 10786 context.type = eContextRegisterLoad; 10787 10788 // for r = 0 to regs-1 10789 for (uint32_t r = 0; r < regs; ++r) 10790 { 10791 if (single_regs) 10792 { 10793 // S[d+r] = MemA[address,4]; address = address+4; 10794 context.SetRegisterPlusOffset (base_reg, address - Rn); 10795 10796 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10797 if (!success) 10798 return false; 10799 10800 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10801 return false; 10802 10803 address = address + 4; 10804 } 10805 else 10806 { 10807 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10808 context.SetRegisterPlusOffset (base_reg, address - Rn); 10809 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10810 if (!success) 10811 return false; 10812 10813 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10814 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10815 if (!success) 10816 return false; 10817 10818 address = address + 8; 10819 // // Combine the word-aligned words in the correct order for current endianness. 10820 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10821 uint64_t data; 10822 if (GetByteOrder() == eByteOrderBig) 10823 { 10824 data = word1; 10825 data = (data << 32) | word2; 10826 } 10827 else 10828 { 10829 data = word2; 10830 data = (data << 32) | word1; 10831 } 10832 10833 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10834 return false; 10835 } 10836 } 10837 } 10838 return true; 10839 } 10840 10841 // A8.6.399 VSTM 10842 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10843 // ARM core register. 10844 bool 10845 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10846 { 10847 #if 0 10848 if ConditionPassed() then 10849 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10850 address = if add then R[n] else R[n]-imm32; 10851 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10852 for r = 0 to regs-1 10853 if single_regs then 10854 MemA[address,4] = S[d+r]; address = address+4; 10855 else 10856 // Store as two word-aligned words in the correct order for current endianness. 10857 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10858 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10859 address = address+8; 10860 #endif 10861 10862 bool success = false; 10863 10864 if (ConditionPassed (opcode)) 10865 { 10866 bool single_regs; 10867 bool add; 10868 bool wback; 10869 uint32_t d; 10870 uint32_t n; 10871 uint32_t imm32; 10872 uint32_t regs; 10873 10874 switch (encoding) 10875 { 10876 case eEncodingT1: 10877 case eEncodingA1: 10878 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10879 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10880 // if P == �1� && W == �0� then SEE VSTR; 10881 // if P == U && W == �1� then UNDEFINED; 10882 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10883 return false; 10884 10885 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10886 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10887 single_regs = false; 10888 add = BitIsSet (opcode, 23); 10889 wback = BitIsSet (opcode, 21); 10890 10891 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10892 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10893 n = Bits32 (opcode, 19, 16); 10894 imm32 = Bits32 (opcode, 7, 0) << 2; 10895 10896 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�. 10897 regs = Bits32 (opcode, 7, 0) / 2; 10898 10899 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10900 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10901 return false; 10902 10903 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10904 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10905 return false; 10906 10907 break; 10908 10909 case eEncodingT2: 10910 case eEncodingA2: 10911 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10912 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10913 // if P == �1� && W == �0� then SEE VSTR; 10914 // if P == U && W == �1� then UNDEFINED; 10915 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10916 return false; 10917 10918 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10919 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10920 single_regs = true; 10921 add = BitIsSet (opcode, 23); 10922 wback = BitIsSet (opcode, 21); 10923 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10924 n = Bits32 (opcode, 19, 16); 10925 10926 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10927 imm32 = Bits32 (opcode, 7, 0) << 2; 10928 regs = Bits32 (opcode, 7, 0); 10929 10930 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10931 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 10932 return false; 10933 10934 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10935 if ((regs == 0) || ((d + regs) > 32)) 10936 return false; 10937 10938 break; 10939 10940 default: 10941 return false; 10942 } 10943 10944 RegisterInfo base_reg; 10945 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10946 10947 uint32_t Rn = ReadCoreReg (n, &success); 10948 if (!success) 10949 return false; 10950 10951 // address = if add then R[n] else R[n]-imm32; 10952 addr_t address; 10953 if (add) 10954 address = Rn; 10955 else 10956 address = Rn - imm32; 10957 10958 EmulateInstruction::Context context; 10959 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10960 if (wback) 10961 { 10962 uint32_t value; 10963 if (add) 10964 value = Rn + imm32; 10965 else 10966 value = Rn - imm32; 10967 10968 context.type = eContextAdjustBaseRegister; 10969 context.SetRegisterPlusOffset (base_reg, value - Rn); 10970 10971 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10972 return false; 10973 } 10974 10975 const uint32_t addr_byte_size = GetAddressByteSize(); 10976 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10977 10978 context.type = eContextRegisterStore; 10979 // for r = 0 to regs-1 10980 for (uint32_t r = 0; r < regs; ++r) 10981 { 10982 10983 if (single_regs) 10984 { 10985 // MemA[address,4] = S[d+r]; address = address+4; 10986 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10987 if (!success) 10988 return false; 10989 10990 RegisterInfo data_reg; 10991 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10992 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10993 if (!MemAWrite (context, address, data, addr_byte_size)) 10994 return false; 10995 10996 address = address + 4; 10997 } 10998 else 10999 { 11000 // // Store as two word-aligned words in the correct order for current endianness. 11001 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11002 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11003 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11004 if (!success) 11005 return false; 11006 11007 RegisterInfo data_reg; 11008 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11009 11010 if (GetByteOrder() == eByteOrderBig) 11011 { 11012 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11013 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11014 return false; 11015 11016 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11017 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 11018 return false; 11019 } 11020 else 11021 { 11022 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11023 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11024 return false; 11025 11026 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11027 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11028 return false; 11029 } 11030 // address = address+8; 11031 address = address + 8; 11032 } 11033 } 11034 } 11035 return true; 11036 } 11037 11038 // A8.6.320 11039 // This instruction loads a single extension register from memory, using an address from an ARM core register, with 11040 // an optional offset. 11041 bool 11042 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 11043 { 11044 #if 0 11045 if ConditionPassed() then 11046 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11047 base = if n == 15 then Align(PC,4) else R[n]; 11048 address = if add then (base + imm32) else (base - imm32); 11049 if single_reg then 11050 S[d] = MemA[address,4]; 11051 else 11052 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11053 // Combine the word-aligned words in the correct order for current endianness. 11054 D[d] = if BigEndian() then word1:word2 else word2:word1; 11055 #endif 11056 11057 bool success = false; 11058 11059 if (ConditionPassed (opcode)) 11060 { 11061 bool single_reg; 11062 bool add; 11063 uint32_t imm32; 11064 uint32_t d; 11065 uint32_t n; 11066 11067 switch (encoding) 11068 { 11069 case eEncodingT1: 11070 case eEncodingA1: 11071 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11072 single_reg = false; 11073 add = BitIsSet (opcode, 23); 11074 imm32 = Bits32 (opcode, 7, 0) << 2; 11075 11076 // d = UInt(D:Vd); n = UInt(Rn); 11077 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11078 n = Bits32 (opcode, 19, 16); 11079 11080 break; 11081 11082 case eEncodingT2: 11083 case eEncodingA2: 11084 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11085 single_reg = true; 11086 add = BitIsSet (opcode, 23); 11087 imm32 = Bits32 (opcode, 7, 0) << 2; 11088 11089 // d = UInt(Vd:D); n = UInt(Rn); 11090 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11091 n = Bits32 (opcode, 19, 16); 11092 11093 break; 11094 11095 default: 11096 return false; 11097 } 11098 RegisterInfo base_reg; 11099 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11100 11101 uint32_t Rn = ReadCoreReg (n, &success); 11102 if (!success) 11103 return false; 11104 11105 // base = if n == 15 then Align(PC,4) else R[n]; 11106 uint32_t base; 11107 if (n == 15) 11108 base = AlignPC (Rn); 11109 else 11110 base = Rn; 11111 11112 // address = if add then (base + imm32) else (base - imm32); 11113 addr_t address; 11114 if (add) 11115 address = base + imm32; 11116 else 11117 address = base - imm32; 11118 11119 const uint32_t addr_byte_size = GetAddressByteSize(); 11120 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11121 11122 EmulateInstruction::Context context; 11123 context.type = eContextRegisterLoad; 11124 context.SetRegisterPlusOffset (base_reg, address - base); 11125 11126 if (single_reg) 11127 { 11128 // S[d] = MemA[address,4]; 11129 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11130 if (!success) 11131 return false; 11132 11133 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11134 return false; 11135 } 11136 else 11137 { 11138 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11139 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11140 if (!success) 11141 return false; 11142 11143 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11144 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11145 if (!success) 11146 return false; 11147 // // Combine the word-aligned words in the correct order for current endianness. 11148 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11149 uint64_t data64; 11150 if (GetByteOrder() == eByteOrderBig) 11151 { 11152 data64 = word1; 11153 data64 = (data64 << 32) | word2; 11154 } 11155 else 11156 { 11157 data64 = word2; 11158 data64 = (data64 << 32) | word1; 11159 } 11160 11161 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11162 return false; 11163 } 11164 } 11165 return true; 11166 } 11167 11168 // A8.6.400 VSTR 11169 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11170 // optional offset. 11171 bool 11172 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11173 { 11174 #if 0 11175 if ConditionPassed() then 11176 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11177 address = if add then (R[n] + imm32) else (R[n] - imm32); 11178 if single_reg then 11179 MemA[address,4] = S[d]; 11180 else 11181 // Store as two word-aligned words in the correct order for current endianness. 11182 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11183 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11184 #endif 11185 11186 bool success = false; 11187 11188 if (ConditionPassed (opcode)) 11189 { 11190 bool single_reg; 11191 bool add; 11192 uint32_t imm32; 11193 uint32_t d; 11194 uint32_t n; 11195 11196 switch (encoding) 11197 { 11198 case eEncodingT1: 11199 case eEncodingA1: 11200 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11201 single_reg = false; 11202 add = BitIsSet (opcode, 23); 11203 imm32 = Bits32 (opcode, 7, 0) << 2; 11204 11205 // d = UInt(D:Vd); n = UInt(Rn); 11206 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11207 n = Bits32 (opcode, 19, 16); 11208 11209 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11210 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11211 return false; 11212 11213 break; 11214 11215 case eEncodingT2: 11216 case eEncodingA2: 11217 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11218 single_reg = true; 11219 add = BitIsSet (opcode, 23); 11220 imm32 = Bits32 (opcode, 7, 0) << 2; 11221 11222 // d = UInt(Vd:D); n = UInt(Rn); 11223 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11224 n = Bits32 (opcode, 19, 16); 11225 11226 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11227 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11228 return false; 11229 11230 break; 11231 11232 default: 11233 return false; 11234 } 11235 11236 RegisterInfo base_reg; 11237 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11238 11239 uint32_t Rn = ReadCoreReg (n, &success); 11240 if (!success) 11241 return false; 11242 11243 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11244 addr_t address; 11245 if (add) 11246 address = Rn + imm32; 11247 else 11248 address = Rn - imm32; 11249 11250 const uint32_t addr_byte_size = GetAddressByteSize(); 11251 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11252 11253 RegisterInfo data_reg; 11254 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11255 EmulateInstruction::Context context; 11256 context.type = eContextRegisterStore; 11257 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11258 11259 if (single_reg) 11260 { 11261 // MemA[address,4] = S[d]; 11262 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11263 if (!success) 11264 return false; 11265 11266 if (!MemAWrite (context, address, data, addr_byte_size)) 11267 return false; 11268 } 11269 else 11270 { 11271 // // Store as two word-aligned words in the correct order for current endianness. 11272 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11273 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11274 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11275 if (!success) 11276 return false; 11277 11278 if (GetByteOrder() == eByteOrderBig) 11279 { 11280 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11281 return false; 11282 11283 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11284 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11285 return false; 11286 } 11287 else 11288 { 11289 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11290 return false; 11291 11292 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11293 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11294 return false; 11295 } 11296 } 11297 } 11298 return true; 11299 } 11300 11301 // A8.6.307 VLDI1 (multiple single elements) 11302 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11303 // element of each register is loaded. 11304 bool 11305 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11306 { 11307 #if 0 11308 if ConditionPassed() then 11309 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11310 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11311 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11312 for r = 0 to regs-1 11313 for e = 0 to elements-1 11314 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11315 address = address + ebytes; 11316 #endif 11317 11318 bool success = false; 11319 11320 if (ConditionPassed (opcode)) 11321 { 11322 uint32_t regs; 11323 uint32_t alignment; 11324 uint32_t ebytes; 11325 uint32_t esize; 11326 uint32_t elements; 11327 uint32_t d; 11328 uint32_t n; 11329 uint32_t m; 11330 bool wback; 11331 bool register_index; 11332 11333 switch (encoding) 11334 { 11335 case eEncodingT1: 11336 case eEncodingA1: 11337 { 11338 // case type of 11339 // when �0111� 11340 // regs = 1; if align<1> == �1� then UNDEFINED; 11341 // when �1010� 11342 // regs = 2; if align == �11� then UNDEFINED; 11343 // when �0110� 11344 // regs = 3; if align<1> == �1� then UNDEFINED; 11345 // when �0010� 11346 // regs = 4; 11347 // otherwise 11348 // SEE �Related encodings�; 11349 uint32_t type = Bits32 (opcode, 11, 8); 11350 uint32_t align = Bits32 (opcode, 5, 4); 11351 if (type == 7) // '0111' 11352 { 11353 regs = 1; 11354 if (BitIsSet (align, 1)) 11355 return false; 11356 } 11357 else if (type == 10) // '1010' 11358 { 11359 regs = 2; 11360 if (align == 3) 11361 return false; 11362 11363 } 11364 else if (type == 6) // '0110' 11365 { 11366 regs = 3; 11367 if (BitIsSet (align, 1)) 11368 return false; 11369 } 11370 else if (type == 2) // '0010' 11371 { 11372 regs = 4; 11373 } 11374 else 11375 return false; 11376 11377 // alignment = if align == �00� then 1 else 4 << UInt(align); 11378 if (align == 0) 11379 alignment = 1; 11380 else 11381 alignment = 4 << align; 11382 11383 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11384 ebytes = 1 << Bits32 (opcode, 7, 6); 11385 esize = 8 * ebytes; 11386 elements = 8 / ebytes; 11387 11388 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11389 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11390 n = Bits32 (opcode, 19, 15); 11391 m = Bits32 (opcode, 3, 0); 11392 11393 // wback = (m != 15); register_index = (m != 15 && m != 13); 11394 wback = (m != 15); 11395 register_index = ((m != 15) && (m != 13)); 11396 11397 // if d+regs > 32 then UNPREDICTABLE; 11398 if ((d + regs) > 32) 11399 return false; 11400 } 11401 break; 11402 11403 default: 11404 return false; 11405 } 11406 11407 RegisterInfo base_reg; 11408 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11409 11410 uint32_t Rn = ReadCoreReg (n, &success); 11411 if (!success) 11412 return false; 11413 11414 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11415 addr_t address = Rn; 11416 if ((address % alignment) != 0) 11417 return false; 11418 11419 EmulateInstruction::Context context; 11420 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11421 if (wback) 11422 { 11423 uint32_t Rm = ReadCoreReg (m, &success); 11424 if (!success) 11425 return false; 11426 11427 uint32_t offset; 11428 if (register_index) 11429 offset = Rm; 11430 else 11431 offset = 8 * regs; 11432 11433 uint32_t value = Rn + offset; 11434 context.type = eContextAdjustBaseRegister; 11435 context.SetRegisterPlusOffset (base_reg, offset); 11436 11437 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11438 return false; 11439 11440 } 11441 11442 // for r = 0 to regs-1 11443 for (uint32_t r = 0; r < regs; ++r) 11444 { 11445 // for e = 0 to elements-1 11446 uint64_t assembled_data = 0; 11447 for (uint32_t e = 0; e < elements; ++e) 11448 { 11449 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11450 context.type = eContextRegisterLoad; 11451 context.SetRegisterPlusOffset (base_reg, address - Rn); 11452 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11453 if (!success) 11454 return false; 11455 11456 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11457 11458 // address = address + ebytes; 11459 address = address + ebytes; 11460 } 11461 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11462 return false; 11463 } 11464 } 11465 return true; 11466 } 11467 11468 // A8.6.308 VLD1 (single element to one lane) 11469 // 11470 bool 11471 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11472 { 11473 #if 0 11474 if ConditionPassed() then 11475 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11476 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11477 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11478 Elem[D[d],index,esize] = MemU[address,ebytes]; 11479 #endif 11480 11481 bool success = false; 11482 11483 if (ConditionPassed (opcode)) 11484 { 11485 uint32_t ebytes; 11486 uint32_t esize; 11487 uint32_t index; 11488 uint32_t alignment; 11489 uint32_t d; 11490 uint32_t n; 11491 uint32_t m; 11492 bool wback; 11493 bool register_index; 11494 11495 switch (encoding) 11496 { 11497 case eEncodingT1: 11498 case eEncodingA1: 11499 { 11500 uint32_t size = Bits32 (opcode, 11, 10); 11501 uint32_t index_align = Bits32 (opcode, 7, 4); 11502 // if size == �11� then SEE VLD1 (single element to all lanes); 11503 if (size == 3) 11504 return EmulateVLD1SingleAll (opcode, encoding); 11505 // case size of 11506 if (size == 0) // when '00' 11507 { 11508 // if index_align<0> != �0� then UNDEFINED; 11509 if (BitIsClear (index_align, 0)) 11510 return false; 11511 11512 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11513 ebytes = 1; 11514 esize = 8; 11515 index = Bits32 (index_align, 3, 1); 11516 alignment = 1; 11517 } 11518 else if (size == 1) // when �01� 11519 { 11520 // if index_align<1> != �0� then UNDEFINED; 11521 if (BitIsClear (index_align, 1)) 11522 return false; 11523 11524 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11525 ebytes = 2; 11526 esize = 16; 11527 index = Bits32 (index_align, 3, 2); 11528 11529 // alignment = if index_align<0> == �0� then 1 else 2; 11530 if (BitIsClear (index_align, 0)) 11531 alignment = 1; 11532 else 11533 alignment = 2; 11534 } 11535 else if (size == 2) // when �10� 11536 { 11537 // if index_align<2> != �0� then UNDEFINED; 11538 if (BitIsClear (index_align, 2)) 11539 return false; 11540 11541 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11542 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11543 return false; 11544 11545 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11546 ebytes = 4; 11547 esize = 32; 11548 index = Bit32 (index_align, 3); 11549 11550 // alignment = if index_align<1:0> == �00� then 1 else 4; 11551 if (Bits32 (index_align, 1, 0) == 0) 11552 alignment = 1; 11553 else 11554 alignment = 4; 11555 } 11556 else 11557 { 11558 return false; 11559 } 11560 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11561 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11562 n = Bits32 (opcode, 19, 16); 11563 m = Bits32 (opcode, 3, 0); 11564 11565 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11566 wback = (m != 15); 11567 register_index = ((m != 15) && (m != 13)); 11568 11569 if (n == 15) 11570 return false; 11571 11572 } 11573 break; 11574 11575 default: 11576 return false; 11577 } 11578 11579 RegisterInfo base_reg; 11580 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11581 11582 uint32_t Rn = ReadCoreReg (n, &success); 11583 if (!success) 11584 return false; 11585 11586 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11587 addr_t address = Rn; 11588 if ((address % alignment) != 0) 11589 return false; 11590 11591 EmulateInstruction::Context context; 11592 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11593 if (wback) 11594 { 11595 uint32_t Rm = ReadCoreReg (m, &success); 11596 if (!success) 11597 return false; 11598 11599 uint32_t offset; 11600 if (register_index) 11601 offset = Rm; 11602 else 11603 offset = ebytes; 11604 11605 uint32_t value = Rn + offset; 11606 11607 context.type = eContextAdjustBaseRegister; 11608 context.SetRegisterPlusOffset (base_reg, offset); 11609 11610 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11611 return false; 11612 } 11613 11614 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11615 uint32_t element = MemURead (context, address, esize, 0, &success); 11616 if (!success) 11617 return false; 11618 11619 element = element << (index * esize); 11620 11621 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11622 if (!success) 11623 return false; 11624 11625 uint64_t all_ones = -1; 11626 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11627 // at element & to the right of element. 11628 if (index > 0) 11629 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11630 // now mask should be 0's where element goes & 1's 11631 // everywhere else. 11632 11633 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11634 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11635 11636 context.type = eContextRegisterLoad; 11637 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11638 return false; 11639 } 11640 return true; 11641 } 11642 11643 // A8.6.391 VST1 (multiple single elements) 11644 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without 11645 // interleaving. Every element of each register is stored. 11646 bool 11647 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11648 { 11649 #if 0 11650 if ConditionPassed() then 11651 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11652 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11653 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11654 for r = 0 to regs-1 11655 for e = 0 to elements-1 11656 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11657 address = address + ebytes; 11658 #endif 11659 11660 bool success = false; 11661 11662 if (ConditionPassed (opcode)) 11663 { 11664 uint32_t regs; 11665 uint32_t alignment; 11666 uint32_t ebytes; 11667 uint32_t esize; 11668 uint32_t elements; 11669 uint32_t d; 11670 uint32_t n; 11671 uint32_t m; 11672 bool wback; 11673 bool register_index; 11674 11675 switch (encoding) 11676 { 11677 case eEncodingT1: 11678 case eEncodingA1: 11679 { 11680 uint32_t type = Bits32 (opcode, 11, 8); 11681 uint32_t align = Bits32 (opcode, 5, 4); 11682 11683 // case type of 11684 if (type == 7) // when �0111� 11685 { 11686 // regs = 1; if align<1> == �1� then UNDEFINED; 11687 regs = 1; 11688 if (BitIsSet (align, 1)) 11689 return false; 11690 } 11691 else if (type == 10) // when �1010� 11692 { 11693 // regs = 2; if align == �11� then UNDEFINED; 11694 regs = 2; 11695 if (align == 3) 11696 return false; 11697 } 11698 else if (type == 6) // when �0110� 11699 { 11700 // regs = 3; if align<1> == �1� then UNDEFINED; 11701 regs = 3; 11702 if (BitIsSet (align, 1)) 11703 return false; 11704 } 11705 else if (type == 2) // when �0010� 11706 // regs = 4; 11707 regs = 4; 11708 else // otherwise 11709 // SEE �Related encodings�; 11710 return false; 11711 11712 // alignment = if align == �00� then 1 else 4 << UInt(align); 11713 if (align == 0) 11714 alignment = 1; 11715 else 11716 alignment = 4 << align; 11717 11718 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11719 ebytes = 1 << Bits32 (opcode,7, 6); 11720 esize = 8 * ebytes; 11721 elements = 8 / ebytes; 11722 11723 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11724 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11725 n = Bits32 (opcode, 19, 16); 11726 m = Bits32 (opcode, 3, 0); 11727 11728 // wback = (m != 15); register_index = (m != 15 && m != 13); 11729 wback = (m != 15); 11730 register_index = ((m != 15) && (m != 13)); 11731 11732 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11733 if ((d + regs) > 32) 11734 return false; 11735 11736 if (n == 15) 11737 return false; 11738 11739 } 11740 break; 11741 11742 default: 11743 return false; 11744 } 11745 11746 RegisterInfo base_reg; 11747 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11748 11749 uint32_t Rn = ReadCoreReg (n, &success); 11750 if (!success) 11751 return false; 11752 11753 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11754 addr_t address = Rn; 11755 if ((address % alignment) != 0) 11756 return false; 11757 11758 EmulateInstruction::Context context; 11759 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11760 if (wback) 11761 { 11762 uint32_t Rm = ReadCoreReg (m, &success); 11763 if (!success) 11764 return false; 11765 11766 uint32_t offset; 11767 if (register_index) 11768 offset = Rm; 11769 else 11770 offset = 8 * regs; 11771 11772 context.type = eContextAdjustBaseRegister; 11773 context.SetRegisterPlusOffset (base_reg, offset); 11774 11775 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11776 return false; 11777 } 11778 11779 RegisterInfo data_reg; 11780 context.type = eContextRegisterStore; 11781 // for r = 0 to regs-1 11782 for (uint32_t r = 0; r < regs; ++r) 11783 { 11784 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11785 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11786 if (!success) 11787 return false; 11788 11789 // for e = 0 to elements-1 11790 for (uint32_t e = 0; e < elements; ++e) 11791 { 11792 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11793 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11794 11795 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11796 if (!MemUWrite (context, address, word, ebytes)) 11797 return false; 11798 11799 // address = address + ebytes; 11800 address = address + ebytes; 11801 } 11802 } 11803 } 11804 return true; 11805 } 11806 11807 // A8.6.392 VST1 (single element from one lane) 11808 // This instruction stores one element to memory from one element of a register. 11809 bool 11810 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11811 { 11812 #if 0 11813 if ConditionPassed() then 11814 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11815 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11816 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11817 MemU[address,ebytes] = Elem[D[d],index,esize]; 11818 #endif 11819 11820 bool success = false; 11821 11822 if (ConditionPassed (opcode)) 11823 { 11824 uint32_t ebytes; 11825 uint32_t esize; 11826 uint32_t index; 11827 uint32_t alignment; 11828 uint32_t d; 11829 uint32_t n; 11830 uint32_t m; 11831 bool wback; 11832 bool register_index; 11833 11834 switch (encoding) 11835 { 11836 case eEncodingT1: 11837 case eEncodingA1: 11838 { 11839 uint32_t size = Bits32 (opcode, 11, 10); 11840 uint32_t index_align = Bits32 (opcode, 7, 4); 11841 11842 // if size == �11� then UNDEFINED; 11843 if (size == 3) 11844 return false; 11845 11846 // case size of 11847 if (size == 0) // when �00� 11848 { 11849 // if index_align<0> != �0� then UNDEFINED; 11850 if (BitIsClear (index_align, 0)) 11851 return false; 11852 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11853 ebytes = 1; 11854 esize = 8; 11855 index = Bits32 (index_align, 3, 1); 11856 alignment = 1; 11857 } 11858 else if (size == 1) // when �01� 11859 { 11860 // if index_align<1> != �0� then UNDEFINED; 11861 if (BitIsClear (index_align, 1)) 11862 return false; 11863 11864 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11865 ebytes = 2; 11866 esize = 16; 11867 index = Bits32 (index_align, 3, 2); 11868 11869 // alignment = if index_align<0> == �0� then 1 else 2; 11870 if (BitIsClear (index_align, 0)) 11871 alignment = 1; 11872 else 11873 alignment = 2; 11874 } 11875 else if (size == 2) // when �10� 11876 { 11877 // if index_align<2> != �0� then UNDEFINED; 11878 if (BitIsClear (index_align, 2)) 11879 return false; 11880 11881 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11882 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11883 return false; 11884 11885 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11886 ebytes = 4; 11887 esize = 32; 11888 index = Bit32 (index_align, 3); 11889 11890 // alignment = if index_align<1:0> == �00� then 1 else 4; 11891 if (Bits32 (index_align, 1, 0) == 0) 11892 alignment = 1; 11893 else 11894 alignment = 4; 11895 } 11896 else 11897 { 11898 return false; 11899 } 11900 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11901 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11902 n = Bits32 (opcode, 19, 16); 11903 m = Bits32 (opcode, 3, 0); 11904 11905 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11906 wback = (m != 15); 11907 register_index = ((m != 15) && (m != 13)); 11908 11909 if (n == 15) 11910 return false; 11911 } 11912 break; 11913 11914 default: 11915 return false; 11916 } 11917 11918 RegisterInfo base_reg; 11919 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11920 11921 uint32_t Rn = ReadCoreReg (n, &success); 11922 if (!success) 11923 return false; 11924 11925 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11926 addr_t address = Rn; 11927 if ((address % alignment) != 0) 11928 return false; 11929 11930 EmulateInstruction::Context context; 11931 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11932 if (wback) 11933 { 11934 uint32_t Rm = ReadCoreReg (m, &success); 11935 if (!success) 11936 return false; 11937 11938 uint32_t offset; 11939 if (register_index) 11940 offset = Rm; 11941 else 11942 offset = ebytes; 11943 11944 context.type = eContextAdjustBaseRegister; 11945 context.SetRegisterPlusOffset (base_reg, offset); 11946 11947 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11948 return false; 11949 } 11950 11951 // MemU[address,ebytes] = Elem[D[d],index,esize]; 11952 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11953 if (!success) 11954 return false; 11955 11956 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 11957 11958 RegisterInfo data_reg; 11959 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 11960 context.type = eContextRegisterStore; 11961 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11962 11963 if (!MemUWrite (context, address, word, ebytes)) 11964 return false; 11965 } 11966 return true; 11967 } 11968 11969 // A8.6.309 VLD1 (single element to all lanes) 11970 // This instruction loads one element from memory into every element of one or two vectors. 11971 bool 11972 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 11973 { 11974 #if 0 11975 if ConditionPassed() then 11976 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11977 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11978 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11979 replicated_element = Replicate(MemU[address,ebytes], elements); 11980 for r = 0 to regs-1 11981 D[d+r] = replicated_element; 11982 #endif 11983 11984 bool success = false; 11985 11986 if (ConditionPassed (opcode)) 11987 { 11988 uint32_t ebytes; 11989 uint32_t elements; 11990 uint32_t regs; 11991 uint32_t alignment; 11992 uint32_t d; 11993 uint32_t n; 11994 uint32_t m; 11995 bool wback; 11996 bool register_index; 11997 11998 switch (encoding) 11999 { 12000 case eEncodingT1: 12001 case eEncodingA1: 12002 { 12003 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED; 12004 uint32_t size = Bits32 (opcode, 7, 6); 12005 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 12006 return false; 12007 12008 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2; 12009 ebytes = 1 << size; 12010 elements = 8 / ebytes; 12011 if (BitIsClear (opcode, 5)) 12012 regs = 1; 12013 else 12014 regs = 2; 12015 12016 //alignment = if a == �0� then 1 else ebytes; 12017 if (BitIsClear (opcode, 4)) 12018 alignment = 1; 12019 else 12020 alignment = ebytes; 12021 12022 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12023 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12024 n = Bits32 (opcode, 19, 16); 12025 m = Bits32 (opcode, 3, 0); 12026 12027 //wback = (m != 15); register_index = (m != 15 && m != 13); 12028 wback = (m != 15); 12029 register_index = ((m != 15) && (m != 13)); 12030 12031 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12032 if ((d + regs) > 32) 12033 return false; 12034 12035 if (n == 15) 12036 return false; 12037 } 12038 break; 12039 12040 default: 12041 return false; 12042 } 12043 12044 RegisterInfo base_reg; 12045 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12046 12047 uint32_t Rn = ReadCoreReg (n, &success); 12048 if (!success) 12049 return false; 12050 12051 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12052 addr_t address = Rn; 12053 if ((address % alignment) != 0) 12054 return false; 12055 12056 EmulateInstruction::Context context; 12057 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12058 if (wback) 12059 { 12060 uint32_t Rm = ReadCoreReg (m, &success); 12061 if (!success) 12062 return false; 12063 12064 uint32_t offset; 12065 if (register_index) 12066 offset = Rm; 12067 else 12068 offset = ebytes; 12069 12070 context.type = eContextAdjustBaseRegister; 12071 context.SetRegisterPlusOffset (base_reg, offset); 12072 12073 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12074 return false; 12075 } 12076 12077 // replicated_element = Replicate(MemU[address,ebytes], elements); 12078 12079 context.type = eContextRegisterLoad; 12080 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12081 if (!success) 12082 return false; 12083 12084 uint64_t replicated_element = 0; 12085 uint32_t esize = ebytes * 8; 12086 for (uint32_t e = 0; e < elements; ++e) 12087 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12088 12089 // for r = 0 to regs-1 12090 for (uint32_t r = 0; r < regs; ++r) 12091 { 12092 // D[d+r] = replicated_element; 12093 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12094 return false; 12095 } 12096 } 12097 return true; 12098 } 12099 12100 // B6.2.13 SUBS PC, LR and related instructions 12101 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12102 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12103 bool 12104 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12105 { 12106 #if 0 12107 if ConditionPassed() then 12108 EncodingSpecificOperations(); 12109 if CurrentInstrSet() == InstrSet_ThumbEE then 12110 UNPREDICTABLE; 12111 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12112 case opcode of 12113 when �0000� result = R[n] AND operand2; // AND 12114 when �0001� result = R[n] EOR operand2; // EOR 12115 when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12116 when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12117 when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12118 when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12119 when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12120 when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12121 when �1100� result = R[n] OR operand2; // ORR 12122 when �1101� result = operand2; // MOV 12123 when �1110� result = R[n] AND NOT(operand2); // BIC 12124 when �1111� result = NOT(operand2); // MVN 12125 CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12126 BranchWritePC(result); 12127 #endif 12128 12129 bool success = false; 12130 12131 if (ConditionPassed (opcode)) 12132 { 12133 uint32_t n; 12134 uint32_t m; 12135 uint32_t imm32; 12136 bool register_form; 12137 ARM_ShifterType shift_t; 12138 uint32_t shift_n; 12139 uint32_t code; 12140 12141 switch (encoding) 12142 { 12143 case eEncodingT1: 12144 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12145 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB 12146 n = 14; 12147 imm32 = Bits32 (opcode, 7, 0); 12148 register_form = false; 12149 code = 2; 12150 12151 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12152 if (InITBlock() && !LastInITBlock()) 12153 return false; 12154 12155 break; 12156 12157 case eEncodingA1: 12158 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12159 n = Bits32 (opcode, 19, 16); 12160 imm32 = ARMExpandImm (opcode); 12161 register_form = false; 12162 code = Bits32 (opcode, 24, 21); 12163 12164 break; 12165 12166 case eEncodingA2: 12167 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12168 n = Bits32 (opcode, 19, 16); 12169 m = Bits32 (opcode, 3, 0); 12170 register_form = true; 12171 12172 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12173 shift_n = DecodeImmShiftARM (opcode, shift_t); 12174 12175 break; 12176 12177 default: 12178 return false; 12179 } 12180 12181 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12182 uint32_t operand2; 12183 if (register_form) 12184 { 12185 uint32_t Rm = ReadCoreReg (m, &success); 12186 if (!success) 12187 return false; 12188 12189 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12190 if (!success) 12191 return false; 12192 } 12193 else 12194 { 12195 operand2 = imm32; 12196 } 12197 12198 uint32_t Rn = ReadCoreReg (n, &success); 12199 if (!success) 12200 return false; 12201 12202 AddWithCarryResult result; 12203 12204 // case opcode of 12205 switch (code) 12206 { 12207 case 0: // when �0000� 12208 // result = R[n] AND operand2; // AND 12209 result.result = Rn & operand2; 12210 break; 12211 12212 case 1: // when �0001� 12213 // result = R[n] EOR operand2; // EOR 12214 result.result = Rn ^ operand2; 12215 break; 12216 12217 case 2: // when �0010� 12218 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12219 result = AddWithCarry (Rn, ~(operand2), 1); 12220 break; 12221 12222 case 3: // when �0011� 12223 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12224 result = AddWithCarry (~(Rn), operand2, 1); 12225 break; 12226 12227 case 4: // when �0100� 12228 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12229 result = AddWithCarry (Rn, operand2, 0); 12230 break; 12231 12232 case 5: // when �0101� 12233 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12234 result = AddWithCarry (Rn, operand2, APSR_C); 12235 break; 12236 12237 case 6: // when �0110� 12238 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12239 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12240 break; 12241 12242 case 7: // when �0111� 12243 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12244 result = AddWithCarry (~(Rn), operand2, APSR_C); 12245 break; 12246 12247 case 10: // when �1100� 12248 // result = R[n] OR operand2; // ORR 12249 result.result = Rn | operand2; 12250 break; 12251 12252 case 11: // when �1101� 12253 // result = operand2; // MOV 12254 result.result = operand2; 12255 break; 12256 12257 case 12: // when �1110� 12258 // result = R[n] AND NOT(operand2); // BIC 12259 result.result = Rn & ~(operand2); 12260 break; 12261 12262 case 15: // when �1111� 12263 // result = NOT(operand2); // MVN 12264 result.result = ~(operand2); 12265 break; 12266 12267 default: 12268 return false; 12269 } 12270 // CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12271 12272 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12273 // the best. 12274 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12275 if (!success) 12276 return false; 12277 12278 CPSRWriteByInstr (spsr, 15, true); 12279 12280 // BranchWritePC(result); 12281 EmulateInstruction::Context context; 12282 context.type = eContextAdjustPC; 12283 context.SetImmediate (result.result); 12284 12285 BranchWritePC (context, result.result); 12286 } 12287 return true; 12288 } 12289 12290 EmulateInstructionARM::ARMOpcode* 12291 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12292 { 12293 static ARMOpcode 12294 g_arm_opcodes[] = 12295 { 12296 //---------------------------------------------------------------------- 12297 // Prologue instructions 12298 //---------------------------------------------------------------------- 12299 12300 // push register(s) 12301 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12302 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12303 12304 // set r7 to point to a stack offset 12305 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12306 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12307 // copy the stack pointer to ip 12308 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12309 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12310 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12311 12312 // adjust the stack pointer 12313 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12314 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12315 12316 // push one register 12317 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12318 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12319 12320 // vector push consecutive extension register(s) 12321 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12322 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12323 12324 //---------------------------------------------------------------------- 12325 // Epilogue instructions 12326 //---------------------------------------------------------------------- 12327 12328 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12329 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12330 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12331 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12332 12333 //---------------------------------------------------------------------- 12334 // Supervisor Call (previously Software Interrupt) 12335 //---------------------------------------------------------------------- 12336 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12337 12338 //---------------------------------------------------------------------- 12339 // Branch instructions 12340 //---------------------------------------------------------------------- 12341 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12342 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 12343 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12344 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12345 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12346 // for example, "bx lr" 12347 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12348 // bxj 12349 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12350 12351 //---------------------------------------------------------------------- 12352 // Data-processing instructions 12353 //---------------------------------------------------------------------- 12354 // adc (immediate) 12355 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12356 // adc (register) 12357 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12358 // add (immediate) 12359 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12360 // add (register) 12361 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12362 // add (register-shifted register) 12363 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12364 // adr 12365 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12366 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12367 // and (immediate) 12368 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12369 // and (register) 12370 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12371 // bic (immediate) 12372 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12373 // bic (register) 12374 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12375 // eor (immediate) 12376 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12377 // eor (register) 12378 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12379 // orr (immediate) 12380 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12381 // orr (register) 12382 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12383 // rsb (immediate) 12384 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12385 // rsb (register) 12386 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12387 // rsc (immediate) 12388 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12389 // rsc (register) 12390 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12391 // sbc (immediate) 12392 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12393 // sbc (register) 12394 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12395 // sub (immediate, ARM) 12396 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12397 // sub (sp minus immediate) 12398 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12399 // sub (register) 12400 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12401 // teq (immediate) 12402 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12403 // teq (register) 12404 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12405 // tst (immediate) 12406 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12407 // tst (register) 12408 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12409 12410 // mov (immediate) 12411 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12412 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12413 // mov (register) 12414 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12415 // mvn (immediate) 12416 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12417 // mvn (register) 12418 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12419 // cmn (immediate) 12420 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12421 // cmn (register) 12422 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12423 // cmp (immediate) 12424 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12425 // cmp (register) 12426 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12427 // asr (immediate) 12428 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12429 // asr (register) 12430 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12431 // lsl (immediate) 12432 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12433 // lsl (register) 12434 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12435 // lsr (immediate) 12436 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12437 // lsr (register) 12438 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12439 // rrx is a special case encoding of ror (immediate) 12440 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12441 // ror (immediate) 12442 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12443 // ror (register) 12444 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12445 // mul 12446 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12447 12448 // subs pc, lr and related instructions 12449 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12450 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12451 12452 //---------------------------------------------------------------------- 12453 // Load instructions 12454 //---------------------------------------------------------------------- 12455 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12456 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12457 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12458 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12459 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12460 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12461 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12462 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12463 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12464 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12465 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12466 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12467 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12468 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12469 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12470 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12471 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12472 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12473 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12474 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12475 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12476 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12477 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12478 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12479 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12480 12481 //---------------------------------------------------------------------- 12482 // Store instructions 12483 //---------------------------------------------------------------------- 12484 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12485 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12486 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12487 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12488 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12489 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12490 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12491 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12492 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12493 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12494 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12495 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12496 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12497 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12498 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12499 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12500 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12501 12502 //---------------------------------------------------------------------- 12503 // Other instructions 12504 //---------------------------------------------------------------------- 12505 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12506 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12507 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12508 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12509 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12510 12511 }; 12512 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 12513 12514 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12515 { 12516 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12517 (g_arm_opcodes[i].variants & arm_isa) != 0) 12518 return &g_arm_opcodes[i]; 12519 } 12520 return NULL; 12521 } 12522 12523 12524 EmulateInstructionARM::ARMOpcode* 12525 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12526 { 12527 12528 static ARMOpcode 12529 g_thumb_opcodes[] = 12530 { 12531 //---------------------------------------------------------------------- 12532 // Prologue instructions 12533 //---------------------------------------------------------------------- 12534 12535 // push register(s) 12536 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12537 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12538 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12539 12540 // set r7 to point to a stack offset 12541 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12542 // copy the stack pointer to r7 12543 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12544 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12545 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12546 12547 // PC-relative load into register (see also EmulateADDSPRm) 12548 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12549 12550 // adjust the stack pointer 12551 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12552 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12553 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12554 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12555 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12556 12557 // vector push consecutive extension register(s) 12558 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12559 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12560 12561 //---------------------------------------------------------------------- 12562 // Epilogue instructions 12563 //---------------------------------------------------------------------- 12564 12565 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12566 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12567 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12568 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12569 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12570 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12571 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12572 12573 //---------------------------------------------------------------------- 12574 // Supervisor Call (previously Software Interrupt) 12575 //---------------------------------------------------------------------- 12576 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12577 12578 //---------------------------------------------------------------------- 12579 // If Then makes up to four following instructions conditional. 12580 //---------------------------------------------------------------------- 12581 // The next 5 opcode _must_ come before the if then instruction 12582 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12583 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12584 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12585 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12586 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12587 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12588 12589 //---------------------------------------------------------------------- 12590 // Branch instructions 12591 //---------------------------------------------------------------------- 12592 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12593 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12594 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12595 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12596 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12597 // J1 == J2 == 1 12598 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12599 // J1 == J2 == 1 12600 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12601 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12602 // for example, "bx lr" 12603 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12604 // bxj 12605 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12606 // compare and branch 12607 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12608 // table branch byte 12609 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12610 // table branch halfword 12611 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12612 12613 //---------------------------------------------------------------------- 12614 // Data-processing instructions 12615 //---------------------------------------------------------------------- 12616 // adc (immediate) 12617 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12618 // adc (register) 12619 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12620 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12621 // add (register) 12622 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12623 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12624 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12625 // adr 12626 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12627 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12628 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12629 // and (immediate) 12630 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12631 // and (register) 12632 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12633 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12634 // bic (immediate) 12635 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12636 // bic (register) 12637 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12638 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12639 // eor (immediate) 12640 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12641 // eor (register) 12642 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12643 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12644 // orr (immediate) 12645 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12646 // orr (register) 12647 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12648 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12649 // rsb (immediate) 12650 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12651 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12652 // rsb (register) 12653 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12654 // sbc (immediate) 12655 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12656 // sbc (register) 12657 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12658 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12659 // add (immediate, Thumb) 12660 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12661 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12662 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12663 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12664 // sub (immediate, Thumb) 12665 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12666 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12667 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12668 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12669 // sub (sp minus immediate) 12670 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12671 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12672 // sub (register) 12673 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12674 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12675 // teq (immediate) 12676 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12677 // teq (register) 12678 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12679 // tst (immediate) 12680 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12681 // tst (register) 12682 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12683 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12684 12685 12686 // move from high register to high register 12687 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12688 // move from low register to low register 12689 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12690 // mov{s}<c>.w <Rd>, <Rm> 12691 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12692 // move immediate 12693 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12694 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12695 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12696 // mvn (immediate) 12697 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12698 // mvn (register) 12699 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12700 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12701 // cmn (immediate) 12702 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12703 // cmn (register) 12704 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12705 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12706 // cmp (immediate) 12707 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12708 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12709 // cmp (register) (Rn and Rm both from r0-r7) 12710 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12711 // cmp (register) (Rn and Rm not both from r0-r7) 12712 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12713 // asr (immediate) 12714 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12715 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12716 // asr (register) 12717 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12718 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12719 // lsl (immediate) 12720 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12721 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12722 // lsl (register) 12723 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12724 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12725 // lsr (immediate) 12726 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12727 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12728 // lsr (register) 12729 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12730 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12731 // rrx is a special case encoding of ror (immediate) 12732 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12733 // ror (immediate) 12734 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12735 // ror (register) 12736 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12737 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12738 // mul 12739 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12740 // mul 12741 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12742 12743 // subs pc, lr and related instructions 12744 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12745 12746 //---------------------------------------------------------------------- 12747 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12748 // otherwise the wrong instructions will be selected. 12749 //---------------------------------------------------------------------- 12750 12751 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12752 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12753 12754 //---------------------------------------------------------------------- 12755 // Load instructions 12756 //---------------------------------------------------------------------- 12757 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12758 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12759 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12760 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12761 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12762 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12763 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12764 // Thumb2 PC-relative load into register 12765 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12766 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12767 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12768 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12769 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12770 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12771 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12772 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12773 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12774 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12775 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12776 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12777 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12778 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12779 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12780 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12781 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12782 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12783 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12784 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12785 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12786 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12787 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12788 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12789 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12790 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12791 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12792 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12793 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12794 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12795 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12796 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12797 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12798 12799 //---------------------------------------------------------------------- 12800 // Store instructions 12801 //---------------------------------------------------------------------- 12802 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12803 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12804 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12805 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12806 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12807 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12808 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12809 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12810 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12811 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12812 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12813 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12814 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12815 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12816 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12817 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12818 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12819 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12820 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12821 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12822 { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12823 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12824 12825 //---------------------------------------------------------------------- 12826 // Other instructions 12827 //---------------------------------------------------------------------- 12828 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12829 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12830 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12831 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12832 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12833 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12834 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12835 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12836 }; 12837 12838 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 12839 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12840 { 12841 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12842 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12843 return &g_thumb_opcodes[i]; 12844 } 12845 return NULL; 12846 } 12847 12848 bool 12849 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12850 { 12851 m_arch = arch; 12852 m_arm_isa = 0; 12853 const char *arch_cstr = arch.GetArchitectureName (); 12854 if (arch_cstr) 12855 { 12856 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12857 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12858 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12859 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12860 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12861 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12862 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12863 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12864 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12865 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12866 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12867 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12868 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12869 } 12870 return m_arm_isa != 0; 12871 } 12872 12873 bool 12874 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12875 { 12876 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12877 { 12878 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12879 m_opcode_mode = eModeThumb; 12880 else 12881 { 12882 AddressClass addr_class = inst_addr.GetAddressClass(); 12883 12884 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 12885 m_opcode_mode = eModeARM; 12886 else if (addr_class == eAddressClassCodeAlternateISA) 12887 m_opcode_mode = eModeThumb; 12888 else 12889 return false; 12890 } 12891 if (m_opcode_mode == eModeThumb) 12892 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 12893 else 12894 m_opcode_cpsr = CPSR_MODE_USR; 12895 return true; 12896 } 12897 return false; 12898 } 12899 12900 bool 12901 EmulateInstructionARM::ReadInstruction () 12902 { 12903 bool success = false; 12904 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 12905 if (success) 12906 { 12907 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 12908 if (success) 12909 { 12910 Context read_inst_context; 12911 read_inst_context.type = eContextReadOpcode; 12912 read_inst_context.SetNoArgs (); 12913 12914 if (m_opcode_cpsr & MASK_CPSR_T) 12915 { 12916 m_opcode_mode = eModeThumb; 12917 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 12918 12919 if (success) 12920 { 12921 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 12922 { 12923 m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder()); 12924 } 12925 else 12926 { 12927 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder()); 12928 } 12929 } 12930 } 12931 else 12932 { 12933 m_opcode_mode = eModeARM; 12934 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder()); 12935 } 12936 } 12937 } 12938 if (!success) 12939 { 12940 m_opcode_mode = eModeInvalid; 12941 m_addr = LLDB_INVALID_ADDRESS; 12942 } 12943 return success; 12944 } 12945 12946 uint32_t 12947 EmulateInstructionARM::ArchVersion () 12948 { 12949 return m_arm_isa; 12950 } 12951 12952 bool 12953 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) 12954 { 12955 // If we are ignoring conditions, then always return true. 12956 // this allows us to iterate over disassembly code and still 12957 // emulate an instruction even if we don't have all the right 12958 // bits set in the CPSR register... 12959 if (m_ignore_conditions) 12960 return true; 12961 12962 if (is_conditional) 12963 *is_conditional = true; 12964 12965 const uint32_t cond = CurrentCond (opcode); 12966 12967 if (cond == UINT32_MAX) 12968 return false; 12969 12970 bool result = false; 12971 switch (UnsignedBits(cond, 3, 1)) 12972 { 12973 case 0: 12974 if (m_opcode_cpsr == 0) 12975 result = true; 12976 else 12977 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 12978 break; 12979 case 1: 12980 if (m_opcode_cpsr == 0) 12981 result = true; 12982 else 12983 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 12984 break; 12985 case 2: 12986 if (m_opcode_cpsr == 0) 12987 result = true; 12988 else 12989 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 12990 break; 12991 case 3: 12992 if (m_opcode_cpsr == 0) 12993 result = true; 12994 else 12995 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 12996 break; 12997 case 4: 12998 if (m_opcode_cpsr == 0) 12999 result = true; 13000 else 13001 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13002 break; 13003 case 5: 13004 if (m_opcode_cpsr == 0) 13005 result = true; 13006 else 13007 { 13008 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13009 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13010 result = n == v; 13011 } 13012 break; 13013 case 6: 13014 if (m_opcode_cpsr == 0) 13015 result = true; 13016 else 13017 { 13018 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13019 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13020 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13021 } 13022 break; 13023 case 7: 13024 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13025 // opcodes different meanings, but always means execution happens. 13026 if (is_conditional) 13027 *is_conditional = false; 13028 result = true; 13029 break; 13030 } 13031 13032 if (cond & 1) 13033 result = !result; 13034 return result; 13035 } 13036 13037 uint32_t 13038 EmulateInstructionARM::CurrentCond (const uint32_t opcode) 13039 { 13040 switch (m_opcode_mode) 13041 { 13042 case eModeInvalid: 13043 break; 13044 13045 case eModeARM: 13046 return UnsignedBits(opcode, 31, 28); 13047 13048 case eModeThumb: 13049 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13050 // 'cond' field of the encoding. 13051 { 13052 const uint32_t byte_size = m_opcode.GetByteSize(); 13053 if (byte_size == 2) 13054 { 13055 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 13056 return Bits32(opcode, 11, 7); 13057 } 13058 else if (byte_size == 4) 13059 { 13060 if (Bits32(opcode, 31, 27) == 0x1e && 13061 Bits32(opcode, 15, 14) == 0x02 && 13062 Bits32(opcode, 12, 12) == 0x00 && 13063 Bits32(opcode, 25, 22) <= 0x0d) 13064 { 13065 return Bits32(opcode, 25, 22); 13066 } 13067 } 13068 else 13069 // We have an invalid thumb instruction, let's bail out. 13070 break; 13071 13072 return m_it_session.GetCond(); 13073 } 13074 } 13075 return UINT32_MAX; // Return invalid value 13076 } 13077 13078 bool 13079 EmulateInstructionARM::InITBlock() 13080 { 13081 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13082 } 13083 13084 bool 13085 EmulateInstructionARM::LastInITBlock() 13086 { 13087 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13088 } 13089 13090 bool 13091 EmulateInstructionARM::BadMode (uint32_t mode) 13092 { 13093 13094 switch (mode) 13095 { 13096 case 16: return false; // '10000' 13097 case 17: return false; // '10001' 13098 case 18: return false; // '10010' 13099 case 19: return false; // '10011' 13100 case 22: return false; // '10110' 13101 case 23: return false; // '10111' 13102 case 27: return false; // '11011' 13103 case 31: return false; // '11111' 13104 default: return true; 13105 } 13106 return true; 13107 } 13108 13109 bool 13110 EmulateInstructionARM::CurrentModeIsPrivileged () 13111 { 13112 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13113 13114 if (BadMode (mode)) 13115 return false; 13116 13117 if (mode == 16) 13118 return false; 13119 13120 return true; 13121 } 13122 13123 void 13124 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13125 { 13126 bool privileged = CurrentModeIsPrivileged(); 13127 13128 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13129 13130 if (BitIsSet (bytemask, 3)) 13131 { 13132 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13133 if (affect_execstate) 13134 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13135 } 13136 13137 if (BitIsSet (bytemask, 2)) 13138 { 13139 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13140 } 13141 13142 if (BitIsSet (bytemask, 1)) 13143 { 13144 if (affect_execstate) 13145 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13146 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13147 if (privileged) 13148 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13149 } 13150 13151 if (BitIsSet (bytemask, 0)) 13152 { 13153 if (privileged) 13154 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13155 if (affect_execstate) 13156 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13157 if (privileged) 13158 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13159 } 13160 13161 m_opcode_cpsr = tmp_cpsr; 13162 } 13163 13164 13165 bool 13166 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13167 { 13168 addr_t target; 13169 13170 // Check the current instruction set. 13171 if (CurrentInstrSet() == eModeARM) 13172 target = addr & 0xfffffffc; 13173 else 13174 target = addr & 0xfffffffe; 13175 13176 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13177 return false; 13178 13179 return true; 13180 } 13181 13182 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13183 bool 13184 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13185 { 13186 addr_t target; 13187 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13188 // we want to record it and issue a WriteRegister callback so the clients 13189 // can track the mode changes accordingly. 13190 bool cpsr_changed = false; 13191 13192 if (BitIsSet(addr, 0)) 13193 { 13194 if (CurrentInstrSet() != eModeThumb) 13195 { 13196 SelectInstrSet(eModeThumb); 13197 cpsr_changed = true; 13198 } 13199 target = addr & 0xfffffffe; 13200 context.SetISA (eModeThumb); 13201 } 13202 else if (BitIsClear(addr, 1)) 13203 { 13204 if (CurrentInstrSet() != eModeARM) 13205 { 13206 SelectInstrSet(eModeARM); 13207 cpsr_changed = true; 13208 } 13209 target = addr & 0xfffffffc; 13210 context.SetISA (eModeARM); 13211 } 13212 else 13213 return false; // address<1:0> == '10' => UNPREDICTABLE 13214 13215 if (cpsr_changed) 13216 { 13217 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13218 return false; 13219 } 13220 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13221 return false; 13222 13223 return true; 13224 } 13225 13226 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13227 bool 13228 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13229 { 13230 if (ArchVersion() >= ARMv5T) 13231 return BXWritePC(context, addr); 13232 else 13233 return BranchWritePC((const Context)context, addr); 13234 } 13235 13236 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13237 bool 13238 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13239 { 13240 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13241 return BXWritePC(context, addr); 13242 else 13243 return BranchWritePC((const Context)context, addr); 13244 } 13245 13246 EmulateInstructionARM::Mode 13247 EmulateInstructionARM::CurrentInstrSet () 13248 { 13249 return m_opcode_mode; 13250 } 13251 13252 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13253 // ReadInstruction() is performed. This function has a side effect of updating 13254 // the m_new_inst_cpsr member variable if necessary. 13255 bool 13256 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13257 { 13258 m_new_inst_cpsr = m_opcode_cpsr; 13259 switch (arm_or_thumb) 13260 { 13261 default: 13262 return false; 13263 case eModeARM: 13264 // Clear the T bit. 13265 m_new_inst_cpsr &= ~MASK_CPSR_T; 13266 break; 13267 case eModeThumb: 13268 // Set the T bit. 13269 m_new_inst_cpsr |= MASK_CPSR_T; 13270 break; 13271 } 13272 return true; 13273 } 13274 13275 // This function returns TRUE if the processor currently provides support for 13276 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13277 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13278 bool 13279 EmulateInstructionARM::UnalignedSupport() 13280 { 13281 return (ArchVersion() >= ARMv7); 13282 } 13283 13284 // The main addition and subtraction instructions can produce status information 13285 // about both unsigned carry and signed overflow conditions. This status 13286 // information can be used to synthesize multi-word additions and subtractions. 13287 EmulateInstructionARM::AddWithCarryResult 13288 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13289 { 13290 uint32_t result; 13291 uint8_t carry_out; 13292 uint8_t overflow; 13293 13294 uint64_t unsigned_sum = x + y + carry_in; 13295 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13296 13297 result = UnsignedBits(unsigned_sum, 31, 0); 13298 // carry_out = (result == unsigned_sum ? 0 : 1); 13299 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13300 13301 if (carry_in) 13302 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13303 else 13304 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13305 13306 AddWithCarryResult res = { result, carry_out, overflow }; 13307 return res; 13308 } 13309 13310 uint32_t 13311 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13312 { 13313 lldb::RegisterKind reg_kind; 13314 uint32_t reg_num; 13315 switch (num) 13316 { 13317 case SP_REG: 13318 reg_kind = eRegisterKindGeneric; 13319 reg_num = LLDB_REGNUM_GENERIC_SP; 13320 break; 13321 case LR_REG: 13322 reg_kind = eRegisterKindGeneric; 13323 reg_num = LLDB_REGNUM_GENERIC_RA; 13324 break; 13325 case PC_REG: 13326 reg_kind = eRegisterKindGeneric; 13327 reg_num = LLDB_REGNUM_GENERIC_PC; 13328 break; 13329 default: 13330 if (num < SP_REG) 13331 { 13332 reg_kind = eRegisterKindDWARF; 13333 reg_num = dwarf_r0 + num; 13334 } 13335 else 13336 { 13337 //assert(0 && "Invalid register number"); 13338 *success = false; 13339 return UINT32_MAX; 13340 } 13341 break; 13342 } 13343 13344 // Read our register. 13345 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13346 13347 // When executing an ARM instruction , PC reads as the address of the current 13348 // instruction plus 8. 13349 // When executing a Thumb instruction , PC reads as the address of the current 13350 // instruction plus 4. 13351 if (num == 15) 13352 { 13353 if (CurrentInstrSet() == eModeARM) 13354 val += 8; 13355 else 13356 val += 4; 13357 } 13358 13359 return val; 13360 } 13361 13362 // Write the result to the ARM core register Rd, and optionally update the 13363 // condition flags based on the result. 13364 // 13365 // This helper method tries to encapsulate the following pseudocode from the 13366 // ARM Architecture Reference Manual: 13367 // 13368 // if d == 15 then // Can only occur for encoding A1 13369 // ALUWritePC(result); // setflags is always FALSE here 13370 // else 13371 // R[d] = result; 13372 // if setflags then 13373 // APSR.N = result<31>; 13374 // APSR.Z = IsZeroBit(result); 13375 // APSR.C = carry; 13376 // // APSR.V unchanged 13377 // 13378 // In the above case, the API client does not pass in the overflow arg, which 13379 // defaults to ~0u. 13380 bool 13381 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13382 const uint32_t result, 13383 const uint32_t Rd, 13384 bool setflags, 13385 const uint32_t carry, 13386 const uint32_t overflow) 13387 { 13388 if (Rd == 15) 13389 { 13390 if (!ALUWritePC (context, result)) 13391 return false; 13392 } 13393 else 13394 { 13395 lldb::RegisterKind reg_kind; 13396 uint32_t reg_num; 13397 switch (Rd) 13398 { 13399 case SP_REG: 13400 reg_kind = eRegisterKindGeneric; 13401 reg_num = LLDB_REGNUM_GENERIC_SP; 13402 break; 13403 case LR_REG: 13404 reg_kind = eRegisterKindGeneric; 13405 reg_num = LLDB_REGNUM_GENERIC_RA; 13406 break; 13407 default: 13408 reg_kind = eRegisterKindDWARF; 13409 reg_num = dwarf_r0 + Rd; 13410 } 13411 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13412 return false; 13413 if (setflags) 13414 return WriteFlags (context, result, carry, overflow); 13415 } 13416 return true; 13417 } 13418 13419 // This helper method tries to encapsulate the following pseudocode from the 13420 // ARM Architecture Reference Manual: 13421 // 13422 // APSR.N = result<31>; 13423 // APSR.Z = IsZeroBit(result); 13424 // APSR.C = carry; 13425 // APSR.V = overflow 13426 // 13427 // Default arguments can be specified for carry and overflow parameters, which means 13428 // not to update the respective flags. 13429 bool 13430 EmulateInstructionARM::WriteFlags (Context &context, 13431 const uint32_t result, 13432 const uint32_t carry, 13433 const uint32_t overflow) 13434 { 13435 m_new_inst_cpsr = m_opcode_cpsr; 13436 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13437 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13438 if (carry != ~0u) 13439 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13440 if (overflow != ~0u) 13441 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13442 if (m_new_inst_cpsr != m_opcode_cpsr) 13443 { 13444 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13445 return false; 13446 } 13447 return true; 13448 } 13449 13450 bool 13451 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13452 { 13453 // Advance the ITSTATE bits to their values for the next instruction. 13454 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13455 m_it_session.ITAdvance(); 13456 13457 ARMOpcode *opcode_data = NULL; 13458 13459 if (m_opcode_mode == eModeThumb) 13460 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13461 else if (m_opcode_mode == eModeARM) 13462 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13463 13464 if (opcode_data == NULL) 13465 return false; 13466 13467 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13468 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13469 13470 bool success = false; 13471 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13472 { 13473 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13474 dwarf_cpsr, 13475 0, 13476 &success); 13477 } 13478 13479 // Only return false if we are unable to read the CPSR if we care about conditions 13480 if (success == false && m_ignore_conditions == false) 13481 return false; 13482 13483 uint32_t orig_pc_value = 0; 13484 if (auto_advance_pc) 13485 { 13486 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13487 if (!success) 13488 return false; 13489 } 13490 13491 // Call the Emulate... function. 13492 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13493 if (!success) 13494 return false; 13495 13496 if (auto_advance_pc) 13497 { 13498 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13499 if (!success) 13500 return false; 13501 13502 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13503 { 13504 if (opcode_data->size == eSize32) 13505 after_pc_value += 4; 13506 else if (opcode_data->size == eSize16) 13507 after_pc_value += 2; 13508 13509 EmulateInstruction::Context context; 13510 context.type = eContextAdvancePC; 13511 context.SetNoArgs(); 13512 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13513 return false; 13514 13515 } 13516 } 13517 return true; 13518 } 13519 13520 bool 13521 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13522 { 13523 if (!test_data) 13524 { 13525 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13526 return false; 13527 } 13528 13529 static ConstString opcode_key ("opcode"); 13530 static ConstString before_key ("before_state"); 13531 static ConstString after_key ("after_state"); 13532 13533 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13534 13535 uint32_t test_opcode; 13536 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13537 { 13538 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13539 return false; 13540 } 13541 test_opcode = value_sp->GetUInt64Value (); 13542 13543 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13544 { 13545 m_opcode_mode = eModeARM; 13546 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13547 } 13548 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13549 { 13550 m_opcode_mode = eModeThumb; 13551 if (test_opcode < 0x10000) 13552 m_opcode.SetOpcode16 (test_opcode, GetByteOrder()); 13553 else 13554 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13555 13556 } 13557 else 13558 { 13559 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13560 return false; 13561 } 13562 13563 EmulationStateARM before_state; 13564 EmulationStateARM after_state; 13565 13566 value_sp = test_data->GetValueForKey (before_key); 13567 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13568 { 13569 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13570 return false; 13571 } 13572 13573 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13574 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13575 { 13576 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13577 return false; 13578 } 13579 13580 value_sp = test_data->GetValueForKey (after_key); 13581 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13582 { 13583 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13584 return false; 13585 } 13586 13587 state_dictionary = value_sp->GetAsDictionary (); 13588 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13589 { 13590 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13591 return false; 13592 } 13593 13594 SetBaton ((void *) &before_state); 13595 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13596 &EmulationStateARM::WritePseudoMemory, 13597 &EmulationStateARM::ReadPseudoRegister, 13598 &EmulationStateARM::WritePseudoRegister); 13599 13600 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13601 if (!success) 13602 { 13603 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13604 return false; 13605 } 13606 13607 success = before_state.CompareState (after_state); 13608 if (!success) 13609 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13610 13611 return success; 13612 } 13613 // 13614 // 13615 //const char * 13616 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13617 //{ 13618 // if (reg_kind == eRegisterKindGeneric) 13619 // { 13620 // switch (reg_num) 13621 // { 13622 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 13623 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 13624 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 13625 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 13626 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13627 // default: return NULL; 13628 // } 13629 // } 13630 // else if (reg_kind == eRegisterKindDWARF) 13631 // { 13632 // return GetARMDWARFRegisterName (reg_num); 13633 // } 13634 // return NULL; 13635 //} 13636 // 13637 bool 13638 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13639 { 13640 unwind_plan.Clear(); 13641 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13642 13643 UnwindPlan::RowSP row(new UnwindPlan::Row); 13644 13645 // Our previous Call Frame Address is the stack pointer 13646 row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0); 13647 13648 // Our previous PC is in the LR 13649 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true); 13650 unwind_plan.AppendRow (row); 13651 13652 // All other registers are the same. 13653 13654 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13655 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 13656 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 13657 return true; 13658 } 13659