1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include <stdlib.h> 11 12 #include "EmulateInstructionARM.h" 13 #include "EmulationStateARM.h" 14 #include "lldb/Core/ArchSpec.h" 15 #include "lldb/Core/Address.h" 16 #include "lldb/Core/ConstString.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Core/Stream.h" 19 #include "lldb/Interpreter/OptionValueArray.h" 20 #include "lldb/Interpreter/OptionValueDictionary.h" 21 #include "lldb/Symbol/UnwindPlan.h" 22 23 #include "Plugins/Process/Utility/ARMDefines.h" 24 #include "Plugins/Process/Utility/ARMUtils.h" 25 #include "Utility/ARM_DWARF_Registers.h" 26 27 #include "llvm/ADT/STLExtras.h" 28 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function 29 // and countTrailingZeros function 30 31 using namespace lldb; 32 using namespace lldb_private; 33 34 // Convenient macro definitions. 35 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 36 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 37 38 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 39 40 //---------------------------------------------------------------------- 41 // 42 // ITSession implementation 43 // 44 //---------------------------------------------------------------------- 45 46 // A8.6.50 47 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 48 static uint32_t 49 CountITSize (uint32_t ITMask) { 50 // First count the trailing zeros of the IT mask. 51 uint32_t TZ = llvm::countTrailingZeros(ITMask); 52 if (TZ > 3) 53 { 54 #ifdef LLDB_CONFIGURATION_DEBUG 55 printf("Encoding error: IT Mask '0000'\n"); 56 #endif 57 return 0; 58 } 59 return (4 - TZ); 60 } 61 62 // Init ITState. Note that at least one bit is always 1 in mask. 63 bool ITSession::InitIT(uint32_t bits7_0) 64 { 65 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 66 if (ITCounter == 0) 67 return false; 68 69 // A8.6.50 IT 70 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 71 if (FirstCond == 0xF) 72 { 73 #ifdef LLDB_CONFIGURATION_DEBUG 74 printf("Encoding error: IT FirstCond '1111'\n"); 75 #endif 76 return false; 77 } 78 if (FirstCond == 0xE && ITCounter != 1) 79 { 80 #ifdef LLDB_CONFIGURATION_DEBUG 81 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 82 #endif 83 return false; 84 } 85 86 ITState = bits7_0; 87 return true; 88 } 89 90 // Update ITState if necessary. 91 void ITSession::ITAdvance() 92 { 93 //assert(ITCounter); 94 --ITCounter; 95 if (ITCounter == 0) 96 ITState = 0; 97 else 98 { 99 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 100 SetBits32(ITState, 4, 0, NewITState4_0); 101 } 102 } 103 104 // Return true if we're inside an IT Block. 105 bool ITSession::InITBlock() 106 { 107 return ITCounter != 0; 108 } 109 110 // Return true if we're the last instruction inside an IT Block. 111 bool ITSession::LastInITBlock() 112 { 113 return ITCounter == 1; 114 } 115 116 // Get condition bits for the current thumb instruction. 117 uint32_t ITSession::GetCond() 118 { 119 if (InITBlock()) 120 return Bits32(ITState, 7, 4); 121 else 122 return COND_AL; 123 } 124 125 // ARM constants used during decoding 126 #define REG_RD 0 127 #define LDM_REGLIST 1 128 #define SP_REG 13 129 #define LR_REG 14 130 #define PC_REG 15 131 #define PC_REGLIST_BIT 0x8000 132 133 #define ARMv4 (1u << 0) 134 #define ARMv4T (1u << 1) 135 #define ARMv5T (1u << 2) 136 #define ARMv5TE (1u << 3) 137 #define ARMv5TEJ (1u << 4) 138 #define ARMv6 (1u << 5) 139 #define ARMv6K (1u << 6) 140 #define ARMv6T2 (1u << 7) 141 #define ARMv7 (1u << 8) 142 #define ARMv7S (1u << 9) 143 #define ARMv8 (1u << 10) 144 #define ARMvAll (0xffffffffu) 145 146 #define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 147 #define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 148 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 149 #define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 150 #define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 151 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8) 152 #define ARMV7_ABOVE (ARMv7|ARMv7S|ARMv8) 153 154 #define No_VFP 0 155 #define VFPv1 (1u << 1) 156 #define VFPv2 (1u << 2) 157 #define VFPv3 (1u << 3) 158 #define AdvancedSIMD (1u << 4) 159 160 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 161 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 162 #define VFPv2v3 (VFPv2 | VFPv3) 163 164 //---------------------------------------------------------------------- 165 // 166 // EmulateInstructionARM implementation 167 // 168 //---------------------------------------------------------------------- 169 170 void 171 EmulateInstructionARM::Initialize () 172 { 173 PluginManager::RegisterPlugin (GetPluginNameStatic (), 174 GetPluginDescriptionStatic (), 175 CreateInstance); 176 } 177 178 void 179 EmulateInstructionARM::Terminate () 180 { 181 PluginManager::UnregisterPlugin (CreateInstance); 182 } 183 184 ConstString 185 EmulateInstructionARM::GetPluginNameStatic () 186 { 187 static ConstString g_name("arm"); 188 return g_name; 189 } 190 191 const char * 192 EmulateInstructionARM::GetPluginDescriptionStatic () 193 { 194 return "Emulate instructions for the ARM architecture."; 195 } 196 197 EmulateInstruction * 198 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) 199 { 200 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(inst_type)) 201 { 202 if (arch.GetTriple().getArch() == llvm::Triple::arm) 203 { 204 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 205 206 if (emulate_insn_ap.get()) 207 return emulate_insn_ap.release(); 208 } 209 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 210 { 211 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 212 213 if (emulate_insn_ap.get()) 214 return emulate_insn_ap.release(); 215 } 216 } 217 218 return NULL; 219 } 220 221 bool 222 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch) 223 { 224 if (arch.GetTriple().getArch () == llvm::Triple::arm) 225 return true; 226 else if (arch.GetTriple().getArch () == llvm::Triple::thumb) 227 return true; 228 229 return false; 230 } 231 232 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 233 bool 234 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 235 { 236 EmulateInstruction::Context context; 237 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 238 context.SetNoArgs (); 239 240 uint32_t random_data = rand (); 241 const uint32_t addr_byte_size = GetAddressByteSize(); 242 243 if (!MemAWrite (context, address, random_data, addr_byte_size)) 244 return false; 245 246 return true; 247 } 248 249 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 250 bool 251 EmulateInstructionARM::WriteBits32Unknown (int n) 252 { 253 EmulateInstruction::Context context; 254 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 255 context.SetNoArgs (); 256 257 bool success; 258 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 259 260 if (!success) 261 return false; 262 263 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 264 return false; 265 266 return true; 267 } 268 269 bool 270 EmulateInstructionARM::GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo ®_info) 271 { 272 if (reg_kind == eRegisterKindGeneric) 273 { 274 switch (reg_num) 275 { 276 case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break; 277 case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break; 278 case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break; 279 case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break; 280 case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break; 281 default: return false; 282 } 283 } 284 285 if (reg_kind == eRegisterKindDWARF) 286 return GetARMDWARFRegisterInfo(reg_num, reg_info); 287 return false; 288 } 289 290 uint32_t 291 EmulateInstructionARM::GetFramePointerRegisterNumber () const 292 { 293 if (m_arch.GetTriple().getEnvironment() == llvm::Triple::Android) 294 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 295 296 bool is_apple = false; 297 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 298 is_apple = true; 299 switch (m_arch.GetTriple().getOS()) 300 { 301 case llvm::Triple::Darwin: 302 case llvm::Triple::MacOSX: 303 case llvm::Triple::IOS: 304 is_apple = true; 305 break; 306 default: 307 break; 308 } 309 310 /* On Apple iOS et al, the frame pointer register is always r7. 311 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 312 */ 313 314 uint32_t fp_regnum = 11; 315 316 if (is_apple) 317 fp_regnum = 7; 318 319 if (m_opcode_mode == eModeThumb) 320 fp_regnum = 7; 321 322 return fp_regnum; 323 } 324 325 uint32_t 326 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 327 { 328 bool is_apple = false; 329 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 330 is_apple = true; 331 switch (m_arch.GetTriple().getOS()) 332 { 333 case llvm::Triple::Darwin: 334 case llvm::Triple::MacOSX: 335 case llvm::Triple::IOS: 336 is_apple = true; 337 break; 338 default: 339 break; 340 } 341 342 /* On Apple iOS et al, the frame pointer register is always r7. 343 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 344 */ 345 346 uint32_t fp_regnum = dwarf_r11; 347 348 if (is_apple) 349 fp_regnum = dwarf_r7; 350 351 if (m_opcode_mode == eModeThumb) 352 fp_regnum = dwarf_r7; 353 354 return fp_regnum; 355 } 356 357 // Push Multiple Registers stores multiple registers to the stack, storing to 358 // consecutive memory locations ending just below the address in SP, and updates 359 // SP to point to the start of the stored data. 360 bool 361 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 362 { 363 #if 0 364 // ARM pseudo code... 365 if (ConditionPassed()) 366 { 367 EncodingSpecificOperations(); 368 NullCheckIfThumbEE(13); 369 address = SP - 4*BitCount(registers); 370 371 for (i = 0 to 14) 372 { 373 if (registers<i> == '1') 374 { 375 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 376 MemA[address,4] = bits(32) UNKNOWN; 377 else 378 MemA[address,4] = R[i]; 379 address = address + 4; 380 } 381 } 382 383 if (registers<15> == '1') // Only possible for encoding A1 or A2 384 MemA[address,4] = PCStoreValue(); 385 386 SP = SP - 4*BitCount(registers); 387 } 388 #endif 389 390 bool conditional = false; 391 bool success = false; 392 if (ConditionPassed(opcode, &conditional)) 393 { 394 const uint32_t addr_byte_size = GetAddressByteSize(); 395 const addr_t sp = ReadCoreReg (SP_REG, &success); 396 if (!success) 397 return false; 398 uint32_t registers = 0; 399 uint32_t Rt; // the source register 400 switch (encoding) { 401 case eEncodingT1: 402 registers = Bits32(opcode, 7, 0); 403 // The M bit represents LR. 404 if (Bit32(opcode, 8)) 405 registers |= (1u << 14); 406 // if BitCount(registers) < 1 then UNPREDICTABLE; 407 if (BitCount(registers) < 1) 408 return false; 409 break; 410 case eEncodingT2: 411 // Ignore bits 15 & 13. 412 registers = Bits32(opcode, 15, 0) & ~0xa000; 413 // if BitCount(registers) < 2 then UNPREDICTABLE; 414 if (BitCount(registers) < 2) 415 return false; 416 break; 417 case eEncodingT3: 418 Rt = Bits32(opcode, 15, 12); 419 // if BadReg(t) then UNPREDICTABLE; 420 if (BadReg(Rt)) 421 return false; 422 registers = (1u << Rt); 423 break; 424 case eEncodingA1: 425 registers = Bits32(opcode, 15, 0); 426 // Instead of return false, let's handle the following case as well, 427 // which amounts to pushing one reg onto the full descending stacks. 428 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 429 break; 430 case eEncodingA2: 431 Rt = Bits32(opcode, 15, 12); 432 // if t == 13 then UNPREDICTABLE; 433 if (Rt == dwarf_sp) 434 return false; 435 registers = (1u << Rt); 436 break; 437 default: 438 return false; 439 } 440 addr_t sp_offset = addr_byte_size * BitCount (registers); 441 addr_t addr = sp - sp_offset; 442 uint32_t i; 443 444 EmulateInstruction::Context context; 445 if (conditional) 446 context.type = EmulateInstruction::eContextRegisterStore; 447 else 448 context.type = EmulateInstruction::eContextPushRegisterOnStack; 449 RegisterInfo reg_info; 450 RegisterInfo sp_reg; 451 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 452 for (i=0; i<15; ++i) 453 { 454 if (BitIsSet (registers, i)) 455 { 456 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 457 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 458 uint32_t reg_value = ReadCoreReg(i, &success); 459 if (!success) 460 return false; 461 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 462 return false; 463 addr += addr_byte_size; 464 } 465 } 466 467 if (BitIsSet (registers, 15)) 468 { 469 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 470 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 471 const uint32_t pc = ReadCoreReg(PC_REG, &success); 472 if (!success) 473 return false; 474 if (!MemAWrite (context, addr, pc, addr_byte_size)) 475 return false; 476 } 477 478 context.type = EmulateInstruction::eContextAdjustStackPointer; 479 context.SetImmediateSigned (-sp_offset); 480 481 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 482 return false; 483 } 484 return true; 485 } 486 487 // Pop Multiple Registers loads multiple registers from the stack, loading from 488 // consecutive memory locations staring at the address in SP, and updates 489 // SP to point just above the loaded data. 490 bool 491 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 492 { 493 #if 0 494 // ARM pseudo code... 495 if (ConditionPassed()) 496 { 497 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 498 address = SP; 499 for i = 0 to 14 500 if registers<i> == '1' then 501 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 502 if registers<15> == '1' then 503 if UnalignedAllowed then 504 LoadWritePC(MemU[address,4]); 505 else 506 LoadWritePC(MemA[address,4]); 507 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 508 if registers<13> == '1' then SP = bits(32) UNKNOWN; 509 } 510 #endif 511 512 bool success = false; 513 514 bool conditional = false; 515 if (ConditionPassed(opcode, &conditional)) 516 { 517 const uint32_t addr_byte_size = GetAddressByteSize(); 518 const addr_t sp = ReadCoreReg (SP_REG, &success); 519 if (!success) 520 return false; 521 uint32_t registers = 0; 522 uint32_t Rt; // the destination register 523 switch (encoding) { 524 case eEncodingT1: 525 registers = Bits32(opcode, 7, 0); 526 // The P bit represents PC. 527 if (Bit32(opcode, 8)) 528 registers |= (1u << 15); 529 // if BitCount(registers) < 1 then UNPREDICTABLE; 530 if (BitCount(registers) < 1) 531 return false; 532 break; 533 case eEncodingT2: 534 // Ignore bit 13. 535 registers = Bits32(opcode, 15, 0) & ~0x2000; 536 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 537 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 538 return false; 539 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 540 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 541 return false; 542 break; 543 case eEncodingT3: 544 Rt = Bits32(opcode, 15, 12); 545 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 546 if (Rt == 13) 547 return false; 548 if (Rt == 15 && InITBlock() && !LastInITBlock()) 549 return false; 550 registers = (1u << Rt); 551 break; 552 case eEncodingA1: 553 registers = Bits32(opcode, 15, 0); 554 // Instead of return false, let's handle the following case as well, 555 // which amounts to popping one reg from the full descending stacks. 556 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 557 558 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 559 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 560 return false; 561 break; 562 case eEncodingA2: 563 Rt = Bits32(opcode, 15, 12); 564 // if t == 13 then UNPREDICTABLE; 565 if (Rt == dwarf_sp) 566 return false; 567 registers = (1u << Rt); 568 break; 569 default: 570 return false; 571 } 572 addr_t sp_offset = addr_byte_size * BitCount (registers); 573 addr_t addr = sp; 574 uint32_t i, data; 575 576 EmulateInstruction::Context context; 577 if (conditional) 578 context.type = EmulateInstruction::eContextRegisterLoad; 579 else 580 context.type = EmulateInstruction::eContextPopRegisterOffStack; 581 582 RegisterInfo sp_reg; 583 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 584 585 for (i=0; i<15; ++i) 586 { 587 if (BitIsSet (registers, i)) 588 { 589 context.SetRegisterPlusOffset (sp_reg, addr - sp); 590 data = MemARead(context, addr, 4, 0, &success); 591 if (!success) 592 return false; 593 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 594 return false; 595 addr += addr_byte_size; 596 } 597 } 598 599 if (BitIsSet (registers, 15)) 600 { 601 context.SetRegisterPlusOffset (sp_reg, addr - sp); 602 data = MemARead(context, addr, 4, 0, &success); 603 if (!success) 604 return false; 605 // In ARMv5T and above, this is an interworking branch. 606 if (!LoadWritePC(context, data)) 607 return false; 608 //addr += addr_byte_size; 609 } 610 611 context.type = EmulateInstruction::eContextAdjustStackPointer; 612 context.SetImmediateSigned (sp_offset); 613 614 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 615 return false; 616 } 617 return true; 618 } 619 620 // Set r7 or ip to point to saved value residing within the stack. 621 // ADD (SP plus immediate) 622 bool 623 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 624 { 625 #if 0 626 // ARM pseudo code... 627 if (ConditionPassed()) 628 { 629 EncodingSpecificOperations(); 630 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 631 if d == 15 then 632 ALUWritePC(result); // setflags is always FALSE here 633 else 634 R[d] = result; 635 if setflags then 636 APSR.N = result<31>; 637 APSR.Z = IsZeroBit(result); 638 APSR.C = carry; 639 APSR.V = overflow; 640 } 641 #endif 642 643 bool success = false; 644 645 if (ConditionPassed(opcode)) 646 { 647 const addr_t sp = ReadCoreReg (SP_REG, &success); 648 if (!success) 649 return false; 650 uint32_t Rd; // the destination register 651 uint32_t imm32; 652 switch (encoding) { 653 case eEncodingT1: 654 Rd = 7; 655 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 656 break; 657 case eEncodingA1: 658 Rd = Bits32(opcode, 15, 12); 659 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 660 break; 661 default: 662 return false; 663 } 664 addr_t sp_offset = imm32; 665 addr_t addr = sp + sp_offset; // a pointer to the stack area 666 667 EmulateInstruction::Context context; 668 if (Rd == GetFramePointerRegisterNumber()) 669 context.type = eContextSetFramePointer; 670 else 671 context.type = EmulateInstruction::eContextRegisterPlusOffset; 672 RegisterInfo sp_reg; 673 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 674 context.SetRegisterPlusOffset (sp_reg, sp_offset); 675 676 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 677 return false; 678 } 679 return true; 680 } 681 682 // Set r7 or ip to the current stack pointer. 683 // MOV (register) 684 bool 685 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 686 { 687 #if 0 688 // ARM pseudo code... 689 if (ConditionPassed()) 690 { 691 EncodingSpecificOperations(); 692 result = R[m]; 693 if d == 15 then 694 ALUWritePC(result); // setflags is always FALSE here 695 else 696 R[d] = result; 697 if setflags then 698 APSR.N = result<31>; 699 APSR.Z = IsZeroBit(result); 700 // APSR.C unchanged 701 // APSR.V unchanged 702 } 703 #endif 704 705 bool success = false; 706 707 if (ConditionPassed(opcode)) 708 { 709 const addr_t sp = ReadCoreReg (SP_REG, &success); 710 if (!success) 711 return false; 712 uint32_t Rd; // the destination register 713 switch (encoding) { 714 case eEncodingT1: 715 Rd = 7; 716 break; 717 case eEncodingA1: 718 Rd = 12; 719 break; 720 default: 721 return false; 722 } 723 724 EmulateInstruction::Context context; 725 if (Rd == GetFramePointerRegisterNumber()) 726 context.type = EmulateInstruction::eContextSetFramePointer; 727 else 728 context.type = EmulateInstruction::eContextRegisterPlusOffset; 729 RegisterInfo sp_reg; 730 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 731 context.SetRegisterPlusOffset (sp_reg, 0); 732 733 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 734 return false; 735 } 736 return true; 737 } 738 739 // Move from high register (r8-r15) to low register (r0-r7). 740 // MOV (register) 741 bool 742 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 743 { 744 return EmulateMOVRdRm (opcode, encoding); 745 } 746 747 // Move from register to register. 748 // MOV (register) 749 bool 750 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 751 { 752 #if 0 753 // ARM pseudo code... 754 if (ConditionPassed()) 755 { 756 EncodingSpecificOperations(); 757 result = R[m]; 758 if d == 15 then 759 ALUWritePC(result); // setflags is always FALSE here 760 else 761 R[d] = result; 762 if setflags then 763 APSR.N = result<31>; 764 APSR.Z = IsZeroBit(result); 765 // APSR.C unchanged 766 // APSR.V unchanged 767 } 768 #endif 769 770 bool success = false; 771 772 if (ConditionPassed(opcode)) 773 { 774 uint32_t Rm; // the source register 775 uint32_t Rd; // the destination register 776 bool setflags; 777 switch (encoding) { 778 case eEncodingT1: 779 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 780 Rm = Bits32(opcode, 6, 3); 781 setflags = false; 782 if (Rd == 15 && InITBlock() && !LastInITBlock()) 783 return false; 784 break; 785 case eEncodingT2: 786 Rd = Bits32(opcode, 2, 0); 787 Rm = Bits32(opcode, 5, 3); 788 setflags = true; 789 if (InITBlock()) 790 return false; 791 break; 792 case eEncodingT3: 793 Rd = Bits32(opcode, 11, 8); 794 Rm = Bits32(opcode, 3, 0); 795 setflags = BitIsSet(opcode, 20); 796 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 797 if (setflags && (BadReg(Rd) || BadReg(Rm))) 798 return false; 799 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 800 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 801 return false; 802 break; 803 case eEncodingA1: 804 Rd = Bits32(opcode, 15, 12); 805 Rm = Bits32(opcode, 3, 0); 806 setflags = BitIsSet(opcode, 20); 807 808 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 809 if (Rd == 15 && setflags) 810 return EmulateSUBSPcLrEtc (opcode, encoding); 811 break; 812 default: 813 return false; 814 } 815 uint32_t result = ReadCoreReg(Rm, &success); 816 if (!success) 817 return false; 818 819 // The context specifies that Rm is to be moved into Rd. 820 EmulateInstruction::Context context; 821 if (Rd == 13) 822 context.type = EmulateInstruction::eContextAdjustStackPointer; 823 else 824 context.type = EmulateInstruction::eContextRegisterPlusOffset; 825 RegisterInfo dwarf_reg; 826 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 827 context.SetRegisterPlusOffset (dwarf_reg, 0); 828 829 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 830 return false; 831 } 832 return true; 833 } 834 835 // Move (immediate) writes an immediate value to the destination register. It 836 // can optionally update the condition flags based on the value. 837 // MOV (immediate) 838 bool 839 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 840 { 841 #if 0 842 // ARM pseudo code... 843 if (ConditionPassed()) 844 { 845 EncodingSpecificOperations(); 846 result = imm32; 847 if d == 15 then // Can only occur for ARM encoding 848 ALUWritePC(result); // setflags is always FALSE here 849 else 850 R[d] = result; 851 if setflags then 852 APSR.N = result<31>; 853 APSR.Z = IsZeroBit(result); 854 APSR.C = carry; 855 // APSR.V unchanged 856 } 857 #endif 858 859 if (ConditionPassed(opcode)) 860 { 861 uint32_t Rd; // the destination register 862 uint32_t imm32; // the immediate value to be written to Rd 863 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 864 // for setflags == false, this value is a don't care 865 // initialized to 0 to silence the static analyzer 866 bool setflags; 867 switch (encoding) { 868 case eEncodingT1: 869 Rd = Bits32(opcode, 10, 8); 870 setflags = !InITBlock(); 871 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 872 carry = APSR_C; 873 874 break; 875 876 case eEncodingT2: 877 Rd = Bits32(opcode, 11, 8); 878 setflags = BitIsSet(opcode, 20); 879 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 880 if (BadReg(Rd)) 881 return false; 882 883 break; 884 885 case eEncodingT3: 886 { 887 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 888 Rd = Bits32 (opcode, 11, 8); 889 setflags = false; 890 uint32_t imm4 = Bits32 (opcode, 19, 16); 891 uint32_t imm3 = Bits32 (opcode, 14, 12); 892 uint32_t i = Bit32 (opcode, 26); 893 uint32_t imm8 = Bits32 (opcode, 7, 0); 894 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 895 896 // if BadReg(d) then UNPREDICTABLE; 897 if (BadReg (Rd)) 898 return false; 899 } 900 break; 901 902 case eEncodingA1: 903 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 904 Rd = Bits32 (opcode, 15, 12); 905 setflags = BitIsSet (opcode, 20); 906 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 907 908 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 909 if ((Rd == 15) && setflags) 910 return EmulateSUBSPcLrEtc (opcode, encoding); 911 912 break; 913 914 case eEncodingA2: 915 { 916 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 917 Rd = Bits32 (opcode, 15, 12); 918 setflags = false; 919 uint32_t imm4 = Bits32 (opcode, 19, 16); 920 uint32_t imm12 = Bits32 (opcode, 11, 0); 921 imm32 = (imm4 << 12) | imm12; 922 923 // if d == 15 then UNPREDICTABLE; 924 if (Rd == 15) 925 return false; 926 } 927 break; 928 929 default: 930 return false; 931 } 932 uint32_t result = imm32; 933 934 // The context specifies that an immediate is to be moved into Rd. 935 EmulateInstruction::Context context; 936 context.type = EmulateInstruction::eContextImmediate; 937 context.SetNoArgs (); 938 939 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 940 return false; 941 } 942 return true; 943 } 944 945 // MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 946 // register. These 32 bits do not depend on whether the source register values are considered to be signed values or 947 // unsigned values. 948 // 949 // Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 950 // limited to only a few forms of the instruction. 951 bool 952 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 953 { 954 #if 0 955 if ConditionPassed() then 956 EncodingSpecificOperations(); 957 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 958 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 959 result = operand1 * operand2; 960 R[d] = result<31:0>; 961 if setflags then 962 APSR.N = result<31>; 963 APSR.Z = IsZeroBit(result); 964 if ArchVersion() == 4 then 965 APSR.C = bit UNKNOWN; 966 // else APSR.C unchanged 967 // APSR.V always unchanged 968 #endif 969 970 if (ConditionPassed(opcode)) 971 { 972 uint32_t d; 973 uint32_t n; 974 uint32_t m; 975 bool setflags; 976 977 // EncodingSpecificOperations(); 978 switch (encoding) 979 { 980 case eEncodingT1: 981 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 982 d = Bits32 (opcode, 2, 0); 983 n = Bits32 (opcode, 5, 3); 984 m = Bits32 (opcode, 2, 0); 985 setflags = !InITBlock(); 986 987 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 988 if ((ArchVersion() < ARMv6) && (d == n)) 989 return false; 990 991 break; 992 993 case eEncodingT2: 994 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 995 d = Bits32 (opcode, 11, 8); 996 n = Bits32 (opcode, 19, 16); 997 m = Bits32 (opcode, 3, 0); 998 setflags = false; 999 1000 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 1001 if (BadReg (d) || BadReg (n) || BadReg (m)) 1002 return false; 1003 1004 break; 1005 1006 case eEncodingA1: 1007 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1008 d = Bits32 (opcode, 19, 16); 1009 n = Bits32 (opcode, 3, 0); 1010 m = Bits32 (opcode, 11, 8); 1011 setflags = BitIsSet (opcode, 20); 1012 1013 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1014 if ((d == 15) || (n == 15) || (m == 15)) 1015 return false; 1016 1017 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1018 if ((ArchVersion() < ARMv6) && (d == n)) 1019 return false; 1020 1021 break; 1022 1023 default: 1024 return false; 1025 } 1026 1027 bool success = false; 1028 1029 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1030 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1031 if (!success) 1032 return false; 1033 1034 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1035 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1036 if (!success) 1037 return false; 1038 1039 // result = operand1 * operand2; 1040 uint64_t result = operand1 * operand2; 1041 1042 // R[d] = result<31:0>; 1043 RegisterInfo op1_reg; 1044 RegisterInfo op2_reg; 1045 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1046 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1047 1048 EmulateInstruction::Context context; 1049 context.type = eContextArithmetic; 1050 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 1051 1052 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 1053 return false; 1054 1055 // if setflags then 1056 if (setflags) 1057 { 1058 // APSR.N = result<31>; 1059 // APSR.Z = IsZeroBit(result); 1060 m_new_inst_cpsr = m_opcode_cpsr; 1061 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 1062 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1063 if (m_new_inst_cpsr != m_opcode_cpsr) 1064 { 1065 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1066 return false; 1067 } 1068 1069 // if ArchVersion() == 4 then 1070 // APSR.C = bit UNKNOWN; 1071 } 1072 } 1073 return true; 1074 } 1075 1076 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1077 // It can optionally update the condition flags based on the value. 1078 bool 1079 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1080 { 1081 #if 0 1082 // ARM pseudo code... 1083 if (ConditionPassed()) 1084 { 1085 EncodingSpecificOperations(); 1086 result = NOT(imm32); 1087 if d == 15 then // Can only occur for ARM encoding 1088 ALUWritePC(result); // setflags is always FALSE here 1089 else 1090 R[d] = result; 1091 if setflags then 1092 APSR.N = result<31>; 1093 APSR.Z = IsZeroBit(result); 1094 APSR.C = carry; 1095 // APSR.V unchanged 1096 } 1097 #endif 1098 1099 if (ConditionPassed(opcode)) 1100 { 1101 uint32_t Rd; // the destination register 1102 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1103 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1104 bool setflags; 1105 switch (encoding) { 1106 case eEncodingT1: 1107 Rd = Bits32(opcode, 11, 8); 1108 setflags = BitIsSet(opcode, 20); 1109 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1110 break; 1111 case eEncodingA1: 1112 Rd = Bits32(opcode, 15, 12); 1113 setflags = BitIsSet(opcode, 20); 1114 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1115 1116 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1117 if (Rd == 15 && setflags) 1118 return EmulateSUBSPcLrEtc (opcode, encoding); 1119 break; 1120 default: 1121 return false; 1122 } 1123 uint32_t result = ~imm32; 1124 1125 // The context specifies that an immediate is to be moved into Rd. 1126 EmulateInstruction::Context context; 1127 context.type = EmulateInstruction::eContextImmediate; 1128 context.SetNoArgs (); 1129 1130 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1131 return false; 1132 } 1133 return true; 1134 } 1135 1136 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1137 // It can optionally update the condition flags based on the result. 1138 bool 1139 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1140 { 1141 #if 0 1142 // ARM pseudo code... 1143 if (ConditionPassed()) 1144 { 1145 EncodingSpecificOperations(); 1146 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1147 result = NOT(shifted); 1148 if d == 15 then // Can only occur for ARM encoding 1149 ALUWritePC(result); // setflags is always FALSE here 1150 else 1151 R[d] = result; 1152 if setflags then 1153 APSR.N = result<31>; 1154 APSR.Z = IsZeroBit(result); 1155 APSR.C = carry; 1156 // APSR.V unchanged 1157 } 1158 #endif 1159 1160 if (ConditionPassed(opcode)) 1161 { 1162 uint32_t Rm; // the source register 1163 uint32_t Rd; // the destination register 1164 ARM_ShifterType shift_t; 1165 uint32_t shift_n; // the shift applied to the value read from Rm 1166 bool setflags; 1167 uint32_t carry; // the carry bit after the shift operation 1168 switch (encoding) { 1169 case eEncodingT1: 1170 Rd = Bits32(opcode, 2, 0); 1171 Rm = Bits32(opcode, 5, 3); 1172 setflags = !InITBlock(); 1173 shift_t = SRType_LSL; 1174 shift_n = 0; 1175 if (InITBlock()) 1176 return false; 1177 break; 1178 case eEncodingT2: 1179 Rd = Bits32(opcode, 11, 8); 1180 Rm = Bits32(opcode, 3, 0); 1181 setflags = BitIsSet(opcode, 20); 1182 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1183 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1184 if (BadReg(Rd) || BadReg(Rm)) 1185 return false; 1186 break; 1187 case eEncodingA1: 1188 Rd = Bits32(opcode, 15, 12); 1189 Rm = Bits32(opcode, 3, 0); 1190 setflags = BitIsSet(opcode, 20); 1191 shift_n = DecodeImmShiftARM(opcode, shift_t); 1192 break; 1193 default: 1194 return false; 1195 } 1196 bool success = false; 1197 uint32_t value = ReadCoreReg(Rm, &success); 1198 if (!success) 1199 return false; 1200 1201 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1202 if (!success) 1203 return false; 1204 uint32_t result = ~shifted; 1205 1206 // The context specifies that an immediate is to be moved into Rd. 1207 EmulateInstruction::Context context; 1208 context.type = EmulateInstruction::eContextImmediate; 1209 context.SetNoArgs (); 1210 1211 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1212 return false; 1213 } 1214 return true; 1215 } 1216 1217 // PC relative immediate load into register, possibly followed by ADD (SP plus register). 1218 // LDR (literal) 1219 bool 1220 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1221 { 1222 #if 0 1223 // ARM pseudo code... 1224 if (ConditionPassed()) 1225 { 1226 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1227 base = Align(PC,4); 1228 address = if add then (base + imm32) else (base - imm32); 1229 data = MemU[address,4]; 1230 if t == 15 then 1231 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1232 elsif UnalignedSupport() || address<1:0> = '00' then 1233 R[t] = data; 1234 else // Can only apply before ARMv7 1235 if CurrentInstrSet() == InstrSet_ARM then 1236 R[t] = ROR(data, 8*UInt(address<1:0>)); 1237 else 1238 R[t] = bits(32) UNKNOWN; 1239 } 1240 #endif 1241 1242 if (ConditionPassed(opcode)) 1243 { 1244 bool success = false; 1245 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1246 if (!success) 1247 return false; 1248 1249 // PC relative immediate load context 1250 EmulateInstruction::Context context; 1251 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1252 RegisterInfo pc_reg; 1253 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1254 context.SetRegisterPlusOffset (pc_reg, 0); 1255 1256 uint32_t Rt; // the destination register 1257 uint32_t imm32; // immediate offset from the PC 1258 bool add; // +imm32 or -imm32? 1259 addr_t base; // the base address 1260 addr_t address; // the PC relative address 1261 uint32_t data; // the literal data value from the PC relative load 1262 switch (encoding) { 1263 case eEncodingT1: 1264 Rt = Bits32(opcode, 10, 8); 1265 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1266 add = true; 1267 break; 1268 case eEncodingT2: 1269 Rt = Bits32(opcode, 15, 12); 1270 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1271 add = BitIsSet(opcode, 23); 1272 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1273 return false; 1274 break; 1275 default: 1276 return false; 1277 } 1278 1279 base = Align(pc, 4); 1280 if (add) 1281 address = base + imm32; 1282 else 1283 address = base - imm32; 1284 1285 context.SetRegisterPlusOffset(pc_reg, address - base); 1286 data = MemURead(context, address, 4, 0, &success); 1287 if (!success) 1288 return false; 1289 1290 if (Rt == 15) 1291 { 1292 if (Bits32(address, 1, 0) == 0) 1293 { 1294 // In ARMv5T and above, this is an interworking branch. 1295 if (!LoadWritePC(context, data)) 1296 return false; 1297 } 1298 else 1299 return false; 1300 } 1301 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1302 { 1303 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1304 return false; 1305 } 1306 else // We don't handle ARM for now. 1307 return false; 1308 1309 } 1310 return true; 1311 } 1312 1313 // An add operation to adjust the SP. 1314 // ADD (SP plus immediate) 1315 bool 1316 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1317 { 1318 #if 0 1319 // ARM pseudo code... 1320 if (ConditionPassed()) 1321 { 1322 EncodingSpecificOperations(); 1323 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1324 if d == 15 then // Can only occur for ARM encoding 1325 ALUWritePC(result); // setflags is always FALSE here 1326 else 1327 R[d] = result; 1328 if setflags then 1329 APSR.N = result<31>; 1330 APSR.Z = IsZeroBit(result); 1331 APSR.C = carry; 1332 APSR.V = overflow; 1333 } 1334 #endif 1335 1336 bool success = false; 1337 1338 if (ConditionPassed(opcode)) 1339 { 1340 const addr_t sp = ReadCoreReg (SP_REG, &success); 1341 if (!success) 1342 return false; 1343 uint32_t imm32; // the immediate operand 1344 uint32_t d; 1345 bool setflags; 1346 switch (encoding) 1347 { 1348 case eEncodingT1: 1349 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1350 d = Bits32 (opcode, 10, 8); 1351 imm32 = (Bits32 (opcode, 7, 0) << 2); 1352 setflags = false; 1353 break; 1354 1355 case eEncodingT2: 1356 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1357 d = 13; 1358 imm32 = ThumbImm7Scaled (opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1359 setflags = false; 1360 break; 1361 1362 case eEncodingT3: 1363 // d = UInt(Rd); setflags = (S == "1"); imm32 = ThumbExpandImm(i:imm3:imm8); 1364 d = Bits32 (opcode, 11, 8); 1365 imm32 = ThumbExpandImm (opcode); 1366 setflags = Bit32 (opcode, 20); 1367 1368 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1369 if (d == 15 && setflags == 1) 1370 return false; // CMN (immediate) not yet supported 1371 1372 // if d == 15 && S == "0" then UNPREDICTABLE; 1373 if (d == 15 && setflags == 0) 1374 return false; 1375 break; 1376 1377 case eEncodingT4: 1378 { 1379 // if Rn == '1111' then SEE ADR; 1380 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1381 d = Bits32 (opcode, 11, 8); 1382 setflags = false; 1383 uint32_t i = Bit32 (opcode, 26); 1384 uint32_t imm3 = Bits32 (opcode, 14, 12); 1385 uint32_t imm8 = Bits32 (opcode, 7, 0); 1386 imm32 = (i << 11) | (imm3 << 8) | imm8; 1387 1388 // if d == 15 then UNPREDICTABLE; 1389 if (d == 15) 1390 return false; 1391 } 1392 break; 1393 1394 default: 1395 return false; 1396 } 1397 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1398 AddWithCarryResult res = AddWithCarry (sp, imm32, 0); 1399 1400 EmulateInstruction::Context context; 1401 if (d == 13) 1402 context.type = EmulateInstruction::eContextAdjustStackPointer; 1403 else 1404 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1405 1406 RegisterInfo sp_reg; 1407 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1408 context.SetRegisterPlusOffset (sp_reg, res.result - sp); 1409 1410 if (d == 15) 1411 { 1412 if (!ALUWritePC (context, res.result)) 1413 return false; 1414 } 1415 else 1416 { 1417 // R[d] = result; 1418 // if setflags then 1419 // APSR.N = result<31>; 1420 // APSR.Z = IsZeroBit(result); 1421 // APSR.C = carry; 1422 // APSR.V = overflow; 1423 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 1424 return false; 1425 } 1426 } 1427 return true; 1428 } 1429 1430 // An add operation to adjust the SP. 1431 // ADD (SP plus register) 1432 bool 1433 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1434 { 1435 #if 0 1436 // ARM pseudo code... 1437 if (ConditionPassed()) 1438 { 1439 EncodingSpecificOperations(); 1440 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1441 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1442 if d == 15 then 1443 ALUWritePC(result); // setflags is always FALSE here 1444 else 1445 R[d] = result; 1446 if setflags then 1447 APSR.N = result<31>; 1448 APSR.Z = IsZeroBit(result); 1449 APSR.C = carry; 1450 APSR.V = overflow; 1451 } 1452 #endif 1453 1454 bool success = false; 1455 1456 if (ConditionPassed(opcode)) 1457 { 1458 const addr_t sp = ReadCoreReg (SP_REG, &success); 1459 if (!success) 1460 return false; 1461 uint32_t Rm; // the second operand 1462 switch (encoding) { 1463 case eEncodingT2: 1464 Rm = Bits32(opcode, 6, 3); 1465 break; 1466 default: 1467 return false; 1468 } 1469 int32_t reg_value = ReadCoreReg(Rm, &success); 1470 if (!success) 1471 return false; 1472 1473 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1474 1475 EmulateInstruction::Context context; 1476 context.type = eContextArithmetic; 1477 RegisterInfo sp_reg; 1478 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1479 1480 RegisterInfo other_reg; 1481 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1482 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1483 1484 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1485 return false; 1486 } 1487 return true; 1488 } 1489 1490 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1491 // at a PC-relative address, and changes instruction set from ARM to Thumb, or 1492 // from Thumb to ARM. 1493 // BLX (immediate) 1494 bool 1495 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1496 { 1497 #if 0 1498 // ARM pseudo code... 1499 if (ConditionPassed()) 1500 { 1501 EncodingSpecificOperations(); 1502 if CurrentInstrSet() == InstrSet_ARM then 1503 LR = PC - 4; 1504 else 1505 LR = PC<31:1> : '1'; 1506 if targetInstrSet == InstrSet_ARM then 1507 targetAddress = Align(PC,4) + imm32; 1508 else 1509 targetAddress = PC + imm32; 1510 SelectInstrSet(targetInstrSet); 1511 BranchWritePC(targetAddress); 1512 } 1513 #endif 1514 1515 bool success = true; 1516 1517 if (ConditionPassed(opcode)) 1518 { 1519 EmulateInstruction::Context context; 1520 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1521 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1522 if (!success) 1523 return false; 1524 addr_t lr; // next instruction address 1525 addr_t target; // target address 1526 int32_t imm32; // PC-relative offset 1527 switch (encoding) { 1528 case eEncodingT1: 1529 { 1530 lr = pc | 1u; // return address 1531 uint32_t S = Bit32(opcode, 26); 1532 uint32_t imm10 = Bits32(opcode, 25, 16); 1533 uint32_t J1 = Bit32(opcode, 13); 1534 uint32_t J2 = Bit32(opcode, 11); 1535 uint32_t imm11 = Bits32(opcode, 10, 0); 1536 uint32_t I1 = !(J1 ^ S); 1537 uint32_t I2 = !(J2 ^ S); 1538 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1539 imm32 = llvm::SignExtend32<25>(imm25); 1540 target = pc + imm32; 1541 SelectInstrSet (eModeThumb); 1542 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1543 if (InITBlock() && !LastInITBlock()) 1544 return false; 1545 break; 1546 } 1547 case eEncodingT2: 1548 { 1549 lr = pc | 1u; // return address 1550 uint32_t S = Bit32(opcode, 26); 1551 uint32_t imm10H = Bits32(opcode, 25, 16); 1552 uint32_t J1 = Bit32(opcode, 13); 1553 uint32_t J2 = Bit32(opcode, 11); 1554 uint32_t imm10L = Bits32(opcode, 10, 1); 1555 uint32_t I1 = !(J1 ^ S); 1556 uint32_t I2 = !(J2 ^ S); 1557 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1558 imm32 = llvm::SignExtend32<25>(imm25); 1559 target = Align(pc, 4) + imm32; 1560 SelectInstrSet (eModeARM); 1561 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1562 if (InITBlock() && !LastInITBlock()) 1563 return false; 1564 break; 1565 } 1566 case eEncodingA1: 1567 lr = pc - 4; // return address 1568 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1569 target = Align(pc, 4) + imm32; 1570 SelectInstrSet (eModeARM); 1571 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1572 break; 1573 case eEncodingA2: 1574 lr = pc - 4; // return address 1575 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1576 target = pc + imm32; 1577 SelectInstrSet (eModeThumb); 1578 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1579 break; 1580 default: 1581 return false; 1582 } 1583 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1584 return false; 1585 if (!BranchWritePC(context, target)) 1586 return false; 1587 if (m_opcode_cpsr != m_new_inst_cpsr) 1588 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1589 return false; 1590 } 1591 return true; 1592 } 1593 1594 // Branch with Link and Exchange (register) calls a subroutine at an address and 1595 // instruction set specified by a register. 1596 // BLX (register) 1597 bool 1598 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1599 { 1600 #if 0 1601 // ARM pseudo code... 1602 if (ConditionPassed()) 1603 { 1604 EncodingSpecificOperations(); 1605 target = R[m]; 1606 if CurrentInstrSet() == InstrSet_ARM then 1607 next_instr_addr = PC - 4; 1608 LR = next_instr_addr; 1609 else 1610 next_instr_addr = PC - 2; 1611 LR = next_instr_addr<31:1> : '1'; 1612 BXWritePC(target); 1613 } 1614 #endif 1615 1616 bool success = false; 1617 1618 if (ConditionPassed(opcode)) 1619 { 1620 EmulateInstruction::Context context; 1621 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1622 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1623 addr_t lr; // next instruction address 1624 if (!success) 1625 return false; 1626 uint32_t Rm; // the register with the target address 1627 switch (encoding) { 1628 case eEncodingT1: 1629 lr = (pc - 2) | 1u; // return address 1630 Rm = Bits32(opcode, 6, 3); 1631 // if m == 15 then UNPREDICTABLE; 1632 if (Rm == 15) 1633 return false; 1634 if (InITBlock() && !LastInITBlock()) 1635 return false; 1636 break; 1637 case eEncodingA1: 1638 lr = pc - 4; // return address 1639 Rm = Bits32(opcode, 3, 0); 1640 // if m == 15 then UNPREDICTABLE; 1641 if (Rm == 15) 1642 return false; 1643 break; 1644 default: 1645 return false; 1646 } 1647 addr_t target = ReadCoreReg (Rm, &success); 1648 if (!success) 1649 return false; 1650 RegisterInfo dwarf_reg; 1651 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1652 context.SetRegister (dwarf_reg); 1653 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1654 return false; 1655 if (!BXWritePC(context, target)) 1656 return false; 1657 } 1658 return true; 1659 } 1660 1661 // Branch and Exchange causes a branch to an address and instruction set specified by a register. 1662 bool 1663 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1664 { 1665 #if 0 1666 // ARM pseudo code... 1667 if (ConditionPassed()) 1668 { 1669 EncodingSpecificOperations(); 1670 BXWritePC(R[m]); 1671 } 1672 #endif 1673 1674 if (ConditionPassed(opcode)) 1675 { 1676 EmulateInstruction::Context context; 1677 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1678 uint32_t Rm; // the register with the target address 1679 switch (encoding) { 1680 case eEncodingT1: 1681 Rm = Bits32(opcode, 6, 3); 1682 if (InITBlock() && !LastInITBlock()) 1683 return false; 1684 break; 1685 case eEncodingA1: 1686 Rm = Bits32(opcode, 3, 0); 1687 break; 1688 default: 1689 return false; 1690 } 1691 bool success = false; 1692 addr_t target = ReadCoreReg (Rm, &success); 1693 if (!success) 1694 return false; 1695 1696 RegisterInfo dwarf_reg; 1697 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1698 context.SetRegister (dwarf_reg); 1699 if (!BXWritePC(context, target)) 1700 return false; 1701 } 1702 return true; 1703 } 1704 1705 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1706 // address and instruction set specified by a register as though it were a BX instruction. 1707 // 1708 // TODO: Emulate Jazelle architecture? 1709 // We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1710 bool 1711 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1712 { 1713 #if 0 1714 // ARM pseudo code... 1715 if (ConditionPassed()) 1716 { 1717 EncodingSpecificOperations(); 1718 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1719 BXWritePC(R[m]); 1720 else 1721 if JazelleAcceptsExecution() then 1722 SwitchToJazelleExecution(); 1723 else 1724 SUBARCHITECTURE_DEFINED handler call; 1725 } 1726 #endif 1727 1728 if (ConditionPassed(opcode)) 1729 { 1730 EmulateInstruction::Context context; 1731 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1732 uint32_t Rm; // the register with the target address 1733 switch (encoding) { 1734 case eEncodingT1: 1735 Rm = Bits32(opcode, 19, 16); 1736 if (BadReg(Rm)) 1737 return false; 1738 if (InITBlock() && !LastInITBlock()) 1739 return false; 1740 break; 1741 case eEncodingA1: 1742 Rm = Bits32(opcode, 3, 0); 1743 if (Rm == 15) 1744 return false; 1745 break; 1746 default: 1747 return false; 1748 } 1749 bool success = false; 1750 addr_t target = ReadCoreReg (Rm, &success); 1751 if (!success) 1752 return false; 1753 1754 RegisterInfo dwarf_reg; 1755 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1756 context.SetRegister (dwarf_reg); 1757 if (!BXWritePC(context, target)) 1758 return false; 1759 } 1760 return true; 1761 } 1762 1763 // Set r7 to point to some ip offset. 1764 // SUB (immediate) 1765 bool 1766 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1767 { 1768 #if 0 1769 // ARM pseudo code... 1770 if (ConditionPassed()) 1771 { 1772 EncodingSpecificOperations(); 1773 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1774 if d == 15 then // Can only occur for ARM encoding 1775 ALUWritePC(result); // setflags is always FALSE here 1776 else 1777 R[d] = result; 1778 if setflags then 1779 APSR.N = result<31>; 1780 APSR.Z = IsZeroBit(result); 1781 APSR.C = carry; 1782 APSR.V = overflow; 1783 } 1784 #endif 1785 1786 if (ConditionPassed(opcode)) 1787 { 1788 bool success = false; 1789 const addr_t ip = ReadCoreReg (12, &success); 1790 if (!success) 1791 return false; 1792 uint32_t imm32; 1793 switch (encoding) { 1794 case eEncodingA1: 1795 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1796 break; 1797 default: 1798 return false; 1799 } 1800 addr_t ip_offset = imm32; 1801 addr_t addr = ip - ip_offset; // the adjusted ip value 1802 1803 EmulateInstruction::Context context; 1804 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1805 RegisterInfo dwarf_reg; 1806 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1807 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1808 1809 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1810 return false; 1811 } 1812 return true; 1813 } 1814 1815 // Set ip to point to some stack offset. 1816 // SUB (SP minus immediate) 1817 bool 1818 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1819 { 1820 #if 0 1821 // ARM pseudo code... 1822 if (ConditionPassed()) 1823 { 1824 EncodingSpecificOperations(); 1825 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1826 if d == 15 then // Can only occur for ARM encoding 1827 ALUWritePC(result); // setflags is always FALSE here 1828 else 1829 R[d] = result; 1830 if setflags then 1831 APSR.N = result<31>; 1832 APSR.Z = IsZeroBit(result); 1833 APSR.C = carry; 1834 APSR.V = overflow; 1835 } 1836 #endif 1837 1838 if (ConditionPassed(opcode)) 1839 { 1840 bool success = false; 1841 const addr_t sp = ReadCoreReg (SP_REG, &success); 1842 if (!success) 1843 return false; 1844 uint32_t imm32; 1845 switch (encoding) { 1846 case eEncodingA1: 1847 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1848 break; 1849 default: 1850 return false; 1851 } 1852 addr_t sp_offset = imm32; 1853 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1854 1855 EmulateInstruction::Context context; 1856 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1857 RegisterInfo dwarf_reg; 1858 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1859 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1860 1861 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1862 return false; 1863 } 1864 return true; 1865 } 1866 1867 // This instruction subtracts an immediate value from the SP value, and writes 1868 // the result to the destination register. 1869 // 1870 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1871 bool 1872 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1873 { 1874 #if 0 1875 // ARM pseudo code... 1876 if (ConditionPassed()) 1877 { 1878 EncodingSpecificOperations(); 1879 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1880 if d == 15 then // Can only occur for ARM encoding 1881 ALUWritePC(result); // setflags is always FALSE here 1882 else 1883 R[d] = result; 1884 if setflags then 1885 APSR.N = result<31>; 1886 APSR.Z = IsZeroBit(result); 1887 APSR.C = carry; 1888 APSR.V = overflow; 1889 } 1890 #endif 1891 1892 bool success = false; 1893 if (ConditionPassed(opcode)) 1894 { 1895 const addr_t sp = ReadCoreReg (SP_REG, &success); 1896 if (!success) 1897 return false; 1898 1899 uint32_t Rd; 1900 bool setflags; 1901 uint32_t imm32; 1902 switch (encoding) { 1903 case eEncodingT1: 1904 Rd = 13; 1905 setflags = false; 1906 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1907 break; 1908 case eEncodingT2: 1909 Rd = Bits32(opcode, 11, 8); 1910 setflags = BitIsSet(opcode, 20); 1911 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1912 if (Rd == 15 && setflags) 1913 return EmulateCMPImm(opcode, eEncodingT2); 1914 if (Rd == 15 && !setflags) 1915 return false; 1916 break; 1917 case eEncodingT3: 1918 Rd = Bits32(opcode, 11, 8); 1919 setflags = false; 1920 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1921 if (Rd == 15) 1922 return false; 1923 break; 1924 case eEncodingA1: 1925 Rd = Bits32(opcode, 15, 12); 1926 setflags = BitIsSet(opcode, 20); 1927 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1928 1929 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1930 if (Rd == 15 && setflags) 1931 return EmulateSUBSPcLrEtc (opcode, encoding); 1932 break; 1933 default: 1934 return false; 1935 } 1936 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1937 1938 EmulateInstruction::Context context; 1939 if (Rd == 13) 1940 { 1941 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1942 // value gets passed down to context.SetImmediateSigned. 1943 context.type = EmulateInstruction::eContextAdjustStackPointer; 1944 context.SetImmediateSigned (-imm64); // the stack pointer offset 1945 } 1946 else 1947 { 1948 context.type = EmulateInstruction::eContextImmediate; 1949 context.SetNoArgs (); 1950 } 1951 1952 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1953 return false; 1954 } 1955 return true; 1956 } 1957 1958 // A store operation to the stack that also updates the SP. 1959 bool 1960 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1961 { 1962 #if 0 1963 // ARM pseudo code... 1964 if (ConditionPassed()) 1965 { 1966 EncodingSpecificOperations(); 1967 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1968 address = if index then offset_addr else R[n]; 1969 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1970 if wback then R[n] = offset_addr; 1971 } 1972 #endif 1973 1974 bool conditional = false; 1975 bool success = false; 1976 if (ConditionPassed(opcode, &conditional)) 1977 { 1978 const uint32_t addr_byte_size = GetAddressByteSize(); 1979 const addr_t sp = ReadCoreReg (SP_REG, &success); 1980 if (!success) 1981 return false; 1982 uint32_t Rt; // the source register 1983 uint32_t imm12; 1984 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1985 1986 bool index; 1987 bool add; 1988 bool wback; 1989 switch (encoding) { 1990 case eEncodingA1: 1991 Rt = Bits32(opcode, 15, 12); 1992 imm12 = Bits32(opcode, 11, 0); 1993 Rn = Bits32 (opcode, 19, 16); 1994 1995 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1996 return false; 1997 1998 index = BitIsSet (opcode, 24); 1999 add = BitIsSet (opcode, 23); 2000 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 2001 2002 if (wback && ((Rn == 15) || (Rn == Rt))) 2003 return false; 2004 break; 2005 default: 2006 return false; 2007 } 2008 addr_t offset_addr; 2009 if (add) 2010 offset_addr = sp + imm12; 2011 else 2012 offset_addr = sp - imm12; 2013 2014 addr_t addr; 2015 if (index) 2016 addr = offset_addr; 2017 else 2018 addr = sp; 2019 2020 EmulateInstruction::Context context; 2021 if (conditional) 2022 context.type = EmulateInstruction::eContextRegisterStore; 2023 else 2024 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2025 RegisterInfo sp_reg; 2026 RegisterInfo dwarf_reg; 2027 2028 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2029 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2030 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2031 if (Rt != 15) 2032 { 2033 uint32_t reg_value = ReadCoreReg(Rt, &success); 2034 if (!success) 2035 return false; 2036 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 2037 return false; 2038 } 2039 else 2040 { 2041 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2042 if (!success) 2043 return false; 2044 if (!MemUWrite (context, addr, pc, addr_byte_size)) 2045 return false; 2046 } 2047 2048 2049 if (wback) 2050 { 2051 context.type = EmulateInstruction::eContextAdjustStackPointer; 2052 context.SetImmediateSigned (addr - sp); 2053 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 2054 return false; 2055 } 2056 } 2057 return true; 2058 } 2059 2060 // Vector Push stores multiple extension registers to the stack. 2061 // It also updates SP to point to the start of the stored data. 2062 bool 2063 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 2064 { 2065 #if 0 2066 // ARM pseudo code... 2067 if (ConditionPassed()) 2068 { 2069 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2070 address = SP - imm32; 2071 SP = SP - imm32; 2072 if single_regs then 2073 for r = 0 to regs-1 2074 MemA[address,4] = S[d+r]; address = address+4; 2075 else 2076 for r = 0 to regs-1 2077 // Store as two word-aligned words in the correct order for current endianness. 2078 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2079 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2080 address = address+8; 2081 } 2082 #endif 2083 2084 bool success = false; 2085 bool conditional = false; 2086 if (ConditionPassed(opcode, &conditional)) 2087 { 2088 const uint32_t addr_byte_size = GetAddressByteSize(); 2089 const addr_t sp = ReadCoreReg (SP_REG, &success); 2090 if (!success) 2091 return false; 2092 bool single_regs; 2093 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2094 uint32_t imm32; // stack offset 2095 uint32_t regs; // number of registers 2096 switch (encoding) { 2097 case eEncodingT1: 2098 case eEncodingA1: 2099 single_regs = false; 2100 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2101 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2102 // If UInt(imm8) is odd, see "FSTMX". 2103 regs = Bits32(opcode, 7, 0) / 2; 2104 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2105 if (regs == 0 || regs > 16 || (d + regs) > 32) 2106 return false; 2107 break; 2108 case eEncodingT2: 2109 case eEncodingA2: 2110 single_regs = true; 2111 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2112 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2113 regs = Bits32(opcode, 7, 0); 2114 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2115 if (regs == 0 || regs > 16 || (d + regs) > 32) 2116 return false; 2117 break; 2118 default: 2119 return false; 2120 } 2121 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2122 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2123 addr_t sp_offset = imm32; 2124 addr_t addr = sp - sp_offset; 2125 uint32_t i; 2126 2127 EmulateInstruction::Context context; 2128 if (conditional) 2129 context.type = EmulateInstruction::eContextRegisterStore; 2130 else 2131 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2132 RegisterInfo dwarf_reg; 2133 RegisterInfo sp_reg; 2134 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2135 for (i=0; i<regs; ++i) 2136 { 2137 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2138 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2139 // uint64_t to accommodate 64-bit registers. 2140 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2141 if (!success) 2142 return false; 2143 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2144 return false; 2145 addr += reg_byte_size; 2146 } 2147 2148 context.type = EmulateInstruction::eContextAdjustStackPointer; 2149 context.SetImmediateSigned (-sp_offset); 2150 2151 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2152 return false; 2153 } 2154 return true; 2155 } 2156 2157 // Vector Pop loads multiple extension registers from the stack. 2158 // It also updates SP to point just above the loaded data. 2159 bool 2160 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2161 { 2162 #if 0 2163 // ARM pseudo code... 2164 if (ConditionPassed()) 2165 { 2166 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2167 address = SP; 2168 SP = SP + imm32; 2169 if single_regs then 2170 for r = 0 to regs-1 2171 S[d+r] = MemA[address,4]; address = address+4; 2172 else 2173 for r = 0 to regs-1 2174 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2175 // Combine the word-aligned words in the correct order for current endianness. 2176 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2177 } 2178 #endif 2179 2180 bool success = false; 2181 bool conditional = false; 2182 if (ConditionPassed(opcode, &conditional)) 2183 { 2184 const uint32_t addr_byte_size = GetAddressByteSize(); 2185 const addr_t sp = ReadCoreReg (SP_REG, &success); 2186 if (!success) 2187 return false; 2188 bool single_regs; 2189 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2190 uint32_t imm32; // stack offset 2191 uint32_t regs; // number of registers 2192 switch (encoding) { 2193 case eEncodingT1: 2194 case eEncodingA1: 2195 single_regs = false; 2196 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2197 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2198 // If UInt(imm8) is odd, see "FLDMX". 2199 regs = Bits32(opcode, 7, 0) / 2; 2200 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2201 if (regs == 0 || regs > 16 || (d + regs) > 32) 2202 return false; 2203 break; 2204 case eEncodingT2: 2205 case eEncodingA2: 2206 single_regs = true; 2207 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2208 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2209 regs = Bits32(opcode, 7, 0); 2210 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2211 if (regs == 0 || regs > 16 || (d + regs) > 32) 2212 return false; 2213 break; 2214 default: 2215 return false; 2216 } 2217 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2218 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2219 addr_t sp_offset = imm32; 2220 addr_t addr = sp; 2221 uint32_t i; 2222 uint64_t data; // uint64_t to accommodate 64-bit registers. 2223 2224 EmulateInstruction::Context context; 2225 if (conditional) 2226 context.type = EmulateInstruction::eContextRegisterLoad; 2227 else 2228 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2229 RegisterInfo dwarf_reg; 2230 RegisterInfo sp_reg; 2231 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2232 for (i=0; i<regs; ++i) 2233 { 2234 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2235 context.SetRegisterPlusOffset (sp_reg, addr - sp); 2236 data = MemARead(context, addr, reg_byte_size, 0, &success); 2237 if (!success) 2238 return false; 2239 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2240 return false; 2241 addr += reg_byte_size; 2242 } 2243 2244 context.type = EmulateInstruction::eContextAdjustStackPointer; 2245 context.SetImmediateSigned (sp_offset); 2246 2247 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2248 return false; 2249 } 2250 return true; 2251 } 2252 2253 // SVC (previously SWI) 2254 bool 2255 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2256 { 2257 #if 0 2258 // ARM pseudo code... 2259 if (ConditionPassed()) 2260 { 2261 EncodingSpecificOperations(); 2262 CallSupervisor(); 2263 } 2264 #endif 2265 2266 bool success = false; 2267 2268 if (ConditionPassed(opcode)) 2269 { 2270 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2271 addr_t lr; // next instruction address 2272 if (!success) 2273 return false; 2274 uint32_t imm32; // the immediate constant 2275 uint32_t mode; // ARM or Thumb mode 2276 switch (encoding) { 2277 case eEncodingT1: 2278 lr = (pc + 2) | 1u; // return address 2279 imm32 = Bits32(opcode, 7, 0); 2280 mode = eModeThumb; 2281 break; 2282 case eEncodingA1: 2283 lr = pc + 4; // return address 2284 imm32 = Bits32(opcode, 23, 0); 2285 mode = eModeARM; 2286 break; 2287 default: 2288 return false; 2289 } 2290 2291 EmulateInstruction::Context context; 2292 context.type = EmulateInstruction::eContextSupervisorCall; 2293 context.SetISAAndImmediate (mode, imm32); 2294 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2295 return false; 2296 } 2297 return true; 2298 } 2299 2300 // If Then makes up to four following instructions (the IT block) conditional. 2301 bool 2302 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2303 { 2304 #if 0 2305 // ARM pseudo code... 2306 EncodingSpecificOperations(); 2307 ITSTATE.IT<7:0> = firstcond:mask; 2308 #endif 2309 2310 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2311 return true; 2312 } 2313 2314 bool 2315 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2316 { 2317 // NOP, nothing to do... 2318 return true; 2319 } 2320 2321 // Branch causes a branch to a target address. 2322 bool 2323 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2324 { 2325 #if 0 2326 // ARM pseudo code... 2327 if (ConditionPassed()) 2328 { 2329 EncodingSpecificOperations(); 2330 BranchWritePC(PC + imm32); 2331 } 2332 #endif 2333 2334 bool success = false; 2335 2336 if (ConditionPassed(opcode)) 2337 { 2338 EmulateInstruction::Context context; 2339 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2340 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2341 if (!success) 2342 return false; 2343 addr_t target; // target address 2344 int32_t imm32; // PC-relative offset 2345 switch (encoding) { 2346 case eEncodingT1: 2347 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2348 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2349 target = pc + imm32; 2350 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2351 break; 2352 case eEncodingT2: 2353 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2354 target = pc + imm32; 2355 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2356 break; 2357 case eEncodingT3: 2358 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2359 { 2360 if (Bits32(opcode, 25, 23) == 7) 2361 return false; // See Branches and miscellaneous control on page A6-235. 2362 2363 uint32_t S = Bit32(opcode, 26); 2364 uint32_t imm6 = Bits32(opcode, 21, 16); 2365 uint32_t J1 = Bit32(opcode, 13); 2366 uint32_t J2 = Bit32(opcode, 11); 2367 uint32_t imm11 = Bits32(opcode, 10, 0); 2368 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2369 imm32 = llvm::SignExtend32<21>(imm21); 2370 target = pc + imm32; 2371 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2372 break; 2373 } 2374 case eEncodingT4: 2375 { 2376 uint32_t S = Bit32(opcode, 26); 2377 uint32_t imm10 = Bits32(opcode, 25, 16); 2378 uint32_t J1 = Bit32(opcode, 13); 2379 uint32_t J2 = Bit32(opcode, 11); 2380 uint32_t imm11 = Bits32(opcode, 10, 0); 2381 uint32_t I1 = !(J1 ^ S); 2382 uint32_t I2 = !(J2 ^ S); 2383 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2384 imm32 = llvm::SignExtend32<25>(imm25); 2385 target = pc + imm32; 2386 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2387 break; 2388 } 2389 case eEncodingA1: 2390 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2391 target = pc + imm32; 2392 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2393 break; 2394 default: 2395 return false; 2396 } 2397 if (!BranchWritePC(context, target)) 2398 return false; 2399 } 2400 return true; 2401 } 2402 2403 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2404 // zero and conditionally branch forward a constant value. They do not affect the condition flags. 2405 // CBNZ, CBZ 2406 bool 2407 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2408 { 2409 #if 0 2410 // ARM pseudo code... 2411 EncodingSpecificOperations(); 2412 if nonzero ^ IsZero(R[n]) then 2413 BranchWritePC(PC + imm32); 2414 #endif 2415 2416 bool success = false; 2417 2418 // Read the register value from the operand register Rn. 2419 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2420 if (!success) 2421 return false; 2422 2423 EmulateInstruction::Context context; 2424 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2425 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2426 if (!success) 2427 return false; 2428 2429 addr_t target; // target address 2430 uint32_t imm32; // PC-relative offset to branch forward 2431 bool nonzero; 2432 switch (encoding) { 2433 case eEncodingT1: 2434 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2435 nonzero = BitIsSet(opcode, 11); 2436 target = pc + imm32; 2437 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2438 break; 2439 default: 2440 return false; 2441 } 2442 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2443 if (!BranchWritePC(context, target)) 2444 return false; 2445 2446 return true; 2447 } 2448 2449 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2450 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2451 // The branch length is twice the value of the byte returned from the table. 2452 // 2453 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2454 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2455 // The branch length is twice the value of the halfword returned from the table. 2456 // TBB, TBH 2457 bool 2458 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2459 { 2460 #if 0 2461 // ARM pseudo code... 2462 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2463 if is_tbh then 2464 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2465 else 2466 halfwords = UInt(MemU[R[n]+R[m], 1]); 2467 BranchWritePC(PC + 2*halfwords); 2468 #endif 2469 2470 bool success = false; 2471 2472 if (ConditionPassed(opcode)) 2473 { 2474 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2475 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2476 bool is_tbh; // true if table branch halfword 2477 switch (encoding) { 2478 case eEncodingT1: 2479 Rn = Bits32(opcode, 19, 16); 2480 Rm = Bits32(opcode, 3, 0); 2481 is_tbh = BitIsSet(opcode, 4); 2482 if (Rn == 13 || BadReg(Rm)) 2483 return false; 2484 if (InITBlock() && !LastInITBlock()) 2485 return false; 2486 break; 2487 default: 2488 return false; 2489 } 2490 2491 // Read the address of the table from the operand register Rn. 2492 // The PC can be used, in which case the table immediately follows this instruction. 2493 uint32_t base = ReadCoreReg(Rn, &success); 2494 if (!success) 2495 return false; 2496 2497 // the table index 2498 uint32_t index = ReadCoreReg(Rm, &success); 2499 if (!success) 2500 return false; 2501 2502 // the offsetted table address 2503 addr_t addr = base + (is_tbh ? index*2 : index); 2504 2505 // PC-relative offset to branch forward 2506 EmulateInstruction::Context context; 2507 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2508 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2509 if (!success) 2510 return false; 2511 2512 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2513 if (!success) 2514 return false; 2515 2516 // target address 2517 addr_t target = pc + offset; 2518 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2519 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2520 2521 if (!BranchWritePC(context, target)) 2522 return false; 2523 } 2524 2525 return true; 2526 } 2527 2528 // This instruction adds an immediate value to a register value, and writes the result to the destination register. 2529 // It can optionally update the condition flags based on the result. 2530 bool 2531 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2532 { 2533 #if 0 2534 if ConditionPassed() then 2535 EncodingSpecificOperations(); 2536 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2537 R[d] = result; 2538 if setflags then 2539 APSR.N = result<31>; 2540 APSR.Z = IsZeroBit(result); 2541 APSR.C = carry; 2542 APSR.V = overflow; 2543 #endif 2544 2545 bool success = false; 2546 2547 if (ConditionPassed(opcode)) 2548 { 2549 uint32_t d; 2550 uint32_t n; 2551 bool setflags; 2552 uint32_t imm32; 2553 uint32_t carry_out; 2554 2555 //EncodingSpecificOperations(); 2556 switch (encoding) 2557 { 2558 case eEncodingT1: 2559 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2560 d = Bits32 (opcode, 2, 0); 2561 n = Bits32 (opcode, 5, 3); 2562 setflags = !InITBlock(); 2563 imm32 = Bits32 (opcode, 8,6); 2564 2565 break; 2566 2567 case eEncodingT2: 2568 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2569 d = Bits32 (opcode, 10, 8); 2570 n = Bits32 (opcode, 10, 8); 2571 setflags = !InITBlock(); 2572 imm32 = Bits32 (opcode, 7, 0); 2573 2574 break; 2575 2576 case eEncodingT3: 2577 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2578 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2579 d = Bits32 (opcode, 11, 8); 2580 n = Bits32 (opcode, 19, 16); 2581 setflags = BitIsSet (opcode, 20); 2582 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2583 2584 // if Rn == '1101' then SEE ADD (SP plus immediate); 2585 if (n == 13) 2586 return EmulateADDSPImm(opcode, eEncodingT3); 2587 2588 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2589 if (BadReg (d) || (n == 15)) 2590 return false; 2591 2592 break; 2593 2594 case eEncodingT4: 2595 { 2596 // if Rn == '1111' then SEE ADR; 2597 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2598 d = Bits32 (opcode, 11, 8); 2599 n = Bits32 (opcode, 19, 16); 2600 setflags = false; 2601 uint32_t i = Bit32 (opcode, 26); 2602 uint32_t imm3 = Bits32 (opcode, 14, 12); 2603 uint32_t imm8 = Bits32 (opcode, 7, 0); 2604 imm32 = (i << 11) | (imm3 << 8) | imm8; 2605 2606 // if Rn == '1101' then SEE ADD (SP plus immediate); 2607 if (n == 13) 2608 return EmulateADDSPImm(opcode, eEncodingT4); 2609 2610 // if BadReg(d) then UNPREDICTABLE; 2611 if (BadReg (d)) 2612 return false; 2613 2614 break; 2615 } 2616 2617 default: 2618 return false; 2619 } 2620 2621 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2622 if (!success) 2623 return false; 2624 2625 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2626 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2627 2628 RegisterInfo reg_n; 2629 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2630 2631 EmulateInstruction::Context context; 2632 context.type = eContextArithmetic; 2633 context.SetRegisterPlusOffset (reg_n, imm32); 2634 2635 //R[d] = result; 2636 //if setflags then 2637 //APSR.N = result<31>; 2638 //APSR.Z = IsZeroBit(result); 2639 //APSR.C = carry; 2640 //APSR.V = overflow; 2641 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2642 return false; 2643 2644 } 2645 return true; 2646 } 2647 2648 // This instruction adds an immediate value to a register value, and writes the result to the destination 2649 // register. It can optionally update the condition flags based on the result. 2650 bool 2651 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2652 { 2653 #if 0 2654 // ARM pseudo code... 2655 if ConditionPassed() then 2656 EncodingSpecificOperations(); 2657 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2658 if d == 15 then 2659 ALUWritePC(result); // setflags is always FALSE here 2660 else 2661 R[d] = result; 2662 if setflags then 2663 APSR.N = result<31>; 2664 APSR.Z = IsZeroBit(result); 2665 APSR.C = carry; 2666 APSR.V = overflow; 2667 #endif 2668 2669 bool success = false; 2670 2671 if (ConditionPassed(opcode)) 2672 { 2673 uint32_t Rd, Rn; 2674 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2675 bool setflags; 2676 switch (encoding) 2677 { 2678 case eEncodingA1: 2679 Rd = Bits32(opcode, 15, 12); 2680 Rn = Bits32(opcode, 19, 16); 2681 setflags = BitIsSet(opcode, 20); 2682 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2683 break; 2684 default: 2685 return false; 2686 } 2687 2688 // Read the first operand. 2689 uint32_t val1 = ReadCoreReg(Rn, &success); 2690 if (!success) 2691 return false; 2692 2693 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2694 2695 EmulateInstruction::Context context; 2696 if (Rd == 13) 2697 context.type = EmulateInstruction::eContextAdjustStackPointer; 2698 else if (Rd == GetFramePointerRegisterNumber()) 2699 context.type = EmulateInstruction::eContextSetFramePointer; 2700 else 2701 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2702 2703 RegisterInfo dwarf_reg; 2704 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2705 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2706 2707 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2708 return false; 2709 } 2710 return true; 2711 } 2712 2713 // This instruction adds a register value and an optionally-shifted register value, and writes the result 2714 // to the destination register. It can optionally update the condition flags based on the result. 2715 bool 2716 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2717 { 2718 #if 0 2719 // ARM pseudo code... 2720 if ConditionPassed() then 2721 EncodingSpecificOperations(); 2722 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2723 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2724 if d == 15 then 2725 ALUWritePC(result); // setflags is always FALSE here 2726 else 2727 R[d] = result; 2728 if setflags then 2729 APSR.N = result<31>; 2730 APSR.Z = IsZeroBit(result); 2731 APSR.C = carry; 2732 APSR.V = overflow; 2733 #endif 2734 2735 bool success = false; 2736 2737 if (ConditionPassed(opcode)) 2738 { 2739 uint32_t Rd, Rn, Rm; 2740 ARM_ShifterType shift_t; 2741 uint32_t shift_n; // the shift applied to the value read from Rm 2742 bool setflags; 2743 switch (encoding) 2744 { 2745 case eEncodingT1: 2746 Rd = Bits32(opcode, 2, 0); 2747 Rn = Bits32(opcode, 5, 3); 2748 Rm = Bits32(opcode, 8, 6); 2749 setflags = !InITBlock(); 2750 shift_t = SRType_LSL; 2751 shift_n = 0; 2752 break; 2753 case eEncodingT2: 2754 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2755 Rm = Bits32(opcode, 6, 3); 2756 setflags = false; 2757 shift_t = SRType_LSL; 2758 shift_n = 0; 2759 if (Rn == 15 && Rm == 15) 2760 return false; 2761 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2762 return false; 2763 break; 2764 case eEncodingA1: 2765 Rd = Bits32(opcode, 15, 12); 2766 Rn = Bits32(opcode, 19, 16); 2767 Rm = Bits32(opcode, 3, 0); 2768 setflags = BitIsSet(opcode, 20); 2769 shift_n = DecodeImmShiftARM(opcode, shift_t); 2770 break; 2771 default: 2772 return false; 2773 } 2774 2775 // Read the first operand. 2776 uint32_t val1 = ReadCoreReg(Rn, &success); 2777 if (!success) 2778 return false; 2779 2780 // Read the second operand. 2781 uint32_t val2 = ReadCoreReg(Rm, &success); 2782 if (!success) 2783 return false; 2784 2785 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2786 if (!success) 2787 return false; 2788 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2789 2790 EmulateInstruction::Context context; 2791 context.type = eContextArithmetic; 2792 RegisterInfo op1_reg; 2793 RegisterInfo op2_reg; 2794 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2795 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2796 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2797 2798 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2799 return false; 2800 } 2801 return true; 2802 } 2803 2804 // Compare Negative (immediate) adds a register value and an immediate value. 2805 // It updates the condition flags based on the result, and discards the result. 2806 bool 2807 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2808 { 2809 #if 0 2810 // ARM pseudo code... 2811 if ConditionPassed() then 2812 EncodingSpecificOperations(); 2813 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2814 APSR.N = result<31>; 2815 APSR.Z = IsZeroBit(result); 2816 APSR.C = carry; 2817 APSR.V = overflow; 2818 #endif 2819 2820 bool success = false; 2821 2822 uint32_t Rn; // the first operand 2823 uint32_t imm32; // the immediate value to be compared with 2824 switch (encoding) { 2825 case eEncodingT1: 2826 Rn = Bits32(opcode, 19, 16); 2827 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2828 if (Rn == 15) 2829 return false; 2830 break; 2831 case eEncodingA1: 2832 Rn = Bits32(opcode, 19, 16); 2833 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2834 break; 2835 default: 2836 return false; 2837 } 2838 // Read the register value from the operand register Rn. 2839 uint32_t reg_val = ReadCoreReg(Rn, &success); 2840 if (!success) 2841 return false; 2842 2843 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2844 2845 EmulateInstruction::Context context; 2846 context.type = EmulateInstruction::eContextImmediate; 2847 context.SetNoArgs (); 2848 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2849 return false; 2850 2851 return true; 2852 } 2853 2854 // Compare Negative (register) adds a register value and an optionally-shifted register value. 2855 // It updates the condition flags based on the result, and discards the result. 2856 bool 2857 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2858 { 2859 #if 0 2860 // ARM pseudo code... 2861 if ConditionPassed() then 2862 EncodingSpecificOperations(); 2863 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2864 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2865 APSR.N = result<31>; 2866 APSR.Z = IsZeroBit(result); 2867 APSR.C = carry; 2868 APSR.V = overflow; 2869 #endif 2870 2871 bool success = false; 2872 2873 uint32_t Rn; // the first operand 2874 uint32_t Rm; // the second operand 2875 ARM_ShifterType shift_t; 2876 uint32_t shift_n; // the shift applied to the value read from Rm 2877 switch (encoding) { 2878 case eEncodingT1: 2879 Rn = Bits32(opcode, 2, 0); 2880 Rm = Bits32(opcode, 5, 3); 2881 shift_t = SRType_LSL; 2882 shift_n = 0; 2883 break; 2884 case eEncodingT2: 2885 Rn = Bits32(opcode, 19, 16); 2886 Rm = Bits32(opcode, 3, 0); 2887 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2888 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2889 if (Rn == 15 || BadReg(Rm)) 2890 return false; 2891 break; 2892 case eEncodingA1: 2893 Rn = Bits32(opcode, 19, 16); 2894 Rm = Bits32(opcode, 3, 0); 2895 shift_n = DecodeImmShiftARM(opcode, shift_t); 2896 break; 2897 default: 2898 return false; 2899 } 2900 // Read the register value from register Rn. 2901 uint32_t val1 = ReadCoreReg(Rn, &success); 2902 if (!success) 2903 return false; 2904 2905 // Read the register value from register Rm. 2906 uint32_t val2 = ReadCoreReg(Rm, &success); 2907 if (!success) 2908 return false; 2909 2910 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2911 if (!success) 2912 return false; 2913 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2914 2915 EmulateInstruction::Context context; 2916 context.type = EmulateInstruction::eContextImmediate; 2917 context.SetNoArgs(); 2918 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2919 return false; 2920 2921 return true; 2922 } 2923 2924 // Compare (immediate) subtracts an immediate value from a register value. 2925 // It updates the condition flags based on the result, and discards the result. 2926 bool 2927 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2928 { 2929 #if 0 2930 // ARM pseudo code... 2931 if ConditionPassed() then 2932 EncodingSpecificOperations(); 2933 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2934 APSR.N = result<31>; 2935 APSR.Z = IsZeroBit(result); 2936 APSR.C = carry; 2937 APSR.V = overflow; 2938 #endif 2939 2940 bool success = false; 2941 2942 uint32_t Rn; // the first operand 2943 uint32_t imm32; // the immediate value to be compared with 2944 switch (encoding) { 2945 case eEncodingT1: 2946 Rn = Bits32(opcode, 10, 8); 2947 imm32 = Bits32(opcode, 7, 0); 2948 break; 2949 case eEncodingT2: 2950 Rn = Bits32(opcode, 19, 16); 2951 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2952 if (Rn == 15) 2953 return false; 2954 break; 2955 case eEncodingA1: 2956 Rn = Bits32(opcode, 19, 16); 2957 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2958 break; 2959 default: 2960 return false; 2961 } 2962 // Read the register value from the operand register Rn. 2963 uint32_t reg_val = ReadCoreReg(Rn, &success); 2964 if (!success) 2965 return false; 2966 2967 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2968 2969 EmulateInstruction::Context context; 2970 context.type = EmulateInstruction::eContextImmediate; 2971 context.SetNoArgs (); 2972 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2973 return false; 2974 2975 return true; 2976 } 2977 2978 // Compare (register) subtracts an optionally-shifted register value from a register value. 2979 // It updates the condition flags based on the result, and discards the result. 2980 bool 2981 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2982 { 2983 #if 0 2984 // ARM pseudo code... 2985 if ConditionPassed() then 2986 EncodingSpecificOperations(); 2987 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2988 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2989 APSR.N = result<31>; 2990 APSR.Z = IsZeroBit(result); 2991 APSR.C = carry; 2992 APSR.V = overflow; 2993 #endif 2994 2995 bool success = false; 2996 2997 uint32_t Rn; // the first operand 2998 uint32_t Rm; // the second operand 2999 ARM_ShifterType shift_t; 3000 uint32_t shift_n; // the shift applied to the value read from Rm 3001 switch (encoding) { 3002 case eEncodingT1: 3003 Rn = Bits32(opcode, 2, 0); 3004 Rm = Bits32(opcode, 5, 3); 3005 shift_t = SRType_LSL; 3006 shift_n = 0; 3007 break; 3008 case eEncodingT2: 3009 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3010 Rm = Bits32(opcode, 6, 3); 3011 shift_t = SRType_LSL; 3012 shift_n = 0; 3013 if (Rn < 8 && Rm < 8) 3014 return false; 3015 if (Rn == 15 || Rm == 15) 3016 return false; 3017 break; 3018 case eEncodingT3: 3019 Rn = Bits32(opcode, 19, 16); 3020 Rm = Bits32(opcode, 3, 0); 3021 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3022 if (Rn == 15 || BadReg(Rm)) 3023 return false; 3024 break; 3025 case eEncodingA1: 3026 Rn = Bits32(opcode, 19, 16); 3027 Rm = Bits32(opcode, 3, 0); 3028 shift_n = DecodeImmShiftARM(opcode, shift_t); 3029 break; 3030 default: 3031 return false; 3032 } 3033 // Read the register value from register Rn. 3034 uint32_t val1 = ReadCoreReg(Rn, &success); 3035 if (!success) 3036 return false; 3037 3038 // Read the register value from register Rm. 3039 uint32_t val2 = ReadCoreReg(Rm, &success); 3040 if (!success) 3041 return false; 3042 3043 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3044 if (!success) 3045 return false; 3046 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3047 3048 EmulateInstruction::Context context; 3049 context.type = EmulateInstruction::eContextImmediate; 3050 context.SetNoArgs(); 3051 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3052 return false; 3053 3054 return true; 3055 } 3056 3057 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 3058 // shifting in copies of its sign bit, and writes the result to the destination register. It can 3059 // optionally update the condition flags based on the result. 3060 bool 3061 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 3062 { 3063 #if 0 3064 // ARM pseudo code... 3065 if ConditionPassed() then 3066 EncodingSpecificOperations(); 3067 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3068 if d == 15 then // Can only occur for ARM encoding 3069 ALUWritePC(result); // setflags is always FALSE here 3070 else 3071 R[d] = result; 3072 if setflags then 3073 APSR.N = result<31>; 3074 APSR.Z = IsZeroBit(result); 3075 APSR.C = carry; 3076 // APSR.V unchanged 3077 #endif 3078 3079 return EmulateShiftImm (opcode, encoding, SRType_ASR); 3080 } 3081 3082 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 3083 // shifting in copies of its sign bit, and writes the result to the destination register. 3084 // The variable number of bits is read from the bottom byte of a register. It can optionally update 3085 // the condition flags based on the result. 3086 bool 3087 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 3088 { 3089 #if 0 3090 // ARM pseudo code... 3091 if ConditionPassed() then 3092 EncodingSpecificOperations(); 3093 shift_n = UInt(R[m]<7:0>); 3094 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3095 R[d] = result; 3096 if setflags then 3097 APSR.N = result<31>; 3098 APSR.Z = IsZeroBit(result); 3099 APSR.C = carry; 3100 // APSR.V unchanged 3101 #endif 3102 3103 return EmulateShiftReg (opcode, encoding, SRType_ASR); 3104 } 3105 3106 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 3107 // shifting in zeros, and writes the result to the destination register. It can optionally 3108 // update the condition flags based on the result. 3109 bool 3110 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 3111 { 3112 #if 0 3113 // ARM pseudo code... 3114 if ConditionPassed() then 3115 EncodingSpecificOperations(); 3116 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3117 if d == 15 then // Can only occur for ARM encoding 3118 ALUWritePC(result); // setflags is always FALSE here 3119 else 3120 R[d] = result; 3121 if setflags then 3122 APSR.N = result<31>; 3123 APSR.Z = IsZeroBit(result); 3124 APSR.C = carry; 3125 // APSR.V unchanged 3126 #endif 3127 3128 return EmulateShiftImm (opcode, encoding, SRType_LSL); 3129 } 3130 3131 // Logical Shift Left (register) shifts a register value left by a variable number of bits, 3132 // shifting in zeros, and writes the result to the destination register. The variable number 3133 // of bits is read from the bottom byte of a register. It can optionally update the condition 3134 // flags based on the result. 3135 bool 3136 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 3137 { 3138 #if 0 3139 // ARM pseudo code... 3140 if ConditionPassed() then 3141 EncodingSpecificOperations(); 3142 shift_n = UInt(R[m]<7:0>); 3143 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3144 R[d] = result; 3145 if setflags then 3146 APSR.N = result<31>; 3147 APSR.Z = IsZeroBit(result); 3148 APSR.C = carry; 3149 // APSR.V unchanged 3150 #endif 3151 3152 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3153 } 3154 3155 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3156 // shifting in zeros, and writes the result to the destination register. It can optionally 3157 // update the condition flags based on the result. 3158 bool 3159 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3160 { 3161 #if 0 3162 // ARM pseudo code... 3163 if ConditionPassed() then 3164 EncodingSpecificOperations(); 3165 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3166 if d == 15 then // Can only occur for ARM encoding 3167 ALUWritePC(result); // setflags is always FALSE here 3168 else 3169 R[d] = result; 3170 if setflags then 3171 APSR.N = result<31>; 3172 APSR.Z = IsZeroBit(result); 3173 APSR.C = carry; 3174 // APSR.V unchanged 3175 #endif 3176 3177 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3178 } 3179 3180 // Logical Shift Right (register) shifts a register value right by a variable number of bits, 3181 // shifting in zeros, and writes the result to the destination register. The variable number 3182 // of bits is read from the bottom byte of a register. It can optionally update the condition 3183 // flags based on the result. 3184 bool 3185 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3186 { 3187 #if 0 3188 // ARM pseudo code... 3189 if ConditionPassed() then 3190 EncodingSpecificOperations(); 3191 shift_n = UInt(R[m]<7:0>); 3192 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3193 R[d] = result; 3194 if setflags then 3195 APSR.N = result<31>; 3196 APSR.Z = IsZeroBit(result); 3197 APSR.C = carry; 3198 // APSR.V unchanged 3199 #endif 3200 3201 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3202 } 3203 3204 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3205 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3206 // It can optionally update the condition flags based on the result. 3207 bool 3208 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3209 { 3210 #if 0 3211 // ARM pseudo code... 3212 if ConditionPassed() then 3213 EncodingSpecificOperations(); 3214 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3215 if d == 15 then // Can only occur for ARM encoding 3216 ALUWritePC(result); // setflags is always FALSE here 3217 else 3218 R[d] = result; 3219 if setflags then 3220 APSR.N = result<31>; 3221 APSR.Z = IsZeroBit(result); 3222 APSR.C = carry; 3223 // APSR.V unchanged 3224 #endif 3225 3226 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3227 } 3228 3229 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3230 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3231 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3232 // flags based on the result. 3233 bool 3234 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3235 { 3236 #if 0 3237 // ARM pseudo code... 3238 if ConditionPassed() then 3239 EncodingSpecificOperations(); 3240 shift_n = UInt(R[m]<7:0>); 3241 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3242 R[d] = result; 3243 if setflags then 3244 APSR.N = result<31>; 3245 APSR.Z = IsZeroBit(result); 3246 APSR.C = carry; 3247 // APSR.V unchanged 3248 #endif 3249 3250 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3251 } 3252 3253 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3254 // with the carry flag shifted into bit [31]. 3255 // 3256 // RRX can optionally update the condition flags based on the result. 3257 // In that case, bit [0] is shifted into the carry flag. 3258 bool 3259 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3260 { 3261 #if 0 3262 // ARM pseudo code... 3263 if ConditionPassed() then 3264 EncodingSpecificOperations(); 3265 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3266 if d == 15 then // Can only occur for ARM encoding 3267 ALUWritePC(result); // setflags is always FALSE here 3268 else 3269 R[d] = result; 3270 if setflags then 3271 APSR.N = result<31>; 3272 APSR.Z = IsZeroBit(result); 3273 APSR.C = carry; 3274 // APSR.V unchanged 3275 #endif 3276 3277 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3278 } 3279 3280 bool 3281 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3282 { 3283 // assert(shift_type == SRType_ASR 3284 // || shift_type == SRType_LSL 3285 // || shift_type == SRType_LSR 3286 // || shift_type == SRType_ROR 3287 // || shift_type == SRType_RRX); 3288 3289 bool success = false; 3290 3291 if (ConditionPassed(opcode)) 3292 { 3293 uint32_t Rd; // the destination register 3294 uint32_t Rm; // the first operand register 3295 uint32_t imm5; // encoding for the shift amount 3296 uint32_t carry; // the carry bit after the shift operation 3297 bool setflags; 3298 3299 // Special case handling! 3300 // A8.6.139 ROR (immediate) -- Encoding T1 3301 ARMEncoding use_encoding = encoding; 3302 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3303 { 3304 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3305 // have the same decoding of bit fields as the other Thumb2 shift operations. 3306 use_encoding = eEncodingT2; 3307 } 3308 3309 switch (use_encoding) { 3310 case eEncodingT1: 3311 // Due to the above special case handling! 3312 if (shift_type == SRType_ROR) 3313 return false; 3314 3315 Rd = Bits32(opcode, 2, 0); 3316 Rm = Bits32(opcode, 5, 3); 3317 setflags = !InITBlock(); 3318 imm5 = Bits32(opcode, 10, 6); 3319 break; 3320 case eEncodingT2: 3321 // A8.6.141 RRX 3322 // There's no imm form of RRX instructions. 3323 if (shift_type == SRType_RRX) 3324 return false; 3325 3326 Rd = Bits32(opcode, 11, 8); 3327 Rm = Bits32(opcode, 3, 0); 3328 setflags = BitIsSet(opcode, 20); 3329 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3330 if (BadReg(Rd) || BadReg(Rm)) 3331 return false; 3332 break; 3333 case eEncodingA1: 3334 Rd = Bits32(opcode, 15, 12); 3335 Rm = Bits32(opcode, 3, 0); 3336 setflags = BitIsSet(opcode, 20); 3337 imm5 = Bits32(opcode, 11, 7); 3338 break; 3339 default: 3340 return false; 3341 } 3342 3343 // A8.6.139 ROR (immediate) 3344 if (shift_type == SRType_ROR && imm5 == 0) 3345 shift_type = SRType_RRX; 3346 3347 // Get the first operand. 3348 uint32_t value = ReadCoreReg (Rm, &success); 3349 if (!success) 3350 return false; 3351 3352 // Decode the shift amount if not RRX. 3353 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3354 3355 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3356 if (!success) 3357 return false; 3358 3359 // The context specifies that an immediate is to be moved into Rd. 3360 EmulateInstruction::Context context; 3361 context.type = EmulateInstruction::eContextImmediate; 3362 context.SetNoArgs (); 3363 3364 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3365 return false; 3366 } 3367 return true; 3368 } 3369 3370 bool 3371 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3372 { 3373 // assert(shift_type == SRType_ASR 3374 // || shift_type == SRType_LSL 3375 // || shift_type == SRType_LSR 3376 // || shift_type == SRType_ROR); 3377 3378 bool success = false; 3379 3380 if (ConditionPassed(opcode)) 3381 { 3382 uint32_t Rd; // the destination register 3383 uint32_t Rn; // the first operand register 3384 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3385 uint32_t carry; // the carry bit after the shift operation 3386 bool setflags; 3387 switch (encoding) { 3388 case eEncodingT1: 3389 Rd = Bits32(opcode, 2, 0); 3390 Rn = Rd; 3391 Rm = Bits32(opcode, 5, 3); 3392 setflags = !InITBlock(); 3393 break; 3394 case eEncodingT2: 3395 Rd = Bits32(opcode, 11, 8); 3396 Rn = Bits32(opcode, 19, 16); 3397 Rm = Bits32(opcode, 3, 0); 3398 setflags = BitIsSet(opcode, 20); 3399 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3400 return false; 3401 break; 3402 case eEncodingA1: 3403 Rd = Bits32(opcode, 15, 12); 3404 Rn = Bits32(opcode, 3, 0); 3405 Rm = Bits32(opcode, 11, 8); 3406 setflags = BitIsSet(opcode, 20); 3407 if (Rd == 15 || Rn == 15 || Rm == 15) 3408 return false; 3409 break; 3410 default: 3411 return false; 3412 } 3413 3414 // Get the first operand. 3415 uint32_t value = ReadCoreReg (Rn, &success); 3416 if (!success) 3417 return false; 3418 // Get the Rm register content. 3419 uint32_t val = ReadCoreReg (Rm, &success); 3420 if (!success) 3421 return false; 3422 3423 // Get the shift amount. 3424 uint32_t amt = Bits32(val, 7, 0); 3425 3426 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3427 if (!success) 3428 return false; 3429 3430 // The context specifies that an immediate is to be moved into Rd. 3431 EmulateInstruction::Context context; 3432 context.type = EmulateInstruction::eContextImmediate; 3433 context.SetNoArgs (); 3434 3435 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3436 return false; 3437 } 3438 return true; 3439 } 3440 3441 // LDM loads multiple registers from consecutive memory locations, using an 3442 // address from a base register. Optionally the address just above the highest of those locations 3443 // can be written back to the base register. 3444 bool 3445 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3446 { 3447 #if 0 3448 // ARM pseudo code... 3449 if ConditionPassed() 3450 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3451 address = R[n]; 3452 3453 for i = 0 to 14 3454 if registers<i> == '1' then 3455 R[i] = MemA[address, 4]; address = address + 4; 3456 if registers<15> == '1' then 3457 LoadWritePC (MemA[address, 4]); 3458 3459 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3460 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3461 3462 #endif 3463 3464 bool success = false; 3465 bool conditional = false; 3466 if (ConditionPassed(opcode, &conditional)) 3467 { 3468 uint32_t n; 3469 uint32_t registers = 0; 3470 bool wback; 3471 const uint32_t addr_byte_size = GetAddressByteSize(); 3472 switch (encoding) 3473 { 3474 case eEncodingT1: 3475 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3476 n = Bits32 (opcode, 10, 8); 3477 registers = Bits32 (opcode, 7, 0); 3478 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3479 wback = BitIsClear (registers, n); 3480 // if BitCount(registers) < 1 then UNPREDICTABLE; 3481 if (BitCount(registers) < 1) 3482 return false; 3483 break; 3484 case eEncodingT2: 3485 // if W == '1' && Rn == '1101' then SEE POP; 3486 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3487 n = Bits32 (opcode, 19, 16); 3488 registers = Bits32 (opcode, 15, 0); 3489 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3490 wback = BitIsSet (opcode, 21); 3491 3492 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3493 if ((n == 15) 3494 || (BitCount (registers) < 2) 3495 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3496 return false; 3497 3498 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3499 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3500 return false; 3501 3502 // if wback && registers<n> == '1' then UNPREDICTABLE; 3503 if (wback 3504 && BitIsSet (registers, n)) 3505 return false; 3506 break; 3507 3508 case eEncodingA1: 3509 n = Bits32 (opcode, 19, 16); 3510 registers = Bits32 (opcode, 15, 0); 3511 wback = BitIsSet (opcode, 21); 3512 if ((n == 15) 3513 || (BitCount (registers) < 1)) 3514 return false; 3515 break; 3516 default: 3517 return false; 3518 } 3519 3520 int32_t offset = 0; 3521 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3522 if (!success) 3523 return false; 3524 3525 EmulateInstruction::Context context; 3526 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3527 RegisterInfo dwarf_reg; 3528 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3529 context.SetRegisterPlusOffset (dwarf_reg, offset); 3530 3531 for (int i = 0; i < 14; ++i) 3532 { 3533 if (BitIsSet (registers, i)) 3534 { 3535 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3536 context.SetRegisterPlusOffset (dwarf_reg, offset); 3537 if (wback && (n == 13)) // Pop Instruction 3538 { 3539 if (conditional) 3540 context.type = EmulateInstruction::eContextRegisterLoad; 3541 else 3542 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3543 } 3544 3545 // R[i] = MemA [address, 4]; address = address + 4; 3546 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3547 if (!success) 3548 return false; 3549 3550 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3551 return false; 3552 3553 offset += addr_byte_size; 3554 } 3555 } 3556 3557 if (BitIsSet (registers, 15)) 3558 { 3559 //LoadWritePC (MemA [address, 4]); 3560 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3561 context.SetRegisterPlusOffset (dwarf_reg, offset); 3562 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3563 if (!success) 3564 return false; 3565 // In ARMv5T and above, this is an interworking branch. 3566 if (!LoadWritePC(context, data)) 3567 return false; 3568 } 3569 3570 if (wback && BitIsClear (registers, n)) 3571 { 3572 // R[n] = R[n] + 4 * BitCount (registers) 3573 int32_t offset = addr_byte_size * BitCount (registers); 3574 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3575 context.SetRegisterPlusOffset (dwarf_reg, offset); 3576 3577 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3578 return false; 3579 } 3580 if (wback && BitIsSet (registers, n)) 3581 // R[n] bits(32) UNKNOWN; 3582 return WriteBits32Unknown (n); 3583 } 3584 return true; 3585 } 3586 3587 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3588 // The consecutive memory locations end at this address and the address just below the lowest of those locations 3589 // can optionally be written back to the base register. 3590 bool 3591 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3592 { 3593 #if 0 3594 // ARM pseudo code... 3595 if ConditionPassed() then 3596 EncodingSpecificOperations(); 3597 address = R[n] - 4*BitCount(registers) + 4; 3598 3599 for i = 0 to 14 3600 if registers<i> == '1' then 3601 R[i] = MemA[address,4]; address = address + 4; 3602 3603 if registers<15> == '1' then 3604 LoadWritePC(MemA[address,4]); 3605 3606 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3607 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3608 #endif 3609 3610 bool success = false; 3611 3612 if (ConditionPassed(opcode)) 3613 { 3614 uint32_t n; 3615 uint32_t registers = 0; 3616 bool wback; 3617 const uint32_t addr_byte_size = GetAddressByteSize(); 3618 3619 // EncodingSpecificOperations(); 3620 switch (encoding) 3621 { 3622 case eEncodingA1: 3623 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3624 n = Bits32 (opcode, 19, 16); 3625 registers = Bits32 (opcode, 15, 0); 3626 wback = BitIsSet (opcode, 21); 3627 3628 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3629 if ((n == 15) || (BitCount (registers) < 1)) 3630 return false; 3631 3632 break; 3633 3634 default: 3635 return false; 3636 } 3637 // address = R[n] - 4*BitCount(registers) + 4; 3638 3639 int32_t offset = 0; 3640 addr_t Rn = ReadCoreReg (n, &success); 3641 3642 if (!success) 3643 return false; 3644 3645 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3646 3647 EmulateInstruction::Context context; 3648 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3649 RegisterInfo dwarf_reg; 3650 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3651 context.SetRegisterPlusOffset (dwarf_reg, offset); 3652 3653 // for i = 0 to 14 3654 for (int i = 0; i < 14; ++i) 3655 { 3656 // if registers<i> == '1' then 3657 if (BitIsSet (registers, i)) 3658 { 3659 // R[i] = MemA[address,4]; address = address + 4; 3660 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3661 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3662 if (!success) 3663 return false; 3664 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3665 return false; 3666 offset += addr_byte_size; 3667 } 3668 } 3669 3670 // if registers<15> == '1' then 3671 // LoadWritePC(MemA[address,4]); 3672 if (BitIsSet (registers, 15)) 3673 { 3674 context.SetRegisterPlusOffset (dwarf_reg, offset); 3675 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3676 if (!success) 3677 return false; 3678 // In ARMv5T and above, this is an interworking branch. 3679 if (!LoadWritePC(context, data)) 3680 return false; 3681 } 3682 3683 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3684 if (wback && BitIsClear (registers, n)) 3685 { 3686 if (!success) 3687 return false; 3688 3689 offset = (addr_byte_size * BitCount (registers)) * -1; 3690 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3691 context.SetImmediateSigned (offset); 3692 addr_t addr = Rn + offset; 3693 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3694 return false; 3695 } 3696 3697 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3698 if (wback && BitIsSet (registers, n)) 3699 return WriteBits32Unknown (n); 3700 } 3701 return true; 3702 } 3703 3704 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3705 // consecutive memory locations end just below this address, and the address of the lowest of those locations can 3706 // be optionally written back to the base register. 3707 bool 3708 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3709 { 3710 #if 0 3711 // ARM pseudo code... 3712 if ConditionPassed() then 3713 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3714 address = R[n] - 4*BitCount(registers); 3715 3716 for i = 0 to 14 3717 if registers<i> == '1' then 3718 R[i] = MemA[address,4]; address = address + 4; 3719 if registers<15> == '1' then 3720 LoadWritePC(MemA[address,4]); 3721 3722 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3723 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3724 #endif 3725 3726 bool success = false; 3727 3728 if (ConditionPassed(opcode)) 3729 { 3730 uint32_t n; 3731 uint32_t registers = 0; 3732 bool wback; 3733 const uint32_t addr_byte_size = GetAddressByteSize(); 3734 switch (encoding) 3735 { 3736 case eEncodingT1: 3737 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3738 n = Bits32 (opcode, 19, 16); 3739 registers = Bits32 (opcode, 15, 0); 3740 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3741 wback = BitIsSet (opcode, 21); 3742 3743 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3744 if ((n == 15) 3745 || (BitCount (registers) < 2) 3746 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3747 return false; 3748 3749 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3750 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3751 return false; 3752 3753 // if wback && registers<n> == '1' then UNPREDICTABLE; 3754 if (wback && BitIsSet (registers, n)) 3755 return false; 3756 3757 break; 3758 3759 case eEncodingA1: 3760 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3761 n = Bits32 (opcode, 19, 16); 3762 registers = Bits32 (opcode, 15, 0); 3763 wback = BitIsSet (opcode, 21); 3764 3765 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3766 if ((n == 15) || (BitCount (registers) < 1)) 3767 return false; 3768 3769 break; 3770 3771 default: 3772 return false; 3773 } 3774 3775 // address = R[n] - 4*BitCount(registers); 3776 3777 int32_t offset = 0; 3778 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3779 3780 if (!success) 3781 return false; 3782 3783 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3784 EmulateInstruction::Context context; 3785 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3786 RegisterInfo dwarf_reg; 3787 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3788 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3789 3790 for (int i = 0; i < 14; ++i) 3791 { 3792 if (BitIsSet (registers, i)) 3793 { 3794 // R[i] = MemA[address,4]; address = address + 4; 3795 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3796 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3797 if (!success) 3798 return false; 3799 3800 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3801 return false; 3802 3803 offset += addr_byte_size; 3804 } 3805 } 3806 3807 // if registers<15> == '1' then 3808 // LoadWritePC(MemA[address,4]); 3809 if (BitIsSet (registers, 15)) 3810 { 3811 context.SetRegisterPlusOffset (dwarf_reg, offset); 3812 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3813 if (!success) 3814 return false; 3815 // In ARMv5T and above, this is an interworking branch. 3816 if (!LoadWritePC(context, data)) 3817 return false; 3818 } 3819 3820 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3821 if (wback && BitIsClear (registers, n)) 3822 { 3823 if (!success) 3824 return false; 3825 3826 offset = (addr_byte_size * BitCount (registers)) * -1; 3827 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3828 context.SetImmediateSigned (offset); 3829 addr_t addr = Rn + offset; 3830 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3831 return false; 3832 } 3833 3834 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3835 if (wback && BitIsSet (registers, n)) 3836 return WriteBits32Unknown (n); 3837 } 3838 return true; 3839 } 3840 3841 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3842 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3843 // optinoally be written back to the base register. 3844 bool 3845 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3846 { 3847 #if 0 3848 if ConditionPassed() then 3849 EncodingSpecificOperations(); 3850 address = R[n] + 4; 3851 3852 for i = 0 to 14 3853 if registers<i> == '1' then 3854 R[i] = MemA[address,4]; address = address + 4; 3855 if registers<15> == '1' then 3856 LoadWritePC(MemA[address,4]); 3857 3858 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3859 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3860 #endif 3861 3862 bool success = false; 3863 3864 if (ConditionPassed(opcode)) 3865 { 3866 uint32_t n; 3867 uint32_t registers = 0; 3868 bool wback; 3869 const uint32_t addr_byte_size = GetAddressByteSize(); 3870 switch (encoding) 3871 { 3872 case eEncodingA1: 3873 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3874 n = Bits32 (opcode, 19, 16); 3875 registers = Bits32 (opcode, 15, 0); 3876 wback = BitIsSet (opcode, 21); 3877 3878 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3879 if ((n == 15) || (BitCount (registers) < 1)) 3880 return false; 3881 3882 break; 3883 default: 3884 return false; 3885 } 3886 // address = R[n] + 4; 3887 3888 int32_t offset = 0; 3889 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3890 3891 if (!success) 3892 return false; 3893 3894 addr_t address = Rn + addr_byte_size; 3895 3896 EmulateInstruction::Context context; 3897 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3898 RegisterInfo dwarf_reg; 3899 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3900 context.SetRegisterPlusOffset (dwarf_reg, offset); 3901 3902 for (int i = 0; i < 14; ++i) 3903 { 3904 if (BitIsSet (registers, i)) 3905 { 3906 // R[i] = MemA[address,4]; address = address + 4; 3907 3908 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3909 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3910 if (!success) 3911 return false; 3912 3913 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3914 return false; 3915 3916 offset += addr_byte_size; 3917 } 3918 } 3919 3920 // if registers<15> == '1' then 3921 // LoadWritePC(MemA[address,4]); 3922 if (BitIsSet (registers, 15)) 3923 { 3924 context.SetRegisterPlusOffset (dwarf_reg, offset); 3925 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3926 if (!success) 3927 return false; 3928 // In ARMv5T and above, this is an interworking branch. 3929 if (!LoadWritePC(context, data)) 3930 return false; 3931 } 3932 3933 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3934 if (wback && BitIsClear (registers, n)) 3935 { 3936 if (!success) 3937 return false; 3938 3939 offset = addr_byte_size * BitCount (registers); 3940 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3941 context.SetImmediateSigned (offset); 3942 addr_t addr = Rn + offset; 3943 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3944 return false; 3945 } 3946 3947 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3948 if (wback && BitIsSet (registers, n)) 3949 return WriteBits32Unknown (n); 3950 } 3951 return true; 3952 } 3953 3954 // Load Register (immediate) calculates an address from a base register value and 3955 // an immediate offset, loads a word from memory, and writes to a register. 3956 // LDR (immediate, Thumb) 3957 bool 3958 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3959 { 3960 #if 0 3961 // ARM pseudo code... 3962 if (ConditionPassed()) 3963 { 3964 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3965 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3966 address = if index then offset_addr else R[n]; 3967 data = MemU[address,4]; 3968 if wback then R[n] = offset_addr; 3969 if t == 15 then 3970 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3971 elsif UnalignedSupport() || address<1:0> = '00' then 3972 R[t] = data; 3973 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3974 } 3975 #endif 3976 3977 bool success = false; 3978 3979 if (ConditionPassed(opcode)) 3980 { 3981 uint32_t Rt; // the destination register 3982 uint32_t Rn; // the base register 3983 uint32_t imm32; // the immediate offset used to form the address 3984 addr_t offset_addr; // the offset address 3985 addr_t address; // the calculated address 3986 uint32_t data; // the literal data value from memory load 3987 bool add, index, wback; 3988 switch (encoding) { 3989 case eEncodingT1: 3990 Rt = Bits32(opcode, 2, 0); 3991 Rn = Bits32(opcode, 5, 3); 3992 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3993 // index = TRUE; add = TRUE; wback = FALSE 3994 add = true; 3995 index = true; 3996 wback = false; 3997 3998 break; 3999 4000 case eEncodingT2: 4001 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4002 Rt = Bits32 (opcode, 10, 8); 4003 Rn = 13; 4004 imm32 = Bits32 (opcode, 7, 0) << 2; 4005 4006 // index = TRUE; add = TRUE; wback = FALSE; 4007 index = true; 4008 add = true; 4009 wback = false; 4010 4011 break; 4012 4013 case eEncodingT3: 4014 // if Rn == '1111' then SEE LDR (literal); 4015 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4016 Rt = Bits32 (opcode, 15, 12); 4017 Rn = Bits32 (opcode, 19, 16); 4018 imm32 = Bits32 (opcode, 11, 0); 4019 4020 // index = TRUE; add = TRUE; wback = FALSE; 4021 index = true; 4022 add = true; 4023 wback = false; 4024 4025 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4026 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4027 return false; 4028 4029 break; 4030 4031 case eEncodingT4: 4032 // if Rn == '1111' then SEE LDR (literal); 4033 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4034 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 4035 // if P == '0' && W == '0' then UNDEFINED; 4036 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 4037 return false; 4038 4039 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4040 Rt = Bits32 (opcode, 15, 12); 4041 Rn = Bits32 (opcode, 19, 16); 4042 imm32 = Bits32 (opcode, 7, 0); 4043 4044 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4045 index = BitIsSet (opcode, 10); 4046 add = BitIsSet (opcode, 9); 4047 wback = BitIsSet (opcode, 8); 4048 4049 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 4050 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 4051 return false; 4052 4053 break; 4054 4055 default: 4056 return false; 4057 } 4058 uint32_t base = ReadCoreReg (Rn, &success); 4059 if (!success) 4060 return false; 4061 if (add) 4062 offset_addr = base + imm32; 4063 else 4064 offset_addr = base - imm32; 4065 4066 address = (index ? offset_addr : base); 4067 4068 RegisterInfo base_reg; 4069 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4070 if (wback) 4071 { 4072 EmulateInstruction::Context ctx; 4073 if (Rn == 13) 4074 { 4075 ctx.type = eContextAdjustStackPointer; 4076 ctx.SetImmediateSigned((int32_t) (offset_addr - base)); 4077 } 4078 else if (Rn == GetFramePointerRegisterNumber()) 4079 { 4080 ctx.type = eContextSetFramePointer; 4081 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4082 } 4083 else 4084 { 4085 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4086 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4087 } 4088 4089 4090 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 4091 return false; 4092 } 4093 4094 // Prepare to write to the Rt register. 4095 EmulateInstruction::Context context; 4096 context.type = EmulateInstruction::eContextRegisterLoad; 4097 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4098 4099 // Read memory from the address. 4100 data = MemURead(context, address, 4, 0, &success); 4101 if (!success) 4102 return false; 4103 4104 if (Rt == 15) 4105 { 4106 if (Bits32(address, 1, 0) == 0) 4107 { 4108 if (!LoadWritePC(context, data)) 4109 return false; 4110 } 4111 else 4112 return false; 4113 } 4114 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 4115 { 4116 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 4117 return false; 4118 } 4119 else 4120 WriteBits32Unknown (Rt); 4121 } 4122 return true; 4123 } 4124 4125 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 4126 // from a base register. The consecutive memory locations start at this address, and the address just above the last 4127 // of those locations can optionally be written back to the base register. 4128 bool 4129 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 4130 { 4131 #if 0 4132 if ConditionPassed() then 4133 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4134 address = R[n]; 4135 4136 for i = 0 to 14 4137 if registers<i> == '1' then 4138 if i == n && wback && i != LowestSetBit(registers) then 4139 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4140 else 4141 MemA[address,4] = R[i]; 4142 address = address + 4; 4143 4144 if registers<15> == '1' then // Only possible for encoding A1 4145 MemA[address,4] = PCStoreValue(); 4146 if wback then R[n] = R[n] + 4*BitCount(registers); 4147 #endif 4148 4149 bool success = false; 4150 4151 if (ConditionPassed(opcode)) 4152 { 4153 uint32_t n; 4154 uint32_t registers = 0; 4155 bool wback; 4156 const uint32_t addr_byte_size = GetAddressByteSize(); 4157 4158 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4159 switch (encoding) 4160 { 4161 case eEncodingT1: 4162 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4163 n = Bits32 (opcode, 10, 8); 4164 registers = Bits32 (opcode, 7, 0); 4165 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4166 wback = true; 4167 4168 // if BitCount(registers) < 1 then UNPREDICTABLE; 4169 if (BitCount (registers) < 1) 4170 return false; 4171 4172 break; 4173 4174 case eEncodingT2: 4175 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4176 n = Bits32 (opcode, 19, 16); 4177 registers = Bits32 (opcode, 15, 0); 4178 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4179 wback = BitIsSet (opcode, 21); 4180 4181 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4182 if ((n == 15) || (BitCount (registers) < 2)) 4183 return false; 4184 4185 // if wback && registers<n> == '1' then UNPREDICTABLE; 4186 if (wback && BitIsSet (registers, n)) 4187 return false; 4188 4189 break; 4190 4191 case eEncodingA1: 4192 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4193 n = Bits32 (opcode, 19, 16); 4194 registers = Bits32 (opcode, 15, 0); 4195 wback = BitIsSet (opcode, 21); 4196 4197 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4198 if ((n == 15) || (BitCount (registers) < 1)) 4199 return false; 4200 4201 break; 4202 4203 default: 4204 return false; 4205 } 4206 4207 // address = R[n]; 4208 int32_t offset = 0; 4209 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4210 if (!success) 4211 return false; 4212 4213 EmulateInstruction::Context context; 4214 context.type = EmulateInstruction::eContextRegisterStore; 4215 RegisterInfo base_reg; 4216 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4217 4218 // for i = 0 to 14 4219 uint32_t lowest_set_bit = 14; 4220 for (uint32_t i = 0; i < 14; ++i) 4221 { 4222 // if registers<i> == '1' then 4223 if (BitIsSet (registers, i)) 4224 { 4225 if (i < lowest_set_bit) 4226 lowest_set_bit = i; 4227 // if i == n && wback && i != LowestSetBit(registers) then 4228 if ((i == n) && wback && (i != lowest_set_bit)) 4229 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4230 WriteBits32UnknownToMemory (address + offset); 4231 else 4232 { 4233 // MemA[address,4] = R[i]; 4234 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4235 if (!success) 4236 return false; 4237 4238 RegisterInfo data_reg; 4239 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4240 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4241 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4242 return false; 4243 } 4244 4245 // address = address + 4; 4246 offset += addr_byte_size; 4247 } 4248 } 4249 4250 // if registers<15> == '1' then // Only possible for encoding A1 4251 // MemA[address,4] = PCStoreValue(); 4252 if (BitIsSet (registers, 15)) 4253 { 4254 RegisterInfo pc_reg; 4255 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4256 context.SetRegisterPlusOffset (pc_reg, 8); 4257 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4258 if (!success) 4259 return false; 4260 4261 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4262 return false; 4263 } 4264 4265 // if wback then R[n] = R[n] + 4*BitCount(registers); 4266 if (wback) 4267 { 4268 offset = addr_byte_size * BitCount (registers); 4269 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4270 context.SetImmediateSigned (offset); 4271 addr_t data = address + offset; 4272 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4273 return false; 4274 } 4275 } 4276 return true; 4277 } 4278 4279 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4280 // from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4281 // of those locations can optionally be written back to the base register. 4282 bool 4283 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4284 { 4285 #if 0 4286 if ConditionPassed() then 4287 EncodingSpecificOperations(); 4288 address = R[n] - 4*BitCount(registers) + 4; 4289 4290 for i = 0 to 14 4291 if registers<i> == '1' then 4292 if i == n && wback && i != LowestSetBit(registers) then 4293 MemA[address,4] = bits(32) UNKNOWN; 4294 else 4295 MemA[address,4] = R[i]; 4296 address = address + 4; 4297 4298 if registers<15> == '1' then 4299 MemA[address,4] = PCStoreValue(); 4300 4301 if wback then R[n] = R[n] - 4*BitCount(registers); 4302 #endif 4303 4304 bool success = false; 4305 4306 if (ConditionPassed(opcode)) 4307 { 4308 uint32_t n; 4309 uint32_t registers = 0; 4310 bool wback; 4311 const uint32_t addr_byte_size = GetAddressByteSize(); 4312 4313 // EncodingSpecificOperations(); 4314 switch (encoding) 4315 { 4316 case eEncodingA1: 4317 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4318 n = Bits32 (opcode, 19, 16); 4319 registers = Bits32 (opcode, 15, 0); 4320 wback = BitIsSet (opcode, 21); 4321 4322 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4323 if ((n == 15) || (BitCount (registers) < 1)) 4324 return false; 4325 break; 4326 default: 4327 return false; 4328 } 4329 4330 // address = R[n] - 4*BitCount(registers) + 4; 4331 int32_t offset = 0; 4332 addr_t Rn = ReadCoreReg (n, &success); 4333 if (!success) 4334 return false; 4335 4336 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4337 4338 EmulateInstruction::Context context; 4339 context.type = EmulateInstruction::eContextRegisterStore; 4340 RegisterInfo base_reg; 4341 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4342 4343 // for i = 0 to 14 4344 uint32_t lowest_bit_set = 14; 4345 for (uint32_t i = 0; i < 14; ++i) 4346 { 4347 // if registers<i> == '1' then 4348 if (BitIsSet (registers, i)) 4349 { 4350 if (i < lowest_bit_set) 4351 lowest_bit_set = i; 4352 //if i == n && wback && i != LowestSetBit(registers) then 4353 if ((i == n) && wback && (i != lowest_bit_set)) 4354 // MemA[address,4] = bits(32) UNKNOWN; 4355 WriteBits32UnknownToMemory (address + offset); 4356 else 4357 { 4358 // MemA[address,4] = R[i]; 4359 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4360 if (!success) 4361 return false; 4362 4363 RegisterInfo data_reg; 4364 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4365 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4366 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4367 return false; 4368 } 4369 4370 // address = address + 4; 4371 offset += addr_byte_size; 4372 } 4373 } 4374 4375 // if registers<15> == '1' then 4376 // MemA[address,4] = PCStoreValue(); 4377 if (BitIsSet (registers, 15)) 4378 { 4379 RegisterInfo pc_reg; 4380 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4381 context.SetRegisterPlusOffset (pc_reg, 8); 4382 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4383 if (!success) 4384 return false; 4385 4386 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4387 return false; 4388 } 4389 4390 // if wback then R[n] = R[n] - 4*BitCount(registers); 4391 if (wback) 4392 { 4393 offset = (addr_byte_size * BitCount (registers)) * -1; 4394 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4395 context.SetImmediateSigned (offset); 4396 addr_t data = Rn + offset; 4397 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4398 return false; 4399 } 4400 } 4401 return true; 4402 } 4403 4404 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4405 // from a base register. The consecutive memory locations end just below this address, and the address of the first of 4406 // those locations can optionally be written back to the base register. 4407 bool 4408 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4409 { 4410 #if 0 4411 if ConditionPassed() then 4412 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4413 address = R[n] - 4*BitCount(registers); 4414 4415 for i = 0 to 14 4416 if registers<i> == '1' then 4417 if i == n && wback && i != LowestSetBit(registers) then 4418 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4419 else 4420 MemA[address,4] = R[i]; 4421 address = address + 4; 4422 4423 if registers<15> == '1' then // Only possible for encoding A1 4424 MemA[address,4] = PCStoreValue(); 4425 4426 if wback then R[n] = R[n] - 4*BitCount(registers); 4427 #endif 4428 4429 4430 bool success = false; 4431 4432 if (ConditionPassed(opcode)) 4433 { 4434 uint32_t n; 4435 uint32_t registers = 0; 4436 bool wback; 4437 const uint32_t addr_byte_size = GetAddressByteSize(); 4438 4439 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4440 switch (encoding) 4441 { 4442 case eEncodingT1: 4443 // if W == '1' && Rn == '1101' then SEE PUSH; 4444 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4445 { 4446 // See PUSH 4447 } 4448 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4449 n = Bits32 (opcode, 19, 16); 4450 registers = Bits32 (opcode, 15, 0); 4451 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4452 wback = BitIsSet (opcode, 21); 4453 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4454 if ((n == 15) || BitCount (registers) < 2) 4455 return false; 4456 // if wback && registers<n> == '1' then UNPREDICTABLE; 4457 if (wback && BitIsSet (registers, n)) 4458 return false; 4459 break; 4460 4461 case eEncodingA1: 4462 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH; 4463 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4464 { 4465 // See Push 4466 } 4467 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4468 n = Bits32 (opcode, 19, 16); 4469 registers = Bits32 (opcode, 15, 0); 4470 wback = BitIsSet (opcode, 21); 4471 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4472 if ((n == 15) || BitCount (registers) < 1) 4473 return false; 4474 break; 4475 4476 default: 4477 return false; 4478 } 4479 4480 // address = R[n] - 4*BitCount(registers); 4481 4482 int32_t offset = 0; 4483 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4484 if (!success) 4485 return false; 4486 4487 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4488 4489 EmulateInstruction::Context context; 4490 context.type = EmulateInstruction::eContextRegisterStore; 4491 RegisterInfo base_reg; 4492 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4493 4494 // for i = 0 to 14 4495 uint32_t lowest_set_bit = 14; 4496 for (uint32_t i = 0; i < 14; ++i) 4497 { 4498 // if registers<i> == '1' then 4499 if (BitIsSet (registers, i)) 4500 { 4501 if (i < lowest_set_bit) 4502 lowest_set_bit = i; 4503 // if i == n && wback && i != LowestSetBit(registers) then 4504 if ((i == n) && wback && (i != lowest_set_bit)) 4505 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4506 WriteBits32UnknownToMemory (address + offset); 4507 else 4508 { 4509 // MemA[address,4] = R[i]; 4510 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4511 if (!success) 4512 return false; 4513 4514 RegisterInfo data_reg; 4515 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4516 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4517 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4518 return false; 4519 } 4520 4521 // address = address + 4; 4522 offset += addr_byte_size; 4523 } 4524 } 4525 4526 // if registers<15> == '1' then // Only possible for encoding A1 4527 // MemA[address,4] = PCStoreValue(); 4528 if (BitIsSet (registers, 15)) 4529 { 4530 RegisterInfo pc_reg; 4531 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4532 context.SetRegisterPlusOffset (pc_reg, 8); 4533 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4534 if (!success) 4535 return false; 4536 4537 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4538 return false; 4539 } 4540 4541 // if wback then R[n] = R[n] - 4*BitCount(registers); 4542 if (wback) 4543 { 4544 offset = (addr_byte_size * BitCount (registers)) * -1; 4545 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4546 context.SetImmediateSigned (offset); 4547 addr_t data = Rn + offset; 4548 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4549 return false; 4550 } 4551 } 4552 return true; 4553 } 4554 4555 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4556 // from a base register. The consecutive memory locations start just above this address, and the address of the last 4557 // of those locations can optionally be written back to the base register. 4558 bool 4559 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4560 { 4561 #if 0 4562 if ConditionPassed() then 4563 EncodingSpecificOperations(); 4564 address = R[n] + 4; 4565 4566 for i = 0 to 14 4567 if registers<i> == '1' then 4568 if i == n && wback && i != LowestSetBit(registers) then 4569 MemA[address,4] = bits(32) UNKNOWN; 4570 else 4571 MemA[address,4] = R[i]; 4572 address = address + 4; 4573 4574 if registers<15> == '1' then 4575 MemA[address,4] = PCStoreValue(); 4576 4577 if wback then R[n] = R[n] + 4*BitCount(registers); 4578 #endif 4579 4580 bool success = false; 4581 4582 if (ConditionPassed(opcode)) 4583 { 4584 uint32_t n; 4585 uint32_t registers = 0; 4586 bool wback; 4587 const uint32_t addr_byte_size = GetAddressByteSize(); 4588 4589 // EncodingSpecificOperations(); 4590 switch (encoding) 4591 { 4592 case eEncodingA1: 4593 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4594 n = Bits32 (opcode, 19, 16); 4595 registers = Bits32 (opcode, 15, 0); 4596 wback = BitIsSet (opcode, 21); 4597 4598 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4599 if ((n == 15) && (BitCount (registers) < 1)) 4600 return false; 4601 break; 4602 default: 4603 return false; 4604 } 4605 // address = R[n] + 4; 4606 4607 int32_t offset = 0; 4608 addr_t Rn = ReadCoreReg (n, &success); 4609 if (!success) 4610 return false; 4611 4612 addr_t address = Rn + addr_byte_size; 4613 4614 EmulateInstruction::Context context; 4615 context.type = EmulateInstruction::eContextRegisterStore; 4616 RegisterInfo base_reg; 4617 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4618 4619 uint32_t lowest_set_bit = 14; 4620 // for i = 0 to 14 4621 for (uint32_t i = 0; i < 14; ++i) 4622 { 4623 // if registers<i> == '1' then 4624 if (BitIsSet (registers, i)) 4625 { 4626 if (i < lowest_set_bit) 4627 lowest_set_bit = i; 4628 // if i == n && wback && i != LowestSetBit(registers) then 4629 if ((i == n) && wback && (i != lowest_set_bit)) 4630 // MemA[address,4] = bits(32) UNKNOWN; 4631 WriteBits32UnknownToMemory (address + offset); 4632 // else 4633 else 4634 { 4635 // MemA[address,4] = R[i]; 4636 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4637 if (!success) 4638 return false; 4639 4640 RegisterInfo data_reg; 4641 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4642 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4643 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4644 return false; 4645 } 4646 4647 // address = address + 4; 4648 offset += addr_byte_size; 4649 } 4650 } 4651 4652 // if registers<15> == '1' then 4653 // MemA[address,4] = PCStoreValue(); 4654 if (BitIsSet (registers, 15)) 4655 { 4656 RegisterInfo pc_reg; 4657 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4658 context.SetRegisterPlusOffset (pc_reg, 8); 4659 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4660 if (!success) 4661 return false; 4662 4663 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4664 return false; 4665 } 4666 4667 // if wback then R[n] = R[n] + 4*BitCount(registers); 4668 if (wback) 4669 { 4670 offset = addr_byte_size * BitCount (registers); 4671 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4672 context.SetImmediateSigned (offset); 4673 addr_t data = Rn + offset; 4674 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4675 return false; 4676 } 4677 } 4678 return true; 4679 } 4680 4681 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word 4682 // from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4683 bool 4684 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4685 { 4686 #if 0 4687 if ConditionPassed() then 4688 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4689 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4690 address = if index then offset_addr else R[n]; 4691 if UnalignedSupport() || address<1:0> == '00' then 4692 MemU[address,4] = R[t]; 4693 else // Can only occur before ARMv7 4694 MemU[address,4] = bits(32) UNKNOWN; 4695 if wback then R[n] = offset_addr; 4696 #endif 4697 4698 bool success = false; 4699 4700 if (ConditionPassed(opcode)) 4701 { 4702 const uint32_t addr_byte_size = GetAddressByteSize(); 4703 4704 uint32_t t; 4705 uint32_t n; 4706 uint32_t imm32; 4707 bool index; 4708 bool add; 4709 bool wback; 4710 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4711 switch (encoding) 4712 { 4713 case eEncodingT1: 4714 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4715 t = Bits32 (opcode, 2, 0); 4716 n = Bits32 (opcode, 5, 3); 4717 imm32 = Bits32 (opcode, 10, 6) << 2; 4718 4719 // index = TRUE; add = TRUE; wback = FALSE; 4720 index = true; 4721 add = false; 4722 wback = false; 4723 break; 4724 4725 case eEncodingT2: 4726 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4727 t = Bits32 (opcode, 10, 8); 4728 n = 13; 4729 imm32 = Bits32 (opcode, 7, 0) << 2; 4730 4731 // index = TRUE; add = TRUE; wback = FALSE; 4732 index = true; 4733 add = true; 4734 wback = false; 4735 break; 4736 4737 case eEncodingT3: 4738 // if Rn == '1111' then UNDEFINED; 4739 if (Bits32 (opcode, 19, 16) == 15) 4740 return false; 4741 4742 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4743 t = Bits32 (opcode, 15, 12); 4744 n = Bits32 (opcode, 19, 16); 4745 imm32 = Bits32 (opcode, 11, 0); 4746 4747 // index = TRUE; add = TRUE; wback = FALSE; 4748 index = true; 4749 add = true; 4750 wback = false; 4751 4752 // if t == 15 then UNPREDICTABLE; 4753 if (t == 15) 4754 return false; 4755 break; 4756 4757 case eEncodingT4: 4758 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4759 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4760 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4761 if ((Bits32 (opcode, 19, 16) == 15) 4762 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4763 return false; 4764 4765 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4766 t = Bits32 (opcode, 15, 12); 4767 n = Bits32 (opcode, 19, 16); 4768 imm32 = Bits32 (opcode, 7, 0); 4769 4770 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4771 index = BitIsSet (opcode, 10); 4772 add = BitIsSet (opcode, 9); 4773 wback = BitIsSet (opcode, 8); 4774 4775 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4776 if ((t == 15) || (wback && (n == t))) 4777 return false; 4778 break; 4779 4780 default: 4781 return false; 4782 } 4783 4784 addr_t offset_addr; 4785 addr_t address; 4786 4787 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4788 uint32_t base_address = ReadCoreReg (n, &success); 4789 if (!success) 4790 return false; 4791 4792 if (add) 4793 offset_addr = base_address + imm32; 4794 else 4795 offset_addr = base_address - imm32; 4796 4797 // address = if index then offset_addr else R[n]; 4798 if (index) 4799 address = offset_addr; 4800 else 4801 address = base_address; 4802 4803 EmulateInstruction::Context context; 4804 context.type = eContextRegisterStore; 4805 RegisterInfo base_reg; 4806 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4807 4808 // if UnalignedSupport() || address<1:0> == '00' then 4809 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4810 { 4811 // MemU[address,4] = R[t]; 4812 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4813 if (!success) 4814 return false; 4815 4816 RegisterInfo data_reg; 4817 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4818 int32_t offset = address - base_address; 4819 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4820 if (!MemUWrite (context, address, data, addr_byte_size)) 4821 return false; 4822 } 4823 else 4824 { 4825 // MemU[address,4] = bits(32) UNKNOWN; 4826 WriteBits32UnknownToMemory (address); 4827 } 4828 4829 // if wback then R[n] = offset_addr; 4830 if (wback) 4831 { 4832 context.type = eContextRegisterLoad; 4833 context.SetAddress (offset_addr); 4834 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4835 return false; 4836 } 4837 } 4838 return true; 4839 } 4840 4841 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4842 // word from a register to memory. The offset register value can optionally be shifted. 4843 bool 4844 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4845 { 4846 #if 0 4847 if ConditionPassed() then 4848 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4849 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4850 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4851 address = if index then offset_addr else R[n]; 4852 if t == 15 then // Only possible for encoding A1 4853 data = PCStoreValue(); 4854 else 4855 data = R[t]; 4856 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4857 MemU[address,4] = data; 4858 else // Can only occur before ARMv7 4859 MemU[address,4] = bits(32) UNKNOWN; 4860 if wback then R[n] = offset_addr; 4861 #endif 4862 4863 bool success = false; 4864 4865 if (ConditionPassed(opcode)) 4866 { 4867 const uint32_t addr_byte_size = GetAddressByteSize(); 4868 4869 uint32_t t; 4870 uint32_t n; 4871 uint32_t m; 4872 ARM_ShifterType shift_t; 4873 uint32_t shift_n; 4874 bool index; 4875 bool add; 4876 bool wback; 4877 4878 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4879 switch (encoding) 4880 { 4881 case eEncodingT1: 4882 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4883 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4884 t = Bits32 (opcode, 2, 0); 4885 n = Bits32 (opcode, 5, 3); 4886 m = Bits32 (opcode, 8, 6); 4887 4888 // index = TRUE; add = TRUE; wback = FALSE; 4889 index = true; 4890 add = true; 4891 wback = false; 4892 4893 // (shift_t, shift_n) = (SRType_LSL, 0); 4894 shift_t = SRType_LSL; 4895 shift_n = 0; 4896 break; 4897 4898 case eEncodingT2: 4899 // if Rn == '1111' then UNDEFINED; 4900 if (Bits32 (opcode, 19, 16) == 15) 4901 return false; 4902 4903 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4904 t = Bits32 (opcode, 15, 12); 4905 n = Bits32 (opcode, 19, 16); 4906 m = Bits32 (opcode, 3, 0); 4907 4908 // index = TRUE; add = TRUE; wback = FALSE; 4909 index = true; 4910 add = true; 4911 wback = false; 4912 4913 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4914 shift_t = SRType_LSL; 4915 shift_n = Bits32 (opcode, 5, 4); 4916 4917 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4918 if ((t == 15) || (BadReg (m))) 4919 return false; 4920 break; 4921 4922 case eEncodingA1: 4923 { 4924 // if P == '0' && W == '1' then SEE STRT; 4925 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4926 t = Bits32 (opcode, 15, 12); 4927 n = Bits32 (opcode, 19, 16); 4928 m = Bits32 (opcode, 3, 0); 4929 4930 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4931 index = BitIsSet (opcode, 24); 4932 add = BitIsSet (opcode, 23); 4933 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4934 4935 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4936 uint32_t typ = Bits32 (opcode, 6, 5); 4937 uint32_t imm5 = Bits32 (opcode, 11, 7); 4938 shift_n = DecodeImmShift(typ, imm5, shift_t); 4939 4940 // if m == 15 then UNPREDICTABLE; 4941 if (m == 15) 4942 return false; 4943 4944 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4945 if (wback && ((n == 15) || (n == t))) 4946 return false; 4947 4948 break; 4949 } 4950 default: 4951 return false; 4952 } 4953 4954 addr_t offset_addr; 4955 addr_t address; 4956 int32_t offset = 0; 4957 4958 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4959 if (!success) 4960 return false; 4961 4962 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4963 if (!success) 4964 return false; 4965 4966 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4967 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4968 if (!success) 4969 return false; 4970 4971 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4972 if (add) 4973 offset_addr = base_address + offset; 4974 else 4975 offset_addr = base_address - offset; 4976 4977 // address = if index then offset_addr else R[n]; 4978 if (index) 4979 address = offset_addr; 4980 else 4981 address = base_address; 4982 4983 uint32_t data; 4984 // if t == 15 then // Only possible for encoding A1 4985 if (t == 15) 4986 // data = PCStoreValue(); 4987 data = ReadCoreReg (PC_REG, &success); 4988 else 4989 // data = R[t]; 4990 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4991 4992 if (!success) 4993 return false; 4994 4995 EmulateInstruction::Context context; 4996 context.type = eContextRegisterStore; 4997 4998 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4999 if (UnalignedSupport () 5000 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 5001 || CurrentInstrSet() == eModeARM) 5002 { 5003 // MemU[address,4] = data; 5004 5005 RegisterInfo base_reg; 5006 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5007 5008 RegisterInfo data_reg; 5009 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5010 5011 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5012 if (!MemUWrite (context, address, data, addr_byte_size)) 5013 return false; 5014 5015 } 5016 else 5017 // MemU[address,4] = bits(32) UNKNOWN; 5018 WriteBits32UnknownToMemory (address); 5019 5020 // if wback then R[n] = offset_addr; 5021 if (wback) 5022 { 5023 context.type = eContextRegisterLoad; 5024 context.SetAddress (offset_addr); 5025 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5026 return false; 5027 } 5028 5029 } 5030 return true; 5031 } 5032 5033 bool 5034 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 5035 { 5036 #if 0 5037 if ConditionPassed() then 5038 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5039 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5040 address = if index then offset_addr else R[n]; 5041 MemU[address,1] = R[t]<7:0>; 5042 if wback then R[n] = offset_addr; 5043 #endif 5044 5045 5046 bool success = false; 5047 5048 if (ConditionPassed(opcode)) 5049 { 5050 uint32_t t; 5051 uint32_t n; 5052 uint32_t imm32; 5053 bool index; 5054 bool add; 5055 bool wback; 5056 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5057 switch (encoding) 5058 { 5059 case eEncodingT1: 5060 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5061 t = Bits32 (opcode, 2, 0); 5062 n = Bits32 (opcode, 5, 3); 5063 imm32 = Bits32 (opcode, 10, 6); 5064 5065 // index = TRUE; add = TRUE; wback = FALSE; 5066 index = true; 5067 add = true; 5068 wback = false; 5069 break; 5070 5071 case eEncodingT2: 5072 // if Rn == '1111' then UNDEFINED; 5073 if (Bits32 (opcode, 19, 16) == 15) 5074 return false; 5075 5076 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5077 t = Bits32 (opcode, 15, 12); 5078 n = Bits32 (opcode, 19, 16); 5079 imm32 = Bits32 (opcode, 11, 0); 5080 5081 // index = TRUE; add = TRUE; wback = FALSE; 5082 index = true; 5083 add = true; 5084 wback = false; 5085 5086 // if BadReg(t) then UNPREDICTABLE; 5087 if (BadReg (t)) 5088 return false; 5089 break; 5090 5091 case eEncodingT3: 5092 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5093 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5094 if (Bits32 (opcode, 19, 16) == 15) 5095 return false; 5096 5097 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5098 t = Bits32 (opcode, 15, 12); 5099 n = Bits32 (opcode, 19, 16); 5100 imm32 = Bits32 (opcode, 7, 0); 5101 5102 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5103 index = BitIsSet (opcode, 10); 5104 add = BitIsSet (opcode, 9); 5105 wback = BitIsSet (opcode, 8); 5106 5107 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5108 if ((BadReg (t)) || (wback && (n == t))) 5109 return false; 5110 break; 5111 5112 default: 5113 return false; 5114 } 5115 5116 addr_t offset_addr; 5117 addr_t address; 5118 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5119 if (!success) 5120 return false; 5121 5122 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5123 if (add) 5124 offset_addr = base_address + imm32; 5125 else 5126 offset_addr = base_address - imm32; 5127 5128 // address = if index then offset_addr else R[n]; 5129 if (index) 5130 address = offset_addr; 5131 else 5132 address = base_address; 5133 5134 // MemU[address,1] = R[t]<7:0> 5135 RegisterInfo base_reg; 5136 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5137 5138 RegisterInfo data_reg; 5139 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5140 5141 EmulateInstruction::Context context; 5142 context.type = eContextRegisterStore; 5143 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5144 5145 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5146 if (!success) 5147 return false; 5148 5149 data = Bits32 (data, 7, 0); 5150 5151 if (!MemUWrite (context, address, data, 1)) 5152 return false; 5153 5154 // if wback then R[n] = offset_addr; 5155 if (wback) 5156 { 5157 context.type = eContextRegisterLoad; 5158 context.SetAddress (offset_addr); 5159 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5160 return false; 5161 } 5162 5163 } 5164 5165 return true; 5166 } 5167 5168 // STRH (register) calculates an address from a base register value and an offset register value, and stores a 5169 // halfword from a register to memory. The offset register value can be shifted left by 0, 1, 2, or 3 bits. 5170 bool 5171 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5172 { 5173 #if 0 5174 if ConditionPassed() then 5175 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5176 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5177 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5178 address = if index then offset_addr else R[n]; 5179 if UnalignedSupport() || address<0> == '0' then 5180 MemU[address,2] = R[t]<15:0>; 5181 else // Can only occur before ARMv7 5182 MemU[address,2] = bits(16) UNKNOWN; 5183 if wback then R[n] = offset_addr; 5184 #endif 5185 5186 bool success = false; 5187 5188 if (ConditionPassed(opcode)) 5189 { 5190 uint32_t t; 5191 uint32_t n; 5192 uint32_t m; 5193 bool index; 5194 bool add; 5195 bool wback; 5196 ARM_ShifterType shift_t; 5197 uint32_t shift_n; 5198 5199 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5200 switch (encoding) 5201 { 5202 case eEncodingT1: 5203 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5204 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5205 t = Bits32 (opcode, 2, 0); 5206 n = Bits32 (opcode, 5, 3); 5207 m = Bits32 (opcode, 8, 6); 5208 5209 // index = TRUE; add = TRUE; wback = FALSE; 5210 index = true; 5211 add = true; 5212 wback = false; 5213 5214 // (shift_t, shift_n) = (SRType_LSL, 0); 5215 shift_t = SRType_LSL; 5216 shift_n = 0; 5217 5218 break; 5219 5220 case eEncodingT2: 5221 // if Rn == '1111' then UNDEFINED; 5222 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5223 t = Bits32 (opcode, 15, 12); 5224 n = Bits32 (opcode, 19, 16); 5225 m = Bits32 (opcode, 3, 0); 5226 if (n == 15) 5227 return false; 5228 5229 // index = TRUE; add = TRUE; wback = FALSE; 5230 index = true; 5231 add = true; 5232 wback = false; 5233 5234 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5235 shift_t = SRType_LSL; 5236 shift_n = Bits32 (opcode, 5, 4); 5237 5238 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5239 if (BadReg (t) || BadReg (m)) 5240 return false; 5241 5242 break; 5243 5244 case eEncodingA1: 5245 // if P == '0' && W == '1' then SEE STRHT; 5246 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5247 t = Bits32 (opcode, 15, 12); 5248 n = Bits32 (opcode, 19, 16); 5249 m = Bits32 (opcode, 3, 0); 5250 5251 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5252 index = BitIsSet (opcode, 24); 5253 add = BitIsSet (opcode, 23); 5254 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5255 5256 // (shift_t, shift_n) = (SRType_LSL, 0); 5257 shift_t = SRType_LSL; 5258 shift_n = 0; 5259 5260 // if t == 15 || m == 15 then UNPREDICTABLE; 5261 if ((t == 15) || (m == 15)) 5262 return false; 5263 5264 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5265 if (wback && ((n == 15) || (n == t))) 5266 return false; 5267 5268 break; 5269 5270 default: 5271 return false; 5272 } 5273 5274 uint32_t Rm = ReadCoreReg (m, &success); 5275 if (!success) 5276 return false; 5277 5278 uint32_t Rn = ReadCoreReg (n, &success); 5279 if (!success) 5280 return false; 5281 5282 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5283 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5284 if (!success) 5285 return false; 5286 5287 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5288 addr_t offset_addr; 5289 if (add) 5290 offset_addr = Rn + offset; 5291 else 5292 offset_addr = Rn - offset; 5293 5294 // address = if index then offset_addr else R[n]; 5295 addr_t address; 5296 if (index) 5297 address = offset_addr; 5298 else 5299 address = Rn; 5300 5301 EmulateInstruction::Context context; 5302 context.type = eContextRegisterStore; 5303 RegisterInfo base_reg; 5304 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5305 RegisterInfo offset_reg; 5306 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5307 5308 // if UnalignedSupport() || address<0> == '0' then 5309 if (UnalignedSupport() || BitIsClear (address, 0)) 5310 { 5311 // MemU[address,2] = R[t]<15:0>; 5312 uint32_t Rt = ReadCoreReg (t, &success); 5313 if (!success) 5314 return false; 5315 5316 EmulateInstruction::Context context; 5317 context.type = eContextRegisterStore; 5318 RegisterInfo base_reg; 5319 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5320 RegisterInfo offset_reg; 5321 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5322 RegisterInfo data_reg; 5323 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5324 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5325 5326 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5327 return false; 5328 } 5329 else // Can only occur before ARMv7 5330 { 5331 // MemU[address,2] = bits(16) UNKNOWN; 5332 } 5333 5334 // if wback then R[n] = offset_addr; 5335 if (wback) 5336 { 5337 context.type = eContextAdjustBaseRegister; 5338 context.SetAddress (offset_addr); 5339 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5340 return false; 5341 } 5342 } 5343 5344 return true; 5345 } 5346 5347 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5348 // and writes the result to the destination register. It can optionally update the condition flags 5349 // based on the result. 5350 bool 5351 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5352 { 5353 #if 0 5354 // ARM pseudo code... 5355 if ConditionPassed() then 5356 EncodingSpecificOperations(); 5357 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5358 if d == 15 then // Can only occur for ARM encoding 5359 ALUWritePC(result); // setflags is always FALSE here 5360 else 5361 R[d] = result; 5362 if setflags then 5363 APSR.N = result<31>; 5364 APSR.Z = IsZeroBit(result); 5365 APSR.C = carry; 5366 APSR.V = overflow; 5367 #endif 5368 5369 bool success = false; 5370 5371 if (ConditionPassed(opcode)) 5372 { 5373 uint32_t Rd, Rn; 5374 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5375 bool setflags; 5376 switch (encoding) 5377 { 5378 case eEncodingT1: 5379 Rd = Bits32(opcode, 11, 8); 5380 Rn = Bits32(opcode, 19, 16); 5381 setflags = BitIsSet(opcode, 20); 5382 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5383 if (BadReg(Rd) || BadReg(Rn)) 5384 return false; 5385 break; 5386 case eEncodingA1: 5387 Rd = Bits32(opcode, 15, 12); 5388 Rn = Bits32(opcode, 19, 16); 5389 setflags = BitIsSet(opcode, 20); 5390 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5391 5392 if (Rd == 15 && setflags) 5393 return EmulateSUBSPcLrEtc (opcode, encoding); 5394 break; 5395 default: 5396 return false; 5397 } 5398 5399 // Read the first operand. 5400 int32_t val1 = ReadCoreReg(Rn, &success); 5401 if (!success) 5402 return false; 5403 5404 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5405 5406 EmulateInstruction::Context context; 5407 context.type = EmulateInstruction::eContextImmediate; 5408 context.SetNoArgs (); 5409 5410 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5411 return false; 5412 } 5413 return true; 5414 } 5415 5416 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5417 // register value, and writes the result to the destination register. It can optionally update the 5418 // condition flags based on the result. 5419 bool 5420 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5421 { 5422 #if 0 5423 // ARM pseudo code... 5424 if ConditionPassed() then 5425 EncodingSpecificOperations(); 5426 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5427 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5428 if d == 15 then // Can only occur for ARM encoding 5429 ALUWritePC(result); // setflags is always FALSE here 5430 else 5431 R[d] = result; 5432 if setflags then 5433 APSR.N = result<31>; 5434 APSR.Z = IsZeroBit(result); 5435 APSR.C = carry; 5436 APSR.V = overflow; 5437 #endif 5438 5439 bool success = false; 5440 5441 if (ConditionPassed(opcode)) 5442 { 5443 uint32_t Rd, Rn, Rm; 5444 ARM_ShifterType shift_t; 5445 uint32_t shift_n; // the shift applied to the value read from Rm 5446 bool setflags; 5447 switch (encoding) 5448 { 5449 case eEncodingT1: 5450 Rd = Rn = Bits32(opcode, 2, 0); 5451 Rm = Bits32(opcode, 5, 3); 5452 setflags = !InITBlock(); 5453 shift_t = SRType_LSL; 5454 shift_n = 0; 5455 break; 5456 case eEncodingT2: 5457 Rd = Bits32(opcode, 11, 8); 5458 Rn = Bits32(opcode, 19, 16); 5459 Rm = Bits32(opcode, 3, 0); 5460 setflags = BitIsSet(opcode, 20); 5461 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5462 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5463 return false; 5464 break; 5465 case eEncodingA1: 5466 Rd = Bits32(opcode, 15, 12); 5467 Rn = Bits32(opcode, 19, 16); 5468 Rm = Bits32(opcode, 3, 0); 5469 setflags = BitIsSet(opcode, 20); 5470 shift_n = DecodeImmShiftARM(opcode, shift_t); 5471 5472 if (Rd == 15 && setflags) 5473 return EmulateSUBSPcLrEtc (opcode, encoding); 5474 break; 5475 default: 5476 return false; 5477 } 5478 5479 // Read the first operand. 5480 int32_t val1 = ReadCoreReg(Rn, &success); 5481 if (!success) 5482 return false; 5483 5484 // Read the second operand. 5485 int32_t val2 = ReadCoreReg(Rm, &success); 5486 if (!success) 5487 return false; 5488 5489 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5490 if (!success) 5491 return false; 5492 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5493 5494 EmulateInstruction::Context context; 5495 context.type = EmulateInstruction::eContextImmediate; 5496 context.SetNoArgs (); 5497 5498 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5499 return false; 5500 } 5501 return true; 5502 } 5503 5504 // This instruction adds an immediate value to the PC value to form a PC-relative address, 5505 // and writes the result to the destination register. 5506 bool 5507 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5508 { 5509 #if 0 5510 // ARM pseudo code... 5511 if ConditionPassed() then 5512 EncodingSpecificOperations(); 5513 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5514 if d == 15 then // Can only occur for ARM encodings 5515 ALUWritePC(result); 5516 else 5517 R[d] = result; 5518 #endif 5519 5520 bool success = false; 5521 5522 if (ConditionPassed(opcode)) 5523 { 5524 uint32_t Rd; 5525 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5526 bool add; 5527 switch (encoding) 5528 { 5529 case eEncodingT1: 5530 Rd = Bits32(opcode, 10, 8); 5531 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5532 add = true; 5533 break; 5534 case eEncodingT2: 5535 case eEncodingT3: 5536 Rd = Bits32(opcode, 11, 8); 5537 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5538 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5539 if (BadReg(Rd)) 5540 return false; 5541 break; 5542 case eEncodingA1: 5543 case eEncodingA2: 5544 Rd = Bits32(opcode, 15, 12); 5545 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5546 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5547 break; 5548 default: 5549 return false; 5550 } 5551 5552 // Read the PC value. 5553 uint32_t pc = ReadCoreReg(PC_REG, &success); 5554 if (!success) 5555 return false; 5556 5557 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5558 5559 EmulateInstruction::Context context; 5560 context.type = EmulateInstruction::eContextImmediate; 5561 context.SetNoArgs (); 5562 5563 if (!WriteCoreReg(context, result, Rd)) 5564 return false; 5565 } 5566 return true; 5567 } 5568 5569 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5570 // to the destination register. It can optionally update the condition flags based on the result. 5571 bool 5572 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5573 { 5574 #if 0 5575 // ARM pseudo code... 5576 if ConditionPassed() then 5577 EncodingSpecificOperations(); 5578 result = R[n] AND imm32; 5579 if d == 15 then // Can only occur for ARM encoding 5580 ALUWritePC(result); // setflags is always FALSE here 5581 else 5582 R[d] = result; 5583 if setflags then 5584 APSR.N = result<31>; 5585 APSR.Z = IsZeroBit(result); 5586 APSR.C = carry; 5587 // APSR.V unchanged 5588 #endif 5589 5590 bool success = false; 5591 5592 if (ConditionPassed(opcode)) 5593 { 5594 uint32_t Rd, Rn; 5595 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5596 bool setflags; 5597 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5598 switch (encoding) 5599 { 5600 case eEncodingT1: 5601 Rd = Bits32(opcode, 11, 8); 5602 Rn = Bits32(opcode, 19, 16); 5603 setflags = BitIsSet(opcode, 20); 5604 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5605 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5606 if (Rd == 15 && setflags) 5607 return EmulateTSTImm(opcode, eEncodingT1); 5608 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5609 return false; 5610 break; 5611 case eEncodingA1: 5612 Rd = Bits32(opcode, 15, 12); 5613 Rn = Bits32(opcode, 19, 16); 5614 setflags = BitIsSet(opcode, 20); 5615 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5616 5617 if (Rd == 15 && setflags) 5618 return EmulateSUBSPcLrEtc (opcode, encoding); 5619 break; 5620 default: 5621 return false; 5622 } 5623 5624 // Read the first operand. 5625 uint32_t val1 = ReadCoreReg(Rn, &success); 5626 if (!success) 5627 return false; 5628 5629 uint32_t result = val1 & imm32; 5630 5631 EmulateInstruction::Context context; 5632 context.type = EmulateInstruction::eContextImmediate; 5633 context.SetNoArgs (); 5634 5635 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5636 return false; 5637 } 5638 return true; 5639 } 5640 5641 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5642 // and writes the result to the destination register. It can optionally update the condition flags 5643 // based on the result. 5644 bool 5645 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5646 { 5647 #if 0 5648 // ARM pseudo code... 5649 if ConditionPassed() then 5650 EncodingSpecificOperations(); 5651 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5652 result = R[n] AND shifted; 5653 if d == 15 then // Can only occur for ARM encoding 5654 ALUWritePC(result); // setflags is always FALSE here 5655 else 5656 R[d] = result; 5657 if setflags then 5658 APSR.N = result<31>; 5659 APSR.Z = IsZeroBit(result); 5660 APSR.C = carry; 5661 // APSR.V unchanged 5662 #endif 5663 5664 bool success = false; 5665 5666 if (ConditionPassed(opcode)) 5667 { 5668 uint32_t Rd, Rn, Rm; 5669 ARM_ShifterType shift_t; 5670 uint32_t shift_n; // the shift applied to the value read from Rm 5671 bool setflags; 5672 uint32_t carry; 5673 switch (encoding) 5674 { 5675 case eEncodingT1: 5676 Rd = Rn = Bits32(opcode, 2, 0); 5677 Rm = Bits32(opcode, 5, 3); 5678 setflags = !InITBlock(); 5679 shift_t = SRType_LSL; 5680 shift_n = 0; 5681 break; 5682 case eEncodingT2: 5683 Rd = Bits32(opcode, 11, 8); 5684 Rn = Bits32(opcode, 19, 16); 5685 Rm = Bits32(opcode, 3, 0); 5686 setflags = BitIsSet(opcode, 20); 5687 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5688 // if Rd == '1111' && S == '1' then SEE TST (register); 5689 if (Rd == 15 && setflags) 5690 return EmulateTSTReg(opcode, eEncodingT2); 5691 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5692 return false; 5693 break; 5694 case eEncodingA1: 5695 Rd = Bits32(opcode, 15, 12); 5696 Rn = Bits32(opcode, 19, 16); 5697 Rm = Bits32(opcode, 3, 0); 5698 setflags = BitIsSet(opcode, 20); 5699 shift_n = DecodeImmShiftARM(opcode, shift_t); 5700 5701 if (Rd == 15 && setflags) 5702 return EmulateSUBSPcLrEtc (opcode, encoding); 5703 break; 5704 default: 5705 return false; 5706 } 5707 5708 // Read the first operand. 5709 uint32_t val1 = ReadCoreReg(Rn, &success); 5710 if (!success) 5711 return false; 5712 5713 // Read the second operand. 5714 uint32_t val2 = ReadCoreReg(Rm, &success); 5715 if (!success) 5716 return false; 5717 5718 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5719 if (!success) 5720 return false; 5721 uint32_t result = val1 & shifted; 5722 5723 EmulateInstruction::Context context; 5724 context.type = EmulateInstruction::eContextImmediate; 5725 context.SetNoArgs (); 5726 5727 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5728 return false; 5729 } 5730 return true; 5731 } 5732 5733 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5734 // immediate value, and writes the result to the destination register. It can optionally update the 5735 // condition flags based on the result. 5736 bool 5737 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5738 { 5739 #if 0 5740 // ARM pseudo code... 5741 if ConditionPassed() then 5742 EncodingSpecificOperations(); 5743 result = R[n] AND NOT(imm32); 5744 if d == 15 then // Can only occur for ARM encoding 5745 ALUWritePC(result); // setflags is always FALSE here 5746 else 5747 R[d] = result; 5748 if setflags then 5749 APSR.N = result<31>; 5750 APSR.Z = IsZeroBit(result); 5751 APSR.C = carry; 5752 // APSR.V unchanged 5753 #endif 5754 5755 bool success = false; 5756 5757 if (ConditionPassed(opcode)) 5758 { 5759 uint32_t Rd, Rn; 5760 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5761 bool setflags; 5762 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5763 switch (encoding) 5764 { 5765 case eEncodingT1: 5766 Rd = Bits32(opcode, 11, 8); 5767 Rn = Bits32(opcode, 19, 16); 5768 setflags = BitIsSet(opcode, 20); 5769 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5770 if (BadReg(Rd) || BadReg(Rn)) 5771 return false; 5772 break; 5773 case eEncodingA1: 5774 Rd = Bits32(opcode, 15, 12); 5775 Rn = Bits32(opcode, 19, 16); 5776 setflags = BitIsSet(opcode, 20); 5777 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5778 5779 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5780 if (Rd == 15 && setflags) 5781 return EmulateSUBSPcLrEtc (opcode, encoding); 5782 break; 5783 default: 5784 return false; 5785 } 5786 5787 // Read the first operand. 5788 uint32_t val1 = ReadCoreReg(Rn, &success); 5789 if (!success) 5790 return false; 5791 5792 uint32_t result = val1 & ~imm32; 5793 5794 EmulateInstruction::Context context; 5795 context.type = EmulateInstruction::eContextImmediate; 5796 context.SetNoArgs (); 5797 5798 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5799 return false; 5800 } 5801 return true; 5802 } 5803 5804 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5805 // optionally-shifted register value, and writes the result to the destination register. 5806 // It can optionally update the condition flags based on the result. 5807 bool 5808 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5809 { 5810 #if 0 5811 // ARM pseudo code... 5812 if ConditionPassed() then 5813 EncodingSpecificOperations(); 5814 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5815 result = R[n] AND NOT(shifted); 5816 if d == 15 then // Can only occur for ARM encoding 5817 ALUWritePC(result); // setflags is always FALSE here 5818 else 5819 R[d] = result; 5820 if setflags then 5821 APSR.N = result<31>; 5822 APSR.Z = IsZeroBit(result); 5823 APSR.C = carry; 5824 // APSR.V unchanged 5825 #endif 5826 5827 bool success = false; 5828 5829 if (ConditionPassed(opcode)) 5830 { 5831 uint32_t Rd, Rn, Rm; 5832 ARM_ShifterType shift_t; 5833 uint32_t shift_n; // the shift applied to the value read from Rm 5834 bool setflags; 5835 uint32_t carry; 5836 switch (encoding) 5837 { 5838 case eEncodingT1: 5839 Rd = Rn = Bits32(opcode, 2, 0); 5840 Rm = Bits32(opcode, 5, 3); 5841 setflags = !InITBlock(); 5842 shift_t = SRType_LSL; 5843 shift_n = 0; 5844 break; 5845 case eEncodingT2: 5846 Rd = Bits32(opcode, 11, 8); 5847 Rn = Bits32(opcode, 19, 16); 5848 Rm = Bits32(opcode, 3, 0); 5849 setflags = BitIsSet(opcode, 20); 5850 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5851 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5852 return false; 5853 break; 5854 case eEncodingA1: 5855 Rd = Bits32(opcode, 15, 12); 5856 Rn = Bits32(opcode, 19, 16); 5857 Rm = Bits32(opcode, 3, 0); 5858 setflags = BitIsSet(opcode, 20); 5859 shift_n = DecodeImmShiftARM(opcode, shift_t); 5860 5861 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5862 if (Rd == 15 && setflags) 5863 return EmulateSUBSPcLrEtc (opcode, encoding); 5864 break; 5865 default: 5866 return false; 5867 } 5868 5869 // Read the first operand. 5870 uint32_t val1 = ReadCoreReg(Rn, &success); 5871 if (!success) 5872 return false; 5873 5874 // Read the second operand. 5875 uint32_t val2 = ReadCoreReg(Rm, &success); 5876 if (!success) 5877 return false; 5878 5879 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5880 if (!success) 5881 return false; 5882 uint32_t result = val1 & ~shifted; 5883 5884 EmulateInstruction::Context context; 5885 context.type = EmulateInstruction::eContextImmediate; 5886 context.SetNoArgs (); 5887 5888 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5889 return false; 5890 } 5891 return true; 5892 } 5893 5894 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5895 // from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5896 bool 5897 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5898 { 5899 #if 0 5900 if ConditionPassed() then 5901 EncodingSpecificOperations(); 5902 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5903 address = if index then offset_addr else R[n]; 5904 data = MemU[address,4]; 5905 if wback then R[n] = offset_addr; 5906 if t == 15 then 5907 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5908 elsif UnalignedSupport() || address<1:0> = '00' then 5909 R[t] = data; 5910 else // Can only apply before ARMv7 5911 R[t] = ROR(data, 8*UInt(address<1:0>)); 5912 #endif 5913 5914 bool success = false; 5915 5916 if (ConditionPassed(opcode)) 5917 { 5918 const uint32_t addr_byte_size = GetAddressByteSize(); 5919 5920 uint32_t t; 5921 uint32_t n; 5922 uint32_t imm32; 5923 bool index; 5924 bool add; 5925 bool wback; 5926 5927 switch (encoding) 5928 { 5929 case eEncodingA1: 5930 // if Rn == '1111' then SEE LDR (literal); 5931 // if P == '0' && W == '1' then SEE LDRT; 5932 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5933 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5934 t = Bits32 (opcode, 15, 12); 5935 n = Bits32 (opcode, 19, 16); 5936 imm32 = Bits32 (opcode, 11, 0); 5937 5938 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5939 index = BitIsSet (opcode, 24); 5940 add = BitIsSet (opcode, 23); 5941 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5942 5943 // if wback && n == t then UNPREDICTABLE; 5944 if (wback && (n == t)) 5945 return false; 5946 5947 break; 5948 5949 default: 5950 return false; 5951 } 5952 5953 addr_t address; 5954 addr_t offset_addr; 5955 addr_t base_address = ReadCoreReg (n, &success); 5956 if (!success) 5957 return false; 5958 5959 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5960 if (add) 5961 offset_addr = base_address + imm32; 5962 else 5963 offset_addr = base_address - imm32; 5964 5965 // address = if index then offset_addr else R[n]; 5966 if (index) 5967 address = offset_addr; 5968 else 5969 address = base_address; 5970 5971 // data = MemU[address,4]; 5972 5973 RegisterInfo base_reg; 5974 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5975 5976 EmulateInstruction::Context context; 5977 context.type = eContextRegisterLoad; 5978 context.SetRegisterPlusOffset (base_reg, address - base_address); 5979 5980 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5981 if (!success) 5982 return false; 5983 5984 // if wback then R[n] = offset_addr; 5985 if (wback) 5986 { 5987 context.type = eContextAdjustBaseRegister; 5988 context.SetAddress (offset_addr); 5989 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5990 return false; 5991 } 5992 5993 // if t == 15 then 5994 if (t == 15) 5995 { 5996 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5997 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5998 { 5999 // LoadWritePC (data); 6000 context.type = eContextRegisterLoad; 6001 context.SetRegisterPlusOffset (base_reg, address - base_address); 6002 LoadWritePC (context, data); 6003 } 6004 else 6005 return false; 6006 } 6007 // elsif UnalignedSupport() || address<1:0> = '00' then 6008 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6009 { 6010 // R[t] = data; 6011 context.type = eContextRegisterLoad; 6012 context.SetRegisterPlusOffset (base_reg, address - base_address); 6013 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6014 return false; 6015 } 6016 // else // Can only apply before ARMv7 6017 else 6018 { 6019 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6020 data = ROR (data, Bits32 (address, 1, 0), &success); 6021 if (!success) 6022 return false; 6023 context.type = eContextRegisterLoad; 6024 context.SetImmediate (data); 6025 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6026 return false; 6027 } 6028 6029 } 6030 return true; 6031 } 6032 6033 // LDR (register) calculates an address from a base register value and an offset register value, loads a word 6034 // from memory, and writes it to a register. The offset register value can optionally be shifted. 6035 bool 6036 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 6037 { 6038 #if 0 6039 if ConditionPassed() then 6040 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6041 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6042 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6043 address = if index then offset_addr else R[n]; 6044 data = MemU[address,4]; 6045 if wback then R[n] = offset_addr; 6046 if t == 15 then 6047 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6048 elsif UnalignedSupport() || address<1:0> = '00' then 6049 R[t] = data; 6050 else // Can only apply before ARMv7 6051 if CurrentInstrSet() == InstrSet_ARM then 6052 R[t] = ROR(data, 8*UInt(address<1:0>)); 6053 else 6054 R[t] = bits(32) UNKNOWN; 6055 #endif 6056 6057 bool success = false; 6058 6059 if (ConditionPassed(opcode)) 6060 { 6061 const uint32_t addr_byte_size = GetAddressByteSize(); 6062 6063 uint32_t t; 6064 uint32_t n; 6065 uint32_t m; 6066 bool index; 6067 bool add; 6068 bool wback; 6069 ARM_ShifterType shift_t; 6070 uint32_t shift_n; 6071 6072 switch (encoding) 6073 { 6074 case eEncodingT1: 6075 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6076 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6077 t = Bits32 (opcode, 2, 0); 6078 n = Bits32 (opcode, 5, 3); 6079 m = Bits32 (opcode, 8, 6); 6080 6081 // index = TRUE; add = TRUE; wback = FALSE; 6082 index = true; 6083 add = true; 6084 wback = false; 6085 6086 // (shift_t, shift_n) = (SRType_LSL, 0); 6087 shift_t = SRType_LSL; 6088 shift_n = 0; 6089 6090 break; 6091 6092 case eEncodingT2: 6093 // if Rn == '1111' then SEE LDR (literal); 6094 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6095 t = Bits32 (opcode, 15, 12); 6096 n = Bits32 (opcode, 19, 16); 6097 m = Bits32 (opcode, 3, 0); 6098 6099 // index = TRUE; add = TRUE; wback = FALSE; 6100 index = true; 6101 add = true; 6102 wback = false; 6103 6104 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6105 shift_t = SRType_LSL; 6106 shift_n = Bits32 (opcode, 5, 4); 6107 6108 // if BadReg(m) then UNPREDICTABLE; 6109 if (BadReg (m)) 6110 return false; 6111 6112 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6113 if ((t == 15) && InITBlock() && !LastInITBlock()) 6114 return false; 6115 6116 break; 6117 6118 case eEncodingA1: 6119 { 6120 // if P == '0' && W == '1' then SEE LDRT; 6121 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6122 t = Bits32 (opcode, 15, 12); 6123 n = Bits32 (opcode, 19, 16); 6124 m = Bits32 (opcode, 3, 0); 6125 6126 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6127 index = BitIsSet (opcode, 24); 6128 add = BitIsSet (opcode, 23); 6129 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6130 6131 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6132 uint32_t type = Bits32 (opcode, 6, 5); 6133 uint32_t imm5 = Bits32 (opcode, 11, 7); 6134 shift_n = DecodeImmShift (type, imm5, shift_t); 6135 6136 // if m == 15 then UNPREDICTABLE; 6137 if (m == 15) 6138 return false; 6139 6140 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6141 if (wback && ((n == 15) || (n == t))) 6142 return false; 6143 } 6144 break; 6145 6146 6147 default: 6148 return false; 6149 } 6150 6151 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6152 if (!success) 6153 return false; 6154 6155 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6156 if (!success) 6157 return false; 6158 6159 addr_t offset_addr; 6160 addr_t address; 6161 6162 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6163 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6164 if (!success) 6165 return false; 6166 6167 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6168 if (add) 6169 offset_addr = Rn + offset; 6170 else 6171 offset_addr = Rn - offset; 6172 6173 // address = if index then offset_addr else R[n]; 6174 if (index) 6175 address = offset_addr; 6176 else 6177 address = Rn; 6178 6179 // data = MemU[address,4]; 6180 RegisterInfo base_reg; 6181 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6182 6183 EmulateInstruction::Context context; 6184 context.type = eContextRegisterLoad; 6185 context.SetRegisterPlusOffset (base_reg, address - Rn); 6186 6187 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6188 if (!success) 6189 return false; 6190 6191 // if wback then R[n] = offset_addr; 6192 if (wback) 6193 { 6194 context.type = eContextAdjustBaseRegister; 6195 context.SetAddress (offset_addr); 6196 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6197 return false; 6198 } 6199 6200 // if t == 15 then 6201 if (t == 15) 6202 { 6203 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6204 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6205 { 6206 context.type = eContextRegisterLoad; 6207 context.SetRegisterPlusOffset (base_reg, address - Rn); 6208 LoadWritePC (context, data); 6209 } 6210 else 6211 return false; 6212 } 6213 // elsif UnalignedSupport() || address<1:0> = '00' then 6214 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6215 { 6216 // R[t] = data; 6217 context.type = eContextRegisterLoad; 6218 context.SetRegisterPlusOffset (base_reg, address - Rn); 6219 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6220 return false; 6221 } 6222 else // Can only apply before ARMv7 6223 { 6224 // if CurrentInstrSet() == InstrSet_ARM then 6225 if (CurrentInstrSet () == eModeARM) 6226 { 6227 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6228 data = ROR (data, Bits32 (address, 1, 0), &success); 6229 if (!success) 6230 return false; 6231 context.type = eContextRegisterLoad; 6232 context.SetImmediate (data); 6233 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6234 return false; 6235 } 6236 else 6237 { 6238 // R[t] = bits(32) UNKNOWN; 6239 WriteBits32Unknown (t); 6240 } 6241 } 6242 } 6243 return true; 6244 } 6245 6246 // LDRB (immediate, Thumb) 6247 bool 6248 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6249 { 6250 #if 0 6251 if ConditionPassed() then 6252 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6253 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6254 address = if index then offset_addr else R[n]; 6255 R[t] = ZeroExtend(MemU[address,1], 32); 6256 if wback then R[n] = offset_addr; 6257 #endif 6258 6259 bool success = false; 6260 6261 if (ConditionPassed(opcode)) 6262 { 6263 uint32_t t; 6264 uint32_t n; 6265 uint32_t imm32; 6266 bool index; 6267 bool add; 6268 bool wback; 6269 6270 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6271 switch (encoding) 6272 { 6273 case eEncodingT1: 6274 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6275 t = Bits32 (opcode, 2, 0); 6276 n = Bits32 (opcode, 5, 3); 6277 imm32 = Bits32 (opcode, 10, 6); 6278 6279 // index = TRUE; add = TRUE; wback = FALSE; 6280 index = true; 6281 add = true; 6282 wback= false; 6283 6284 break; 6285 6286 case eEncodingT2: 6287 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6288 t = Bits32 (opcode, 15, 12); 6289 n = Bits32 (opcode, 19, 16); 6290 imm32 = Bits32 (opcode, 11, 0); 6291 6292 // index = TRUE; add = TRUE; wback = FALSE; 6293 index = true; 6294 add = true; 6295 wback = false; 6296 6297 // if Rt == '1111' then SEE PLD; 6298 if (t == 15) 6299 return false; // PLD is not implemented yet 6300 6301 // if Rn == '1111' then SEE LDRB (literal); 6302 if (n == 15) 6303 return EmulateLDRBLiteral(opcode, eEncodingT1); 6304 6305 // if t == 13 then UNPREDICTABLE; 6306 if (t == 13) 6307 return false; 6308 6309 break; 6310 6311 case eEncodingT3: 6312 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6313 // if P == '0' && W == '0' then UNDEFINED; 6314 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6315 return false; 6316 6317 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6318 t = Bits32 (opcode, 15, 12); 6319 n = Bits32 (opcode, 19, 16); 6320 imm32 = Bits32 (opcode, 7, 0); 6321 6322 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6323 index = BitIsSet (opcode, 10); 6324 add = BitIsSet (opcode, 9); 6325 wback = BitIsSet (opcode, 8); 6326 6327 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6328 if (t == 15) 6329 return false; // PLD is not implemented yet 6330 6331 // if Rn == '1111' then SEE LDRB (literal); 6332 if (n == 15) 6333 return EmulateLDRBLiteral(opcode, eEncodingT1); 6334 6335 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6336 if (BadReg (t) || (wback && (n == t))) 6337 return false; 6338 6339 break; 6340 6341 default: 6342 return false; 6343 } 6344 6345 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6346 if (!success) 6347 return false; 6348 6349 addr_t address; 6350 addr_t offset_addr; 6351 6352 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6353 if (add) 6354 offset_addr = Rn + imm32; 6355 else 6356 offset_addr = Rn - imm32; 6357 6358 // address = if index then offset_addr else R[n]; 6359 if (index) 6360 address = offset_addr; 6361 else 6362 address = Rn; 6363 6364 // R[t] = ZeroExtend(MemU[address,1], 32); 6365 RegisterInfo base_reg; 6366 RegisterInfo data_reg; 6367 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6368 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6369 6370 EmulateInstruction::Context context; 6371 context.type = eContextRegisterLoad; 6372 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6373 6374 uint64_t data = MemURead (context, address, 1, 0, &success); 6375 if (!success) 6376 return false; 6377 6378 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6379 return false; 6380 6381 // if wback then R[n] = offset_addr; 6382 if (wback) 6383 { 6384 context.type = eContextAdjustBaseRegister; 6385 context.SetAddress (offset_addr); 6386 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6387 return false; 6388 } 6389 } 6390 return true; 6391 } 6392 6393 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6394 // zero-extends it to form a 32-bit word and writes it to a register. 6395 bool 6396 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6397 { 6398 #if 0 6399 if ConditionPassed() then 6400 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6401 base = Align(PC,4); 6402 address = if add then (base + imm32) else (base - imm32); 6403 R[t] = ZeroExtend(MemU[address,1], 32); 6404 #endif 6405 6406 bool success = false; 6407 6408 if (ConditionPassed(opcode)) 6409 { 6410 uint32_t t; 6411 uint32_t imm32; 6412 bool add; 6413 switch (encoding) 6414 { 6415 case eEncodingT1: 6416 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6417 t = Bits32 (opcode, 15, 12); 6418 imm32 = Bits32 (opcode, 11, 0); 6419 add = BitIsSet (opcode, 23); 6420 6421 // if Rt == '1111' then SEE PLD; 6422 if (t == 15) 6423 return false; // PLD is not implemented yet 6424 6425 // if t == 13 then UNPREDICTABLE; 6426 if (t == 13) 6427 return false; 6428 6429 break; 6430 6431 case eEncodingA1: 6432 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6433 t = Bits32 (opcode, 15, 12); 6434 imm32 = Bits32 (opcode, 11, 0); 6435 add = BitIsSet (opcode, 23); 6436 6437 // if t == 15 then UNPREDICTABLE; 6438 if (t == 15) 6439 return false; 6440 break; 6441 6442 default: 6443 return false; 6444 } 6445 6446 // base = Align(PC,4); 6447 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6448 if (!success) 6449 return false; 6450 6451 uint32_t base = AlignPC (pc_val); 6452 6453 addr_t address; 6454 // address = if add then (base + imm32) else (base - imm32); 6455 if (add) 6456 address = base + imm32; 6457 else 6458 address = base - imm32; 6459 6460 // R[t] = ZeroExtend(MemU[address,1], 32); 6461 EmulateInstruction::Context context; 6462 context.type = eContextRelativeBranchImmediate; 6463 context.SetImmediate (address - base); 6464 6465 uint64_t data = MemURead (context, address, 1, 0, &success); 6466 if (!success) 6467 return false; 6468 6469 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6470 return false; 6471 } 6472 return true; 6473 } 6474 6475 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6476 // memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6477 // optionally be shifted. 6478 bool 6479 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6480 { 6481 #if 0 6482 if ConditionPassed() then 6483 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6484 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6485 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6486 address = if index then offset_addr else R[n]; 6487 R[t] = ZeroExtend(MemU[address,1],32); 6488 if wback then R[n] = offset_addr; 6489 #endif 6490 6491 bool success = false; 6492 6493 if (ConditionPassed(opcode)) 6494 { 6495 uint32_t t; 6496 uint32_t n; 6497 uint32_t m; 6498 bool index; 6499 bool add; 6500 bool wback; 6501 ARM_ShifterType shift_t; 6502 uint32_t shift_n; 6503 6504 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6505 switch (encoding) 6506 { 6507 case eEncodingT1: 6508 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6509 t = Bits32 (opcode, 2, 0); 6510 n = Bits32 (opcode, 5, 3); 6511 m = Bits32 (opcode, 8, 6); 6512 6513 // index = TRUE; add = TRUE; wback = FALSE; 6514 index = true; 6515 add = true; 6516 wback = false; 6517 6518 // (shift_t, shift_n) = (SRType_LSL, 0); 6519 shift_t = SRType_LSL; 6520 shift_n = 0; 6521 break; 6522 6523 case eEncodingT2: 6524 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6525 t = Bits32 (opcode, 15, 12); 6526 n = Bits32 (opcode, 19, 16); 6527 m = Bits32 (opcode, 3, 0); 6528 6529 // index = TRUE; add = TRUE; wback = FALSE; 6530 index = true; 6531 add = true; 6532 wback = false; 6533 6534 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6535 shift_t = SRType_LSL; 6536 shift_n = Bits32 (opcode, 5, 4); 6537 6538 // if Rt == '1111' then SEE PLD; 6539 if (t == 15) 6540 return false; // PLD is not implemented yet 6541 6542 // if Rn == '1111' then SEE LDRB (literal); 6543 if (n == 15) 6544 return EmulateLDRBLiteral(opcode, eEncodingT1); 6545 6546 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6547 if ((t == 13) || BadReg (m)) 6548 return false; 6549 break; 6550 6551 case eEncodingA1: 6552 { 6553 // if P == '0' && W == '1' then SEE LDRBT; 6554 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6555 t = Bits32 (opcode, 15, 12); 6556 n = Bits32 (opcode, 19, 16); 6557 m = Bits32 (opcode, 3, 0); 6558 6559 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6560 index = BitIsSet (opcode, 24); 6561 add = BitIsSet (opcode, 23); 6562 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6563 6564 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6565 uint32_t type = Bits32 (opcode, 6, 5); 6566 uint32_t imm5 = Bits32 (opcode, 11, 7); 6567 shift_n = DecodeImmShift (type, imm5, shift_t); 6568 6569 // if t == 15 || m == 15 then UNPREDICTABLE; 6570 if ((t == 15) || (m == 15)) 6571 return false; 6572 6573 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6574 if (wback && ((n == 15) || (n == t))) 6575 return false; 6576 } 6577 break; 6578 6579 default: 6580 return false; 6581 } 6582 6583 addr_t offset_addr; 6584 addr_t address; 6585 6586 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6587 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6588 if (!success) 6589 return false; 6590 6591 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6592 if (!success) 6593 return false; 6594 6595 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6596 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6597 if (!success) 6598 return false; 6599 6600 if (add) 6601 offset_addr = Rn + offset; 6602 else 6603 offset_addr = Rn - offset; 6604 6605 // address = if index then offset_addr else R[n]; 6606 if (index) 6607 address = offset_addr; 6608 else 6609 address = Rn; 6610 6611 // R[t] = ZeroExtend(MemU[address,1],32); 6612 RegisterInfo base_reg; 6613 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6614 6615 EmulateInstruction::Context context; 6616 context.type = eContextRegisterLoad; 6617 context.SetRegisterPlusOffset (base_reg, address - Rn); 6618 6619 uint64_t data = MemURead (context, address, 1, 0, &success); 6620 if (!success) 6621 return false; 6622 6623 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6624 return false; 6625 6626 // if wback then R[n] = offset_addr; 6627 if (wback) 6628 { 6629 context.type = eContextAdjustBaseRegister; 6630 context.SetAddress (offset_addr); 6631 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6632 return false; 6633 } 6634 } 6635 return true; 6636 } 6637 6638 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6639 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6640 // post-indexed, or pre-indexed addressing. 6641 bool 6642 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6643 { 6644 #if 0 6645 if ConditionPassed() then 6646 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6647 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6648 address = if index then offset_addr else R[n]; 6649 data = MemU[address,2]; 6650 if wback then R[n] = offset_addr; 6651 if UnalignedSupport() || address<0> = '0' then 6652 R[t] = ZeroExtend(data, 32); 6653 else // Can only apply before ARMv7 6654 R[t] = bits(32) UNKNOWN; 6655 #endif 6656 6657 6658 bool success = false; 6659 6660 if (ConditionPassed(opcode)) 6661 { 6662 uint32_t t; 6663 uint32_t n; 6664 uint32_t imm32; 6665 bool index; 6666 bool add; 6667 bool wback; 6668 6669 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6670 switch (encoding) 6671 { 6672 case eEncodingT1: 6673 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6674 t = Bits32 (opcode, 2, 0); 6675 n = Bits32 (opcode, 5, 3); 6676 imm32 = Bits32 (opcode, 10, 6) << 1; 6677 6678 // index = TRUE; add = TRUE; wback = FALSE; 6679 index = true; 6680 add = true; 6681 wback = false; 6682 6683 break; 6684 6685 case eEncodingT2: 6686 // if Rt == '1111' then SEE "Unallocated memory hints"; 6687 // if Rn == '1111' then SEE LDRH (literal); 6688 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6689 t = Bits32 (opcode, 15, 12); 6690 n = Bits32 (opcode, 19, 16); 6691 imm32 = Bits32 (opcode, 11, 0); 6692 6693 // index = TRUE; add = TRUE; wback = FALSE; 6694 index = true; 6695 add = true; 6696 wback = false; 6697 6698 // if t == 13 then UNPREDICTABLE; 6699 if (t == 13) 6700 return false; 6701 break; 6702 6703 case eEncodingT3: 6704 // if Rn == '1111' then SEE LDRH (literal); 6705 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6706 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6707 // if P == '0' && W == '0' then UNDEFINED; 6708 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6709 return false; 6710 6711 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6712 t = Bits32 (opcode, 15, 12); 6713 n = Bits32 (opcode, 19, 16); 6714 imm32 = Bits32 (opcode, 7, 0); 6715 6716 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6717 index = BitIsSet (opcode, 10); 6718 add = BitIsSet (opcode, 9); 6719 wback = BitIsSet (opcode, 8); 6720 6721 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6722 if (BadReg (t) || (wback && (n == t))) 6723 return false; 6724 break; 6725 6726 default: 6727 return false; 6728 } 6729 6730 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6731 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6732 if (!success) 6733 return false; 6734 6735 addr_t offset_addr; 6736 addr_t address; 6737 6738 if (add) 6739 offset_addr = Rn + imm32; 6740 else 6741 offset_addr = Rn - imm32; 6742 6743 // address = if index then offset_addr else R[n]; 6744 if (index) 6745 address = offset_addr; 6746 else 6747 address = Rn; 6748 6749 // data = MemU[address,2]; 6750 RegisterInfo base_reg; 6751 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6752 6753 EmulateInstruction::Context context; 6754 context.type = eContextRegisterLoad; 6755 context.SetRegisterPlusOffset (base_reg, address - Rn); 6756 6757 uint64_t data = MemURead (context, address, 2, 0, &success); 6758 if (!success) 6759 return false; 6760 6761 // if wback then R[n] = offset_addr; 6762 if (wback) 6763 { 6764 context.type = eContextAdjustBaseRegister; 6765 context.SetAddress (offset_addr); 6766 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6767 return false; 6768 } 6769 6770 // if UnalignedSupport() || address<0> = '0' then 6771 if (UnalignedSupport () || BitIsClear (address, 0)) 6772 { 6773 // R[t] = ZeroExtend(data, 32); 6774 context.type = eContextRegisterLoad; 6775 context.SetRegisterPlusOffset (base_reg, address - Rn); 6776 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6777 return false; 6778 } 6779 else // Can only apply before ARMv7 6780 { 6781 // R[t] = bits(32) UNKNOWN; 6782 WriteBits32Unknown (t); 6783 } 6784 } 6785 return true; 6786 } 6787 6788 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6789 // zero-extends it to form a 32-bit word, and writes it to a register. 6790 bool 6791 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6792 { 6793 #if 0 6794 if ConditionPassed() then 6795 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6796 base = Align(PC,4); 6797 address = if add then (base + imm32) else (base - imm32); 6798 data = MemU[address,2]; 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 imm32; 6811 bool add; 6812 6813 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6814 switch (encoding) 6815 { 6816 case eEncodingT1: 6817 // if Rt == '1111' then SEE "Unallocated memory hints"; 6818 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6819 t = Bits32 (opcode, 15, 12); 6820 imm32 = Bits32 (opcode, 11, 0); 6821 add = BitIsSet (opcode, 23); 6822 6823 // if t == 13 then UNPREDICTABLE; 6824 if (t == 13) 6825 return false; 6826 6827 break; 6828 6829 case eEncodingA1: 6830 { 6831 uint32_t imm4H = Bits32 (opcode, 11, 8); 6832 uint32_t imm4L = Bits32 (opcode, 3, 0); 6833 6834 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6835 t = Bits32 (opcode, 15, 12); 6836 imm32 = (imm4H << 4) | imm4L; 6837 add = BitIsSet (opcode, 23); 6838 6839 // if t == 15 then UNPREDICTABLE; 6840 if (t == 15) 6841 return false; 6842 break; 6843 } 6844 6845 default: 6846 return false; 6847 } 6848 6849 // base = Align(PC,4); 6850 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6851 if (!success) 6852 return false; 6853 6854 addr_t base = AlignPC (pc_value); 6855 addr_t address; 6856 6857 // address = if add then (base + imm32) else (base - imm32); 6858 if (add) 6859 address = base + imm32; 6860 else 6861 address = base - imm32; 6862 6863 // data = MemU[address,2]; 6864 RegisterInfo base_reg; 6865 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6866 6867 EmulateInstruction::Context context; 6868 context.type = eContextRegisterLoad; 6869 context.SetRegisterPlusOffset (base_reg, address - base); 6870 6871 uint64_t data = MemURead (context, address, 2, 0, &success); 6872 if (!success) 6873 return false; 6874 6875 6876 // if UnalignedSupport() || address<0> = '0' then 6877 if (UnalignedSupport () || BitIsClear (address, 0)) 6878 { 6879 // R[t] = ZeroExtend(data, 32); 6880 context.type = eContextRegisterLoad; 6881 context.SetRegisterPlusOffset (base_reg, address - base); 6882 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6883 return false; 6884 6885 } 6886 else // Can only apply before ARMv7 6887 { 6888 // R[t] = bits(32) UNKNOWN; 6889 WriteBits32Unknown (t); 6890 } 6891 } 6892 return true; 6893 } 6894 6895 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6896 // from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6897 // be shifted left by 0, 1, 2, or 3 bits. 6898 bool 6899 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6900 { 6901 #if 0 6902 if ConditionPassed() then 6903 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6904 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6905 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6906 address = if index then offset_addr else R[n]; 6907 data = MemU[address,2]; 6908 if wback then R[n] = offset_addr; 6909 if UnalignedSupport() || address<0> = '0' then 6910 R[t] = ZeroExtend(data, 32); 6911 else // Can only apply before ARMv7 6912 R[t] = bits(32) UNKNOWN; 6913 #endif 6914 6915 bool success = false; 6916 6917 if (ConditionPassed(opcode)) 6918 { 6919 uint32_t t; 6920 uint32_t n; 6921 uint32_t m; 6922 bool index; 6923 bool add; 6924 bool wback; 6925 ARM_ShifterType shift_t; 6926 uint32_t shift_n; 6927 6928 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6929 switch (encoding) 6930 { 6931 case eEncodingT1: 6932 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6933 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6934 t = Bits32 (opcode, 2, 0); 6935 n = Bits32 (opcode, 5, 3); 6936 m = Bits32 (opcode, 8, 6); 6937 6938 // index = TRUE; add = TRUE; wback = FALSE; 6939 index = true; 6940 add = true; 6941 wback = false; 6942 6943 // (shift_t, shift_n) = (SRType_LSL, 0); 6944 shift_t = SRType_LSL; 6945 shift_n = 0; 6946 6947 break; 6948 6949 case eEncodingT2: 6950 // if Rn == '1111' then SEE LDRH (literal); 6951 // if Rt == '1111' then SEE "Unallocated memory hints"; 6952 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6953 t = Bits32 (opcode, 15, 12); 6954 n = Bits32 (opcode, 19, 16); 6955 m = Bits32 (opcode, 3, 0); 6956 6957 // index = TRUE; add = TRUE; wback = FALSE; 6958 index = true; 6959 add = true; 6960 wback = false; 6961 6962 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6963 shift_t = SRType_LSL; 6964 shift_n = Bits32 (opcode, 5, 4); 6965 6966 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6967 if ((t == 13) || BadReg (m)) 6968 return false; 6969 break; 6970 6971 case eEncodingA1: 6972 // if P == '0' && W == '1' then SEE LDRHT; 6973 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6974 t = Bits32 (opcode, 15, 12); 6975 n = Bits32 (opcode, 19, 16); 6976 m = Bits32 (opcode, 3, 0); 6977 6978 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6979 index = BitIsSet (opcode, 24); 6980 add = BitIsSet (opcode, 23); 6981 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6982 6983 // (shift_t, shift_n) = (SRType_LSL, 0); 6984 shift_t = SRType_LSL; 6985 shift_n = 0; 6986 6987 // if t == 15 || m == 15 then UNPREDICTABLE; 6988 if ((t == 15) || (m == 15)) 6989 return false; 6990 6991 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6992 if (wback && ((n == 15) || (n == t))) 6993 return false; 6994 6995 break; 6996 6997 default: 6998 return false; 6999 } 7000 7001 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7002 7003 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7004 if (!success) 7005 return false; 7006 7007 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7008 if (!success) 7009 return false; 7010 7011 addr_t offset_addr; 7012 addr_t address; 7013 7014 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7015 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7016 if (!success) 7017 return false; 7018 7019 if (add) 7020 offset_addr = Rn + offset; 7021 else 7022 offset_addr = Rn - offset; 7023 7024 // address = if index then offset_addr else R[n]; 7025 if (index) 7026 address = offset_addr; 7027 else 7028 address = Rn; 7029 7030 // data = MemU[address,2]; 7031 RegisterInfo base_reg; 7032 RegisterInfo offset_reg; 7033 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7034 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7035 7036 EmulateInstruction::Context context; 7037 context.type = eContextRegisterLoad; 7038 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7039 uint64_t data = MemURead (context, address, 2, 0, &success); 7040 if (!success) 7041 return false; 7042 7043 // if wback then R[n] = offset_addr; 7044 if (wback) 7045 { 7046 context.type = eContextAdjustBaseRegister; 7047 context.SetAddress (offset_addr); 7048 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7049 return false; 7050 } 7051 7052 // if UnalignedSupport() || address<0> = '0' then 7053 if (UnalignedSupport() || BitIsClear (address, 0)) 7054 { 7055 // R[t] = ZeroExtend(data, 32); 7056 context.type = eContextRegisterLoad; 7057 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7058 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7059 return false; 7060 } 7061 else // Can only apply before ARMv7 7062 { 7063 // R[t] = bits(32) UNKNOWN; 7064 WriteBits32Unknown (t); 7065 } 7066 } 7067 return true; 7068 } 7069 7070 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 7071 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 7072 // or pre-indexed addressing. 7073 bool 7074 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 7075 { 7076 #if 0 7077 if ConditionPassed() then 7078 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7079 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7080 address = if index then offset_addr else R[n]; 7081 R[t] = SignExtend(MemU[address,1], 32); 7082 if wback then R[n] = offset_addr; 7083 #endif 7084 7085 bool success = false; 7086 7087 if (ConditionPassed(opcode)) 7088 { 7089 uint32_t t; 7090 uint32_t n; 7091 uint32_t imm32; 7092 bool index; 7093 bool add; 7094 bool wback; 7095 7096 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7097 switch (encoding) 7098 { 7099 case eEncodingT1: 7100 // if Rt == '1111' then SEE PLI; 7101 // if Rn == '1111' then SEE LDRSB (literal); 7102 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7103 t = Bits32 (opcode, 15, 12); 7104 n = Bits32 (opcode, 19, 16); 7105 imm32 = Bits32 (opcode, 11, 0); 7106 7107 // index = TRUE; add = TRUE; wback = FALSE; 7108 index = true; 7109 add = true; 7110 wback = false; 7111 7112 // if t == 13 then UNPREDICTABLE; 7113 if (t == 13) 7114 return false; 7115 7116 break; 7117 7118 case eEncodingT2: 7119 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7120 // if Rn == '1111' then SEE LDRSB (literal); 7121 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7122 // if P == '0' && W == '0' then UNDEFINED; 7123 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7124 return false; 7125 7126 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7127 t = Bits32 (opcode, 15, 12); 7128 n = Bits32 (opcode, 19, 16); 7129 imm32 = Bits32 (opcode, 7, 0); 7130 7131 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7132 index = BitIsSet (opcode, 10); 7133 add = BitIsSet (opcode, 9); 7134 wback = BitIsSet (opcode, 8); 7135 7136 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7137 if (((t == 13) || ((t == 15) 7138 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 7139 || (wback && (n == t))) 7140 return false; 7141 7142 break; 7143 7144 case eEncodingA1: 7145 { 7146 // if Rn == '1111' then SEE LDRSB (literal); 7147 // if P == '0' && W == '1' then SEE LDRSBT; 7148 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7149 t = Bits32 (opcode, 15, 12); 7150 n = Bits32 (opcode, 19, 16); 7151 7152 uint32_t imm4H = Bits32 (opcode, 11, 8); 7153 uint32_t imm4L = Bits32 (opcode, 3, 0); 7154 imm32 = (imm4H << 4) | imm4L; 7155 7156 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7157 index = BitIsSet (opcode, 24); 7158 add = BitIsSet (opcode, 23); 7159 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7160 7161 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7162 if ((t == 15) || (wback && (n == t))) 7163 return false; 7164 7165 break; 7166 } 7167 7168 default: 7169 return false; 7170 } 7171 7172 uint64_t Rn = ReadCoreReg (n, &success); 7173 if (!success) 7174 return false; 7175 7176 addr_t offset_addr; 7177 addr_t address; 7178 7179 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7180 if (add) 7181 offset_addr = Rn + imm32; 7182 else 7183 offset_addr = Rn - imm32; 7184 7185 // address = if index then offset_addr else R[n]; 7186 if (index) 7187 address = offset_addr; 7188 else 7189 address = Rn; 7190 7191 // R[t] = SignExtend(MemU[address,1], 32); 7192 RegisterInfo base_reg; 7193 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7194 7195 EmulateInstruction::Context context; 7196 context.type = eContextRegisterLoad; 7197 context.SetRegisterPlusOffset (base_reg, address - Rn); 7198 7199 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7200 if (!success) 7201 return false; 7202 7203 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7204 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7205 return false; 7206 7207 // if wback then R[n] = offset_addr; 7208 if (wback) 7209 { 7210 context.type = eContextAdjustBaseRegister; 7211 context.SetAddress (offset_addr); 7212 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7213 return false; 7214 } 7215 } 7216 7217 return true; 7218 } 7219 7220 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7221 // sign-extends it to form a 32-bit word, and writes tit to a register. 7222 bool 7223 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7224 { 7225 #if 0 7226 if ConditionPassed() then 7227 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7228 base = Align(PC,4); 7229 address = if add then (base + imm32) else (base - imm32); 7230 R[t] = SignExtend(MemU[address,1], 32); 7231 #endif 7232 7233 bool success = false; 7234 7235 if (ConditionPassed(opcode)) 7236 { 7237 uint32_t t; 7238 uint32_t imm32; 7239 bool add; 7240 7241 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7242 switch (encoding) 7243 { 7244 case eEncodingT1: 7245 // if Rt == '1111' then SEE PLI; 7246 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7247 t = Bits32 (opcode, 15, 12); 7248 imm32 = Bits32 (opcode, 11, 0); 7249 add = BitIsSet (opcode, 23); 7250 7251 // if t == 13 then UNPREDICTABLE; 7252 if (t == 13) 7253 return false; 7254 7255 break; 7256 7257 case eEncodingA1: 7258 { 7259 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7260 t = Bits32 (opcode, 15, 12); 7261 uint32_t imm4H = Bits32 (opcode, 11, 8); 7262 uint32_t imm4L = Bits32 (opcode, 3, 0); 7263 imm32 = (imm4H << 4) | imm4L; 7264 add = BitIsSet (opcode, 23); 7265 7266 // if t == 15 then UNPREDICTABLE; 7267 if (t == 15) 7268 return false; 7269 7270 break; 7271 } 7272 7273 default: 7274 return false; 7275 } 7276 7277 // base = Align(PC,4); 7278 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7279 if (!success) 7280 return false; 7281 uint64_t base = AlignPC (pc_value); 7282 7283 // address = if add then (base + imm32) else (base - imm32); 7284 addr_t address; 7285 if (add) 7286 address = base + imm32; 7287 else 7288 address = base - imm32; 7289 7290 // R[t] = SignExtend(MemU[address,1], 32); 7291 RegisterInfo base_reg; 7292 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7293 7294 EmulateInstruction::Context context; 7295 context.type = eContextRegisterLoad; 7296 context.SetRegisterPlusOffset (base_reg, address - base); 7297 7298 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7299 if (!success) 7300 return false; 7301 7302 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7303 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7304 return false; 7305 } 7306 return true; 7307 } 7308 7309 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7310 // memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7311 // shifted left by 0, 1, 2, or 3 bits. 7312 bool 7313 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7314 { 7315 #if 0 7316 if ConditionPassed() then 7317 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7318 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7319 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7320 address = if index then offset_addr else R[n]; 7321 R[t] = SignExtend(MemU[address,1], 32); 7322 if wback then R[n] = offset_addr; 7323 #endif 7324 7325 bool success = false; 7326 7327 if (ConditionPassed(opcode)) 7328 { 7329 uint32_t t; 7330 uint32_t n; 7331 uint32_t m; 7332 bool index; 7333 bool add; 7334 bool wback; 7335 ARM_ShifterType shift_t; 7336 uint32_t shift_n; 7337 7338 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7339 switch (encoding) 7340 { 7341 case eEncodingT1: 7342 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7343 t = Bits32 (opcode, 2, 0); 7344 n = Bits32 (opcode, 5, 3); 7345 m = Bits32 (opcode, 8, 6); 7346 7347 // index = TRUE; add = TRUE; wback = FALSE; 7348 index = true; 7349 add = true; 7350 wback = false; 7351 7352 // (shift_t, shift_n) = (SRType_LSL, 0); 7353 shift_t = SRType_LSL; 7354 shift_n = 0; 7355 7356 break; 7357 7358 case eEncodingT2: 7359 // if Rt == '1111' then SEE PLI; 7360 // if Rn == '1111' then SEE LDRSB (literal); 7361 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7362 t = Bits32 (opcode, 15, 12); 7363 n = Bits32 (opcode, 19, 16); 7364 m = Bits32 (opcode, 3, 0); 7365 7366 // index = TRUE; add = TRUE; wback = FALSE; 7367 index = true; 7368 add = true; 7369 wback = false; 7370 7371 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7372 shift_t = SRType_LSL; 7373 shift_n = Bits32 (opcode, 5, 4); 7374 7375 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7376 if ((t == 13) || BadReg (m)) 7377 return false; 7378 break; 7379 7380 case eEncodingA1: 7381 // if P == '0' && W == '1' then SEE LDRSBT; 7382 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7383 t = Bits32 (opcode, 15, 12); 7384 n = Bits32 (opcode, 19, 16); 7385 m = Bits32 (opcode, 3, 0); 7386 7387 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7388 index = BitIsSet (opcode, 24); 7389 add = BitIsSet (opcode, 23); 7390 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7391 7392 // (shift_t, shift_n) = (SRType_LSL, 0); 7393 shift_t = SRType_LSL; 7394 shift_n = 0; 7395 7396 // if t == 15 || m == 15 then UNPREDICTABLE; 7397 if ((t == 15) || (m == 15)) 7398 return false; 7399 7400 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7401 if (wback && ((n == 15) || (n == t))) 7402 return false; 7403 break; 7404 7405 default: 7406 return false; 7407 } 7408 7409 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7410 if (!success) 7411 return false; 7412 7413 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7414 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7415 if (!success) 7416 return false; 7417 7418 addr_t offset_addr; 7419 addr_t address; 7420 7421 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7422 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7423 if (!success) 7424 return false; 7425 7426 if (add) 7427 offset_addr = Rn + offset; 7428 else 7429 offset_addr = Rn - offset; 7430 7431 // address = if index then offset_addr else R[n]; 7432 if (index) 7433 address = offset_addr; 7434 else 7435 address = Rn; 7436 7437 // R[t] = SignExtend(MemU[address,1], 32); 7438 RegisterInfo base_reg; 7439 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7440 RegisterInfo offset_reg; 7441 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7442 7443 EmulateInstruction::Context context; 7444 context.type = eContextRegisterLoad; 7445 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7446 7447 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7448 if (!success) 7449 return false; 7450 7451 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7452 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7453 return false; 7454 7455 // if wback then R[n] = offset_addr; 7456 if (wback) 7457 { 7458 context.type = eContextAdjustBaseRegister; 7459 context.SetAddress (offset_addr); 7460 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7461 return false; 7462 } 7463 } 7464 return true; 7465 } 7466 7467 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7468 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7469 // pre-indexed addressing. 7470 bool 7471 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7472 { 7473 #if 0 7474 if ConditionPassed() then 7475 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7476 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7477 address = if index then offset_addr else R[n]; 7478 data = MemU[address,2]; 7479 if wback then R[n] = offset_addr; 7480 if UnalignedSupport() || address<0> = '0' then 7481 R[t] = SignExtend(data, 32); 7482 else // Can only apply before ARMv7 7483 R[t] = bits(32) UNKNOWN; 7484 #endif 7485 7486 bool success = false; 7487 7488 if (ConditionPassed(opcode)) 7489 { 7490 uint32_t t; 7491 uint32_t n; 7492 uint32_t imm32; 7493 bool index; 7494 bool add; 7495 bool wback; 7496 7497 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7498 switch (encoding) 7499 { 7500 case eEncodingT1: 7501 // if Rn == '1111' then SEE LDRSH (literal); 7502 // if Rt == '1111' then SEE "Unallocated memory hints"; 7503 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7504 t = Bits32 (opcode, 15, 12); 7505 n = Bits32 (opcode, 19, 16); 7506 imm32 = Bits32 (opcode, 11, 0); 7507 7508 // index = TRUE; add = TRUE; wback = FALSE; 7509 index = true; 7510 add = true; 7511 wback = false; 7512 7513 // if t == 13 then UNPREDICTABLE; 7514 if (t == 13) 7515 return false; 7516 7517 break; 7518 7519 case eEncodingT2: 7520 // if Rn == '1111' then SEE LDRSH (literal); 7521 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7522 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7523 // if P == '0' && W == '0' then UNDEFINED; 7524 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7525 return false; 7526 7527 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7528 t = Bits32 (opcode, 15, 12); 7529 n = Bits32 (opcode, 19, 16); 7530 imm32 = Bits32 (opcode, 7, 0); 7531 7532 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7533 index = BitIsSet (opcode, 10); 7534 add = BitIsSet (opcode, 9); 7535 wback = BitIsSet (opcode, 8); 7536 7537 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7538 if (BadReg (t) || (wback && (n == t))) 7539 return false; 7540 7541 break; 7542 7543 case eEncodingA1: 7544 { 7545 // if Rn == '1111' then SEE LDRSH (literal); 7546 // if P == '0' && W == '1' then SEE LDRSHT; 7547 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7548 t = Bits32 (opcode, 15, 12); 7549 n = Bits32 (opcode, 19, 16); 7550 uint32_t imm4H = Bits32 (opcode, 11,8); 7551 uint32_t imm4L = Bits32 (opcode, 3, 0); 7552 imm32 = (imm4H << 4) | imm4L; 7553 7554 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7555 index = BitIsSet (opcode, 24); 7556 add = BitIsSet (opcode, 23); 7557 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7558 7559 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7560 if ((t == 15) || (wback && (n == t))) 7561 return false; 7562 7563 break; 7564 } 7565 7566 default: 7567 return false; 7568 } 7569 7570 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7571 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7572 if (!success) 7573 return false; 7574 7575 addr_t offset_addr; 7576 if (add) 7577 offset_addr = Rn + imm32; 7578 else 7579 offset_addr = Rn - imm32; 7580 7581 // address = if index then offset_addr else R[n]; 7582 addr_t address; 7583 if (index) 7584 address = offset_addr; 7585 else 7586 address = Rn; 7587 7588 // data = MemU[address,2]; 7589 RegisterInfo base_reg; 7590 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7591 7592 EmulateInstruction::Context context; 7593 context.type = eContextRegisterLoad; 7594 context.SetRegisterPlusOffset (base_reg, address - Rn); 7595 7596 uint64_t data = MemURead (context, address, 2, 0, &success); 7597 if (!success) 7598 return false; 7599 7600 // if wback then R[n] = offset_addr; 7601 if (wback) 7602 { 7603 context.type = eContextAdjustBaseRegister; 7604 context.SetAddress (offset_addr); 7605 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7606 return false; 7607 } 7608 7609 // if UnalignedSupport() || address<0> = '0' then 7610 if (UnalignedSupport() || BitIsClear (address, 0)) 7611 { 7612 // R[t] = SignExtend(data, 32); 7613 int64_t signed_data = llvm::SignExtend64<16>(data); 7614 context.type = eContextRegisterLoad; 7615 context.SetRegisterPlusOffset (base_reg, address - Rn); 7616 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7617 return false; 7618 } 7619 else // Can only apply before ARMv7 7620 { 7621 // R[t] = bits(32) UNKNOWN; 7622 WriteBits32Unknown (t); 7623 } 7624 } 7625 return true; 7626 } 7627 7628 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7629 // sign-extends it to from a 32-bit word, and writes it to a register. 7630 bool 7631 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7632 { 7633 #if 0 7634 if ConditionPassed() then 7635 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7636 base = Align(PC,4); 7637 address = if add then (base + imm32) else (base - imm32); 7638 data = MemU[address,2]; 7639 if UnalignedSupport() || address<0> = '0' then 7640 R[t] = SignExtend(data, 32); 7641 else // Can only apply before ARMv7 7642 R[t] = bits(32) UNKNOWN; 7643 #endif 7644 7645 bool success = false; 7646 7647 if (ConditionPassed(opcode)) 7648 { 7649 uint32_t t; 7650 uint32_t imm32; 7651 bool add; 7652 7653 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7654 switch (encoding) 7655 { 7656 case eEncodingT1: 7657 // if Rt == '1111' then SEE "Unallocated memory hints"; 7658 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7659 t = Bits32 (opcode, 15, 12); 7660 imm32 = Bits32 (opcode, 11, 0); 7661 add = BitIsSet (opcode, 23); 7662 7663 // if t == 13 then UNPREDICTABLE; 7664 if (t == 13) 7665 return false; 7666 7667 break; 7668 7669 case eEncodingA1: 7670 { 7671 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7672 t = Bits32 (opcode, 15, 12); 7673 uint32_t imm4H = Bits32 (opcode, 11, 8); 7674 uint32_t imm4L = Bits32 (opcode, 3, 0); 7675 imm32 = (imm4H << 4) | imm4L; 7676 add = BitIsSet (opcode, 23); 7677 7678 // if t == 15 then UNPREDICTABLE; 7679 if (t == 15) 7680 return false; 7681 7682 break; 7683 } 7684 default: 7685 return false; 7686 } 7687 7688 // base = Align(PC,4); 7689 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7690 if (!success) 7691 return false; 7692 7693 uint64_t base = AlignPC (pc_value); 7694 7695 addr_t address; 7696 // address = if add then (base + imm32) else (base - imm32); 7697 if (add) 7698 address = base + imm32; 7699 else 7700 address = base - imm32; 7701 7702 // data = MemU[address,2]; 7703 RegisterInfo base_reg; 7704 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7705 7706 EmulateInstruction::Context context; 7707 context.type = eContextRegisterLoad; 7708 context.SetRegisterPlusOffset (base_reg, imm32); 7709 7710 uint64_t data = MemURead (context, address, 2, 0, &success); 7711 if (!success) 7712 return false; 7713 7714 // if UnalignedSupport() || address<0> = '0' then 7715 if (UnalignedSupport() || BitIsClear (address, 0)) 7716 { 7717 // R[t] = SignExtend(data, 32); 7718 int64_t signed_data = llvm::SignExtend64<16>(data); 7719 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7720 return false; 7721 } 7722 else // Can only apply before ARMv7 7723 { 7724 // R[t] = bits(32) UNKNOWN; 7725 WriteBits32Unknown (t); 7726 } 7727 } 7728 return true; 7729 } 7730 7731 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7732 // from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7733 // shifted left by 0, 1, 2, or 3 bits. 7734 bool 7735 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7736 { 7737 #if 0 7738 if ConditionPassed() then 7739 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7740 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7741 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7742 address = if index then offset_addr else R[n]; 7743 data = MemU[address,2]; 7744 if wback then R[n] = offset_addr; 7745 if UnalignedSupport() || address<0> = '0' then 7746 R[t] = SignExtend(data, 32); 7747 else // Can only apply before ARMv7 7748 R[t] = bits(32) UNKNOWN; 7749 #endif 7750 7751 bool success = false; 7752 7753 if (ConditionPassed(opcode)) 7754 { 7755 uint32_t t; 7756 uint32_t n; 7757 uint32_t m; 7758 bool index; 7759 bool add; 7760 bool wback; 7761 ARM_ShifterType shift_t; 7762 uint32_t shift_n; 7763 7764 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7765 switch (encoding) 7766 { 7767 case eEncodingT1: 7768 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7769 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7770 t = Bits32 (opcode, 2, 0); 7771 n = Bits32 (opcode, 5, 3); 7772 m = Bits32 (opcode, 8, 6); 7773 7774 // index = TRUE; add = TRUE; wback = FALSE; 7775 index = true; 7776 add = true; 7777 wback = false; 7778 7779 // (shift_t, shift_n) = (SRType_LSL, 0); 7780 shift_t = SRType_LSL; 7781 shift_n = 0; 7782 7783 break; 7784 7785 case eEncodingT2: 7786 // if Rn == '1111' then SEE LDRSH (literal); 7787 // if Rt == '1111' then SEE "Unallocated memory hints"; 7788 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7789 t = Bits32 (opcode, 15, 12); 7790 n = Bits32 (opcode, 19, 16); 7791 m = Bits32 (opcode, 3, 0); 7792 7793 // index = TRUE; add = TRUE; wback = FALSE; 7794 index = true; 7795 add = true; 7796 wback = false; 7797 7798 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7799 shift_t = SRType_LSL; 7800 shift_n = Bits32 (opcode, 5, 4); 7801 7802 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7803 if ((t == 13) || BadReg (m)) 7804 return false; 7805 7806 break; 7807 7808 case eEncodingA1: 7809 // if P == '0' && W == '1' then SEE LDRSHT; 7810 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7811 t = Bits32 (opcode, 15, 12); 7812 n = Bits32 (opcode, 19, 16); 7813 m = Bits32 (opcode, 3, 0); 7814 7815 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7816 index = BitIsSet (opcode, 24); 7817 add = BitIsSet (opcode, 23); 7818 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7819 7820 // (shift_t, shift_n) = (SRType_LSL, 0); 7821 shift_t = SRType_LSL; 7822 shift_n = 0; 7823 7824 // if t == 15 || m == 15 then UNPREDICTABLE; 7825 if ((t == 15) || (m == 15)) 7826 return false; 7827 7828 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7829 if (wback && ((n == 15) || (n == t))) 7830 return false; 7831 7832 break; 7833 7834 default: 7835 return false; 7836 } 7837 7838 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7839 if (!success) 7840 return false; 7841 7842 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7843 if (!success) 7844 return false; 7845 7846 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7847 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7848 if (!success) 7849 return false; 7850 7851 addr_t offset_addr; 7852 addr_t address; 7853 7854 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7855 if (add) 7856 offset_addr = Rn + offset; 7857 else 7858 offset_addr = Rn - offset; 7859 7860 // address = if index then offset_addr else R[n]; 7861 if (index) 7862 address = offset_addr; 7863 else 7864 address = Rn; 7865 7866 // data = MemU[address,2]; 7867 RegisterInfo base_reg; 7868 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7869 7870 RegisterInfo offset_reg; 7871 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7872 7873 EmulateInstruction::Context context; 7874 context.type = eContextRegisterLoad; 7875 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7876 7877 uint64_t data = MemURead (context, address, 2, 0, &success); 7878 if (!success) 7879 return false; 7880 7881 // if wback then R[n] = offset_addr; 7882 if (wback) 7883 { 7884 context.type = eContextAdjustBaseRegister; 7885 context.SetAddress (offset_addr); 7886 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7887 return false; 7888 } 7889 7890 // if UnalignedSupport() || address<0> = '0' then 7891 if (UnalignedSupport() || BitIsClear (address, 0)) 7892 { 7893 // R[t] = SignExtend(data, 32); 7894 context.type = eContextRegisterLoad; 7895 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7896 7897 int64_t signed_data = llvm::SignExtend64<16>(data); 7898 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7899 return false; 7900 } 7901 else // Can only apply before ARMv7 7902 { 7903 // R[t] = bits(32) UNKNOWN; 7904 WriteBits32Unknown (t); 7905 } 7906 } 7907 return true; 7908 } 7909 7910 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7911 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7912 bool 7913 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7914 { 7915 #if 0 7916 if ConditionPassed() then 7917 EncodingSpecificOperations(); 7918 rotated = ROR(R[m], rotation); 7919 R[d] = SignExtend(rotated<7:0>, 32); 7920 #endif 7921 7922 bool success = false; 7923 7924 if (ConditionPassed(opcode)) 7925 { 7926 uint32_t d; 7927 uint32_t m; 7928 uint32_t rotation; 7929 7930 // EncodingSpecificOperations(); 7931 switch (encoding) 7932 { 7933 case eEncodingT1: 7934 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7935 d = Bits32 (opcode, 2, 0); 7936 m = Bits32 (opcode, 5, 3); 7937 rotation = 0; 7938 7939 break; 7940 7941 case eEncodingT2: 7942 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7943 d = Bits32 (opcode, 11, 8); 7944 m = Bits32 (opcode, 3, 0); 7945 rotation = Bits32 (opcode, 5, 4) << 3; 7946 7947 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7948 if (BadReg (d) || BadReg (m)) 7949 return false; 7950 7951 break; 7952 7953 case eEncodingA1: 7954 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7955 d = Bits32 (opcode, 15, 12); 7956 m = Bits32 (opcode, 3, 0); 7957 rotation = Bits32 (opcode, 11, 10) << 3; 7958 7959 // if d == 15 || m == 15 then UNPREDICTABLE; 7960 if ((d == 15) || (m == 15)) 7961 return false; 7962 7963 break; 7964 7965 default: 7966 return false; 7967 } 7968 7969 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7970 if (!success) 7971 return false; 7972 7973 // rotated = ROR(R[m], rotation); 7974 uint64_t rotated = ROR (Rm, rotation, &success); 7975 if (!success) 7976 return false; 7977 7978 // R[d] = SignExtend(rotated<7:0>, 32); 7979 int64_t data = llvm::SignExtend64<8>(rotated); 7980 7981 RegisterInfo source_reg; 7982 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7983 7984 EmulateInstruction::Context context; 7985 context.type = eContextRegisterLoad; 7986 context.SetRegister (source_reg); 7987 7988 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7989 return false; 7990 } 7991 return true; 7992 } 7993 7994 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7995 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7996 bool 7997 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7998 { 7999 #if 0 8000 if ConditionPassed() then 8001 EncodingSpecificOperations(); 8002 rotated = ROR(R[m], rotation); 8003 R[d] = SignExtend(rotated<15:0>, 32); 8004 #endif 8005 8006 bool success = false; 8007 8008 if (ConditionPassed(opcode)) 8009 { 8010 uint32_t d; 8011 uint32_t m; 8012 uint32_t rotation; 8013 8014 // EncodingSpecificOperations(); 8015 switch (encoding) 8016 { 8017 case eEncodingT1: 8018 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8019 d = Bits32 (opcode, 2, 0); 8020 m = Bits32 (opcode, 5, 3); 8021 rotation = 0; 8022 8023 break; 8024 8025 case eEncodingT2: 8026 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8027 d = Bits32 (opcode, 11, 8); 8028 m = Bits32 (opcode, 3, 0); 8029 rotation = Bits32 (opcode, 5, 4) << 3; 8030 8031 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8032 if (BadReg (d) || BadReg (m)) 8033 return false; 8034 8035 break; 8036 8037 case eEncodingA1: 8038 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8039 d = Bits32 (opcode, 15, 12); 8040 m = Bits32 (opcode, 3, 0); 8041 rotation = Bits32 (opcode, 11, 10) << 3; 8042 8043 // if d == 15 || m == 15 then UNPREDICTABLE; 8044 if ((d == 15) || (m == 15)) 8045 return false; 8046 8047 break; 8048 8049 default: 8050 return false; 8051 } 8052 8053 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8054 if (!success) 8055 return false; 8056 8057 // rotated = ROR(R[m], rotation); 8058 uint64_t rotated = ROR (Rm, rotation, &success); 8059 if (!success) 8060 return false; 8061 8062 // R[d] = SignExtend(rotated<15:0>, 32); 8063 RegisterInfo source_reg; 8064 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8065 8066 EmulateInstruction::Context context; 8067 context.type = eContextRegisterLoad; 8068 context.SetRegister (source_reg); 8069 8070 int64_t data = llvm::SignExtend64<16> (rotated); 8071 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 8072 return false; 8073 } 8074 8075 return true; 8076 } 8077 8078 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 8079 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 8080 bool 8081 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 8082 { 8083 #if 0 8084 if ConditionPassed() then 8085 EncodingSpecificOperations(); 8086 rotated = ROR(R[m], rotation); 8087 R[d] = ZeroExtend(rotated<7:0>, 32); 8088 #endif 8089 8090 bool success = false; 8091 8092 if (ConditionPassed(opcode)) 8093 { 8094 uint32_t d; 8095 uint32_t m; 8096 uint32_t rotation; 8097 8098 // EncodingSpecificOperations(); 8099 switch (encoding) 8100 { 8101 case eEncodingT1: 8102 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8103 d = Bits32 (opcode, 2, 0); 8104 m = Bits32 (opcode, 5, 3); 8105 rotation = 0; 8106 8107 break; 8108 8109 case eEncodingT2: 8110 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8111 d = Bits32 (opcode, 11, 8); 8112 m = Bits32 (opcode, 3, 0); 8113 rotation = Bits32 (opcode, 5, 4) << 3; 8114 8115 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8116 if (BadReg (d) || BadReg (m)) 8117 return false; 8118 8119 break; 8120 8121 case eEncodingA1: 8122 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8123 d = Bits32 (opcode, 15, 12); 8124 m = Bits32 (opcode, 3, 0); 8125 rotation = Bits32 (opcode, 11, 10) << 3; 8126 8127 // if d == 15 || m == 15 then UNPREDICTABLE; 8128 if ((d == 15) || (m == 15)) 8129 return false; 8130 8131 break; 8132 8133 default: 8134 return false; 8135 } 8136 8137 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8138 if (!success) 8139 return false; 8140 8141 // rotated = ROR(R[m], rotation); 8142 uint64_t rotated = ROR (Rm, rotation, &success); 8143 if (!success) 8144 return false; 8145 8146 // R[d] = ZeroExtend(rotated<7:0>, 32); 8147 RegisterInfo source_reg; 8148 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8149 8150 EmulateInstruction::Context context; 8151 context.type = eContextRegisterLoad; 8152 context.SetRegister (source_reg); 8153 8154 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 8155 return false; 8156 } 8157 return true; 8158 } 8159 8160 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 8161 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 8162 bool 8163 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 8164 { 8165 #if 0 8166 if ConditionPassed() then 8167 EncodingSpecificOperations(); 8168 rotated = ROR(R[m], rotation); 8169 R[d] = ZeroExtend(rotated<15:0>, 32); 8170 #endif 8171 8172 bool success = false; 8173 8174 if (ConditionPassed(opcode)) 8175 { 8176 uint32_t d; 8177 uint32_t m; 8178 uint32_t rotation; 8179 8180 switch (encoding) 8181 { 8182 case eEncodingT1: 8183 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8184 d = Bits32 (opcode, 2, 0); 8185 m = Bits32 (opcode, 5, 3); 8186 rotation = 0; 8187 8188 break; 8189 8190 case eEncodingT2: 8191 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8192 d = Bits32 (opcode, 11, 8); 8193 m = Bits32 (opcode, 3, 0); 8194 rotation = Bits32 (opcode, 5, 4) << 3; 8195 8196 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8197 if (BadReg (d) || BadReg (m)) 8198 return false; 8199 8200 break; 8201 8202 case eEncodingA1: 8203 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8204 d = Bits32 (opcode, 15, 12); 8205 m = Bits32 (opcode, 3, 0); 8206 rotation = Bits32 (opcode, 11, 10) << 3; 8207 8208 // if d == 15 || m == 15 then UNPREDICTABLE; 8209 if ((d == 15) || (m == 15)) 8210 return false; 8211 8212 break; 8213 8214 default: 8215 return false; 8216 } 8217 8218 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8219 if (!success) 8220 return false; 8221 8222 // rotated = ROR(R[m], rotation); 8223 uint64_t rotated = ROR (Rm, rotation, &success); 8224 if (!success) 8225 return false; 8226 8227 // R[d] = ZeroExtend(rotated<15:0>, 32); 8228 RegisterInfo source_reg; 8229 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8230 8231 EmulateInstruction::Context context; 8232 context.type = eContextRegisterLoad; 8233 context.SetRegister (source_reg); 8234 8235 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8236 return false; 8237 } 8238 return true; 8239 } 8240 8241 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8242 // word respectively. 8243 bool 8244 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8245 { 8246 #if 0 8247 if ConditionPassed() then 8248 EncodingSpecificOperations(); 8249 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8250 UNPREDICTABLE; 8251 else 8252 address = if increment then R[n] else R[n]-8; 8253 if wordhigher then address = address+4; 8254 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8255 BranchWritePC(MemA[address,4]); 8256 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8257 #endif 8258 8259 bool success = false; 8260 8261 if (ConditionPassed(opcode)) 8262 { 8263 uint32_t n; 8264 bool wback; 8265 bool increment; 8266 bool wordhigher; 8267 8268 // EncodingSpecificOperations(); 8269 switch (encoding) 8270 { 8271 case eEncodingT1: 8272 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8273 n = Bits32 (opcode, 19, 16); 8274 wback = BitIsSet (opcode, 21); 8275 increment = false; 8276 wordhigher = false; 8277 8278 // if n == 15 then UNPREDICTABLE; 8279 if (n == 15) 8280 return false; 8281 8282 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8283 if (InITBlock() && !LastInITBlock()) 8284 return false; 8285 8286 break; 8287 8288 case eEncodingT2: 8289 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8290 n = Bits32 (opcode, 19, 16); 8291 wback = BitIsSet (opcode, 21); 8292 increment = true; 8293 wordhigher = false; 8294 8295 // if n == 15 then UNPREDICTABLE; 8296 if (n == 15) 8297 return false; 8298 8299 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8300 if (InITBlock() && !LastInITBlock()) 8301 return false; 8302 8303 break; 8304 8305 case eEncodingA1: 8306 // n = UInt(Rn); 8307 n = Bits32 (opcode, 19, 16); 8308 8309 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8310 wback = BitIsSet (opcode, 21); 8311 increment = BitIsSet (opcode, 23); 8312 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8313 8314 // if n == 15 then UNPREDICTABLE; 8315 if (n == 15) 8316 return false; 8317 8318 break; 8319 8320 default: 8321 return false; 8322 } 8323 8324 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8325 if (!CurrentModeIsPrivileged ()) 8326 // UNPREDICTABLE; 8327 return false; 8328 else 8329 { 8330 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8331 if (!success) 8332 return false; 8333 8334 addr_t address; 8335 // address = if increment then R[n] else R[n]-8; 8336 if (increment) 8337 address = Rn; 8338 else 8339 address = Rn - 8; 8340 8341 // if wordhigher then address = address+4; 8342 if (wordhigher) 8343 address = address + 4; 8344 8345 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8346 RegisterInfo base_reg; 8347 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8348 8349 EmulateInstruction::Context context; 8350 context.type = eContextReturnFromException; 8351 context.SetRegisterPlusOffset (base_reg, address - Rn); 8352 8353 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8354 if (!success) 8355 return false; 8356 8357 CPSRWriteByInstr (data, 15, true); 8358 8359 // BranchWritePC(MemA[address,4]); 8360 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8361 if (!success) 8362 return false; 8363 8364 BranchWritePC (context, data2); 8365 8366 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8367 if (wback) 8368 { 8369 context.type = eContextAdjustBaseRegister; 8370 if (increment) 8371 { 8372 context.SetOffset (8); 8373 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8374 return false; 8375 } 8376 else 8377 { 8378 context.SetOffset (-8); 8379 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8380 return false; 8381 } 8382 } // if wback 8383 } 8384 } // if ConditionPassed() 8385 return true; 8386 } 8387 8388 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8389 // and writes the result to the destination register. It can optionally update the condition flags based on 8390 // the result. 8391 bool 8392 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8393 { 8394 #if 0 8395 // ARM pseudo code... 8396 if ConditionPassed() then 8397 EncodingSpecificOperations(); 8398 result = R[n] EOR imm32; 8399 if d == 15 then // Can only occur for ARM encoding 8400 ALUWritePC(result); // setflags is always FALSE here 8401 else 8402 R[d] = result; 8403 if setflags then 8404 APSR.N = result<31>; 8405 APSR.Z = IsZeroBit(result); 8406 APSR.C = carry; 8407 // APSR.V unchanged 8408 #endif 8409 8410 bool success = false; 8411 8412 if (ConditionPassed(opcode)) 8413 { 8414 uint32_t Rd, Rn; 8415 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8416 bool setflags; 8417 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8418 switch (encoding) 8419 { 8420 case eEncodingT1: 8421 Rd = Bits32(opcode, 11, 8); 8422 Rn = Bits32(opcode, 19, 16); 8423 setflags = BitIsSet(opcode, 20); 8424 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8425 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8426 if (Rd == 15 && setflags) 8427 return EmulateTEQImm (opcode, eEncodingT1); 8428 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8429 return false; 8430 break; 8431 case eEncodingA1: 8432 Rd = Bits32(opcode, 15, 12); 8433 Rn = Bits32(opcode, 19, 16); 8434 setflags = BitIsSet(opcode, 20); 8435 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8436 8437 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8438 if (Rd == 15 && setflags) 8439 return EmulateSUBSPcLrEtc (opcode, encoding); 8440 break; 8441 default: 8442 return false; 8443 } 8444 8445 // Read the first operand. 8446 uint32_t val1 = ReadCoreReg(Rn, &success); 8447 if (!success) 8448 return false; 8449 8450 uint32_t result = val1 ^ imm32; 8451 8452 EmulateInstruction::Context context; 8453 context.type = EmulateInstruction::eContextImmediate; 8454 context.SetNoArgs (); 8455 8456 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8457 return false; 8458 } 8459 return true; 8460 } 8461 8462 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8463 // optionally-shifted register value, and writes the result to the destination register. 8464 // It can optionally update the condition flags based on the result. 8465 bool 8466 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8467 { 8468 #if 0 8469 // ARM pseudo code... 8470 if ConditionPassed() then 8471 EncodingSpecificOperations(); 8472 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8473 result = R[n] EOR shifted; 8474 if d == 15 then // Can only occur for ARM encoding 8475 ALUWritePC(result); // setflags is always FALSE here 8476 else 8477 R[d] = result; 8478 if setflags then 8479 APSR.N = result<31>; 8480 APSR.Z = IsZeroBit(result); 8481 APSR.C = carry; 8482 // APSR.V unchanged 8483 #endif 8484 8485 bool success = false; 8486 8487 if (ConditionPassed(opcode)) 8488 { 8489 uint32_t Rd, Rn, Rm; 8490 ARM_ShifterType shift_t; 8491 uint32_t shift_n; // the shift applied to the value read from Rm 8492 bool setflags; 8493 uint32_t carry; 8494 switch (encoding) 8495 { 8496 case eEncodingT1: 8497 Rd = Rn = Bits32(opcode, 2, 0); 8498 Rm = Bits32(opcode, 5, 3); 8499 setflags = !InITBlock(); 8500 shift_t = SRType_LSL; 8501 shift_n = 0; 8502 break; 8503 case eEncodingT2: 8504 Rd = Bits32(opcode, 11, 8); 8505 Rn = Bits32(opcode, 19, 16); 8506 Rm = Bits32(opcode, 3, 0); 8507 setflags = BitIsSet(opcode, 20); 8508 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8509 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8510 if (Rd == 15 && setflags) 8511 return EmulateTEQReg (opcode, eEncodingT1); 8512 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8513 return false; 8514 break; 8515 case eEncodingA1: 8516 Rd = Bits32(opcode, 15, 12); 8517 Rn = Bits32(opcode, 19, 16); 8518 Rm = Bits32(opcode, 3, 0); 8519 setflags = BitIsSet(opcode, 20); 8520 shift_n = DecodeImmShiftARM(opcode, shift_t); 8521 8522 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8523 if (Rd == 15 && setflags) 8524 return EmulateSUBSPcLrEtc (opcode, encoding); 8525 break; 8526 default: 8527 return false; 8528 } 8529 8530 // Read the first operand. 8531 uint32_t val1 = ReadCoreReg(Rn, &success); 8532 if (!success) 8533 return false; 8534 8535 // Read the second operand. 8536 uint32_t val2 = ReadCoreReg(Rm, &success); 8537 if (!success) 8538 return false; 8539 8540 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8541 if (!success) 8542 return false; 8543 uint32_t result = val1 ^ shifted; 8544 8545 EmulateInstruction::Context context; 8546 context.type = EmulateInstruction::eContextImmediate; 8547 context.SetNoArgs (); 8548 8549 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8550 return false; 8551 } 8552 return true; 8553 } 8554 8555 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8556 // writes the result to the destination register. It can optionally update the condition flags based 8557 // on the result. 8558 bool 8559 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8560 { 8561 #if 0 8562 // ARM pseudo code... 8563 if ConditionPassed() then 8564 EncodingSpecificOperations(); 8565 result = R[n] OR imm32; 8566 if d == 15 then // Can only occur for ARM encoding 8567 ALUWritePC(result); // setflags is always FALSE here 8568 else 8569 R[d] = result; 8570 if setflags then 8571 APSR.N = result<31>; 8572 APSR.Z = IsZeroBit(result); 8573 APSR.C = carry; 8574 // APSR.V unchanged 8575 #endif 8576 8577 bool success = false; 8578 8579 if (ConditionPassed(opcode)) 8580 { 8581 uint32_t Rd, Rn; 8582 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8583 bool setflags; 8584 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8585 switch (encoding) 8586 { 8587 case eEncodingT1: 8588 Rd = Bits32(opcode, 11, 8); 8589 Rn = Bits32(opcode, 19, 16); 8590 setflags = BitIsSet(opcode, 20); 8591 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8592 // if Rn == '1111' then SEE MOV (immediate); 8593 if (Rn == 15) 8594 return EmulateMOVRdImm (opcode, eEncodingT2); 8595 if (BadReg(Rd) || Rn == 13) 8596 return false; 8597 break; 8598 case eEncodingA1: 8599 Rd = Bits32(opcode, 15, 12); 8600 Rn = Bits32(opcode, 19, 16); 8601 setflags = BitIsSet(opcode, 20); 8602 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8603 8604 if (Rd == 15 && setflags) 8605 return EmulateSUBSPcLrEtc (opcode, encoding); 8606 break; 8607 default: 8608 return false; 8609 } 8610 8611 // Read the first operand. 8612 uint32_t val1 = ReadCoreReg(Rn, &success); 8613 if (!success) 8614 return false; 8615 8616 uint32_t result = val1 | imm32; 8617 8618 EmulateInstruction::Context context; 8619 context.type = EmulateInstruction::eContextImmediate; 8620 context.SetNoArgs (); 8621 8622 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8623 return false; 8624 } 8625 return true; 8626 } 8627 8628 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8629 // value, and writes the result to the destination register. It can optionally update the condition flags based 8630 // on the result. 8631 bool 8632 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8633 { 8634 #if 0 8635 // ARM pseudo code... 8636 if ConditionPassed() then 8637 EncodingSpecificOperations(); 8638 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8639 result = R[n] OR shifted; 8640 if d == 15 then // Can only occur for ARM encoding 8641 ALUWritePC(result); // setflags is always FALSE here 8642 else 8643 R[d] = result; 8644 if setflags then 8645 APSR.N = result<31>; 8646 APSR.Z = IsZeroBit(result); 8647 APSR.C = carry; 8648 // APSR.V unchanged 8649 #endif 8650 8651 bool success = false; 8652 8653 if (ConditionPassed(opcode)) 8654 { 8655 uint32_t Rd, Rn, Rm; 8656 ARM_ShifterType shift_t; 8657 uint32_t shift_n; // the shift applied to the value read from Rm 8658 bool setflags; 8659 uint32_t carry; 8660 switch (encoding) 8661 { 8662 case eEncodingT1: 8663 Rd = Rn = Bits32(opcode, 2, 0); 8664 Rm = Bits32(opcode, 5, 3); 8665 setflags = !InITBlock(); 8666 shift_t = SRType_LSL; 8667 shift_n = 0; 8668 break; 8669 case eEncodingT2: 8670 Rd = Bits32(opcode, 11, 8); 8671 Rn = Bits32(opcode, 19, 16); 8672 Rm = Bits32(opcode, 3, 0); 8673 setflags = BitIsSet(opcode, 20); 8674 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8675 // if Rn == '1111' then SEE MOV (register); 8676 if (Rn == 15) 8677 return EmulateMOVRdRm (opcode, eEncodingT3); 8678 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8679 return false; 8680 break; 8681 case eEncodingA1: 8682 Rd = Bits32(opcode, 15, 12); 8683 Rn = Bits32(opcode, 19, 16); 8684 Rm = Bits32(opcode, 3, 0); 8685 setflags = BitIsSet(opcode, 20); 8686 shift_n = DecodeImmShiftARM(opcode, shift_t); 8687 8688 if (Rd == 15 && setflags) 8689 return EmulateSUBSPcLrEtc (opcode, encoding); 8690 break; 8691 default: 8692 return false; 8693 } 8694 8695 // Read the first operand. 8696 uint32_t val1 = ReadCoreReg(Rn, &success); 8697 if (!success) 8698 return false; 8699 8700 // Read the second operand. 8701 uint32_t val2 = ReadCoreReg(Rm, &success); 8702 if (!success) 8703 return false; 8704 8705 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8706 if (!success) 8707 return false; 8708 uint32_t result = val1 | shifted; 8709 8710 EmulateInstruction::Context context; 8711 context.type = EmulateInstruction::eContextImmediate; 8712 context.SetNoArgs (); 8713 8714 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8715 return false; 8716 } 8717 return true; 8718 } 8719 8720 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8721 // the destination register. It can optionally update the condition flags based on the result. 8722 bool 8723 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8724 { 8725 #if 0 8726 // ARM pseudo code... 8727 if ConditionPassed() then 8728 EncodingSpecificOperations(); 8729 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8730 if d == 15 then // Can only occur for ARM encoding 8731 ALUWritePC(result); // setflags is always FALSE here 8732 else 8733 R[d] = result; 8734 if setflags then 8735 APSR.N = result<31>; 8736 APSR.Z = IsZeroBit(result); 8737 APSR.C = carry; 8738 APSR.V = overflow; 8739 #endif 8740 8741 bool success = false; 8742 8743 uint32_t Rd; // the destination register 8744 uint32_t Rn; // the first operand 8745 bool setflags; 8746 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8747 switch (encoding) { 8748 case eEncodingT1: 8749 Rd = Bits32(opcode, 2, 0); 8750 Rn = Bits32(opcode, 5, 3); 8751 setflags = !InITBlock(); 8752 imm32 = 0; 8753 break; 8754 case eEncodingT2: 8755 Rd = Bits32(opcode, 11, 8); 8756 Rn = Bits32(opcode, 19, 16); 8757 setflags = BitIsSet(opcode, 20); 8758 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8759 if (BadReg(Rd) || BadReg(Rn)) 8760 return false; 8761 break; 8762 case eEncodingA1: 8763 Rd = Bits32(opcode, 15, 12); 8764 Rn = Bits32(opcode, 19, 16); 8765 setflags = BitIsSet(opcode, 20); 8766 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8767 8768 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8769 if (Rd == 15 && setflags) 8770 return EmulateSUBSPcLrEtc (opcode, encoding); 8771 break; 8772 default: 8773 return false; 8774 } 8775 // Read the register value from the operand register Rn. 8776 uint32_t reg_val = ReadCoreReg(Rn, &success); 8777 if (!success) 8778 return false; 8779 8780 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8781 8782 EmulateInstruction::Context context; 8783 context.type = EmulateInstruction::eContextImmediate; 8784 context.SetNoArgs (); 8785 8786 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8787 return false; 8788 8789 return true; 8790 } 8791 8792 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8793 // result to the destination register. It can optionally update the condition flags based on the result. 8794 bool 8795 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8796 { 8797 #if 0 8798 // ARM pseudo code... 8799 if ConditionPassed() then 8800 EncodingSpecificOperations(); 8801 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8802 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8803 if d == 15 then // Can only occur for ARM encoding 8804 ALUWritePC(result); // setflags is always FALSE here 8805 else 8806 R[d] = result; 8807 if setflags then 8808 APSR.N = result<31>; 8809 APSR.Z = IsZeroBit(result); 8810 APSR.C = carry; 8811 APSR.V = overflow; 8812 #endif 8813 8814 bool success = false; 8815 8816 uint32_t Rd; // the destination register 8817 uint32_t Rn; // the first operand 8818 uint32_t Rm; // the second operand 8819 bool setflags; 8820 ARM_ShifterType shift_t; 8821 uint32_t shift_n; // the shift applied to the value read from Rm 8822 switch (encoding) { 8823 case eEncodingT1: 8824 Rd = Bits32(opcode, 11, 8); 8825 Rn = Bits32(opcode, 19, 16); 8826 Rm = Bits32(opcode, 3, 0); 8827 setflags = BitIsSet(opcode, 20); 8828 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8829 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8830 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8831 return false; 8832 break; 8833 case eEncodingA1: 8834 Rd = Bits32(opcode, 15, 12); 8835 Rn = Bits32(opcode, 19, 16); 8836 Rm = Bits32(opcode, 3, 0); 8837 setflags = BitIsSet(opcode, 20); 8838 shift_n = DecodeImmShiftARM(opcode, shift_t); 8839 8840 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8841 if (Rd == 15 && setflags) 8842 return EmulateSUBSPcLrEtc (opcode, encoding); 8843 break; 8844 default: 8845 return false; 8846 } 8847 // Read the register value from register Rn. 8848 uint32_t val1 = ReadCoreReg(Rn, &success); 8849 if (!success) 8850 return false; 8851 8852 // Read the register value from register Rm. 8853 uint32_t val2 = ReadCoreReg(Rm, &success); 8854 if (!success) 8855 return false; 8856 8857 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8858 if (!success) 8859 return false; 8860 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8861 8862 EmulateInstruction::Context context; 8863 context.type = EmulateInstruction::eContextImmediate; 8864 context.SetNoArgs(); 8865 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8866 return false; 8867 8868 return true; 8869 } 8870 8871 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8872 // an immediate value, and writes the result to the destination register. It can optionally update the condition 8873 // flags based on the result. 8874 bool 8875 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8876 { 8877 #if 0 8878 // ARM pseudo code... 8879 if ConditionPassed() then 8880 EncodingSpecificOperations(); 8881 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8882 if d == 15 then 8883 ALUWritePC(result); // setflags is always FALSE here 8884 else 8885 R[d] = result; 8886 if setflags then 8887 APSR.N = result<31>; 8888 APSR.Z = IsZeroBit(result); 8889 APSR.C = carry; 8890 APSR.V = overflow; 8891 #endif 8892 8893 bool success = false; 8894 8895 uint32_t Rd; // the destination register 8896 uint32_t Rn; // the first operand 8897 bool setflags; 8898 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8899 switch (encoding) { 8900 case eEncodingA1: 8901 Rd = Bits32(opcode, 15, 12); 8902 Rn = Bits32(opcode, 19, 16); 8903 setflags = BitIsSet(opcode, 20); 8904 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8905 8906 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8907 if (Rd == 15 && setflags) 8908 return EmulateSUBSPcLrEtc (opcode, encoding); 8909 break; 8910 default: 8911 return false; 8912 } 8913 // Read the register value from the operand register Rn. 8914 uint32_t reg_val = ReadCoreReg(Rn, &success); 8915 if (!success) 8916 return false; 8917 8918 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8919 8920 EmulateInstruction::Context context; 8921 context.type = EmulateInstruction::eContextImmediate; 8922 context.SetNoArgs (); 8923 8924 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8925 return false; 8926 8927 return true; 8928 } 8929 8930 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8931 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8932 // condition flags based on the result. 8933 bool 8934 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8935 { 8936 #if 0 8937 // ARM pseudo code... 8938 if ConditionPassed() then 8939 EncodingSpecificOperations(); 8940 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8941 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8942 if d == 15 then 8943 ALUWritePC(result); // setflags is always FALSE here 8944 else 8945 R[d] = result; 8946 if setflags then 8947 APSR.N = result<31>; 8948 APSR.Z = IsZeroBit(result); 8949 APSR.C = carry; 8950 APSR.V = overflow; 8951 #endif 8952 8953 bool success = false; 8954 8955 uint32_t Rd; // the destination register 8956 uint32_t Rn; // the first operand 8957 uint32_t Rm; // the second operand 8958 bool setflags; 8959 ARM_ShifterType shift_t; 8960 uint32_t shift_n; // the shift applied to the value read from Rm 8961 switch (encoding) { 8962 case eEncodingA1: 8963 Rd = Bits32(opcode, 15, 12); 8964 Rn = Bits32(opcode, 19, 16); 8965 Rm = Bits32(opcode, 3, 0); 8966 setflags = BitIsSet(opcode, 20); 8967 shift_n = DecodeImmShiftARM(opcode, shift_t); 8968 8969 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8970 if (Rd == 15 && setflags) 8971 return EmulateSUBSPcLrEtc (opcode, encoding); 8972 break; 8973 default: 8974 return false; 8975 } 8976 // Read the register value from register Rn. 8977 uint32_t val1 = ReadCoreReg(Rn, &success); 8978 if (!success) 8979 return false; 8980 8981 // Read the register value from register Rm. 8982 uint32_t val2 = ReadCoreReg(Rm, &success); 8983 if (!success) 8984 return false; 8985 8986 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8987 if (!success) 8988 return false; 8989 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8990 8991 EmulateInstruction::Context context; 8992 context.type = EmulateInstruction::eContextImmediate; 8993 context.SetNoArgs(); 8994 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8995 return false; 8996 8997 return true; 8998 } 8999 9000 // Subtract with Carry (immediate) subtracts an immediate value and the value of 9001 // NOT (Carry flag) from a register value, and writes the result to the destination register. 9002 // It can optionally update the condition flags based on the result. 9003 bool 9004 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 9005 { 9006 #if 0 9007 // ARM pseudo code... 9008 if ConditionPassed() then 9009 EncodingSpecificOperations(); 9010 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 9011 if d == 15 then // Can only occur for ARM encoding 9012 ALUWritePC(result); // setflags is always FALSE here 9013 else 9014 R[d] = result; 9015 if setflags then 9016 APSR.N = result<31>; 9017 APSR.Z = IsZeroBit(result); 9018 APSR.C = carry; 9019 APSR.V = overflow; 9020 #endif 9021 9022 bool success = false; 9023 9024 uint32_t Rd; // the destination register 9025 uint32_t Rn; // the first operand 9026 bool setflags; 9027 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 9028 switch (encoding) { 9029 case eEncodingT1: 9030 Rd = Bits32(opcode, 11, 8); 9031 Rn = Bits32(opcode, 19, 16); 9032 setflags = BitIsSet(opcode, 20); 9033 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9034 if (BadReg(Rd) || BadReg(Rn)) 9035 return false; 9036 break; 9037 case eEncodingA1: 9038 Rd = Bits32(opcode, 15, 12); 9039 Rn = Bits32(opcode, 19, 16); 9040 setflags = BitIsSet(opcode, 20); 9041 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9042 9043 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9044 if (Rd == 15 && setflags) 9045 return EmulateSUBSPcLrEtc (opcode, encoding); 9046 break; 9047 default: 9048 return false; 9049 } 9050 // Read the register value from the operand register Rn. 9051 uint32_t reg_val = ReadCoreReg(Rn, &success); 9052 if (!success) 9053 return false; 9054 9055 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9056 9057 EmulateInstruction::Context context; 9058 context.type = EmulateInstruction::eContextImmediate; 9059 context.SetNoArgs (); 9060 9061 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9062 return false; 9063 9064 return true; 9065 } 9066 9067 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 9068 // NOT (Carry flag) from a register value, and writes the result to the destination register. 9069 // It can optionally update the condition flags based on the result. 9070 bool 9071 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 9072 { 9073 #if 0 9074 // ARM pseudo code... 9075 if ConditionPassed() then 9076 EncodingSpecificOperations(); 9077 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9078 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9079 if d == 15 then // Can only occur for ARM encoding 9080 ALUWritePC(result); // setflags is always FALSE here 9081 else 9082 R[d] = result; 9083 if setflags then 9084 APSR.N = result<31>; 9085 APSR.Z = IsZeroBit(result); 9086 APSR.C = carry; 9087 APSR.V = overflow; 9088 #endif 9089 9090 bool success = false; 9091 9092 uint32_t Rd; // the destination register 9093 uint32_t Rn; // the first operand 9094 uint32_t Rm; // the second operand 9095 bool setflags; 9096 ARM_ShifterType shift_t; 9097 uint32_t shift_n; // the shift applied to the value read from Rm 9098 switch (encoding) { 9099 case eEncodingT1: 9100 Rd = Rn = Bits32(opcode, 2, 0); 9101 Rm = Bits32(opcode, 5, 3); 9102 setflags = !InITBlock(); 9103 shift_t = SRType_LSL; 9104 shift_n = 0; 9105 break; 9106 case eEncodingT2: 9107 Rd = Bits32(opcode, 11, 8); 9108 Rn = Bits32(opcode, 19, 16); 9109 Rm = Bits32(opcode, 3, 0); 9110 setflags = BitIsSet(opcode, 20); 9111 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9112 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9113 return false; 9114 break; 9115 case eEncodingA1: 9116 Rd = Bits32(opcode, 15, 12); 9117 Rn = Bits32(opcode, 19, 16); 9118 Rm = Bits32(opcode, 3, 0); 9119 setflags = BitIsSet(opcode, 20); 9120 shift_n = DecodeImmShiftARM(opcode, shift_t); 9121 9122 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9123 if (Rd == 15 && setflags) 9124 return EmulateSUBSPcLrEtc (opcode, encoding); 9125 break; 9126 default: 9127 return false; 9128 } 9129 // Read the register value from register Rn. 9130 uint32_t val1 = ReadCoreReg(Rn, &success); 9131 if (!success) 9132 return false; 9133 9134 // Read the register value from register Rm. 9135 uint32_t val2 = ReadCoreReg(Rm, &success); 9136 if (!success) 9137 return false; 9138 9139 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9140 if (!success) 9141 return false; 9142 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9143 9144 EmulateInstruction::Context context; 9145 context.type = EmulateInstruction::eContextImmediate; 9146 context.SetNoArgs(); 9147 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9148 return false; 9149 9150 return true; 9151 } 9152 9153 // This instruction subtracts an immediate value from a register value, and writes the result 9154 // to the destination register. It can optionally update the condition flags based on the result. 9155 bool 9156 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9157 { 9158 #if 0 9159 // ARM pseudo code... 9160 if ConditionPassed() then 9161 EncodingSpecificOperations(); 9162 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9163 R[d] = result; 9164 if setflags then 9165 APSR.N = result<31>; 9166 APSR.Z = IsZeroBit(result); 9167 APSR.C = carry; 9168 APSR.V = overflow; 9169 #endif 9170 9171 bool success = false; 9172 9173 uint32_t Rd; // the destination register 9174 uint32_t Rn; // the first operand 9175 bool setflags; 9176 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9177 switch (encoding) { 9178 case eEncodingT1: 9179 Rd = Bits32(opcode, 2, 0); 9180 Rn = Bits32(opcode, 5, 3); 9181 setflags = !InITBlock(); 9182 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9183 break; 9184 case eEncodingT2: 9185 Rd = Rn = Bits32(opcode, 10, 8); 9186 setflags = !InITBlock(); 9187 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9188 break; 9189 case eEncodingT3: 9190 Rd = Bits32(opcode, 11, 8); 9191 Rn = Bits32(opcode, 19, 16); 9192 setflags = BitIsSet(opcode, 20); 9193 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9194 9195 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9196 if (Rd == 15 && setflags) 9197 return EmulateCMPImm (opcode, eEncodingT2); 9198 9199 // if Rn == '1101' then SEE SUB (SP minus immediate); 9200 if (Rn == 13) 9201 return EmulateSUBSPImm (opcode, eEncodingT2); 9202 9203 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9204 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9205 return false; 9206 break; 9207 case eEncodingT4: 9208 Rd = Bits32(opcode, 11, 8); 9209 Rn = Bits32(opcode, 19, 16); 9210 setflags = BitIsSet(opcode, 20); 9211 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9212 9213 // if Rn == '1111' then SEE ADR; 9214 if (Rn == 15) 9215 return EmulateADR (opcode, eEncodingT2); 9216 9217 // if Rn == '1101' then SEE SUB (SP minus immediate); 9218 if (Rn == 13) 9219 return EmulateSUBSPImm (opcode, eEncodingT3); 9220 9221 if (BadReg(Rd)) 9222 return false; 9223 break; 9224 default: 9225 return false; 9226 } 9227 // Read the register value from the operand register Rn. 9228 uint32_t reg_val = ReadCoreReg(Rn, &success); 9229 if (!success) 9230 return false; 9231 9232 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9233 9234 EmulateInstruction::Context context; 9235 context.type = EmulateInstruction::eContextImmediate; 9236 context.SetNoArgs (); 9237 9238 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9239 return false; 9240 9241 return true; 9242 } 9243 9244 // This instruction subtracts an immediate value from a register value, and writes the result 9245 // to the destination register. It can optionally update the condition flags based on the result. 9246 bool 9247 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9248 { 9249 #if 0 9250 // ARM pseudo code... 9251 if ConditionPassed() then 9252 EncodingSpecificOperations(); 9253 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9254 if d == 15 then 9255 ALUWritePC(result); // setflags is always FALSE here 9256 else 9257 R[d] = result; 9258 if setflags then 9259 APSR.N = result<31>; 9260 APSR.Z = IsZeroBit(result); 9261 APSR.C = carry; 9262 APSR.V = overflow; 9263 #endif 9264 9265 bool success = false; 9266 9267 if (ConditionPassed(opcode)) 9268 { 9269 uint32_t Rd; // the destination register 9270 uint32_t Rn; // the first operand 9271 bool setflags; 9272 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9273 switch (encoding) { 9274 case eEncodingA1: 9275 Rd = Bits32(opcode, 15, 12); 9276 Rn = Bits32(opcode, 19, 16); 9277 setflags = BitIsSet(opcode, 20); 9278 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9279 9280 // if Rn == '1111' && S == '0' then SEE ADR; 9281 if (Rn == 15 && !setflags) 9282 return EmulateADR (opcode, eEncodingA2); 9283 9284 // if Rn == '1101' then SEE SUB (SP minus immediate); 9285 if (Rn == 13) 9286 return EmulateSUBSPImm (opcode, eEncodingA1); 9287 9288 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9289 if (Rd == 15 && setflags) 9290 return EmulateSUBSPcLrEtc (opcode, encoding); 9291 break; 9292 default: 9293 return false; 9294 } 9295 // Read the register value from the operand register Rn. 9296 uint32_t reg_val = ReadCoreReg(Rn, &success); 9297 if (!success) 9298 return false; 9299 9300 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9301 9302 EmulateInstruction::Context context; 9303 if (Rd == 13) 9304 context.type = EmulateInstruction::eContextAdjustStackPointer; 9305 else 9306 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9307 9308 RegisterInfo dwarf_reg; 9309 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 9310 int64_t imm32_signed = imm32; 9311 context.SetRegisterPlusOffset (dwarf_reg, -imm32_signed); 9312 9313 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9314 return false; 9315 } 9316 return true; 9317 } 9318 9319 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9320 // immediate value. It updates the condition flags based on the result, and discards the result. 9321 bool 9322 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9323 { 9324 #if 0 9325 // ARM pseudo code... 9326 if ConditionPassed() then 9327 EncodingSpecificOperations(); 9328 result = R[n] EOR imm32; 9329 APSR.N = result<31>; 9330 APSR.Z = IsZeroBit(result); 9331 APSR.C = carry; 9332 // APSR.V unchanged 9333 #endif 9334 9335 bool success = false; 9336 9337 if (ConditionPassed(opcode)) 9338 { 9339 uint32_t Rn; 9340 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9341 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9342 switch (encoding) 9343 { 9344 case eEncodingT1: 9345 Rn = Bits32(opcode, 19, 16); 9346 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9347 if (BadReg(Rn)) 9348 return false; 9349 break; 9350 case eEncodingA1: 9351 Rn = Bits32(opcode, 19, 16); 9352 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9353 break; 9354 default: 9355 return false; 9356 } 9357 9358 // Read the first operand. 9359 uint32_t val1 = ReadCoreReg(Rn, &success); 9360 if (!success) 9361 return false; 9362 9363 uint32_t result = val1 ^ imm32; 9364 9365 EmulateInstruction::Context context; 9366 context.type = EmulateInstruction::eContextImmediate; 9367 context.SetNoArgs (); 9368 9369 if (!WriteFlags(context, result, carry)) 9370 return false; 9371 } 9372 return true; 9373 } 9374 9375 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9376 // optionally-shifted register value. It updates the condition flags based on the result, and discards 9377 // the result. 9378 bool 9379 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9380 { 9381 #if 0 9382 // ARM pseudo code... 9383 if ConditionPassed() then 9384 EncodingSpecificOperations(); 9385 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9386 result = R[n] EOR shifted; 9387 APSR.N = result<31>; 9388 APSR.Z = IsZeroBit(result); 9389 APSR.C = carry; 9390 // APSR.V unchanged 9391 #endif 9392 9393 bool success = false; 9394 9395 if (ConditionPassed(opcode)) 9396 { 9397 uint32_t Rn, Rm; 9398 ARM_ShifterType shift_t; 9399 uint32_t shift_n; // the shift applied to the value read from Rm 9400 uint32_t carry; 9401 switch (encoding) 9402 { 9403 case eEncodingT1: 9404 Rn = Bits32(opcode, 19, 16); 9405 Rm = Bits32(opcode, 3, 0); 9406 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9407 if (BadReg(Rn) || BadReg(Rm)) 9408 return false; 9409 break; 9410 case eEncodingA1: 9411 Rn = Bits32(opcode, 19, 16); 9412 Rm = Bits32(opcode, 3, 0); 9413 shift_n = DecodeImmShiftARM(opcode, shift_t); 9414 break; 9415 default: 9416 return false; 9417 } 9418 9419 // Read the first operand. 9420 uint32_t val1 = ReadCoreReg(Rn, &success); 9421 if (!success) 9422 return false; 9423 9424 // Read the second operand. 9425 uint32_t val2 = ReadCoreReg(Rm, &success); 9426 if (!success) 9427 return false; 9428 9429 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9430 if (!success) 9431 return false; 9432 uint32_t result = val1 ^ shifted; 9433 9434 EmulateInstruction::Context context; 9435 context.type = EmulateInstruction::eContextImmediate; 9436 context.SetNoArgs (); 9437 9438 if (!WriteFlags(context, result, carry)) 9439 return false; 9440 } 9441 return true; 9442 } 9443 9444 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9445 // It updates the condition flags based on the result, and discards the result. 9446 bool 9447 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9448 { 9449 #if 0 9450 // ARM pseudo code... 9451 if ConditionPassed() then 9452 EncodingSpecificOperations(); 9453 result = R[n] AND imm32; 9454 APSR.N = result<31>; 9455 APSR.Z = IsZeroBit(result); 9456 APSR.C = carry; 9457 // APSR.V unchanged 9458 #endif 9459 9460 bool success = false; 9461 9462 if (ConditionPassed(opcode)) 9463 { 9464 uint32_t Rn; 9465 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9466 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9467 switch (encoding) 9468 { 9469 case eEncodingT1: 9470 Rn = Bits32(opcode, 19, 16); 9471 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9472 if (BadReg(Rn)) 9473 return false; 9474 break; 9475 case eEncodingA1: 9476 Rn = Bits32(opcode, 19, 16); 9477 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9478 break; 9479 default: 9480 return false; 9481 } 9482 9483 // Read the first operand. 9484 uint32_t val1 = ReadCoreReg(Rn, &success); 9485 if (!success) 9486 return false; 9487 9488 uint32_t result = val1 & imm32; 9489 9490 EmulateInstruction::Context context; 9491 context.type = EmulateInstruction::eContextImmediate; 9492 context.SetNoArgs (); 9493 9494 if (!WriteFlags(context, result, carry)) 9495 return false; 9496 } 9497 return true; 9498 } 9499 9500 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9501 // It updates the condition flags based on the result, and discards the result. 9502 bool 9503 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9504 { 9505 #if 0 9506 // ARM pseudo code... 9507 if ConditionPassed() then 9508 EncodingSpecificOperations(); 9509 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9510 result = R[n] AND shifted; 9511 APSR.N = result<31>; 9512 APSR.Z = IsZeroBit(result); 9513 APSR.C = carry; 9514 // APSR.V unchanged 9515 #endif 9516 9517 bool success = false; 9518 9519 if (ConditionPassed(opcode)) 9520 { 9521 uint32_t Rn, Rm; 9522 ARM_ShifterType shift_t; 9523 uint32_t shift_n; // the shift applied to the value read from Rm 9524 uint32_t carry; 9525 switch (encoding) 9526 { 9527 case eEncodingT1: 9528 Rn = Bits32(opcode, 2, 0); 9529 Rm = Bits32(opcode, 5, 3); 9530 shift_t = SRType_LSL; 9531 shift_n = 0; 9532 break; 9533 case eEncodingT2: 9534 Rn = Bits32(opcode, 19, 16); 9535 Rm = Bits32(opcode, 3, 0); 9536 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9537 if (BadReg(Rn) || BadReg(Rm)) 9538 return false; 9539 break; 9540 case eEncodingA1: 9541 Rn = Bits32(opcode, 19, 16); 9542 Rm = Bits32(opcode, 3, 0); 9543 shift_n = DecodeImmShiftARM(opcode, shift_t); 9544 break; 9545 default: 9546 return false; 9547 } 9548 9549 // Read the first operand. 9550 uint32_t val1 = ReadCoreReg(Rn, &success); 9551 if (!success) 9552 return false; 9553 9554 // Read the second operand. 9555 uint32_t val2 = ReadCoreReg(Rm, &success); 9556 if (!success) 9557 return false; 9558 9559 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9560 if (!success) 9561 return false; 9562 uint32_t result = val1 & shifted; 9563 9564 EmulateInstruction::Context context; 9565 context.type = EmulateInstruction::eContextImmediate; 9566 context.SetNoArgs (); 9567 9568 if (!WriteFlags(context, result, carry)) 9569 return false; 9570 } 9571 return true; 9572 } 9573 9574 // A8.6.216 SUB (SP minus register) 9575 bool 9576 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9577 { 9578 #if 0 9579 if ConditionPassed() then 9580 EncodingSpecificOperations(); 9581 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9582 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9583 if d == 15 then // Can only occur for ARM encoding 9584 ALUWritePC(result); // setflags is always FALSE here 9585 else 9586 R[d] = result; 9587 if setflags then 9588 APSR.N = result<31>; 9589 APSR.Z = IsZeroBit(result); 9590 APSR.C = carry; 9591 APSR.V = overflow; 9592 #endif 9593 9594 bool success = false; 9595 9596 if (ConditionPassed(opcode)) 9597 { 9598 uint32_t d; 9599 uint32_t m; 9600 bool setflags; 9601 ARM_ShifterType shift_t; 9602 uint32_t shift_n; 9603 9604 switch (encoding) 9605 { 9606 case eEncodingT1: 9607 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9608 d = Bits32 (opcode, 11, 8); 9609 m = Bits32 (opcode, 3, 0); 9610 setflags = BitIsSet (opcode, 20); 9611 9612 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9613 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9614 9615 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9616 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9617 return false; 9618 9619 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9620 if ((d == 15) || BadReg (m)) 9621 return false; 9622 break; 9623 9624 case eEncodingA1: 9625 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9626 d = Bits32 (opcode, 15, 12); 9627 m = Bits32 (opcode, 3, 0); 9628 setflags = BitIsSet (opcode, 20); 9629 9630 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9631 if (d == 15 && setflags) 9632 EmulateSUBSPcLrEtc (opcode, encoding); 9633 9634 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9635 shift_n = DecodeImmShiftARM (opcode, shift_t); 9636 break; 9637 9638 default: 9639 return false; 9640 } 9641 9642 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9643 uint32_t Rm = ReadCoreReg (m, &success); 9644 if (!success) 9645 return false; 9646 9647 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9648 if (!success) 9649 return false; 9650 9651 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9652 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9653 if (!success) 9654 return false; 9655 9656 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9657 9658 EmulateInstruction::Context context; 9659 context.type = eContextArithmetic; 9660 RegisterInfo sp_reg; 9661 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9662 RegisterInfo dwarf_reg; 9663 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9664 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9665 9666 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9667 return false; 9668 } 9669 return true; 9670 } 9671 9672 9673 // A8.6.7 ADD (register-shifted register) 9674 bool 9675 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9676 { 9677 #if 0 9678 if ConditionPassed() then 9679 EncodingSpecificOperations(); 9680 shift_n = UInt(R[s]<7:0>); 9681 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9682 (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9683 R[d] = result; 9684 if setflags then 9685 APSR.N = result<31>; 9686 APSR.Z = IsZeroBit(result); 9687 APSR.C = carry; 9688 APSR.V = overflow; 9689 #endif 9690 9691 bool success = false; 9692 9693 if (ConditionPassed(opcode)) 9694 { 9695 uint32_t d; 9696 uint32_t n; 9697 uint32_t m; 9698 uint32_t s; 9699 bool setflags; 9700 ARM_ShifterType shift_t; 9701 9702 switch (encoding) 9703 { 9704 case eEncodingA1: 9705 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9706 d = Bits32 (opcode, 15, 12); 9707 n = Bits32 (opcode, 19, 16); 9708 m = Bits32 (opcode, 3, 0); 9709 s = Bits32 (opcode, 11, 8); 9710 9711 // setflags = (S == �1�); shift_t = DecodeRegShift(type); 9712 setflags = BitIsSet (opcode, 20); 9713 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9714 9715 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9716 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9717 return false; 9718 break; 9719 9720 default: 9721 return false; 9722 } 9723 9724 // shift_n = UInt(R[s]<7:0>); 9725 uint32_t Rs = ReadCoreReg (s, &success); 9726 if (!success) 9727 return false; 9728 9729 uint32_t shift_n = Bits32 (Rs, 7, 0); 9730 9731 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9732 uint32_t Rm = ReadCoreReg (m, &success); 9733 if (!success) 9734 return false; 9735 9736 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9737 if (!success) 9738 return false; 9739 9740 // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9741 uint32_t Rn = ReadCoreReg (n, &success); 9742 if (!success) 9743 return false; 9744 9745 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9746 9747 // R[d] = result; 9748 EmulateInstruction::Context context; 9749 context.type = eContextArithmetic; 9750 RegisterInfo reg_n; 9751 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9752 RegisterInfo reg_m; 9753 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9754 9755 context.SetRegisterRegisterOperands (reg_n, reg_m); 9756 9757 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9758 return false; 9759 9760 // if setflags then 9761 // APSR.N = result<31>; 9762 // APSR.Z = IsZeroBit(result); 9763 // APSR.C = carry; 9764 // APSR.V = overflow; 9765 if (setflags) 9766 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9767 } 9768 return true; 9769 } 9770 9771 // A8.6.213 SUB (register) 9772 bool 9773 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9774 { 9775 #if 0 9776 if ConditionPassed() then 9777 EncodingSpecificOperations(); 9778 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9779 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9780 if d == 15 then // Can only occur for ARM encoding 9781 ALUWritePC(result); // setflags is always FALSE here 9782 else 9783 R[d] = result; 9784 if setflags then 9785 APSR.N = result<31>; 9786 APSR.Z = IsZeroBit(result); 9787 APSR.C = carry; 9788 APSR.V = overflow; 9789 #endif 9790 9791 bool success = false; 9792 9793 if (ConditionPassed(opcode)) 9794 { 9795 uint32_t d; 9796 uint32_t n; 9797 uint32_t m; 9798 bool setflags; 9799 ARM_ShifterType shift_t; 9800 uint32_t shift_n; 9801 9802 switch (encoding) 9803 { 9804 case eEncodingT1: 9805 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9806 d = Bits32 (opcode, 2, 0); 9807 n = Bits32 (opcode, 5, 3); 9808 m = Bits32 (opcode, 8, 6); 9809 setflags = !InITBlock(); 9810 9811 // (shift_t, shift_n) = (SRType_LSL, 0); 9812 shift_t = SRType_LSL; 9813 shift_n = 0; 9814 9815 break; 9816 9817 case eEncodingT2: 9818 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 9819 d = Bits32 (opcode, 11, 8); 9820 n = Bits32 (opcode, 19, 16); 9821 m = Bits32 (opcode, 3, 0); 9822 setflags = BitIsSet (opcode, 20); 9823 9824 // if Rd == "1111" && S == "1" then SEE CMP (register); 9825 if (d == 15 && setflags == 1) 9826 return EmulateCMPImm (opcode, eEncodingT3); 9827 9828 // if Rn == "1101" then SEE SUB (SP minus register); 9829 if (n == 13) 9830 return EmulateSUBSPReg (opcode, eEncodingT1); 9831 9832 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9833 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9834 9835 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9836 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9837 return false; 9838 9839 break; 9840 9841 case eEncodingA1: 9842 // if Rn == �1101� then SEE SUB (SP minus register); 9843 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9844 d = Bits32 (opcode, 15, 12); 9845 n = Bits32 (opcode, 19, 16); 9846 m = Bits32 (opcode, 3, 0); 9847 setflags = BitIsSet (opcode, 20); 9848 9849 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9850 if ((d == 15) && setflags) 9851 EmulateSUBSPcLrEtc (opcode, encoding); 9852 9853 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9854 shift_n = DecodeImmShiftARM (opcode, shift_t); 9855 9856 break; 9857 9858 default: 9859 return false; 9860 } 9861 9862 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9863 uint32_t Rm = ReadCoreReg (m, &success); 9864 if (!success) 9865 return false; 9866 9867 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9868 if (!success) 9869 return false; 9870 9871 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9872 uint32_t Rn = ReadCoreReg (n, &success); 9873 if (!success) 9874 return false; 9875 9876 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9877 9878 // if d == 15 then // Can only occur for ARM encoding 9879 // ALUWritePC(result); // setflags is always FALSE here 9880 // else 9881 // R[d] = result; 9882 // if setflags then 9883 // APSR.N = result<31>; 9884 // APSR.Z = IsZeroBit(result); 9885 // APSR.C = carry; 9886 // APSR.V = overflow; 9887 9888 EmulateInstruction::Context context; 9889 context.type = eContextArithmetic; 9890 RegisterInfo reg_n; 9891 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9892 RegisterInfo reg_m; 9893 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9894 context.SetRegisterRegisterOperands (reg_n, reg_m); 9895 9896 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9897 return false; 9898 } 9899 return true; 9900 } 9901 9902 // A8.6.202 STREX 9903 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9904 // word from a register to memory if the executing processor has exclusive access to the memory addressed. 9905 bool 9906 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9907 { 9908 #if 0 9909 if ConditionPassed() then 9910 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9911 address = R[n] + imm32; 9912 if ExclusiveMonitorsPass(address,4) then 9913 MemA[address,4] = R[t]; 9914 R[d] = 0; 9915 else 9916 R[d] = 1; 9917 #endif 9918 9919 bool success = false; 9920 9921 if (ConditionPassed(opcode)) 9922 { 9923 uint32_t d; 9924 uint32_t t; 9925 uint32_t n; 9926 uint32_t imm32; 9927 const uint32_t addr_byte_size = GetAddressByteSize(); 9928 9929 switch (encoding) 9930 { 9931 case eEncodingT1: 9932 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 9933 d = Bits32 (opcode, 11, 8); 9934 t = Bits32 (opcode, 15, 12); 9935 n = Bits32 (opcode, 19, 16); 9936 imm32 = Bits32 (opcode, 7, 0) << 2; 9937 9938 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9939 if (BadReg (d) || BadReg (t) || (n == 15)) 9940 return false; 9941 9942 // if d == n || d == t then UNPREDICTABLE; 9943 if ((d == n) || (d == t)) 9944 return false; 9945 9946 break; 9947 9948 case eEncodingA1: 9949 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9950 d = Bits32 (opcode, 15, 12); 9951 t = Bits32 (opcode, 3, 0); 9952 n = Bits32 (opcode, 19, 16); 9953 imm32 = 0; 9954 9955 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9956 if ((d == 15) || (t == 15) || (n == 15)) 9957 return false; 9958 9959 // if d == n || d == t then UNPREDICTABLE; 9960 if ((d == n) || (d == t)) 9961 return false; 9962 9963 break; 9964 9965 default: 9966 return false; 9967 } 9968 9969 // address = R[n] + imm32; 9970 uint32_t Rn = ReadCoreReg (n, &success); 9971 if (!success) 9972 return false; 9973 9974 addr_t address = Rn + imm32; 9975 9976 RegisterInfo base_reg; 9977 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9978 RegisterInfo data_reg; 9979 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9980 EmulateInstruction::Context context; 9981 context.type = eContextRegisterStore; 9982 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9983 9984 // if ExclusiveMonitorsPass(address,4) then 9985 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9986 // always return true. 9987 if (true) 9988 { 9989 // MemA[address,4] = R[t]; 9990 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9991 if (!success) 9992 return false; 9993 9994 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9995 return false; 9996 9997 // R[d] = 0; 9998 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9999 return false; 10000 } 10001 #if 0 // unreachable because if true 10002 else 10003 { 10004 // R[d] = 1; 10005 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 10006 return false; 10007 } 10008 #endif // unreachable because if true 10009 } 10010 return true; 10011 } 10012 10013 // A8.6.197 STRB (immediate, ARM) 10014 bool 10015 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 10016 { 10017 #if 0 10018 if ConditionPassed() then 10019 EncodingSpecificOperations(); 10020 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10021 address = if index then offset_addr else R[n]; 10022 MemU[address,1] = R[t]<7:0>; 10023 if wback then R[n] = offset_addr; 10024 #endif 10025 10026 bool success = false; 10027 10028 if (ConditionPassed(opcode)) 10029 { 10030 uint32_t t; 10031 uint32_t n; 10032 uint32_t imm32; 10033 bool index; 10034 bool add; 10035 bool wback; 10036 10037 switch (encoding) 10038 { 10039 case eEncodingA1: 10040 // if P == �0� && W == �1� then SEE STRBT; 10041 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10042 t = Bits32 (opcode, 15, 12); 10043 n = Bits32 (opcode, 19, 16); 10044 imm32 = Bits32 (opcode, 11, 0); 10045 10046 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10047 index = BitIsSet (opcode, 24); 10048 add = BitIsSet (opcode, 23); 10049 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10050 10051 // if t == 15 then UNPREDICTABLE; 10052 if (t == 15) 10053 return false; 10054 10055 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10056 if (wback && ((n == 15) || (n == t))) 10057 return false; 10058 10059 break; 10060 10061 default: 10062 return false; 10063 } 10064 10065 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10066 uint32_t Rn = ReadCoreReg (n, &success); 10067 if (!success) 10068 return false; 10069 10070 addr_t offset_addr; 10071 if (add) 10072 offset_addr = Rn + imm32; 10073 else 10074 offset_addr = Rn - imm32; 10075 10076 // address = if index then offset_addr else R[n]; 10077 addr_t address; 10078 if (index) 10079 address = offset_addr; 10080 else 10081 address = Rn; 10082 10083 // MemU[address,1] = R[t]<7:0>; 10084 uint32_t Rt = ReadCoreReg (t, &success); 10085 if (!success) 10086 return false; 10087 10088 RegisterInfo base_reg; 10089 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10090 RegisterInfo data_reg; 10091 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10092 EmulateInstruction::Context context; 10093 context.type = eContextRegisterStore; 10094 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10095 10096 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 10097 return false; 10098 10099 // if wback then R[n] = offset_addr; 10100 if (wback) 10101 { 10102 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10103 return false; 10104 } 10105 } 10106 return true; 10107 } 10108 10109 // A8.6.194 STR (immediate, ARM) 10110 bool 10111 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 10112 { 10113 #if 0 10114 if ConditionPassed() then 10115 EncodingSpecificOperations(); 10116 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10117 address = if index then offset_addr else R[n]; 10118 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10119 if wback then R[n] = offset_addr; 10120 #endif 10121 10122 bool success = false; 10123 10124 if (ConditionPassed(opcode)) 10125 { 10126 uint32_t t; 10127 uint32_t n; 10128 uint32_t imm32; 10129 bool index; 10130 bool add; 10131 bool wback; 10132 10133 const uint32_t addr_byte_size = GetAddressByteSize(); 10134 10135 switch (encoding) 10136 { 10137 case eEncodingA1: 10138 // if P == �0� && W == �1� then SEE STRT; 10139 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH; 10140 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10141 t = Bits32 (opcode, 15, 12); 10142 n = Bits32 (opcode, 19, 16); 10143 imm32 = Bits32 (opcode, 11, 0); 10144 10145 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10146 index = BitIsSet (opcode, 24); 10147 add = BitIsSet (opcode, 23); 10148 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10149 10150 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10151 if (wback && ((n == 15) || (n == t))) 10152 return false; 10153 10154 break; 10155 10156 default: 10157 return false; 10158 } 10159 10160 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10161 uint32_t Rn = ReadCoreReg (n, &success); 10162 if (!success) 10163 return false; 10164 10165 addr_t offset_addr; 10166 if (add) 10167 offset_addr = Rn + imm32; 10168 else 10169 offset_addr = Rn - imm32; 10170 10171 // address = if index then offset_addr else R[n]; 10172 addr_t address; 10173 if (index) 10174 address = offset_addr; 10175 else 10176 address = Rn; 10177 10178 RegisterInfo base_reg; 10179 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10180 RegisterInfo data_reg; 10181 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10182 EmulateInstruction::Context context; 10183 context.type = eContextRegisterStore; 10184 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10185 10186 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10187 uint32_t Rt = ReadCoreReg (t, &success); 10188 if (!success) 10189 return false; 10190 10191 if (t == 15) 10192 { 10193 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10194 if (!success) 10195 return false; 10196 10197 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10198 return false; 10199 } 10200 else 10201 { 10202 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10203 return false; 10204 } 10205 10206 // if wback then R[n] = offset_addr; 10207 if (wback) 10208 { 10209 context.type = eContextAdjustBaseRegister; 10210 context.SetImmediate (offset_addr); 10211 10212 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10213 return false; 10214 } 10215 } 10216 return true; 10217 } 10218 10219 // A8.6.66 LDRD (immediate) 10220 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10221 // words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10222 bool 10223 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10224 { 10225 #if 0 10226 if ConditionPassed() then 10227 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10228 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10229 address = if index then offset_addr else R[n]; 10230 R[t] = MemA[address,4]; 10231 R[t2] = MemA[address+4,4]; 10232 if wback then R[n] = offset_addr; 10233 #endif 10234 10235 bool success = false; 10236 10237 if (ConditionPassed(opcode)) 10238 { 10239 uint32_t t; 10240 uint32_t t2; 10241 uint32_t n; 10242 uint32_t imm32; 10243 bool index; 10244 bool add; 10245 bool wback; 10246 10247 switch (encoding) 10248 { 10249 case eEncodingT1: 10250 //if P == �0� && W == �0� then SEE �Related encodings�; 10251 //if Rn == �1111� then SEE LDRD (literal); 10252 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10253 t = Bits32 (opcode, 15, 12); 10254 t2 = Bits32 (opcode, 11, 8); 10255 n = Bits32 (opcode, 19, 16); 10256 imm32 = Bits32 (opcode, 7, 0) << 2; 10257 10258 //index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10259 index = BitIsSet (opcode, 24); 10260 add = BitIsSet (opcode, 23); 10261 wback = BitIsSet (opcode, 21); 10262 10263 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10264 if (wback && ((n == t) || (n == t2))) 10265 return false; 10266 10267 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10268 if (BadReg (t) || BadReg (t2) || (t == t2)) 10269 return false; 10270 10271 break; 10272 10273 case eEncodingA1: 10274 //if Rn == �1111� then SEE LDRD (literal); 10275 //if Rt<0> == �1� then UNPREDICTABLE; 10276 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10277 t = Bits32 (opcode, 15, 12); 10278 if (BitIsSet (t, 0)) 10279 return false; 10280 t2 = t + 1; 10281 n = Bits32 (opcode, 19, 16); 10282 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10283 10284 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10285 index = BitIsSet (opcode, 24); 10286 add = BitIsSet (opcode, 23); 10287 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10288 10289 //if P == �0� && W == �1� then UNPREDICTABLE; 10290 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10291 return false; 10292 10293 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10294 if (wback && ((n == t) || (n == t2))) 10295 return false; 10296 10297 //if t2 == 15 then UNPREDICTABLE; 10298 if (t2 == 15) 10299 return false; 10300 10301 break; 10302 10303 default: 10304 return false; 10305 } 10306 10307 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10308 uint32_t Rn = ReadCoreReg (n, &success); 10309 if (!success) 10310 return false; 10311 10312 addr_t offset_addr; 10313 if (add) 10314 offset_addr = Rn + imm32; 10315 else 10316 offset_addr = Rn - imm32; 10317 10318 //address = if index then offset_addr else R[n]; 10319 addr_t address; 10320 if (index) 10321 address = offset_addr; 10322 else 10323 address = Rn; 10324 10325 //R[t] = MemA[address,4]; 10326 RegisterInfo base_reg; 10327 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10328 10329 EmulateInstruction::Context context; 10330 context.type = eContextRegisterLoad; 10331 context.SetRegisterPlusOffset (base_reg, address - Rn); 10332 10333 const uint32_t addr_byte_size = GetAddressByteSize(); 10334 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10335 if (!success) 10336 return false; 10337 10338 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10339 return false; 10340 10341 //R[t2] = MemA[address+4,4]; 10342 10343 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10344 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10345 if (!success) 10346 return false; 10347 10348 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10349 return false; 10350 10351 //if wback then R[n] = offset_addr; 10352 if (wback) 10353 { 10354 context.type = eContextAdjustBaseRegister; 10355 context.SetAddress (offset_addr); 10356 10357 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10358 return false; 10359 } 10360 } 10361 return true; 10362 } 10363 10364 // A8.6.68 LDRD (register) 10365 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10366 // words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10367 bool 10368 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10369 { 10370 #if 0 10371 if ConditionPassed() then 10372 EncodingSpecificOperations(); 10373 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10374 address = if index then offset_addr else R[n]; 10375 R[t] = MemA[address,4]; 10376 R[t2] = MemA[address+4,4]; 10377 if wback then R[n] = offset_addr; 10378 #endif 10379 10380 bool success = false; 10381 10382 if (ConditionPassed(opcode)) 10383 { 10384 uint32_t t; 10385 uint32_t t2; 10386 uint32_t n; 10387 uint32_t m; 10388 bool index; 10389 bool add; 10390 bool wback; 10391 10392 switch (encoding) 10393 { 10394 case eEncodingA1: 10395 // if Rt<0> == �1� then UNPREDICTABLE; 10396 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10397 t = Bits32 (opcode, 15, 12); 10398 if (BitIsSet (t, 0)) 10399 return false; 10400 t2 = t + 1; 10401 n = Bits32 (opcode, 19, 16); 10402 m = Bits32 (opcode, 3, 0); 10403 10404 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10405 index = BitIsSet (opcode, 24); 10406 add = BitIsSet (opcode, 23); 10407 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10408 10409 // if P == �0� && W == �1� then UNPREDICTABLE; 10410 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10411 return false; 10412 10413 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10414 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10415 return false; 10416 10417 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10418 if (wback && ((n == 15) || (n == t) || (n == t2))) 10419 return false; 10420 10421 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10422 if ((ArchVersion() < 6) && wback && (m == n)) 10423 return false; 10424 break; 10425 10426 default: 10427 return false; 10428 } 10429 10430 uint32_t Rn = ReadCoreReg (n, &success); 10431 if (!success) 10432 return false; 10433 RegisterInfo base_reg; 10434 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10435 10436 uint32_t Rm = ReadCoreReg (m, &success); 10437 if (!success) 10438 return false; 10439 RegisterInfo offset_reg; 10440 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10441 10442 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10443 addr_t offset_addr; 10444 if (add) 10445 offset_addr = Rn + Rm; 10446 else 10447 offset_addr = Rn - Rm; 10448 10449 // address = if index then offset_addr else R[n]; 10450 addr_t address; 10451 if (index) 10452 address = offset_addr; 10453 else 10454 address = Rn; 10455 10456 EmulateInstruction::Context context; 10457 context.type = eContextRegisterLoad; 10458 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10459 10460 // R[t] = MemA[address,4]; 10461 const uint32_t addr_byte_size = GetAddressByteSize(); 10462 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10463 if (!success) 10464 return false; 10465 10466 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10467 return false; 10468 10469 // R[t2] = MemA[address+4,4]; 10470 10471 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10472 if (!success) 10473 return false; 10474 10475 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10476 return false; 10477 10478 // if wback then R[n] = offset_addr; 10479 if (wback) 10480 { 10481 context.type = eContextAdjustBaseRegister; 10482 context.SetAddress (offset_addr); 10483 10484 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10485 return false; 10486 } 10487 } 10488 return true; 10489 } 10490 10491 // A8.6.200 STRD (immediate) 10492 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10493 // stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10494 bool 10495 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10496 { 10497 #if 0 10498 if ConditionPassed() then 10499 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10500 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10501 address = if index then offset_addr else R[n]; 10502 MemA[address,4] = R[t]; 10503 MemA[address+4,4] = R[t2]; 10504 if wback then R[n] = offset_addr; 10505 #endif 10506 10507 bool success = false; 10508 10509 if (ConditionPassed(opcode)) 10510 { 10511 uint32_t t; 10512 uint32_t t2; 10513 uint32_t n; 10514 uint32_t imm32; 10515 bool index; 10516 bool add; 10517 bool wback; 10518 10519 switch (encoding) 10520 { 10521 case eEncodingT1: 10522 // if P == �0� && W == �0� then SEE �Related encodings�; 10523 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10524 t = Bits32 (opcode, 15, 12); 10525 t2 = Bits32 (opcode, 11, 8); 10526 n = Bits32 (opcode, 19, 16); 10527 imm32 = Bits32 (opcode, 7, 0) << 2; 10528 10529 // index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10530 index = BitIsSet (opcode, 24); 10531 add = BitIsSet (opcode, 23); 10532 wback = BitIsSet (opcode, 21); 10533 10534 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10535 if (wback && ((n == t) || (n == t2))) 10536 return false; 10537 10538 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10539 if ((n == 15) || BadReg (t) || BadReg (t2)) 10540 return false; 10541 10542 break; 10543 10544 case eEncodingA1: 10545 // if Rt<0> == �1� then UNPREDICTABLE; 10546 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 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 imm32 = (Bits32 (opcode, 11, 8) << 4) | 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 wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10565 if (wback && ((n == 15) || (n == t) || (n == t2))) 10566 return false; 10567 10568 // if t2 == 15 then UNPREDICTABLE; 10569 if (t2 == 15) 10570 return false; 10571 10572 break; 10573 10574 default: 10575 return false; 10576 } 10577 10578 RegisterInfo base_reg; 10579 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10580 10581 uint32_t Rn = ReadCoreReg (n, &success); 10582 if (!success) 10583 return false; 10584 10585 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10586 addr_t offset_addr; 10587 if (add) 10588 offset_addr = Rn + imm32; 10589 else 10590 offset_addr = Rn - imm32; 10591 10592 //address = if index then offset_addr else R[n]; 10593 addr_t address; 10594 if (index) 10595 address = offset_addr; 10596 else 10597 address = Rn; 10598 10599 //MemA[address,4] = R[t]; 10600 RegisterInfo data_reg; 10601 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10602 10603 uint32_t data = ReadCoreReg (t, &success); 10604 if (!success) 10605 return false; 10606 10607 EmulateInstruction::Context context; 10608 context.type = eContextRegisterStore; 10609 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10610 10611 const uint32_t addr_byte_size = GetAddressByteSize(); 10612 10613 if (!MemAWrite (context, address, data, addr_byte_size)) 10614 return false; 10615 10616 //MemA[address+4,4] = R[t2]; 10617 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10618 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10619 10620 data = ReadCoreReg (t2, &success); 10621 if (!success) 10622 return false; 10623 10624 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10625 return false; 10626 10627 //if wback then R[n] = offset_addr; 10628 if (wback) 10629 { 10630 context.type = eContextAdjustBaseRegister; 10631 context.SetAddress (offset_addr); 10632 10633 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10634 return false; 10635 } 10636 } 10637 return true; 10638 } 10639 10640 10641 // A8.6.201 STRD (register) 10642 bool 10643 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10644 { 10645 #if 0 10646 if ConditionPassed() then 10647 EncodingSpecificOperations(); 10648 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10649 address = if index then offset_addr else R[n]; 10650 MemA[address,4] = R[t]; 10651 MemA[address+4,4] = R[t2]; 10652 if wback then R[n] = offset_addr; 10653 #endif 10654 10655 bool success = false; 10656 10657 if (ConditionPassed(opcode)) 10658 { 10659 uint32_t t; 10660 uint32_t t2; 10661 uint32_t n; 10662 uint32_t m; 10663 bool index; 10664 bool add; 10665 bool wback; 10666 10667 switch (encoding) 10668 { 10669 case eEncodingA1: 10670 // if Rt<0> == �1� then UNPREDICTABLE; 10671 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10672 t = Bits32 (opcode, 15, 12); 10673 if (BitIsSet (t, 0)) 10674 return false; 10675 10676 t2 = t+1; 10677 n = Bits32 (opcode, 19, 16); 10678 m = Bits32 (opcode, 3, 0); 10679 10680 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10681 index = BitIsSet (opcode, 24); 10682 add = BitIsSet (opcode, 23); 10683 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10684 10685 // if P == �0� && W == �1� then UNPREDICTABLE; 10686 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10687 return false; 10688 10689 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10690 if ((t2 == 15) || (m == 15)) 10691 return false; 10692 10693 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10694 if (wback && ((n == 15) || (n == t) || (n == t2))) 10695 return false; 10696 10697 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10698 if ((ArchVersion() < 6) && wback && (m == n)) 10699 return false; 10700 10701 break; 10702 10703 default: 10704 return false; 10705 } 10706 10707 RegisterInfo base_reg; 10708 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10709 RegisterInfo offset_reg; 10710 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10711 RegisterInfo data_reg; 10712 10713 uint32_t Rn = ReadCoreReg (n, &success); 10714 if (!success) 10715 return false; 10716 10717 uint32_t Rm = ReadCoreReg (m, &success); 10718 if (!success) 10719 return false; 10720 10721 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10722 addr_t offset_addr; 10723 if (add) 10724 offset_addr = Rn + Rm; 10725 else 10726 offset_addr = Rn - Rm; 10727 10728 // address = if index then offset_addr else R[n]; 10729 addr_t address; 10730 if (index) 10731 address = offset_addr; 10732 else 10733 address = Rn; 10734 // MemA[address,4] = R[t]; 10735 uint32_t Rt = ReadCoreReg (t, &success); 10736 if (!success) 10737 return false; 10738 10739 EmulateInstruction::Context context; 10740 context.type = eContextRegisterStore; 10741 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10742 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10743 10744 const uint32_t addr_byte_size = GetAddressByteSize(); 10745 10746 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10747 return false; 10748 10749 // MemA[address+4,4] = R[t2]; 10750 uint32_t Rt2 = ReadCoreReg (t2, &success); 10751 if (!success) 10752 return false; 10753 10754 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10755 10756 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10757 10758 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10759 return false; 10760 10761 // if wback then R[n] = offset_addr; 10762 if (wback) 10763 { 10764 context.type = eContextAdjustBaseRegister; 10765 context.SetAddress (offset_addr); 10766 10767 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10768 return false; 10769 10770 } 10771 } 10772 return true; 10773 } 10774 10775 // A8.6.319 VLDM 10776 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10777 // an ARM core register. 10778 bool 10779 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10780 { 10781 #if 0 10782 if ConditionPassed() then 10783 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10784 address = if add then R[n] else R[n]-imm32; 10785 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10786 for r = 0 to regs-1 10787 if single_regs then 10788 S[d+r] = MemA[address,4]; address = address+4; 10789 else 10790 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10791 // Combine the word-aligned words in the correct order for current endianness. 10792 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10793 #endif 10794 10795 bool success = false; 10796 10797 if (ConditionPassed(opcode)) 10798 { 10799 bool single_regs; 10800 bool add; 10801 bool wback; 10802 uint32_t d; 10803 uint32_t n; 10804 uint32_t imm32; 10805 uint32_t regs; 10806 10807 switch (encoding) 10808 { 10809 case eEncodingT1: 10810 case eEncodingA1: 10811 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10812 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10813 // if P == �1� && W == �0� then SEE VLDR; 10814 // if P == U && W == �1� then UNDEFINED; 10815 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10816 return false; 10817 10818 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10819 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10820 single_regs = false; 10821 add = BitIsSet (opcode, 23); 10822 wback = BitIsSet (opcode, 21); 10823 10824 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10825 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10826 n = Bits32 (opcode, 19, 16); 10827 imm32 = Bits32 (opcode, 7, 0) << 2; 10828 10829 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�. 10830 regs = Bits32 (opcode, 7, 0) / 2; 10831 10832 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10833 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10834 return false; 10835 10836 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10837 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10838 return false; 10839 10840 break; 10841 10842 case eEncodingT2: 10843 case eEncodingA2: 10844 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10845 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10846 // if P == �1� && W == �0� then SEE VLDR; 10847 // if P == U && W == �1� then UNDEFINED; 10848 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10849 return false; 10850 10851 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10852 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10853 single_regs = true; 10854 add = BitIsSet (opcode, 23); 10855 wback = BitIsSet (opcode, 21); 10856 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10857 n = Bits32 (opcode, 19, 16); 10858 10859 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10860 imm32 = Bits32 (opcode, 7, 0) << 2; 10861 regs = Bits32 (opcode, 7, 0); 10862 10863 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10864 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10865 return false; 10866 10867 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10868 if ((regs == 0) || ((d + regs) > 32)) 10869 return false; 10870 break; 10871 10872 default: 10873 return false; 10874 } 10875 10876 RegisterInfo base_reg; 10877 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10878 10879 uint32_t Rn = ReadCoreReg (n, &success); 10880 if (!success) 10881 return false; 10882 10883 // address = if add then R[n] else R[n]-imm32; 10884 addr_t address; 10885 if (add) 10886 address = Rn; 10887 else 10888 address = Rn - imm32; 10889 10890 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10891 EmulateInstruction::Context context; 10892 10893 if (wback) 10894 { 10895 uint32_t value; 10896 if (add) 10897 value = Rn + imm32; 10898 else 10899 value = Rn - imm32; 10900 10901 context.type = eContextAdjustBaseRegister; 10902 context.SetImmediateSigned (value - Rn); 10903 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10904 return false; 10905 10906 } 10907 10908 const uint32_t addr_byte_size = GetAddressByteSize(); 10909 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10910 10911 context.type = eContextRegisterLoad; 10912 10913 // for r = 0 to regs-1 10914 for (uint32_t r = 0; r < regs; ++r) 10915 { 10916 if (single_regs) 10917 { 10918 // S[d+r] = MemA[address,4]; address = address+4; 10919 context.SetRegisterPlusOffset (base_reg, address - Rn); 10920 10921 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10922 if (!success) 10923 return false; 10924 10925 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10926 return false; 10927 10928 address = address + 4; 10929 } 10930 else 10931 { 10932 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10933 context.SetRegisterPlusOffset (base_reg, address - Rn); 10934 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10935 if (!success) 10936 return false; 10937 10938 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10939 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10940 if (!success) 10941 return false; 10942 10943 address = address + 8; 10944 // // Combine the word-aligned words in the correct order for current endianness. 10945 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10946 uint64_t data; 10947 if (GetByteOrder() == eByteOrderBig) 10948 { 10949 data = word1; 10950 data = (data << 32) | word2; 10951 } 10952 else 10953 { 10954 data = word2; 10955 data = (data << 32) | word1; 10956 } 10957 10958 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10959 return false; 10960 } 10961 } 10962 } 10963 return true; 10964 } 10965 10966 // A8.6.399 VSTM 10967 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10968 // ARM core register. 10969 bool 10970 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10971 { 10972 #if 0 10973 if ConditionPassed() then 10974 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10975 address = if add then R[n] else R[n]-imm32; 10976 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10977 for r = 0 to regs-1 10978 if single_regs then 10979 MemA[address,4] = S[d+r]; address = address+4; 10980 else 10981 // Store as two word-aligned words in the correct order for current endianness. 10982 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10983 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10984 address = address+8; 10985 #endif 10986 10987 bool success = false; 10988 10989 if (ConditionPassed (opcode)) 10990 { 10991 bool single_regs; 10992 bool add; 10993 bool wback; 10994 uint32_t d; 10995 uint32_t n; 10996 uint32_t imm32; 10997 uint32_t regs; 10998 10999 switch (encoding) 11000 { 11001 case eEncodingT1: 11002 case eEncodingA1: 11003 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 11004 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 11005 // if P == �1� && W == �0� then SEE VSTR; 11006 // if P == U && W == �1� then UNDEFINED; 11007 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 11008 return false; 11009 11010 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 11011 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 11012 single_regs = false; 11013 add = BitIsSet (opcode, 23); 11014 wback = BitIsSet (opcode, 21); 11015 11016 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 11017 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11018 n = Bits32 (opcode, 19, 16); 11019 imm32 = Bits32 (opcode, 7, 0) << 2; 11020 11021 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�. 11022 regs = Bits32 (opcode, 7, 0) / 2; 11023 11024 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 11025 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11026 return false; 11027 11028 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11029 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11030 return false; 11031 11032 break; 11033 11034 case eEncodingT2: 11035 case eEncodingA2: 11036 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 11037 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 11038 // if P == �1� && W == �0� then SEE VSTR; 11039 // if P == U && W == �1� then UNDEFINED; 11040 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 11041 return false; 11042 11043 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 11044 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 11045 single_regs = true; 11046 add = BitIsSet (opcode, 23); 11047 wback = BitIsSet (opcode, 21); 11048 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11049 n = Bits32 (opcode, 19, 16); 11050 11051 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 11052 imm32 = Bits32 (opcode, 7, 0) << 2; 11053 regs = Bits32 (opcode, 7, 0); 11054 11055 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 11056 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 11057 return false; 11058 11059 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11060 if ((regs == 0) || ((d + regs) > 32)) 11061 return false; 11062 11063 break; 11064 11065 default: 11066 return false; 11067 } 11068 11069 RegisterInfo base_reg; 11070 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11071 11072 uint32_t Rn = ReadCoreReg (n, &success); 11073 if (!success) 11074 return false; 11075 11076 // address = if add then R[n] else R[n]-imm32; 11077 addr_t address; 11078 if (add) 11079 address = Rn; 11080 else 11081 address = Rn - imm32; 11082 11083 EmulateInstruction::Context context; 11084 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11085 if (wback) 11086 { 11087 uint32_t value; 11088 if (add) 11089 value = Rn + imm32; 11090 else 11091 value = Rn - imm32; 11092 11093 context.type = eContextAdjustBaseRegister; 11094 context.SetRegisterPlusOffset (base_reg, value - Rn); 11095 11096 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11097 return false; 11098 } 11099 11100 const uint32_t addr_byte_size = GetAddressByteSize(); 11101 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11102 11103 context.type = eContextRegisterStore; 11104 // for r = 0 to regs-1 11105 for (uint32_t r = 0; r < regs; ++r) 11106 { 11107 11108 if (single_regs) 11109 { 11110 // MemA[address,4] = S[d+r]; address = address+4; 11111 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11112 if (!success) 11113 return false; 11114 11115 RegisterInfo data_reg; 11116 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11117 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11118 if (!MemAWrite (context, address, data, addr_byte_size)) 11119 return false; 11120 11121 address = address + 4; 11122 } 11123 else 11124 { 11125 // // Store as two word-aligned words in the correct order for current endianness. 11126 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11127 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11128 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11129 if (!success) 11130 return false; 11131 11132 RegisterInfo data_reg; 11133 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11134 11135 if (GetByteOrder() == eByteOrderBig) 11136 { 11137 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11138 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11139 return false; 11140 11141 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11142 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 11143 return false; 11144 } 11145 else 11146 { 11147 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11148 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11149 return false; 11150 11151 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11152 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11153 return false; 11154 } 11155 // address = address+8; 11156 address = address + 8; 11157 } 11158 } 11159 } 11160 return true; 11161 } 11162 11163 // A8.6.320 11164 // This instruction loads a single extension register from memory, using an address from an ARM core register, with 11165 // an optional offset. 11166 bool 11167 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 11168 { 11169 #if 0 11170 if ConditionPassed() then 11171 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11172 base = if n == 15 then Align(PC,4) else R[n]; 11173 address = if add then (base + imm32) else (base - imm32); 11174 if single_reg then 11175 S[d] = MemA[address,4]; 11176 else 11177 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11178 // Combine the word-aligned words in the correct order for current endianness. 11179 D[d] = if BigEndian() then word1:word2 else word2:word1; 11180 #endif 11181 11182 bool success = false; 11183 11184 if (ConditionPassed (opcode)) 11185 { 11186 bool single_reg; 11187 bool add; 11188 uint32_t imm32; 11189 uint32_t d; 11190 uint32_t n; 11191 11192 switch (encoding) 11193 { 11194 case eEncodingT1: 11195 case eEncodingA1: 11196 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11197 single_reg = false; 11198 add = BitIsSet (opcode, 23); 11199 imm32 = Bits32 (opcode, 7, 0) << 2; 11200 11201 // d = UInt(D:Vd); n = UInt(Rn); 11202 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11203 n = Bits32 (opcode, 19, 16); 11204 11205 break; 11206 11207 case eEncodingT2: 11208 case eEncodingA2: 11209 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11210 single_reg = true; 11211 add = BitIsSet (opcode, 23); 11212 imm32 = Bits32 (opcode, 7, 0) << 2; 11213 11214 // d = UInt(Vd:D); n = UInt(Rn); 11215 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11216 n = Bits32 (opcode, 19, 16); 11217 11218 break; 11219 11220 default: 11221 return false; 11222 } 11223 RegisterInfo base_reg; 11224 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11225 11226 uint32_t Rn = ReadCoreReg (n, &success); 11227 if (!success) 11228 return false; 11229 11230 // base = if n == 15 then Align(PC,4) else R[n]; 11231 uint32_t base; 11232 if (n == 15) 11233 base = AlignPC (Rn); 11234 else 11235 base = Rn; 11236 11237 // address = if add then (base + imm32) else (base - imm32); 11238 addr_t address; 11239 if (add) 11240 address = base + imm32; 11241 else 11242 address = base - imm32; 11243 11244 const uint32_t addr_byte_size = GetAddressByteSize(); 11245 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11246 11247 EmulateInstruction::Context context; 11248 context.type = eContextRegisterLoad; 11249 context.SetRegisterPlusOffset (base_reg, address - base); 11250 11251 if (single_reg) 11252 { 11253 // S[d] = MemA[address,4]; 11254 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11255 if (!success) 11256 return false; 11257 11258 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11259 return false; 11260 } 11261 else 11262 { 11263 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11264 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11265 if (!success) 11266 return false; 11267 11268 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11269 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11270 if (!success) 11271 return false; 11272 // // Combine the word-aligned words in the correct order for current endianness. 11273 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11274 uint64_t data64; 11275 if (GetByteOrder() == eByteOrderBig) 11276 { 11277 data64 = word1; 11278 data64 = (data64 << 32) | word2; 11279 } 11280 else 11281 { 11282 data64 = word2; 11283 data64 = (data64 << 32) | word1; 11284 } 11285 11286 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11287 return false; 11288 } 11289 } 11290 return true; 11291 } 11292 11293 // A8.6.400 VSTR 11294 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11295 // optional offset. 11296 bool 11297 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11298 { 11299 #if 0 11300 if ConditionPassed() then 11301 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11302 address = if add then (R[n] + imm32) else (R[n] - imm32); 11303 if single_reg then 11304 MemA[address,4] = S[d]; 11305 else 11306 // Store as two word-aligned words in the correct order for current endianness. 11307 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11308 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11309 #endif 11310 11311 bool success = false; 11312 11313 if (ConditionPassed (opcode)) 11314 { 11315 bool single_reg; 11316 bool add; 11317 uint32_t imm32; 11318 uint32_t d; 11319 uint32_t n; 11320 11321 switch (encoding) 11322 { 11323 case eEncodingT1: 11324 case eEncodingA1: 11325 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11326 single_reg = false; 11327 add = BitIsSet (opcode, 23); 11328 imm32 = Bits32 (opcode, 7, 0) << 2; 11329 11330 // d = UInt(D:Vd); n = UInt(Rn); 11331 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11332 n = Bits32 (opcode, 19, 16); 11333 11334 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11335 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11336 return false; 11337 11338 break; 11339 11340 case eEncodingT2: 11341 case eEncodingA2: 11342 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11343 single_reg = true; 11344 add = BitIsSet (opcode, 23); 11345 imm32 = Bits32 (opcode, 7, 0) << 2; 11346 11347 // d = UInt(Vd:D); n = UInt(Rn); 11348 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11349 n = Bits32 (opcode, 19, 16); 11350 11351 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11352 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11353 return false; 11354 11355 break; 11356 11357 default: 11358 return false; 11359 } 11360 11361 RegisterInfo base_reg; 11362 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11363 11364 uint32_t Rn = ReadCoreReg (n, &success); 11365 if (!success) 11366 return false; 11367 11368 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11369 addr_t address; 11370 if (add) 11371 address = Rn + imm32; 11372 else 11373 address = Rn - imm32; 11374 11375 const uint32_t addr_byte_size = GetAddressByteSize(); 11376 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11377 11378 RegisterInfo data_reg; 11379 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11380 EmulateInstruction::Context context; 11381 context.type = eContextRegisterStore; 11382 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11383 11384 if (single_reg) 11385 { 11386 // MemA[address,4] = S[d]; 11387 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11388 if (!success) 11389 return false; 11390 11391 if (!MemAWrite (context, address, data, addr_byte_size)) 11392 return false; 11393 } 11394 else 11395 { 11396 // // Store as two word-aligned words in the correct order for current endianness. 11397 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11398 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11399 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11400 if (!success) 11401 return false; 11402 11403 if (GetByteOrder() == eByteOrderBig) 11404 { 11405 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11406 return false; 11407 11408 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11409 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11410 return false; 11411 } 11412 else 11413 { 11414 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11415 return false; 11416 11417 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11418 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11419 return false; 11420 } 11421 } 11422 } 11423 return true; 11424 } 11425 11426 // A8.6.307 VLDI1 (multiple single elements) 11427 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11428 // element of each register is loaded. 11429 bool 11430 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11431 { 11432 #if 0 11433 if ConditionPassed() then 11434 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11435 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11436 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11437 for r = 0 to regs-1 11438 for e = 0 to elements-1 11439 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11440 address = address + ebytes; 11441 #endif 11442 11443 bool success = false; 11444 11445 if (ConditionPassed (opcode)) 11446 { 11447 uint32_t regs; 11448 uint32_t alignment; 11449 uint32_t ebytes; 11450 uint32_t esize; 11451 uint32_t elements; 11452 uint32_t d; 11453 uint32_t n; 11454 uint32_t m; 11455 bool wback; 11456 bool register_index; 11457 11458 switch (encoding) 11459 { 11460 case eEncodingT1: 11461 case eEncodingA1: 11462 { 11463 // case type of 11464 // when �0111� 11465 // regs = 1; if align<1> == �1� then UNDEFINED; 11466 // when �1010� 11467 // regs = 2; if align == �11� then UNDEFINED; 11468 // when �0110� 11469 // regs = 3; if align<1> == �1� then UNDEFINED; 11470 // when �0010� 11471 // regs = 4; 11472 // otherwise 11473 // SEE �Related encodings�; 11474 uint32_t type = Bits32 (opcode, 11, 8); 11475 uint32_t align = Bits32 (opcode, 5, 4); 11476 if (type == 7) // '0111' 11477 { 11478 regs = 1; 11479 if (BitIsSet (align, 1)) 11480 return false; 11481 } 11482 else if (type == 10) // '1010' 11483 { 11484 regs = 2; 11485 if (align == 3) 11486 return false; 11487 11488 } 11489 else if (type == 6) // '0110' 11490 { 11491 regs = 3; 11492 if (BitIsSet (align, 1)) 11493 return false; 11494 } 11495 else if (type == 2) // '0010' 11496 { 11497 regs = 4; 11498 } 11499 else 11500 return false; 11501 11502 // alignment = if align == �00� then 1 else 4 << UInt(align); 11503 if (align == 0) 11504 alignment = 1; 11505 else 11506 alignment = 4 << align; 11507 11508 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11509 ebytes = 1 << Bits32 (opcode, 7, 6); 11510 esize = 8 * ebytes; 11511 elements = 8 / ebytes; 11512 11513 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11514 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11515 n = Bits32 (opcode, 19, 15); 11516 m = Bits32 (opcode, 3, 0); 11517 11518 // wback = (m != 15); register_index = (m != 15 && m != 13); 11519 wback = (m != 15); 11520 register_index = ((m != 15) && (m != 13)); 11521 11522 // if d+regs > 32 then UNPREDICTABLE; 11523 if ((d + regs) > 32) 11524 return false; 11525 } 11526 break; 11527 11528 default: 11529 return false; 11530 } 11531 11532 RegisterInfo base_reg; 11533 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11534 11535 uint32_t Rn = ReadCoreReg (n, &success); 11536 if (!success) 11537 return false; 11538 11539 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11540 addr_t address = Rn; 11541 if ((address % alignment) != 0) 11542 return false; 11543 11544 EmulateInstruction::Context context; 11545 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11546 if (wback) 11547 { 11548 uint32_t Rm = ReadCoreReg (m, &success); 11549 if (!success) 11550 return false; 11551 11552 uint32_t offset; 11553 if (register_index) 11554 offset = Rm; 11555 else 11556 offset = 8 * regs; 11557 11558 uint32_t value = Rn + offset; 11559 context.type = eContextAdjustBaseRegister; 11560 context.SetRegisterPlusOffset (base_reg, offset); 11561 11562 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11563 return false; 11564 11565 } 11566 11567 // for r = 0 to regs-1 11568 for (uint32_t r = 0; r < regs; ++r) 11569 { 11570 // for e = 0 to elements-1 11571 uint64_t assembled_data = 0; 11572 for (uint32_t e = 0; e < elements; ++e) 11573 { 11574 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11575 context.type = eContextRegisterLoad; 11576 context.SetRegisterPlusOffset (base_reg, address - Rn); 11577 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11578 if (!success) 11579 return false; 11580 11581 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11582 11583 // address = address + ebytes; 11584 address = address + ebytes; 11585 } 11586 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11587 return false; 11588 } 11589 } 11590 return true; 11591 } 11592 11593 // A8.6.308 VLD1 (single element to one lane) 11594 // 11595 bool 11596 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11597 { 11598 #if 0 11599 if ConditionPassed() then 11600 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11601 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11602 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11603 Elem[D[d],index,esize] = MemU[address,ebytes]; 11604 #endif 11605 11606 bool success = false; 11607 11608 if (ConditionPassed (opcode)) 11609 { 11610 uint32_t ebytes; 11611 uint32_t esize; 11612 uint32_t index; 11613 uint32_t alignment; 11614 uint32_t d; 11615 uint32_t n; 11616 uint32_t m; 11617 bool wback; 11618 bool register_index; 11619 11620 switch (encoding) 11621 { 11622 case eEncodingT1: 11623 case eEncodingA1: 11624 { 11625 uint32_t size = Bits32 (opcode, 11, 10); 11626 uint32_t index_align = Bits32 (opcode, 7, 4); 11627 // if size == �11� then SEE VLD1 (single element to all lanes); 11628 if (size == 3) 11629 return EmulateVLD1SingleAll (opcode, encoding); 11630 // case size of 11631 if (size == 0) // when '00' 11632 { 11633 // if index_align<0> != �0� then UNDEFINED; 11634 if (BitIsClear (index_align, 0)) 11635 return false; 11636 11637 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11638 ebytes = 1; 11639 esize = 8; 11640 index = Bits32 (index_align, 3, 1); 11641 alignment = 1; 11642 } 11643 else if (size == 1) // when �01� 11644 { 11645 // if index_align<1> != �0� then UNDEFINED; 11646 if (BitIsClear (index_align, 1)) 11647 return false; 11648 11649 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11650 ebytes = 2; 11651 esize = 16; 11652 index = Bits32 (index_align, 3, 2); 11653 11654 // alignment = if index_align<0> == �0� then 1 else 2; 11655 if (BitIsClear (index_align, 0)) 11656 alignment = 1; 11657 else 11658 alignment = 2; 11659 } 11660 else if (size == 2) // when �10� 11661 { 11662 // if index_align<2> != �0� then UNDEFINED; 11663 if (BitIsClear (index_align, 2)) 11664 return false; 11665 11666 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11667 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11668 return false; 11669 11670 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11671 ebytes = 4; 11672 esize = 32; 11673 index = Bit32 (index_align, 3); 11674 11675 // alignment = if index_align<1:0> == �00� then 1 else 4; 11676 if (Bits32 (index_align, 1, 0) == 0) 11677 alignment = 1; 11678 else 11679 alignment = 4; 11680 } 11681 else 11682 { 11683 return false; 11684 } 11685 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11686 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11687 n = Bits32 (opcode, 19, 16); 11688 m = Bits32 (opcode, 3, 0); 11689 11690 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11691 wback = (m != 15); 11692 register_index = ((m != 15) && (m != 13)); 11693 11694 if (n == 15) 11695 return false; 11696 11697 } 11698 break; 11699 11700 default: 11701 return false; 11702 } 11703 11704 RegisterInfo base_reg; 11705 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11706 11707 uint32_t Rn = ReadCoreReg (n, &success); 11708 if (!success) 11709 return false; 11710 11711 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11712 addr_t address = Rn; 11713 if ((address % alignment) != 0) 11714 return false; 11715 11716 EmulateInstruction::Context context; 11717 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11718 if (wback) 11719 { 11720 uint32_t Rm = ReadCoreReg (m, &success); 11721 if (!success) 11722 return false; 11723 11724 uint32_t offset; 11725 if (register_index) 11726 offset = Rm; 11727 else 11728 offset = ebytes; 11729 11730 uint32_t value = Rn + offset; 11731 11732 context.type = eContextAdjustBaseRegister; 11733 context.SetRegisterPlusOffset (base_reg, offset); 11734 11735 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11736 return false; 11737 } 11738 11739 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11740 uint32_t element = MemURead (context, address, esize, 0, &success); 11741 if (!success) 11742 return false; 11743 11744 element = element << (index * esize); 11745 11746 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11747 if (!success) 11748 return false; 11749 11750 uint64_t all_ones = -1; 11751 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11752 // at element & to the right of element. 11753 if (index > 0) 11754 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11755 // now mask should be 0's where element goes & 1's 11756 // everywhere else. 11757 11758 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11759 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11760 11761 context.type = eContextRegisterLoad; 11762 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11763 return false; 11764 } 11765 return true; 11766 } 11767 11768 // A8.6.391 VST1 (multiple single elements) 11769 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without 11770 // interleaving. Every element of each register is stored. 11771 bool 11772 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11773 { 11774 #if 0 11775 if ConditionPassed() then 11776 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11777 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11778 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11779 for r = 0 to regs-1 11780 for e = 0 to elements-1 11781 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11782 address = address + ebytes; 11783 #endif 11784 11785 bool success = false; 11786 11787 if (ConditionPassed (opcode)) 11788 { 11789 uint32_t regs; 11790 uint32_t alignment; 11791 uint32_t ebytes; 11792 uint32_t esize; 11793 uint32_t elements; 11794 uint32_t d; 11795 uint32_t n; 11796 uint32_t m; 11797 bool wback; 11798 bool register_index; 11799 11800 switch (encoding) 11801 { 11802 case eEncodingT1: 11803 case eEncodingA1: 11804 { 11805 uint32_t type = Bits32 (opcode, 11, 8); 11806 uint32_t align = Bits32 (opcode, 5, 4); 11807 11808 // case type of 11809 if (type == 7) // when �0111� 11810 { 11811 // regs = 1; if align<1> == �1� then UNDEFINED; 11812 regs = 1; 11813 if (BitIsSet (align, 1)) 11814 return false; 11815 } 11816 else if (type == 10) // when �1010� 11817 { 11818 // regs = 2; if align == �11� then UNDEFINED; 11819 regs = 2; 11820 if (align == 3) 11821 return false; 11822 } 11823 else if (type == 6) // when �0110� 11824 { 11825 // regs = 3; if align<1> == �1� then UNDEFINED; 11826 regs = 3; 11827 if (BitIsSet (align, 1)) 11828 return false; 11829 } 11830 else if (type == 2) // when �0010� 11831 // regs = 4; 11832 regs = 4; 11833 else // otherwise 11834 // SEE �Related encodings�; 11835 return false; 11836 11837 // alignment = if align == �00� then 1 else 4 << UInt(align); 11838 if (align == 0) 11839 alignment = 1; 11840 else 11841 alignment = 4 << align; 11842 11843 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11844 ebytes = 1 << Bits32 (opcode,7, 6); 11845 esize = 8 * ebytes; 11846 elements = 8 / ebytes; 11847 11848 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11849 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11850 n = Bits32 (opcode, 19, 16); 11851 m = Bits32 (opcode, 3, 0); 11852 11853 // wback = (m != 15); register_index = (m != 15 && m != 13); 11854 wback = (m != 15); 11855 register_index = ((m != 15) && (m != 13)); 11856 11857 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11858 if ((d + regs) > 32) 11859 return false; 11860 11861 if (n == 15) 11862 return false; 11863 11864 } 11865 break; 11866 11867 default: 11868 return false; 11869 } 11870 11871 RegisterInfo base_reg; 11872 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11873 11874 uint32_t Rn = ReadCoreReg (n, &success); 11875 if (!success) 11876 return false; 11877 11878 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11879 addr_t address = Rn; 11880 if ((address % alignment) != 0) 11881 return false; 11882 11883 EmulateInstruction::Context context; 11884 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11885 if (wback) 11886 { 11887 uint32_t Rm = ReadCoreReg (m, &success); 11888 if (!success) 11889 return false; 11890 11891 uint32_t offset; 11892 if (register_index) 11893 offset = Rm; 11894 else 11895 offset = 8 * regs; 11896 11897 context.type = eContextAdjustBaseRegister; 11898 context.SetRegisterPlusOffset (base_reg, offset); 11899 11900 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11901 return false; 11902 } 11903 11904 RegisterInfo data_reg; 11905 context.type = eContextRegisterStore; 11906 // for r = 0 to regs-1 11907 for (uint32_t r = 0; r < regs; ++r) 11908 { 11909 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11910 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11911 if (!success) 11912 return false; 11913 11914 // for e = 0 to elements-1 11915 for (uint32_t e = 0; e < elements; ++e) 11916 { 11917 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11918 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11919 11920 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11921 if (!MemUWrite (context, address, word, ebytes)) 11922 return false; 11923 11924 // address = address + ebytes; 11925 address = address + ebytes; 11926 } 11927 } 11928 } 11929 return true; 11930 } 11931 11932 // A8.6.392 VST1 (single element from one lane) 11933 // This instruction stores one element to memory from one element of a register. 11934 bool 11935 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11936 { 11937 #if 0 11938 if ConditionPassed() then 11939 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11940 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11941 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11942 MemU[address,ebytes] = Elem[D[d],index,esize]; 11943 #endif 11944 11945 bool success = false; 11946 11947 if (ConditionPassed (opcode)) 11948 { 11949 uint32_t ebytes; 11950 uint32_t esize; 11951 uint32_t index; 11952 uint32_t alignment; 11953 uint32_t d; 11954 uint32_t n; 11955 uint32_t m; 11956 bool wback; 11957 bool register_index; 11958 11959 switch (encoding) 11960 { 11961 case eEncodingT1: 11962 case eEncodingA1: 11963 { 11964 uint32_t size = Bits32 (opcode, 11, 10); 11965 uint32_t index_align = Bits32 (opcode, 7, 4); 11966 11967 // if size == �11� then UNDEFINED; 11968 if (size == 3) 11969 return false; 11970 11971 // case size of 11972 if (size == 0) // when �00� 11973 { 11974 // if index_align<0> != �0� then UNDEFINED; 11975 if (BitIsClear (index_align, 0)) 11976 return false; 11977 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11978 ebytes = 1; 11979 esize = 8; 11980 index = Bits32 (index_align, 3, 1); 11981 alignment = 1; 11982 } 11983 else if (size == 1) // when �01� 11984 { 11985 // if index_align<1> != �0� then UNDEFINED; 11986 if (BitIsClear (index_align, 1)) 11987 return false; 11988 11989 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11990 ebytes = 2; 11991 esize = 16; 11992 index = Bits32 (index_align, 3, 2); 11993 11994 // alignment = if index_align<0> == �0� then 1 else 2; 11995 if (BitIsClear (index_align, 0)) 11996 alignment = 1; 11997 else 11998 alignment = 2; 11999 } 12000 else if (size == 2) // when �10� 12001 { 12002 // if index_align<2> != �0� then UNDEFINED; 12003 if (BitIsClear (index_align, 2)) 12004 return false; 12005 12006 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 12007 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 12008 return false; 12009 12010 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12011 ebytes = 4; 12012 esize = 32; 12013 index = Bit32 (index_align, 3); 12014 12015 // alignment = if index_align<1:0> == �00� then 1 else 4; 12016 if (Bits32 (index_align, 1, 0) == 0) 12017 alignment = 1; 12018 else 12019 alignment = 4; 12020 } 12021 else 12022 { 12023 return false; 12024 } 12025 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12026 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12027 n = Bits32 (opcode, 19, 16); 12028 m = Bits32 (opcode, 3, 0); 12029 12030 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 12031 wback = (m != 15); 12032 register_index = ((m != 15) && (m != 13)); 12033 12034 if (n == 15) 12035 return false; 12036 } 12037 break; 12038 12039 default: 12040 return false; 12041 } 12042 12043 RegisterInfo base_reg; 12044 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12045 12046 uint32_t Rn = ReadCoreReg (n, &success); 12047 if (!success) 12048 return false; 12049 12050 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12051 addr_t address = Rn; 12052 if ((address % alignment) != 0) 12053 return false; 12054 12055 EmulateInstruction::Context context; 12056 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12057 if (wback) 12058 { 12059 uint32_t Rm = ReadCoreReg (m, &success); 12060 if (!success) 12061 return false; 12062 12063 uint32_t offset; 12064 if (register_index) 12065 offset = Rm; 12066 else 12067 offset = ebytes; 12068 12069 context.type = eContextAdjustBaseRegister; 12070 context.SetRegisterPlusOffset (base_reg, offset); 12071 12072 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12073 return false; 12074 } 12075 12076 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12077 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12078 if (!success) 12079 return false; 12080 12081 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 12082 12083 RegisterInfo data_reg; 12084 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12085 context.type = eContextRegisterStore; 12086 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 12087 12088 if (!MemUWrite (context, address, word, ebytes)) 12089 return false; 12090 } 12091 return true; 12092 } 12093 12094 // A8.6.309 VLD1 (single element to all lanes) 12095 // This instruction loads one element from memory into every element of one or two vectors. 12096 bool 12097 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 12098 { 12099 #if 0 12100 if ConditionPassed() then 12101 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12102 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12103 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12104 replicated_element = Replicate(MemU[address,ebytes], elements); 12105 for r = 0 to regs-1 12106 D[d+r] = replicated_element; 12107 #endif 12108 12109 bool success = false; 12110 12111 if (ConditionPassed (opcode)) 12112 { 12113 uint32_t ebytes; 12114 uint32_t elements; 12115 uint32_t regs; 12116 uint32_t alignment; 12117 uint32_t d; 12118 uint32_t n; 12119 uint32_t m; 12120 bool wback; 12121 bool register_index; 12122 12123 switch (encoding) 12124 { 12125 case eEncodingT1: 12126 case eEncodingA1: 12127 { 12128 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED; 12129 uint32_t size = Bits32 (opcode, 7, 6); 12130 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 12131 return false; 12132 12133 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2; 12134 ebytes = 1 << size; 12135 elements = 8 / ebytes; 12136 if (BitIsClear (opcode, 5)) 12137 regs = 1; 12138 else 12139 regs = 2; 12140 12141 //alignment = if a == �0� then 1 else ebytes; 12142 if (BitIsClear (opcode, 4)) 12143 alignment = 1; 12144 else 12145 alignment = ebytes; 12146 12147 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12148 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12149 n = Bits32 (opcode, 19, 16); 12150 m = Bits32 (opcode, 3, 0); 12151 12152 //wback = (m != 15); register_index = (m != 15 && m != 13); 12153 wback = (m != 15); 12154 register_index = ((m != 15) && (m != 13)); 12155 12156 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12157 if ((d + regs) > 32) 12158 return false; 12159 12160 if (n == 15) 12161 return false; 12162 } 12163 break; 12164 12165 default: 12166 return false; 12167 } 12168 12169 RegisterInfo base_reg; 12170 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12171 12172 uint32_t Rn = ReadCoreReg (n, &success); 12173 if (!success) 12174 return false; 12175 12176 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12177 addr_t address = Rn; 12178 if ((address % alignment) != 0) 12179 return false; 12180 12181 EmulateInstruction::Context context; 12182 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12183 if (wback) 12184 { 12185 uint32_t Rm = ReadCoreReg (m, &success); 12186 if (!success) 12187 return false; 12188 12189 uint32_t offset; 12190 if (register_index) 12191 offset = Rm; 12192 else 12193 offset = ebytes; 12194 12195 context.type = eContextAdjustBaseRegister; 12196 context.SetRegisterPlusOffset (base_reg, offset); 12197 12198 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12199 return false; 12200 } 12201 12202 // replicated_element = Replicate(MemU[address,ebytes], elements); 12203 12204 context.type = eContextRegisterLoad; 12205 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12206 if (!success) 12207 return false; 12208 12209 uint64_t replicated_element = 0; 12210 uint32_t esize = ebytes * 8; 12211 for (uint32_t e = 0; e < elements; ++e) 12212 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12213 12214 // for r = 0 to regs-1 12215 for (uint32_t r = 0; r < regs; ++r) 12216 { 12217 // D[d+r] = replicated_element; 12218 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12219 return false; 12220 } 12221 } 12222 return true; 12223 } 12224 12225 // B6.2.13 SUBS PC, LR and related instructions 12226 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12227 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12228 bool 12229 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12230 { 12231 #if 0 12232 if ConditionPassed() then 12233 EncodingSpecificOperations(); 12234 if CurrentInstrSet() == InstrSet_ThumbEE then 12235 UNPREDICTABLE; 12236 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12237 case opcode of 12238 when �0000� result = R[n] AND operand2; // AND 12239 when �0001� result = R[n] EOR operand2; // EOR 12240 when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12241 when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12242 when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12243 when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12244 when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12245 when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12246 when �1100� result = R[n] OR operand2; // ORR 12247 when �1101� result = operand2; // MOV 12248 when �1110� result = R[n] AND NOT(operand2); // BIC 12249 when �1111� result = NOT(operand2); // MVN 12250 CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12251 BranchWritePC(result); 12252 #endif 12253 12254 bool success = false; 12255 12256 if (ConditionPassed (opcode)) 12257 { 12258 uint32_t n; 12259 uint32_t m; 12260 uint32_t imm32; 12261 bool register_form; 12262 ARM_ShifterType shift_t; 12263 uint32_t shift_n; 12264 uint32_t code; 12265 12266 switch (encoding) 12267 { 12268 case eEncodingT1: 12269 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12270 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB 12271 n = 14; 12272 imm32 = Bits32 (opcode, 7, 0); 12273 register_form = false; 12274 code = 2; 12275 12276 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12277 if (InITBlock() && !LastInITBlock()) 12278 return false; 12279 12280 break; 12281 12282 case eEncodingA1: 12283 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12284 n = Bits32 (opcode, 19, 16); 12285 imm32 = ARMExpandImm (opcode); 12286 register_form = false; 12287 code = Bits32 (opcode, 24, 21); 12288 12289 break; 12290 12291 case eEncodingA2: 12292 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12293 n = Bits32 (opcode, 19, 16); 12294 m = Bits32 (opcode, 3, 0); 12295 register_form = true; 12296 12297 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12298 shift_n = DecodeImmShiftARM (opcode, shift_t); 12299 12300 break; 12301 12302 default: 12303 return false; 12304 } 12305 12306 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12307 uint32_t operand2; 12308 if (register_form) 12309 { 12310 uint32_t Rm = ReadCoreReg (m, &success); 12311 if (!success) 12312 return false; 12313 12314 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12315 if (!success) 12316 return false; 12317 } 12318 else 12319 { 12320 operand2 = imm32; 12321 } 12322 12323 uint32_t Rn = ReadCoreReg (n, &success); 12324 if (!success) 12325 return false; 12326 12327 AddWithCarryResult result; 12328 12329 // case opcode of 12330 switch (code) 12331 { 12332 case 0: // when �0000� 12333 // result = R[n] AND operand2; // AND 12334 result.result = Rn & operand2; 12335 break; 12336 12337 case 1: // when �0001� 12338 // result = R[n] EOR operand2; // EOR 12339 result.result = Rn ^ operand2; 12340 break; 12341 12342 case 2: // when �0010� 12343 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12344 result = AddWithCarry (Rn, ~(operand2), 1); 12345 break; 12346 12347 case 3: // when �0011� 12348 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12349 result = AddWithCarry (~(Rn), operand2, 1); 12350 break; 12351 12352 case 4: // when �0100� 12353 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12354 result = AddWithCarry (Rn, operand2, 0); 12355 break; 12356 12357 case 5: // when �0101� 12358 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12359 result = AddWithCarry (Rn, operand2, APSR_C); 12360 break; 12361 12362 case 6: // when �0110� 12363 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12364 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12365 break; 12366 12367 case 7: // when �0111� 12368 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12369 result = AddWithCarry (~(Rn), operand2, APSR_C); 12370 break; 12371 12372 case 10: // when �1100� 12373 // result = R[n] OR operand2; // ORR 12374 result.result = Rn | operand2; 12375 break; 12376 12377 case 11: // when �1101� 12378 // result = operand2; // MOV 12379 result.result = operand2; 12380 break; 12381 12382 case 12: // when �1110� 12383 // result = R[n] AND NOT(operand2); // BIC 12384 result.result = Rn & ~(operand2); 12385 break; 12386 12387 case 15: // when �1111� 12388 // result = NOT(operand2); // MVN 12389 result.result = ~(operand2); 12390 break; 12391 12392 default: 12393 return false; 12394 } 12395 // CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12396 12397 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12398 // the best. 12399 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12400 if (!success) 12401 return false; 12402 12403 CPSRWriteByInstr (spsr, 15, true); 12404 12405 // BranchWritePC(result); 12406 EmulateInstruction::Context context; 12407 context.type = eContextAdjustPC; 12408 context.SetImmediate (result.result); 12409 12410 BranchWritePC (context, result.result); 12411 } 12412 return true; 12413 } 12414 12415 EmulateInstructionARM::ARMOpcode* 12416 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12417 { 12418 static ARMOpcode 12419 g_arm_opcodes[] = 12420 { 12421 //---------------------------------------------------------------------- 12422 // Prologue instructions 12423 //---------------------------------------------------------------------- 12424 12425 // push register(s) 12426 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12427 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12428 12429 // set r7 to point to a stack offset 12430 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12431 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12432 // copy the stack pointer to ip 12433 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12434 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12435 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12436 12437 // adjust the stack pointer 12438 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12439 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12440 12441 // push one register 12442 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12443 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12444 12445 // vector push consecutive extension register(s) 12446 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12447 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12448 12449 //---------------------------------------------------------------------- 12450 // Epilogue instructions 12451 //---------------------------------------------------------------------- 12452 12453 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12454 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12455 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12456 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12457 12458 //---------------------------------------------------------------------- 12459 // Supervisor Call (previously Software Interrupt) 12460 //---------------------------------------------------------------------- 12461 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12462 12463 //---------------------------------------------------------------------- 12464 // Branch instructions 12465 //---------------------------------------------------------------------- 12466 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>". 12467 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12468 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12469 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12470 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12471 // for example, "bx lr" 12472 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12473 // bxj 12474 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12475 12476 //---------------------------------------------------------------------- 12477 // Data-processing instructions 12478 //---------------------------------------------------------------------- 12479 // adc (immediate) 12480 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12481 // adc (register) 12482 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12483 // add (immediate) 12484 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12485 // add (register) 12486 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12487 // add (register-shifted register) 12488 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12489 // adr 12490 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12491 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12492 // and (immediate) 12493 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12494 // and (register) 12495 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12496 // bic (immediate) 12497 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12498 // bic (register) 12499 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12500 // eor (immediate) 12501 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12502 // eor (register) 12503 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12504 // orr (immediate) 12505 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12506 // orr (register) 12507 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12508 // rsb (immediate) 12509 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12510 // rsb (register) 12511 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12512 // rsc (immediate) 12513 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12514 // rsc (register) 12515 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12516 // sbc (immediate) 12517 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12518 // sbc (register) 12519 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12520 // sub (immediate, ARM) 12521 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12522 // sub (sp minus immediate) 12523 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12524 // sub (register) 12525 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12526 // teq (immediate) 12527 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12528 // teq (register) 12529 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12530 // tst (immediate) 12531 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12532 // tst (register) 12533 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12534 12535 // mov (immediate) 12536 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12537 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12538 // mov (register) 12539 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12540 // mvn (immediate) 12541 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12542 // mvn (register) 12543 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12544 // cmn (immediate) 12545 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12546 // cmn (register) 12547 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12548 // cmp (immediate) 12549 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12550 // cmp (register) 12551 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12552 // asr (immediate) 12553 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12554 // asr (register) 12555 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12556 // lsl (immediate) 12557 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12558 // lsl (register) 12559 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12560 // lsr (immediate) 12561 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12562 // lsr (register) 12563 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12564 // rrx is a special case encoding of ror (immediate) 12565 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12566 // ror (immediate) 12567 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12568 // ror (register) 12569 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12570 // mul 12571 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12572 12573 // subs pc, lr and related instructions 12574 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12575 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12576 12577 //---------------------------------------------------------------------- 12578 // Load instructions 12579 //---------------------------------------------------------------------- 12580 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12581 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12582 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12583 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12584 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12585 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12586 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12587 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12588 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12589 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12590 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12591 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12592 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12593 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12594 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12595 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12596 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12597 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12598 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12599 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12600 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12601 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12602 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12603 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12604 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12605 12606 //---------------------------------------------------------------------- 12607 // Store instructions 12608 //---------------------------------------------------------------------- 12609 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12610 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12611 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12612 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12613 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12614 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12615 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12616 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12617 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12618 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12619 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12620 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12621 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12622 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12623 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12624 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12625 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12626 12627 //---------------------------------------------------------------------- 12628 // Other instructions 12629 //---------------------------------------------------------------------- 12630 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12631 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12632 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12633 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12634 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12635 12636 }; 12637 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 12638 12639 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12640 { 12641 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12642 (g_arm_opcodes[i].variants & arm_isa) != 0) 12643 return &g_arm_opcodes[i]; 12644 } 12645 return NULL; 12646 } 12647 12648 12649 EmulateInstructionARM::ARMOpcode* 12650 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12651 { 12652 12653 static ARMOpcode 12654 g_thumb_opcodes[] = 12655 { 12656 //---------------------------------------------------------------------- 12657 // Prologue instructions 12658 //---------------------------------------------------------------------- 12659 12660 // push register(s) 12661 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12662 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12663 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12664 12665 // set r7 to point to a stack offset 12666 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12667 // copy the stack pointer to r7 12668 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12669 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12670 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12671 12672 // PC-relative load into register (see also EmulateADDSPRm) 12673 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12674 12675 // adjust the stack pointer 12676 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12677 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12678 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12679 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12680 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12681 12682 // vector push consecutive extension register(s) 12683 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12684 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12685 12686 //---------------------------------------------------------------------- 12687 // Epilogue instructions 12688 //---------------------------------------------------------------------- 12689 12690 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12691 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12692 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12693 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12694 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12695 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12696 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12697 12698 //---------------------------------------------------------------------- 12699 // Supervisor Call (previously Software Interrupt) 12700 //---------------------------------------------------------------------- 12701 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12702 12703 //---------------------------------------------------------------------- 12704 // If Then makes up to four following instructions conditional. 12705 //---------------------------------------------------------------------- 12706 // The next 5 opcode _must_ come before the if then instruction 12707 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12708 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12709 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12710 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12711 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12712 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12713 12714 //---------------------------------------------------------------------- 12715 // Branch instructions 12716 //---------------------------------------------------------------------- 12717 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12718 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12719 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12720 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12721 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12722 // J1 == J2 == 1 12723 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12724 // J1 == J2 == 1 12725 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12726 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12727 // for example, "bx lr" 12728 { 0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12729 // bxj 12730 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12731 // compare and branch 12732 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12733 // table branch byte 12734 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12735 // table branch halfword 12736 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12737 12738 //---------------------------------------------------------------------- 12739 // Data-processing instructions 12740 //---------------------------------------------------------------------- 12741 // adc (immediate) 12742 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12743 // adc (register) 12744 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12745 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12746 // add (register) 12747 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12748 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12749 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12750 // adr 12751 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12752 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12753 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12754 // and (immediate) 12755 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12756 // and (register) 12757 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12758 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12759 // bic (immediate) 12760 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12761 // bic (register) 12762 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12763 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12764 // eor (immediate) 12765 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12766 // eor (register) 12767 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12768 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12769 // orr (immediate) 12770 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12771 // orr (register) 12772 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12773 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12774 // rsb (immediate) 12775 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12776 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12777 // rsb (register) 12778 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12779 // sbc (immediate) 12780 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12781 // sbc (register) 12782 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12783 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12784 // add (immediate, Thumb) 12785 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12786 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12787 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12788 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12789 // sub (immediate, Thumb) 12790 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12791 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12792 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12793 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12794 // sub (sp minus immediate) 12795 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12796 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12797 // sub (register) 12798 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12799 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12800 // teq (immediate) 12801 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12802 // teq (register) 12803 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12804 // tst (immediate) 12805 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12806 // tst (register) 12807 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12808 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12809 12810 12811 // move from high register to high register 12812 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12813 // move from low register to low register 12814 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12815 // mov{s}<c>.w <Rd>, <Rm> 12816 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12817 // move immediate 12818 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12819 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12820 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12821 // mvn (immediate) 12822 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12823 // mvn (register) 12824 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12825 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12826 // cmn (immediate) 12827 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12828 // cmn (register) 12829 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12830 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12831 // cmp (immediate) 12832 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12833 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12834 // cmp (register) (Rn and Rm both from r0-r7) 12835 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12836 // cmp (register) (Rn and Rm not both from r0-r7) 12837 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12838 { 0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 12839 // asr (immediate) 12840 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12841 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12842 // asr (register) 12843 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12844 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12845 // lsl (immediate) 12846 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12847 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12848 // lsl (register) 12849 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12850 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12851 // lsr (immediate) 12852 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12853 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12854 // lsr (register) 12855 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12856 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12857 // rrx is a special case encoding of ror (immediate) 12858 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12859 // ror (immediate) 12860 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12861 // ror (register) 12862 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12863 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12864 // mul 12865 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12866 // mul 12867 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12868 12869 // subs pc, lr and related instructions 12870 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12871 12872 //---------------------------------------------------------------------- 12873 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12874 // otherwise the wrong instructions will be selected. 12875 //---------------------------------------------------------------------- 12876 12877 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12878 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12879 12880 //---------------------------------------------------------------------- 12881 // Load instructions 12882 //---------------------------------------------------------------------- 12883 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12884 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12885 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12886 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12887 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12888 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12889 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12890 // Thumb2 PC-relative load into register 12891 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12892 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12893 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12894 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12895 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12896 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12897 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12898 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12899 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12900 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12901 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12902 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12903 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12904 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12905 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12906 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12907 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12908 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12909 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12910 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12911 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12912 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12913 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12914 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12915 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12916 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12917 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12918 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12919 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12920 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12921 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12922 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12923 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12924 12925 //---------------------------------------------------------------------- 12926 // Store instructions 12927 //---------------------------------------------------------------------- 12928 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12929 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12930 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12931 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12932 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12933 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12934 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12935 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12936 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12937 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12938 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12939 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12940 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12941 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12942 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12943 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12944 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12945 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12946 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12947 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12948 { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12949 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12950 12951 //---------------------------------------------------------------------- 12952 // Other instructions 12953 //---------------------------------------------------------------------- 12954 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12955 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12956 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12957 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12958 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12959 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12960 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12961 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12962 }; 12963 12964 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 12965 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12966 { 12967 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12968 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12969 return &g_thumb_opcodes[i]; 12970 } 12971 return NULL; 12972 } 12973 12974 bool 12975 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12976 { 12977 m_arch = arch; 12978 m_arm_isa = 0; 12979 const char *arch_cstr = arch.GetArchitectureName (); 12980 if (arch_cstr) 12981 { 12982 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12983 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12984 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12985 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12986 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12987 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12988 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12989 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12990 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12991 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12992 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12993 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12994 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12995 } 12996 return m_arm_isa != 0; 12997 } 12998 12999 bool 13000 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 13001 { 13002 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 13003 { 13004 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 13005 m_opcode_mode = eModeThumb; 13006 else 13007 { 13008 AddressClass addr_class = inst_addr.GetAddressClass(); 13009 13010 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 13011 m_opcode_mode = eModeARM; 13012 else if (addr_class == eAddressClassCodeAlternateISA) 13013 m_opcode_mode = eModeThumb; 13014 else 13015 return false; 13016 } 13017 if (m_opcode_mode == eModeThumb) 13018 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13019 else 13020 m_opcode_cpsr = CPSR_MODE_USR; 13021 return true; 13022 } 13023 return false; 13024 } 13025 13026 bool 13027 EmulateInstructionARM::ReadInstruction () 13028 { 13029 bool success = false; 13030 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13031 if (success) 13032 { 13033 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 13034 if (success) 13035 { 13036 Context read_inst_context; 13037 read_inst_context.type = eContextReadOpcode; 13038 read_inst_context.SetNoArgs (); 13039 13040 if (m_opcode_cpsr & MASK_CPSR_T) 13041 { 13042 m_opcode_mode = eModeThumb; 13043 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13044 13045 if (success) 13046 { 13047 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 13048 { 13049 m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder()); 13050 } 13051 else 13052 { 13053 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder()); 13054 } 13055 } 13056 } 13057 else 13058 { 13059 m_opcode_mode = eModeARM; 13060 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder()); 13061 } 13062 } 13063 } 13064 if (!success) 13065 { 13066 m_opcode_mode = eModeInvalid; 13067 m_addr = LLDB_INVALID_ADDRESS; 13068 } 13069 return success; 13070 } 13071 13072 uint32_t 13073 EmulateInstructionARM::ArchVersion () 13074 { 13075 return m_arm_isa; 13076 } 13077 13078 bool 13079 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) 13080 { 13081 // If we are ignoring conditions, then always return true. 13082 // this allows us to iterate over disassembly code and still 13083 // emulate an instruction even if we don't have all the right 13084 // bits set in the CPSR register... 13085 if (m_ignore_conditions) 13086 return true; 13087 13088 if (is_conditional) 13089 *is_conditional = true; 13090 13091 const uint32_t cond = CurrentCond (opcode); 13092 13093 if (cond == UINT32_MAX) 13094 return false; 13095 13096 bool result = false; 13097 switch (UnsignedBits(cond, 3, 1)) 13098 { 13099 case 0: 13100 if (m_opcode_cpsr == 0) 13101 result = true; 13102 else 13103 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13104 break; 13105 case 1: 13106 if (m_opcode_cpsr == 0) 13107 result = true; 13108 else 13109 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13110 break; 13111 case 2: 13112 if (m_opcode_cpsr == 0) 13113 result = true; 13114 else 13115 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13116 break; 13117 case 3: 13118 if (m_opcode_cpsr == 0) 13119 result = true; 13120 else 13121 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13122 break; 13123 case 4: 13124 if (m_opcode_cpsr == 0) 13125 result = true; 13126 else 13127 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13128 break; 13129 case 5: 13130 if (m_opcode_cpsr == 0) 13131 result = true; 13132 else 13133 { 13134 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13135 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13136 result = n == v; 13137 } 13138 break; 13139 case 6: 13140 if (m_opcode_cpsr == 0) 13141 result = true; 13142 else 13143 { 13144 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13145 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13146 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13147 } 13148 break; 13149 case 7: 13150 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13151 // opcodes different meanings, but always means execution happens. 13152 if (is_conditional) 13153 *is_conditional = false; 13154 return true; 13155 } 13156 13157 if (cond & 1) 13158 result = !result; 13159 return result; 13160 } 13161 13162 uint32_t 13163 EmulateInstructionARM::CurrentCond (const uint32_t opcode) 13164 { 13165 switch (m_opcode_mode) 13166 { 13167 case eModeInvalid: 13168 break; 13169 13170 case eModeARM: 13171 return UnsignedBits(opcode, 31, 28); 13172 13173 case eModeThumb: 13174 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13175 // 'cond' field of the encoding. 13176 { 13177 const uint32_t byte_size = m_opcode.GetByteSize(); 13178 if (byte_size == 2) 13179 { 13180 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 13181 return Bits32(opcode, 11, 8); 13182 } 13183 else if (byte_size == 4) 13184 { 13185 if (Bits32(opcode, 31, 27) == 0x1e && 13186 Bits32(opcode, 15, 14) == 0x02 && 13187 Bits32(opcode, 12, 12) == 0x00 && 13188 Bits32(opcode, 25, 22) <= 0x0d) 13189 { 13190 return Bits32(opcode, 25, 22); 13191 } 13192 } 13193 else 13194 // We have an invalid thumb instruction, let's bail out. 13195 break; 13196 13197 return m_it_session.GetCond(); 13198 } 13199 } 13200 return UINT32_MAX; // Return invalid value 13201 } 13202 13203 bool 13204 EmulateInstructionARM::InITBlock() 13205 { 13206 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13207 } 13208 13209 bool 13210 EmulateInstructionARM::LastInITBlock() 13211 { 13212 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13213 } 13214 13215 bool 13216 EmulateInstructionARM::BadMode (uint32_t mode) 13217 { 13218 13219 switch (mode) 13220 { 13221 case 16: return false; // '10000' 13222 case 17: return false; // '10001' 13223 case 18: return false; // '10010' 13224 case 19: return false; // '10011' 13225 case 22: return false; // '10110' 13226 case 23: return false; // '10111' 13227 case 27: return false; // '11011' 13228 case 31: return false; // '11111' 13229 default: return true; 13230 } 13231 return true; 13232 } 13233 13234 bool 13235 EmulateInstructionARM::CurrentModeIsPrivileged () 13236 { 13237 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13238 13239 if (BadMode (mode)) 13240 return false; 13241 13242 if (mode == 16) 13243 return false; 13244 13245 return true; 13246 } 13247 13248 void 13249 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13250 { 13251 bool privileged = CurrentModeIsPrivileged(); 13252 13253 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13254 13255 if (BitIsSet (bytemask, 3)) 13256 { 13257 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13258 if (affect_execstate) 13259 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13260 } 13261 13262 if (BitIsSet (bytemask, 2)) 13263 { 13264 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13265 } 13266 13267 if (BitIsSet (bytemask, 1)) 13268 { 13269 if (affect_execstate) 13270 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13271 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13272 if (privileged) 13273 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13274 } 13275 13276 if (BitIsSet (bytemask, 0)) 13277 { 13278 if (privileged) 13279 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13280 if (affect_execstate) 13281 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13282 if (privileged) 13283 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13284 } 13285 13286 m_opcode_cpsr = tmp_cpsr; 13287 } 13288 13289 13290 bool 13291 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13292 { 13293 addr_t target; 13294 13295 // Check the current instruction set. 13296 if (CurrentInstrSet() == eModeARM) 13297 target = addr & 0xfffffffc; 13298 else 13299 target = addr & 0xfffffffe; 13300 13301 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13302 return false; 13303 13304 return true; 13305 } 13306 13307 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13308 bool 13309 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13310 { 13311 addr_t target; 13312 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13313 // we want to record it and issue a WriteRegister callback so the clients 13314 // can track the mode changes accordingly. 13315 bool cpsr_changed = false; 13316 13317 if (BitIsSet(addr, 0)) 13318 { 13319 if (CurrentInstrSet() != eModeThumb) 13320 { 13321 SelectInstrSet(eModeThumb); 13322 cpsr_changed = true; 13323 } 13324 target = addr & 0xfffffffe; 13325 context.SetISA (eModeThumb); 13326 } 13327 else if (BitIsClear(addr, 1)) 13328 { 13329 if (CurrentInstrSet() != eModeARM) 13330 { 13331 SelectInstrSet(eModeARM); 13332 cpsr_changed = true; 13333 } 13334 target = addr & 0xfffffffc; 13335 context.SetISA (eModeARM); 13336 } 13337 else 13338 return false; // address<1:0> == '10' => UNPREDICTABLE 13339 13340 if (cpsr_changed) 13341 { 13342 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13343 return false; 13344 } 13345 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13346 return false; 13347 13348 return true; 13349 } 13350 13351 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13352 bool 13353 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13354 { 13355 if (ArchVersion() >= ARMv5T) 13356 return BXWritePC(context, addr); 13357 else 13358 return BranchWritePC((const Context)context, addr); 13359 } 13360 13361 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13362 bool 13363 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13364 { 13365 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13366 return BXWritePC(context, addr); 13367 else 13368 return BranchWritePC((const Context)context, addr); 13369 } 13370 13371 EmulateInstructionARM::Mode 13372 EmulateInstructionARM::CurrentInstrSet () 13373 { 13374 return m_opcode_mode; 13375 } 13376 13377 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13378 // ReadInstruction() is performed. This function has a side effect of updating 13379 // the m_new_inst_cpsr member variable if necessary. 13380 bool 13381 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13382 { 13383 m_new_inst_cpsr = m_opcode_cpsr; 13384 switch (arm_or_thumb) 13385 { 13386 default: 13387 return false; 13388 case eModeARM: 13389 // Clear the T bit. 13390 m_new_inst_cpsr &= ~MASK_CPSR_T; 13391 break; 13392 case eModeThumb: 13393 // Set the T bit. 13394 m_new_inst_cpsr |= MASK_CPSR_T; 13395 break; 13396 } 13397 return true; 13398 } 13399 13400 // This function returns TRUE if the processor currently provides support for 13401 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13402 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13403 bool 13404 EmulateInstructionARM::UnalignedSupport() 13405 { 13406 return (ArchVersion() >= ARMv7); 13407 } 13408 13409 // The main addition and subtraction instructions can produce status information 13410 // about both unsigned carry and signed overflow conditions. This status 13411 // information can be used to synthesize multi-word additions and subtractions. 13412 EmulateInstructionARM::AddWithCarryResult 13413 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13414 { 13415 uint32_t result; 13416 uint8_t carry_out; 13417 uint8_t overflow; 13418 13419 uint64_t unsigned_sum = x + y + carry_in; 13420 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13421 13422 result = UnsignedBits(unsigned_sum, 31, 0); 13423 // carry_out = (result == unsigned_sum ? 0 : 1); 13424 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13425 13426 if (carry_in) 13427 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13428 else 13429 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13430 13431 AddWithCarryResult res = { result, carry_out, overflow }; 13432 return res; 13433 } 13434 13435 uint32_t 13436 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13437 { 13438 lldb::RegisterKind reg_kind; 13439 uint32_t reg_num; 13440 switch (num) 13441 { 13442 case SP_REG: 13443 reg_kind = eRegisterKindGeneric; 13444 reg_num = LLDB_REGNUM_GENERIC_SP; 13445 break; 13446 case LR_REG: 13447 reg_kind = eRegisterKindGeneric; 13448 reg_num = LLDB_REGNUM_GENERIC_RA; 13449 break; 13450 case PC_REG: 13451 reg_kind = eRegisterKindGeneric; 13452 reg_num = LLDB_REGNUM_GENERIC_PC; 13453 break; 13454 default: 13455 if (num < SP_REG) 13456 { 13457 reg_kind = eRegisterKindDWARF; 13458 reg_num = dwarf_r0 + num; 13459 } 13460 else 13461 { 13462 //assert(0 && "Invalid register number"); 13463 *success = false; 13464 return UINT32_MAX; 13465 } 13466 break; 13467 } 13468 13469 // Read our register. 13470 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13471 13472 // When executing an ARM instruction , PC reads as the address of the current 13473 // instruction plus 8. 13474 // When executing a Thumb instruction , PC reads as the address of the current 13475 // instruction plus 4. 13476 if (num == 15) 13477 { 13478 if (CurrentInstrSet() == eModeARM) 13479 val += 8; 13480 else 13481 val += 4; 13482 } 13483 13484 return val; 13485 } 13486 13487 // Write the result to the ARM core register Rd, and optionally update the 13488 // condition flags based on the result. 13489 // 13490 // This helper method tries to encapsulate the following pseudocode from the 13491 // ARM Architecture Reference Manual: 13492 // 13493 // if d == 15 then // Can only occur for encoding A1 13494 // ALUWritePC(result); // setflags is always FALSE here 13495 // else 13496 // R[d] = result; 13497 // if setflags then 13498 // APSR.N = result<31>; 13499 // APSR.Z = IsZeroBit(result); 13500 // APSR.C = carry; 13501 // // APSR.V unchanged 13502 // 13503 // In the above case, the API client does not pass in the overflow arg, which 13504 // defaults to ~0u. 13505 bool 13506 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13507 const uint32_t result, 13508 const uint32_t Rd, 13509 bool setflags, 13510 const uint32_t carry, 13511 const uint32_t overflow) 13512 { 13513 if (Rd == 15) 13514 { 13515 if (!ALUWritePC (context, result)) 13516 return false; 13517 } 13518 else 13519 { 13520 lldb::RegisterKind reg_kind; 13521 uint32_t reg_num; 13522 switch (Rd) 13523 { 13524 case SP_REG: 13525 reg_kind = eRegisterKindGeneric; 13526 reg_num = LLDB_REGNUM_GENERIC_SP; 13527 break; 13528 case LR_REG: 13529 reg_kind = eRegisterKindGeneric; 13530 reg_num = LLDB_REGNUM_GENERIC_RA; 13531 break; 13532 default: 13533 reg_kind = eRegisterKindDWARF; 13534 reg_num = dwarf_r0 + Rd; 13535 } 13536 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13537 return false; 13538 if (setflags) 13539 return WriteFlags (context, result, carry, overflow); 13540 } 13541 return true; 13542 } 13543 13544 // This helper method tries to encapsulate the following pseudocode from the 13545 // ARM Architecture Reference Manual: 13546 // 13547 // APSR.N = result<31>; 13548 // APSR.Z = IsZeroBit(result); 13549 // APSR.C = carry; 13550 // APSR.V = overflow 13551 // 13552 // Default arguments can be specified for carry and overflow parameters, which means 13553 // not to update the respective flags. 13554 bool 13555 EmulateInstructionARM::WriteFlags (Context &context, 13556 const uint32_t result, 13557 const uint32_t carry, 13558 const uint32_t overflow) 13559 { 13560 m_new_inst_cpsr = m_opcode_cpsr; 13561 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13562 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13563 if (carry != ~0u) 13564 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13565 if (overflow != ~0u) 13566 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13567 if (m_new_inst_cpsr != m_opcode_cpsr) 13568 { 13569 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13570 return false; 13571 } 13572 return true; 13573 } 13574 13575 bool 13576 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13577 { 13578 // Advance the ITSTATE bits to their values for the next instruction. 13579 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13580 m_it_session.ITAdvance(); 13581 13582 ARMOpcode *opcode_data = NULL; 13583 13584 if (m_opcode_mode == eModeThumb) 13585 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13586 else if (m_opcode_mode == eModeARM) 13587 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13588 13589 if (opcode_data == NULL) 13590 return false; 13591 13592 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13593 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13594 13595 bool success = false; 13596 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13597 { 13598 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13599 dwarf_cpsr, 13600 0, 13601 &success); 13602 } 13603 13604 // Only return false if we are unable to read the CPSR if we care about conditions 13605 if (success == false && m_ignore_conditions == false) 13606 return false; 13607 13608 uint32_t orig_pc_value = 0; 13609 if (auto_advance_pc) 13610 { 13611 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13612 if (!success) 13613 return false; 13614 } 13615 13616 // Call the Emulate... function. 13617 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13618 if (!success) 13619 return false; 13620 13621 if (auto_advance_pc) 13622 { 13623 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13624 if (!success) 13625 return false; 13626 13627 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13628 { 13629 if (opcode_data->size == eSize32) 13630 after_pc_value += 4; 13631 else if (opcode_data->size == eSize16) 13632 after_pc_value += 2; 13633 13634 EmulateInstruction::Context context; 13635 context.type = eContextAdvancePC; 13636 context.SetNoArgs(); 13637 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13638 return false; 13639 13640 } 13641 } 13642 return true; 13643 } 13644 13645 bool 13646 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13647 { 13648 if (!test_data) 13649 { 13650 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13651 return false; 13652 } 13653 13654 static ConstString opcode_key ("opcode"); 13655 static ConstString before_key ("before_state"); 13656 static ConstString after_key ("after_state"); 13657 13658 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13659 13660 uint32_t test_opcode; 13661 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13662 { 13663 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13664 return false; 13665 } 13666 test_opcode = value_sp->GetUInt64Value (); 13667 13668 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13669 { 13670 m_opcode_mode = eModeARM; 13671 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13672 } 13673 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13674 { 13675 m_opcode_mode = eModeThumb; 13676 if (test_opcode < 0x10000) 13677 m_opcode.SetOpcode16 (test_opcode, GetByteOrder()); 13678 else 13679 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13680 13681 } 13682 else 13683 { 13684 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13685 return false; 13686 } 13687 13688 EmulationStateARM before_state; 13689 EmulationStateARM after_state; 13690 13691 value_sp = test_data->GetValueForKey (before_key); 13692 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13693 { 13694 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13695 return false; 13696 } 13697 13698 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13699 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13700 { 13701 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13702 return false; 13703 } 13704 13705 value_sp = test_data->GetValueForKey (after_key); 13706 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13707 { 13708 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13709 return false; 13710 } 13711 13712 state_dictionary = value_sp->GetAsDictionary (); 13713 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13714 { 13715 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13716 return false; 13717 } 13718 13719 SetBaton ((void *) &before_state); 13720 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13721 &EmulationStateARM::WritePseudoMemory, 13722 &EmulationStateARM::ReadPseudoRegister, 13723 &EmulationStateARM::WritePseudoRegister); 13724 13725 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13726 if (!success) 13727 { 13728 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13729 return false; 13730 } 13731 13732 success = before_state.CompareState (after_state); 13733 if (!success) 13734 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13735 13736 return success; 13737 } 13738 // 13739 // 13740 //const char * 13741 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13742 //{ 13743 // if (reg_kind == eRegisterKindGeneric) 13744 // { 13745 // switch (reg_num) 13746 // { 13747 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 13748 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 13749 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 13750 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 13751 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13752 // default: return NULL; 13753 // } 13754 // } 13755 // else if (reg_kind == eRegisterKindDWARF) 13756 // { 13757 // return GetARMDWARFRegisterName (reg_num); 13758 // } 13759 // return NULL; 13760 //} 13761 // 13762 bool 13763 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13764 { 13765 unwind_plan.Clear(); 13766 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13767 13768 UnwindPlan::RowSP row(new UnwindPlan::Row); 13769 13770 // Our previous Call Frame Address is the stack pointer 13771 row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0); 13772 13773 unwind_plan.AppendRow (row); 13774 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13775 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 13776 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 13777 unwind_plan.SetReturnAddressRegister (dwarf_lr); 13778 return true; 13779 } 13780