1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include <stdlib.h> 11 12 #include "EmulateInstructionARM.h" 13 #include "EmulationStateARM.h" 14 #include "lldb/Core/ArchSpec.h" 15 #include "lldb/Core/Address.h" 16 #include "lldb/Core/ConstString.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Core/Stream.h" 19 #include "lldb/Interpreter/OptionValueArray.h" 20 #include "lldb/Interpreter/OptionValueDictionary.h" 21 #include "lldb/Symbol/UnwindPlan.h" 22 23 #include "Plugins/Process/Utility/ARMDefines.h" 24 #include "Plugins/Process/Utility/ARMUtils.h" 25 #include "Utility/ARM_DWARF_Registers.h" 26 27 #include "llvm/ADT/STLExtras.h" 28 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function 29 // and countTrailingZeros function 30 31 using namespace lldb; 32 using namespace lldb_private; 33 34 // Convenient macro definitions. 35 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 36 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 37 38 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 39 40 //---------------------------------------------------------------------- 41 // 42 // ITSession implementation 43 // 44 //---------------------------------------------------------------------- 45 46 // A8.6.50 47 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 48 static uint32_t 49 CountITSize (uint32_t ITMask) { 50 // First count the trailing zeros of the IT mask. 51 uint32_t TZ = llvm::countTrailingZeros(ITMask); 52 if (TZ > 3) 53 { 54 #ifdef LLDB_CONFIGURATION_DEBUG 55 printf("Encoding error: IT Mask '0000'\n"); 56 #endif 57 return 0; 58 } 59 return (4 - TZ); 60 } 61 62 // Init ITState. Note that at least one bit is always 1 in mask. 63 bool ITSession::InitIT(uint32_t bits7_0) 64 { 65 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 66 if (ITCounter == 0) 67 return false; 68 69 // A8.6.50 IT 70 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 71 if (FirstCond == 0xF) 72 { 73 #ifdef LLDB_CONFIGURATION_DEBUG 74 printf("Encoding error: IT FirstCond '1111'\n"); 75 #endif 76 return false; 77 } 78 if (FirstCond == 0xE && ITCounter != 1) 79 { 80 #ifdef LLDB_CONFIGURATION_DEBUG 81 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 82 #endif 83 return false; 84 } 85 86 ITState = bits7_0; 87 return true; 88 } 89 90 // Update ITState if necessary. 91 void ITSession::ITAdvance() 92 { 93 //assert(ITCounter); 94 --ITCounter; 95 if (ITCounter == 0) 96 ITState = 0; 97 else 98 { 99 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 100 SetBits32(ITState, 4, 0, NewITState4_0); 101 } 102 } 103 104 // Return true if we're inside an IT Block. 105 bool ITSession::InITBlock() 106 { 107 return ITCounter != 0; 108 } 109 110 // Return true if we're the last instruction inside an IT Block. 111 bool ITSession::LastInITBlock() 112 { 113 return ITCounter == 1; 114 } 115 116 // Get condition bits for the current thumb instruction. 117 uint32_t ITSession::GetCond() 118 { 119 if (InITBlock()) 120 return Bits32(ITState, 7, 4); 121 else 122 return COND_AL; 123 } 124 125 // ARM constants used during decoding 126 #define REG_RD 0 127 #define LDM_REGLIST 1 128 #define SP_REG 13 129 #define LR_REG 14 130 #define PC_REG 15 131 #define PC_REGLIST_BIT 0x8000 132 133 #define ARMv4 (1u << 0) 134 #define ARMv4T (1u << 1) 135 #define ARMv5T (1u << 2) 136 #define ARMv5TE (1u << 3) 137 #define ARMv5TEJ (1u << 4) 138 #define ARMv6 (1u << 5) 139 #define ARMv6K (1u << 6) 140 #define ARMv6T2 (1u << 7) 141 #define ARMv7 (1u << 8) 142 #define ARMv7S (1u << 9) 143 #define ARMv8 (1u << 10) 144 #define ARMvAll (0xffffffffu) 145 146 #define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 147 #define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 148 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 149 #define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 150 #define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 151 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8) 152 #define ARMV7_ABOVE (ARMv7|ARMv7S|ARMv8) 153 154 #define No_VFP 0 155 #define VFPv1 (1u << 1) 156 #define VFPv2 (1u << 2) 157 #define VFPv3 (1u << 3) 158 #define AdvancedSIMD (1u << 4) 159 160 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 161 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 162 #define VFPv2v3 (VFPv2 | VFPv3) 163 164 //---------------------------------------------------------------------- 165 // 166 // EmulateInstructionARM implementation 167 // 168 //---------------------------------------------------------------------- 169 170 void 171 EmulateInstructionARM::Initialize () 172 { 173 PluginManager::RegisterPlugin (GetPluginNameStatic (), 174 GetPluginDescriptionStatic (), 175 CreateInstance); 176 } 177 178 void 179 EmulateInstructionARM::Terminate () 180 { 181 PluginManager::UnregisterPlugin (CreateInstance); 182 } 183 184 ConstString 185 EmulateInstructionARM::GetPluginNameStatic () 186 { 187 static ConstString g_name("arm"); 188 return g_name; 189 } 190 191 const char * 192 EmulateInstructionARM::GetPluginDescriptionStatic () 193 { 194 return "Emulate instructions for the ARM architecture."; 195 } 196 197 EmulateInstruction * 198 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) 199 { 200 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(inst_type)) 201 { 202 if (arch.GetTriple().getArch() == llvm::Triple::arm) 203 { 204 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 205 206 if (emulate_insn_ap.get()) 207 return emulate_insn_ap.release(); 208 } 209 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 210 { 211 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 212 213 if (emulate_insn_ap.get()) 214 return emulate_insn_ap.release(); 215 } 216 } 217 218 return NULL; 219 } 220 221 bool 222 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch) 223 { 224 if (arch.GetTriple().getArch () == llvm::Triple::arm) 225 return true; 226 else if (arch.GetTriple().getArch () == llvm::Triple::thumb) 227 return true; 228 229 return false; 230 } 231 232 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 233 bool 234 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 235 { 236 EmulateInstruction::Context context; 237 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 238 context.SetNoArgs (); 239 240 uint32_t random_data = rand (); 241 const uint32_t addr_byte_size = GetAddressByteSize(); 242 243 if (!MemAWrite (context, address, random_data, addr_byte_size)) 244 return false; 245 246 return true; 247 } 248 249 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 250 bool 251 EmulateInstructionARM::WriteBits32Unknown (int n) 252 { 253 EmulateInstruction::Context context; 254 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 255 context.SetNoArgs (); 256 257 bool success; 258 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 259 260 if (!success) 261 return false; 262 263 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 264 return false; 265 266 return true; 267 } 268 269 bool 270 EmulateInstructionARM::GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo ®_info) 271 { 272 if (reg_kind == eRegisterKindGeneric) 273 { 274 switch (reg_num) 275 { 276 case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break; 277 case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break; 278 case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break; 279 case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break; 280 case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break; 281 default: return false; 282 } 283 } 284 285 if (reg_kind == eRegisterKindDWARF) 286 return GetARMDWARFRegisterInfo(reg_num, reg_info); 287 return false; 288 } 289 290 uint32_t 291 EmulateInstructionARM::GetFramePointerRegisterNumber () const 292 { 293 bool is_apple = false; 294 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 295 is_apple = true; 296 switch (m_arch.GetTriple().getOS()) 297 { 298 case llvm::Triple::Darwin: 299 case llvm::Triple::MacOSX: 300 case llvm::Triple::IOS: 301 is_apple = true; 302 break; 303 default: 304 break; 305 } 306 307 /* On Apple iOS et al, the frame pointer register is always r7. 308 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 309 */ 310 311 uint32_t fp_regnum = 11; 312 313 if (is_apple) 314 fp_regnum = 7; 315 316 if (m_opcode_mode == eModeThumb) 317 fp_regnum = 7; 318 319 return fp_regnum; 320 } 321 322 uint32_t 323 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 324 { 325 bool is_apple = false; 326 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 327 is_apple = true; 328 switch (m_arch.GetTriple().getOS()) 329 { 330 case llvm::Triple::Darwin: 331 case llvm::Triple::MacOSX: 332 case llvm::Triple::IOS: 333 is_apple = true; 334 break; 335 default: 336 break; 337 } 338 339 /* On Apple iOS et al, the frame pointer register is always r7. 340 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 341 */ 342 343 uint32_t fp_regnum = dwarf_r11; 344 345 if (is_apple) 346 fp_regnum = dwarf_r7; 347 348 if (m_opcode_mode == eModeThumb) 349 fp_regnum = dwarf_r7; 350 351 return fp_regnum; 352 } 353 354 // Push Multiple Registers stores multiple registers to the stack, storing to 355 // consecutive memory locations ending just below the address in SP, and updates 356 // SP to point to the start of the stored data. 357 bool 358 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 359 { 360 #if 0 361 // ARM pseudo code... 362 if (ConditionPassed()) 363 { 364 EncodingSpecificOperations(); 365 NullCheckIfThumbEE(13); 366 address = SP - 4*BitCount(registers); 367 368 for (i = 0 to 14) 369 { 370 if (registers<i> == '1') 371 { 372 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 373 MemA[address,4] = bits(32) UNKNOWN; 374 else 375 MemA[address,4] = R[i]; 376 address = address + 4; 377 } 378 } 379 380 if (registers<15> == '1') // Only possible for encoding A1 or A2 381 MemA[address,4] = PCStoreValue(); 382 383 SP = SP - 4*BitCount(registers); 384 } 385 #endif 386 387 bool conditional = false; 388 bool success = false; 389 if (ConditionPassed(opcode, &conditional)) 390 { 391 const uint32_t addr_byte_size = GetAddressByteSize(); 392 const addr_t sp = ReadCoreReg (SP_REG, &success); 393 if (!success) 394 return false; 395 uint32_t registers = 0; 396 uint32_t Rt; // the source register 397 switch (encoding) { 398 case eEncodingT1: 399 registers = Bits32(opcode, 7, 0); 400 // The M bit represents LR. 401 if (Bit32(opcode, 8)) 402 registers |= (1u << 14); 403 // if BitCount(registers) < 1 then UNPREDICTABLE; 404 if (BitCount(registers) < 1) 405 return false; 406 break; 407 case eEncodingT2: 408 // Ignore bits 15 & 13. 409 registers = Bits32(opcode, 15, 0) & ~0xa000; 410 // if BitCount(registers) < 2 then UNPREDICTABLE; 411 if (BitCount(registers) < 2) 412 return false; 413 break; 414 case eEncodingT3: 415 Rt = Bits32(opcode, 15, 12); 416 // if BadReg(t) then UNPREDICTABLE; 417 if (BadReg(Rt)) 418 return false; 419 registers = (1u << Rt); 420 break; 421 case eEncodingA1: 422 registers = Bits32(opcode, 15, 0); 423 // Instead of return false, let's handle the following case as well, 424 // which amounts to pushing one reg onto the full descending stacks. 425 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 426 break; 427 case eEncodingA2: 428 Rt = Bits32(opcode, 15, 12); 429 // if t == 13 then UNPREDICTABLE; 430 if (Rt == dwarf_sp) 431 return false; 432 registers = (1u << Rt); 433 break; 434 default: 435 return false; 436 } 437 addr_t sp_offset = addr_byte_size * BitCount (registers); 438 addr_t addr = sp - sp_offset; 439 uint32_t i; 440 441 EmulateInstruction::Context context; 442 if (conditional) 443 context.type = EmulateInstruction::eContextRegisterStore; 444 else 445 context.type = EmulateInstruction::eContextPushRegisterOnStack; 446 RegisterInfo reg_info; 447 RegisterInfo sp_reg; 448 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 449 for (i=0; i<15; ++i) 450 { 451 if (BitIsSet (registers, i)) 452 { 453 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 454 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 455 uint32_t reg_value = ReadCoreReg(i, &success); 456 if (!success) 457 return false; 458 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 459 return false; 460 addr += addr_byte_size; 461 } 462 } 463 464 if (BitIsSet (registers, 15)) 465 { 466 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 467 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 468 const uint32_t pc = ReadCoreReg(PC_REG, &success); 469 if (!success) 470 return false; 471 if (!MemAWrite (context, addr, pc, addr_byte_size)) 472 return false; 473 } 474 475 context.type = EmulateInstruction::eContextAdjustStackPointer; 476 context.SetImmediateSigned (-sp_offset); 477 478 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 479 return false; 480 } 481 return true; 482 } 483 484 // Pop Multiple Registers loads multiple registers from the stack, loading from 485 // consecutive memory locations staring at the address in SP, and updates 486 // SP to point just above the loaded data. 487 bool 488 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 489 { 490 #if 0 491 // ARM pseudo code... 492 if (ConditionPassed()) 493 { 494 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 495 address = SP; 496 for i = 0 to 14 497 if registers<i> == '1' then 498 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 499 if registers<15> == '1' then 500 if UnalignedAllowed then 501 LoadWritePC(MemU[address,4]); 502 else 503 LoadWritePC(MemA[address,4]); 504 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 505 if registers<13> == '1' then SP = bits(32) UNKNOWN; 506 } 507 #endif 508 509 bool success = false; 510 511 bool conditional = false; 512 if (ConditionPassed(opcode, &conditional)) 513 { 514 const uint32_t addr_byte_size = GetAddressByteSize(); 515 const addr_t sp = ReadCoreReg (SP_REG, &success); 516 if (!success) 517 return false; 518 uint32_t registers = 0; 519 uint32_t Rt; // the destination register 520 switch (encoding) { 521 case eEncodingT1: 522 registers = Bits32(opcode, 7, 0); 523 // The P bit represents PC. 524 if (Bit32(opcode, 8)) 525 registers |= (1u << 15); 526 // if BitCount(registers) < 1 then UNPREDICTABLE; 527 if (BitCount(registers) < 1) 528 return false; 529 break; 530 case eEncodingT2: 531 // Ignore bit 13. 532 registers = Bits32(opcode, 15, 0) & ~0x2000; 533 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 534 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 535 return false; 536 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 537 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 538 return false; 539 break; 540 case eEncodingT3: 541 Rt = Bits32(opcode, 15, 12); 542 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 543 if (Rt == 13) 544 return false; 545 if (Rt == 15 && InITBlock() && !LastInITBlock()) 546 return false; 547 registers = (1u << Rt); 548 break; 549 case eEncodingA1: 550 registers = Bits32(opcode, 15, 0); 551 // Instead of return false, let's handle the following case as well, 552 // which amounts to popping one reg from the full descending stacks. 553 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 554 555 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 556 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 557 return false; 558 break; 559 case eEncodingA2: 560 Rt = Bits32(opcode, 15, 12); 561 // if t == 13 then UNPREDICTABLE; 562 if (Rt == dwarf_sp) 563 return false; 564 registers = (1u << Rt); 565 break; 566 default: 567 return false; 568 } 569 addr_t sp_offset = addr_byte_size * BitCount (registers); 570 addr_t addr = sp; 571 uint32_t i, data; 572 573 EmulateInstruction::Context context; 574 if (conditional) 575 context.type = EmulateInstruction::eContextRegisterLoad; 576 else 577 context.type = EmulateInstruction::eContextPopRegisterOffStack; 578 579 RegisterInfo sp_reg; 580 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 581 582 for (i=0; i<15; ++i) 583 { 584 if (BitIsSet (registers, i)) 585 { 586 context.SetRegisterPlusOffset (sp_reg, addr - sp); 587 data = MemARead(context, addr, 4, 0, &success); 588 if (!success) 589 return false; 590 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 591 return false; 592 addr += addr_byte_size; 593 } 594 } 595 596 if (BitIsSet (registers, 15)) 597 { 598 context.SetRegisterPlusOffset (sp_reg, addr - sp); 599 data = MemARead(context, addr, 4, 0, &success); 600 if (!success) 601 return false; 602 // In ARMv5T and above, this is an interworking branch. 603 if (!LoadWritePC(context, data)) 604 return false; 605 //addr += addr_byte_size; 606 } 607 608 context.type = EmulateInstruction::eContextAdjustStackPointer; 609 context.SetImmediateSigned (sp_offset); 610 611 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 612 return false; 613 } 614 return true; 615 } 616 617 // Set r7 or ip to point to saved value residing within the stack. 618 // ADD (SP plus immediate) 619 bool 620 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 621 { 622 #if 0 623 // ARM pseudo code... 624 if (ConditionPassed()) 625 { 626 EncodingSpecificOperations(); 627 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 628 if d == 15 then 629 ALUWritePC(result); // setflags is always FALSE here 630 else 631 R[d] = result; 632 if setflags then 633 APSR.N = result<31>; 634 APSR.Z = IsZeroBit(result); 635 APSR.C = carry; 636 APSR.V = overflow; 637 } 638 #endif 639 640 bool success = false; 641 642 if (ConditionPassed(opcode)) 643 { 644 const addr_t sp = ReadCoreReg (SP_REG, &success); 645 if (!success) 646 return false; 647 uint32_t Rd; // the destination register 648 uint32_t imm32; 649 switch (encoding) { 650 case eEncodingT1: 651 Rd = 7; 652 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 653 break; 654 case eEncodingA1: 655 Rd = Bits32(opcode, 15, 12); 656 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 657 break; 658 default: 659 return false; 660 } 661 addr_t sp_offset = imm32; 662 addr_t addr = sp + sp_offset; // a pointer to the stack area 663 664 EmulateInstruction::Context context; 665 context.type = eContextSetFramePointer; 666 RegisterInfo sp_reg; 667 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 668 context.SetRegisterPlusOffset (sp_reg, sp_offset); 669 670 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 671 return false; 672 } 673 return true; 674 } 675 676 // Set r7 or ip to the current stack pointer. 677 // MOV (register) 678 bool 679 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 680 { 681 #if 0 682 // ARM pseudo code... 683 if (ConditionPassed()) 684 { 685 EncodingSpecificOperations(); 686 result = R[m]; 687 if d == 15 then 688 ALUWritePC(result); // setflags is always FALSE here 689 else 690 R[d] = result; 691 if setflags then 692 APSR.N = result<31>; 693 APSR.Z = IsZeroBit(result); 694 // APSR.C unchanged 695 // APSR.V unchanged 696 } 697 #endif 698 699 bool success = false; 700 701 if (ConditionPassed(opcode)) 702 { 703 const addr_t sp = ReadCoreReg (SP_REG, &success); 704 if (!success) 705 return false; 706 uint32_t Rd; // the destination register 707 switch (encoding) { 708 case eEncodingT1: 709 Rd = 7; 710 break; 711 case eEncodingA1: 712 Rd = 12; 713 break; 714 default: 715 return false; 716 } 717 718 EmulateInstruction::Context context; 719 if (Rd == GetFramePointerRegisterNumber()) 720 context.type = EmulateInstruction::eContextSetFramePointer; 721 else 722 context.type = EmulateInstruction::eContextRegisterPlusOffset; 723 RegisterInfo sp_reg; 724 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 725 context.SetRegisterPlusOffset (sp_reg, 0); 726 727 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 728 return false; 729 } 730 return true; 731 } 732 733 // Move from high register (r8-r15) to low register (r0-r7). 734 // MOV (register) 735 bool 736 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 737 { 738 return EmulateMOVRdRm (opcode, encoding); 739 } 740 741 // Move from register to register. 742 // MOV (register) 743 bool 744 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 745 { 746 #if 0 747 // ARM pseudo code... 748 if (ConditionPassed()) 749 { 750 EncodingSpecificOperations(); 751 result = R[m]; 752 if d == 15 then 753 ALUWritePC(result); // setflags is always FALSE here 754 else 755 R[d] = result; 756 if setflags then 757 APSR.N = result<31>; 758 APSR.Z = IsZeroBit(result); 759 // APSR.C unchanged 760 // APSR.V unchanged 761 } 762 #endif 763 764 bool success = false; 765 766 if (ConditionPassed(opcode)) 767 { 768 uint32_t Rm; // the source register 769 uint32_t Rd; // the destination register 770 bool setflags; 771 switch (encoding) { 772 case eEncodingT1: 773 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 774 Rm = Bits32(opcode, 6, 3); 775 setflags = false; 776 if (Rd == 15 && InITBlock() && !LastInITBlock()) 777 return false; 778 break; 779 case eEncodingT2: 780 Rd = Bits32(opcode, 2, 0); 781 Rm = Bits32(opcode, 5, 3); 782 setflags = true; 783 if (InITBlock()) 784 return false; 785 break; 786 case eEncodingT3: 787 Rd = Bits32(opcode, 11, 8); 788 Rm = Bits32(opcode, 3, 0); 789 setflags = BitIsSet(opcode, 20); 790 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 791 if (setflags && (BadReg(Rd) || BadReg(Rm))) 792 return false; 793 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 794 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 795 return false; 796 break; 797 case eEncodingA1: 798 Rd = Bits32(opcode, 15, 12); 799 Rm = Bits32(opcode, 3, 0); 800 setflags = BitIsSet(opcode, 20); 801 802 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 803 if (Rd == 15 && setflags) 804 return EmulateSUBSPcLrEtc (opcode, encoding); 805 break; 806 default: 807 return false; 808 } 809 uint32_t result = ReadCoreReg(Rm, &success); 810 if (!success) 811 return false; 812 813 // The context specifies that Rm is to be moved into Rd. 814 EmulateInstruction::Context context; 815 context.type = EmulateInstruction::eContextRegisterLoad; 816 RegisterInfo dwarf_reg; 817 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 818 context.SetRegister (dwarf_reg); 819 820 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 821 return false; 822 } 823 return true; 824 } 825 826 // Move (immediate) writes an immediate value to the destination register. It 827 // can optionally update the condition flags based on the value. 828 // MOV (immediate) 829 bool 830 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 831 { 832 #if 0 833 // ARM pseudo code... 834 if (ConditionPassed()) 835 { 836 EncodingSpecificOperations(); 837 result = imm32; 838 if d == 15 then // Can only occur for ARM encoding 839 ALUWritePC(result); // setflags is always FALSE here 840 else 841 R[d] = result; 842 if setflags then 843 APSR.N = result<31>; 844 APSR.Z = IsZeroBit(result); 845 APSR.C = carry; 846 // APSR.V unchanged 847 } 848 #endif 849 850 if (ConditionPassed(opcode)) 851 { 852 uint32_t Rd; // the destination register 853 uint32_t imm32; // the immediate value to be written to Rd 854 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 855 // for setflags == false, this value is a don't care 856 // initialized to 0 to silence the static analyzer 857 bool setflags; 858 switch (encoding) { 859 case eEncodingT1: 860 Rd = Bits32(opcode, 10, 8); 861 setflags = !InITBlock(); 862 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 863 carry = APSR_C; 864 865 break; 866 867 case eEncodingT2: 868 Rd = Bits32(opcode, 11, 8); 869 setflags = BitIsSet(opcode, 20); 870 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 871 if (BadReg(Rd)) 872 return false; 873 874 break; 875 876 case eEncodingT3: 877 { 878 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 879 Rd = Bits32 (opcode, 11, 8); 880 setflags = false; 881 uint32_t imm4 = Bits32 (opcode, 19, 16); 882 uint32_t imm3 = Bits32 (opcode, 14, 12); 883 uint32_t i = Bit32 (opcode, 26); 884 uint32_t imm8 = Bits32 (opcode, 7, 0); 885 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 886 887 // if BadReg(d) then UNPREDICTABLE; 888 if (BadReg (Rd)) 889 return false; 890 } 891 break; 892 893 case eEncodingA1: 894 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 895 Rd = Bits32 (opcode, 15, 12); 896 setflags = BitIsSet (opcode, 20); 897 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 898 899 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 900 if ((Rd == 15) && setflags) 901 return EmulateSUBSPcLrEtc (opcode, encoding); 902 903 break; 904 905 case eEncodingA2: 906 { 907 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 908 Rd = Bits32 (opcode, 15, 12); 909 setflags = false; 910 uint32_t imm4 = Bits32 (opcode, 19, 16); 911 uint32_t imm12 = Bits32 (opcode, 11, 0); 912 imm32 = (imm4 << 12) | imm12; 913 914 // if d == 15 then UNPREDICTABLE; 915 if (Rd == 15) 916 return false; 917 } 918 break; 919 920 default: 921 return false; 922 } 923 uint32_t result = imm32; 924 925 // The context specifies that an immediate is to be moved into Rd. 926 EmulateInstruction::Context context; 927 context.type = EmulateInstruction::eContextImmediate; 928 context.SetNoArgs (); 929 930 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 931 return false; 932 } 933 return true; 934 } 935 936 // MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 937 // register. These 32 bits do not depend on whether the source register values are considered to be signed values or 938 // unsigned values. 939 // 940 // Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 941 // limited to only a few forms of the instruction. 942 bool 943 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 944 { 945 #if 0 946 if ConditionPassed() then 947 EncodingSpecificOperations(); 948 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 949 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 950 result = operand1 * operand2; 951 R[d] = result<31:0>; 952 if setflags then 953 APSR.N = result<31>; 954 APSR.Z = IsZeroBit(result); 955 if ArchVersion() == 4 then 956 APSR.C = bit UNKNOWN; 957 // else APSR.C unchanged 958 // APSR.V always unchanged 959 #endif 960 961 if (ConditionPassed(opcode)) 962 { 963 uint32_t d; 964 uint32_t n; 965 uint32_t m; 966 bool setflags; 967 968 // EncodingSpecificOperations(); 969 switch (encoding) 970 { 971 case eEncodingT1: 972 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 973 d = Bits32 (opcode, 2, 0); 974 n = Bits32 (opcode, 5, 3); 975 m = Bits32 (opcode, 2, 0); 976 setflags = !InITBlock(); 977 978 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 979 if ((ArchVersion() < ARMv6) && (d == n)) 980 return false; 981 982 break; 983 984 case eEncodingT2: 985 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 986 d = Bits32 (opcode, 11, 8); 987 n = Bits32 (opcode, 19, 16); 988 m = Bits32 (opcode, 3, 0); 989 setflags = false; 990 991 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 992 if (BadReg (d) || BadReg (n) || BadReg (m)) 993 return false; 994 995 break; 996 997 case eEncodingA1: 998 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 999 d = Bits32 (opcode, 19, 16); 1000 n = Bits32 (opcode, 3, 0); 1001 m = Bits32 (opcode, 11, 8); 1002 setflags = BitIsSet (opcode, 20); 1003 1004 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1005 if ((d == 15) || (n == 15) || (m == 15)) 1006 return false; 1007 1008 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1009 if ((ArchVersion() < ARMv6) && (d == n)) 1010 return false; 1011 1012 break; 1013 1014 default: 1015 return false; 1016 } 1017 1018 bool success = false; 1019 1020 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1021 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1022 if (!success) 1023 return false; 1024 1025 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1026 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1027 if (!success) 1028 return false; 1029 1030 // result = operand1 * operand2; 1031 uint64_t result = operand1 * operand2; 1032 1033 // R[d] = result<31:0>; 1034 RegisterInfo op1_reg; 1035 RegisterInfo op2_reg; 1036 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1037 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1038 1039 EmulateInstruction::Context context; 1040 context.type = eContextArithmetic; 1041 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 1042 1043 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 1044 return false; 1045 1046 // if setflags then 1047 if (setflags) 1048 { 1049 // APSR.N = result<31>; 1050 // APSR.Z = IsZeroBit(result); 1051 m_new_inst_cpsr = m_opcode_cpsr; 1052 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 1053 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1054 if (m_new_inst_cpsr != m_opcode_cpsr) 1055 { 1056 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1057 return false; 1058 } 1059 1060 // if ArchVersion() == 4 then 1061 // APSR.C = bit UNKNOWN; 1062 } 1063 } 1064 return true; 1065 } 1066 1067 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1068 // It can optionally update the condition flags based on the value. 1069 bool 1070 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1071 { 1072 #if 0 1073 // ARM pseudo code... 1074 if (ConditionPassed()) 1075 { 1076 EncodingSpecificOperations(); 1077 result = NOT(imm32); 1078 if d == 15 then // Can only occur for ARM encoding 1079 ALUWritePC(result); // setflags is always FALSE here 1080 else 1081 R[d] = result; 1082 if setflags then 1083 APSR.N = result<31>; 1084 APSR.Z = IsZeroBit(result); 1085 APSR.C = carry; 1086 // APSR.V unchanged 1087 } 1088 #endif 1089 1090 if (ConditionPassed(opcode)) 1091 { 1092 uint32_t Rd; // the destination register 1093 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1094 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1095 bool setflags; 1096 switch (encoding) { 1097 case eEncodingT1: 1098 Rd = Bits32(opcode, 11, 8); 1099 setflags = BitIsSet(opcode, 20); 1100 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1101 break; 1102 case eEncodingA1: 1103 Rd = Bits32(opcode, 15, 12); 1104 setflags = BitIsSet(opcode, 20); 1105 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1106 1107 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1108 if (Rd == 15 && setflags) 1109 return EmulateSUBSPcLrEtc (opcode, encoding); 1110 break; 1111 default: 1112 return false; 1113 } 1114 uint32_t result = ~imm32; 1115 1116 // The context specifies that an immediate is to be moved into Rd. 1117 EmulateInstruction::Context context; 1118 context.type = EmulateInstruction::eContextImmediate; 1119 context.SetNoArgs (); 1120 1121 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1122 return false; 1123 } 1124 return true; 1125 } 1126 1127 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1128 // It can optionally update the condition flags based on the result. 1129 bool 1130 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1131 { 1132 #if 0 1133 // ARM pseudo code... 1134 if (ConditionPassed()) 1135 { 1136 EncodingSpecificOperations(); 1137 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1138 result = NOT(shifted); 1139 if d == 15 then // Can only occur for ARM encoding 1140 ALUWritePC(result); // setflags is always FALSE here 1141 else 1142 R[d] = result; 1143 if setflags then 1144 APSR.N = result<31>; 1145 APSR.Z = IsZeroBit(result); 1146 APSR.C = carry; 1147 // APSR.V unchanged 1148 } 1149 #endif 1150 1151 if (ConditionPassed(opcode)) 1152 { 1153 uint32_t Rm; // the source register 1154 uint32_t Rd; // the destination register 1155 ARM_ShifterType shift_t; 1156 uint32_t shift_n; // the shift applied to the value read from Rm 1157 bool setflags; 1158 uint32_t carry; // the carry bit after the shift operation 1159 switch (encoding) { 1160 case eEncodingT1: 1161 Rd = Bits32(opcode, 2, 0); 1162 Rm = Bits32(opcode, 5, 3); 1163 setflags = !InITBlock(); 1164 shift_t = SRType_LSL; 1165 shift_n = 0; 1166 if (InITBlock()) 1167 return false; 1168 break; 1169 case eEncodingT2: 1170 Rd = Bits32(opcode, 11, 8); 1171 Rm = Bits32(opcode, 3, 0); 1172 setflags = BitIsSet(opcode, 20); 1173 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1174 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1175 if (BadReg(Rd) || BadReg(Rm)) 1176 return false; 1177 break; 1178 case eEncodingA1: 1179 Rd = Bits32(opcode, 15, 12); 1180 Rm = Bits32(opcode, 3, 0); 1181 setflags = BitIsSet(opcode, 20); 1182 shift_n = DecodeImmShiftARM(opcode, shift_t); 1183 break; 1184 default: 1185 return false; 1186 } 1187 bool success = false; 1188 uint32_t value = ReadCoreReg(Rm, &success); 1189 if (!success) 1190 return false; 1191 1192 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1193 if (!success) 1194 return false; 1195 uint32_t result = ~shifted; 1196 1197 // The context specifies that an immediate is to be moved into Rd. 1198 EmulateInstruction::Context context; 1199 context.type = EmulateInstruction::eContextImmediate; 1200 context.SetNoArgs (); 1201 1202 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1203 return false; 1204 } 1205 return true; 1206 } 1207 1208 // PC relative immediate load into register, possibly followed by ADD (SP plus register). 1209 // LDR (literal) 1210 bool 1211 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1212 { 1213 #if 0 1214 // ARM pseudo code... 1215 if (ConditionPassed()) 1216 { 1217 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1218 base = Align(PC,4); 1219 address = if add then (base + imm32) else (base - imm32); 1220 data = MemU[address,4]; 1221 if t == 15 then 1222 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1223 elsif UnalignedSupport() || address<1:0> = '00' then 1224 R[t] = data; 1225 else // Can only apply before ARMv7 1226 if CurrentInstrSet() == InstrSet_ARM then 1227 R[t] = ROR(data, 8*UInt(address<1:0>)); 1228 else 1229 R[t] = bits(32) UNKNOWN; 1230 } 1231 #endif 1232 1233 if (ConditionPassed(opcode)) 1234 { 1235 bool success = false; 1236 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1237 if (!success) 1238 return false; 1239 1240 // PC relative immediate load context 1241 EmulateInstruction::Context context; 1242 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1243 RegisterInfo pc_reg; 1244 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1245 context.SetRegisterPlusOffset (pc_reg, 0); 1246 1247 uint32_t Rt; // the destination register 1248 uint32_t imm32; // immediate offset from the PC 1249 bool add; // +imm32 or -imm32? 1250 addr_t base; // the base address 1251 addr_t address; // the PC relative address 1252 uint32_t data; // the literal data value from the PC relative load 1253 switch (encoding) { 1254 case eEncodingT1: 1255 Rt = Bits32(opcode, 10, 8); 1256 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1257 add = true; 1258 break; 1259 case eEncodingT2: 1260 Rt = Bits32(opcode, 15, 12); 1261 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1262 add = BitIsSet(opcode, 23); 1263 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1264 return false; 1265 break; 1266 default: 1267 return false; 1268 } 1269 1270 base = Align(pc, 4); 1271 if (add) 1272 address = base + imm32; 1273 else 1274 address = base - imm32; 1275 1276 context.SetRegisterPlusOffset(pc_reg, address - base); 1277 data = MemURead(context, address, 4, 0, &success); 1278 if (!success) 1279 return false; 1280 1281 if (Rt == 15) 1282 { 1283 if (Bits32(address, 1, 0) == 0) 1284 { 1285 // In ARMv5T and above, this is an interworking branch. 1286 if (!LoadWritePC(context, data)) 1287 return false; 1288 } 1289 else 1290 return false; 1291 } 1292 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1293 { 1294 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1295 return false; 1296 } 1297 else // We don't handle ARM for now. 1298 return false; 1299 1300 } 1301 return true; 1302 } 1303 1304 // An add operation to adjust the SP. 1305 // ADD (SP plus immediate) 1306 bool 1307 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1308 { 1309 #if 0 1310 // ARM pseudo code... 1311 if (ConditionPassed()) 1312 { 1313 EncodingSpecificOperations(); 1314 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1315 if d == 15 then // Can only occur for ARM encoding 1316 ALUWritePC(result); // setflags is always FALSE here 1317 else 1318 R[d] = result; 1319 if setflags then 1320 APSR.N = result<31>; 1321 APSR.Z = IsZeroBit(result); 1322 APSR.C = carry; 1323 APSR.V = overflow; 1324 } 1325 #endif 1326 1327 bool success = false; 1328 1329 if (ConditionPassed(opcode)) 1330 { 1331 const addr_t sp = ReadCoreReg (SP_REG, &success); 1332 if (!success) 1333 return false; 1334 uint32_t imm32; // the immediate operand 1335 uint32_t d; 1336 //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1 1337 switch (encoding) 1338 { 1339 case eEncodingT1: 1340 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1341 d = Bits32 (opcode, 10, 8); 1342 imm32 = (Bits32 (opcode, 7, 0) << 2); 1343 1344 break; 1345 1346 case eEncodingT2: 1347 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1348 d = 13; 1349 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1350 1351 break; 1352 1353 default: 1354 return false; 1355 } 1356 addr_t sp_offset = imm32; 1357 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1358 1359 EmulateInstruction::Context context; 1360 if (d == 13) 1361 context.type = EmulateInstruction::eContextAdjustStackPointer; 1362 else 1363 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1364 1365 RegisterInfo sp_reg; 1366 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1367 context.SetRegisterPlusOffset (sp_reg, sp_offset); 1368 1369 if (d == 15) 1370 { 1371 if (!ALUWritePC (context, addr)) 1372 return false; 1373 } 1374 else 1375 { 1376 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr)) 1377 return false; 1378 1379 // Add this back if/when support eEncodingT3 eEncodingA1 1380 //if (setflags) 1381 //{ 1382 // APSR.N = result<31>; 1383 // APSR.Z = IsZeroBit(result); 1384 // APSR.C = carry; 1385 // APSR.V = overflow; 1386 //} 1387 } 1388 } 1389 return true; 1390 } 1391 1392 // An add operation to adjust the SP. 1393 // ADD (SP plus register) 1394 bool 1395 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1396 { 1397 #if 0 1398 // ARM pseudo code... 1399 if (ConditionPassed()) 1400 { 1401 EncodingSpecificOperations(); 1402 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1403 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1404 if d == 15 then 1405 ALUWritePC(result); // setflags is always FALSE here 1406 else 1407 R[d] = result; 1408 if setflags then 1409 APSR.N = result<31>; 1410 APSR.Z = IsZeroBit(result); 1411 APSR.C = carry; 1412 APSR.V = overflow; 1413 } 1414 #endif 1415 1416 bool success = false; 1417 1418 if (ConditionPassed(opcode)) 1419 { 1420 const addr_t sp = ReadCoreReg (SP_REG, &success); 1421 if (!success) 1422 return false; 1423 uint32_t Rm; // the second operand 1424 switch (encoding) { 1425 case eEncodingT2: 1426 Rm = Bits32(opcode, 6, 3); 1427 break; 1428 default: 1429 return false; 1430 } 1431 int32_t reg_value = ReadCoreReg(Rm, &success); 1432 if (!success) 1433 return false; 1434 1435 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1436 1437 EmulateInstruction::Context context; 1438 context.type = eContextArithmetic; 1439 RegisterInfo sp_reg; 1440 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1441 1442 RegisterInfo other_reg; 1443 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1444 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1445 1446 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1447 return false; 1448 } 1449 return true; 1450 } 1451 1452 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1453 // at a PC-relative address, and changes instruction set from ARM to Thumb, or 1454 // from Thumb to ARM. 1455 // BLX (immediate) 1456 bool 1457 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1458 { 1459 #if 0 1460 // ARM pseudo code... 1461 if (ConditionPassed()) 1462 { 1463 EncodingSpecificOperations(); 1464 if CurrentInstrSet() == InstrSet_ARM then 1465 LR = PC - 4; 1466 else 1467 LR = PC<31:1> : '1'; 1468 if targetInstrSet == InstrSet_ARM then 1469 targetAddress = Align(PC,4) + imm32; 1470 else 1471 targetAddress = PC + imm32; 1472 SelectInstrSet(targetInstrSet); 1473 BranchWritePC(targetAddress); 1474 } 1475 #endif 1476 1477 bool success = true; 1478 1479 if (ConditionPassed(opcode)) 1480 { 1481 EmulateInstruction::Context context; 1482 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1483 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1484 if (!success) 1485 return false; 1486 addr_t lr; // next instruction address 1487 addr_t target; // target address 1488 int32_t imm32; // PC-relative offset 1489 switch (encoding) { 1490 case eEncodingT1: 1491 { 1492 lr = pc | 1u; // return address 1493 uint32_t S = Bit32(opcode, 26); 1494 uint32_t imm10 = Bits32(opcode, 25, 16); 1495 uint32_t J1 = Bit32(opcode, 13); 1496 uint32_t J2 = Bit32(opcode, 11); 1497 uint32_t imm11 = Bits32(opcode, 10, 0); 1498 uint32_t I1 = !(J1 ^ S); 1499 uint32_t I2 = !(J2 ^ S); 1500 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1501 imm32 = llvm::SignExtend32<25>(imm25); 1502 target = pc + imm32; 1503 SelectInstrSet (eModeThumb); 1504 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1505 if (InITBlock() && !LastInITBlock()) 1506 return false; 1507 break; 1508 } 1509 case eEncodingT2: 1510 { 1511 lr = pc | 1u; // return address 1512 uint32_t S = Bit32(opcode, 26); 1513 uint32_t imm10H = Bits32(opcode, 25, 16); 1514 uint32_t J1 = Bit32(opcode, 13); 1515 uint32_t J2 = Bit32(opcode, 11); 1516 uint32_t imm10L = Bits32(opcode, 10, 1); 1517 uint32_t I1 = !(J1 ^ S); 1518 uint32_t I2 = !(J2 ^ S); 1519 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1520 imm32 = llvm::SignExtend32<25>(imm25); 1521 target = Align(pc, 4) + imm32; 1522 SelectInstrSet (eModeARM); 1523 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1524 if (InITBlock() && !LastInITBlock()) 1525 return false; 1526 break; 1527 } 1528 case eEncodingA1: 1529 lr = pc - 4; // return address 1530 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1531 target = Align(pc, 4) + imm32; 1532 SelectInstrSet (eModeARM); 1533 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1534 break; 1535 case eEncodingA2: 1536 lr = pc - 4; // return address 1537 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1538 target = pc + imm32; 1539 SelectInstrSet (eModeThumb); 1540 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1541 break; 1542 default: 1543 return false; 1544 } 1545 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1546 return false; 1547 if (!BranchWritePC(context, target)) 1548 return false; 1549 if (m_opcode_cpsr != m_new_inst_cpsr) 1550 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1551 return false; 1552 } 1553 return true; 1554 } 1555 1556 // Branch with Link and Exchange (register) calls a subroutine at an address and 1557 // instruction set specified by a register. 1558 // BLX (register) 1559 bool 1560 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1561 { 1562 #if 0 1563 // ARM pseudo code... 1564 if (ConditionPassed()) 1565 { 1566 EncodingSpecificOperations(); 1567 target = R[m]; 1568 if CurrentInstrSet() == InstrSet_ARM then 1569 next_instr_addr = PC - 4; 1570 LR = next_instr_addr; 1571 else 1572 next_instr_addr = PC - 2; 1573 LR = next_instr_addr<31:1> : '1'; 1574 BXWritePC(target); 1575 } 1576 #endif 1577 1578 bool success = false; 1579 1580 if (ConditionPassed(opcode)) 1581 { 1582 EmulateInstruction::Context context; 1583 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1584 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1585 addr_t lr; // next instruction address 1586 if (!success) 1587 return false; 1588 uint32_t Rm; // the register with the target address 1589 switch (encoding) { 1590 case eEncodingT1: 1591 lr = (pc - 2) | 1u; // return address 1592 Rm = Bits32(opcode, 6, 3); 1593 // if m == 15 then UNPREDICTABLE; 1594 if (Rm == 15) 1595 return false; 1596 if (InITBlock() && !LastInITBlock()) 1597 return false; 1598 break; 1599 case eEncodingA1: 1600 lr = pc - 4; // return address 1601 Rm = Bits32(opcode, 3, 0); 1602 // if m == 15 then UNPREDICTABLE; 1603 if (Rm == 15) 1604 return false; 1605 break; 1606 default: 1607 return false; 1608 } 1609 addr_t target = ReadCoreReg (Rm, &success); 1610 if (!success) 1611 return false; 1612 RegisterInfo dwarf_reg; 1613 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1614 context.SetRegister (dwarf_reg); 1615 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1616 return false; 1617 if (!BXWritePC(context, target)) 1618 return false; 1619 } 1620 return true; 1621 } 1622 1623 // Branch and Exchange causes a branch to an address and instruction set specified by a register. 1624 bool 1625 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1626 { 1627 #if 0 1628 // ARM pseudo code... 1629 if (ConditionPassed()) 1630 { 1631 EncodingSpecificOperations(); 1632 BXWritePC(R[m]); 1633 } 1634 #endif 1635 1636 if (ConditionPassed(opcode)) 1637 { 1638 EmulateInstruction::Context context; 1639 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1640 uint32_t Rm; // the register with the target address 1641 switch (encoding) { 1642 case eEncodingT1: 1643 Rm = Bits32(opcode, 6, 3); 1644 if (InITBlock() && !LastInITBlock()) 1645 return false; 1646 break; 1647 case eEncodingA1: 1648 Rm = Bits32(opcode, 3, 0); 1649 break; 1650 default: 1651 return false; 1652 } 1653 bool success = false; 1654 addr_t target = ReadCoreReg (Rm, &success); 1655 if (!success) 1656 return false; 1657 1658 RegisterInfo dwarf_reg; 1659 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1660 context.SetRegister (dwarf_reg); 1661 if (!BXWritePC(context, target)) 1662 return false; 1663 } 1664 return true; 1665 } 1666 1667 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1668 // address and instruction set specified by a register as though it were a BX instruction. 1669 // 1670 // TODO: Emulate Jazelle architecture? 1671 // We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1672 bool 1673 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1674 { 1675 #if 0 1676 // ARM pseudo code... 1677 if (ConditionPassed()) 1678 { 1679 EncodingSpecificOperations(); 1680 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1681 BXWritePC(R[m]); 1682 else 1683 if JazelleAcceptsExecution() then 1684 SwitchToJazelleExecution(); 1685 else 1686 SUBARCHITECTURE_DEFINED handler call; 1687 } 1688 #endif 1689 1690 if (ConditionPassed(opcode)) 1691 { 1692 EmulateInstruction::Context context; 1693 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1694 uint32_t Rm; // the register with the target address 1695 switch (encoding) { 1696 case eEncodingT1: 1697 Rm = Bits32(opcode, 19, 16); 1698 if (BadReg(Rm)) 1699 return false; 1700 if (InITBlock() && !LastInITBlock()) 1701 return false; 1702 break; 1703 case eEncodingA1: 1704 Rm = Bits32(opcode, 3, 0); 1705 if (Rm == 15) 1706 return false; 1707 break; 1708 default: 1709 return false; 1710 } 1711 bool success = false; 1712 addr_t target = ReadCoreReg (Rm, &success); 1713 if (!success) 1714 return false; 1715 1716 RegisterInfo dwarf_reg; 1717 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1718 context.SetRegister (dwarf_reg); 1719 if (!BXWritePC(context, target)) 1720 return false; 1721 } 1722 return true; 1723 } 1724 1725 // Set r7 to point to some ip offset. 1726 // SUB (immediate) 1727 bool 1728 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1729 { 1730 #if 0 1731 // ARM pseudo code... 1732 if (ConditionPassed()) 1733 { 1734 EncodingSpecificOperations(); 1735 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1736 if d == 15 then // Can only occur for ARM encoding 1737 ALUWritePC(result); // setflags is always FALSE here 1738 else 1739 R[d] = result; 1740 if setflags then 1741 APSR.N = result<31>; 1742 APSR.Z = IsZeroBit(result); 1743 APSR.C = carry; 1744 APSR.V = overflow; 1745 } 1746 #endif 1747 1748 if (ConditionPassed(opcode)) 1749 { 1750 bool success = false; 1751 const addr_t ip = ReadCoreReg (12, &success); 1752 if (!success) 1753 return false; 1754 uint32_t imm32; 1755 switch (encoding) { 1756 case eEncodingA1: 1757 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1758 break; 1759 default: 1760 return false; 1761 } 1762 addr_t ip_offset = imm32; 1763 addr_t addr = ip - ip_offset; // the adjusted ip value 1764 1765 EmulateInstruction::Context context; 1766 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1767 RegisterInfo dwarf_reg; 1768 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1769 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1770 1771 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1772 return false; 1773 } 1774 return true; 1775 } 1776 1777 // Set ip to point to some stack offset. 1778 // SUB (SP minus immediate) 1779 bool 1780 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1781 { 1782 #if 0 1783 // ARM pseudo code... 1784 if (ConditionPassed()) 1785 { 1786 EncodingSpecificOperations(); 1787 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1788 if d == 15 then // Can only occur for ARM encoding 1789 ALUWritePC(result); // setflags is always FALSE here 1790 else 1791 R[d] = result; 1792 if setflags then 1793 APSR.N = result<31>; 1794 APSR.Z = IsZeroBit(result); 1795 APSR.C = carry; 1796 APSR.V = overflow; 1797 } 1798 #endif 1799 1800 if (ConditionPassed(opcode)) 1801 { 1802 bool success = false; 1803 const addr_t sp = ReadCoreReg (SP_REG, &success); 1804 if (!success) 1805 return false; 1806 uint32_t imm32; 1807 switch (encoding) { 1808 case eEncodingA1: 1809 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1810 break; 1811 default: 1812 return false; 1813 } 1814 addr_t sp_offset = imm32; 1815 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1816 1817 EmulateInstruction::Context context; 1818 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1819 RegisterInfo dwarf_reg; 1820 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1821 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1822 1823 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1824 return false; 1825 } 1826 return true; 1827 } 1828 1829 // This instruction subtracts an immediate value from the SP value, and writes 1830 // the result to the destination register. 1831 // 1832 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1833 bool 1834 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1835 { 1836 #if 0 1837 // ARM pseudo code... 1838 if (ConditionPassed()) 1839 { 1840 EncodingSpecificOperations(); 1841 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1842 if d == 15 then // Can only occur for ARM encoding 1843 ALUWritePC(result); // setflags is always FALSE here 1844 else 1845 R[d] = result; 1846 if setflags then 1847 APSR.N = result<31>; 1848 APSR.Z = IsZeroBit(result); 1849 APSR.C = carry; 1850 APSR.V = overflow; 1851 } 1852 #endif 1853 1854 bool success = false; 1855 if (ConditionPassed(opcode)) 1856 { 1857 const addr_t sp = ReadCoreReg (SP_REG, &success); 1858 if (!success) 1859 return false; 1860 1861 uint32_t Rd; 1862 bool setflags; 1863 uint32_t imm32; 1864 switch (encoding) { 1865 case eEncodingT1: 1866 Rd = 13; 1867 setflags = false; 1868 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1869 break; 1870 case eEncodingT2: 1871 Rd = Bits32(opcode, 11, 8); 1872 setflags = BitIsSet(opcode, 20); 1873 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1874 if (Rd == 15 && setflags) 1875 return EmulateCMPImm(opcode, eEncodingT2); 1876 if (Rd == 15 && !setflags) 1877 return false; 1878 break; 1879 case eEncodingT3: 1880 Rd = Bits32(opcode, 11, 8); 1881 setflags = false; 1882 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1883 if (Rd == 15) 1884 return false; 1885 break; 1886 case eEncodingA1: 1887 Rd = Bits32(opcode, 15, 12); 1888 setflags = BitIsSet(opcode, 20); 1889 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1890 1891 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1892 if (Rd == 15 && setflags) 1893 return EmulateSUBSPcLrEtc (opcode, encoding); 1894 break; 1895 default: 1896 return false; 1897 } 1898 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1899 1900 EmulateInstruction::Context context; 1901 if (Rd == 13) 1902 { 1903 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1904 // value gets passed down to context.SetImmediateSigned. 1905 context.type = EmulateInstruction::eContextAdjustStackPointer; 1906 context.SetImmediateSigned (-imm64); // the stack pointer offset 1907 } 1908 else 1909 { 1910 context.type = EmulateInstruction::eContextImmediate; 1911 context.SetNoArgs (); 1912 } 1913 1914 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1915 return false; 1916 } 1917 return true; 1918 } 1919 1920 // A store operation to the stack that also updates the SP. 1921 bool 1922 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1923 { 1924 #if 0 1925 // ARM pseudo code... 1926 if (ConditionPassed()) 1927 { 1928 EncodingSpecificOperations(); 1929 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1930 address = if index then offset_addr else R[n]; 1931 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1932 if wback then R[n] = offset_addr; 1933 } 1934 #endif 1935 1936 bool conditional = false; 1937 bool success = false; 1938 if (ConditionPassed(opcode, &conditional)) 1939 { 1940 const uint32_t addr_byte_size = GetAddressByteSize(); 1941 const addr_t sp = ReadCoreReg (SP_REG, &success); 1942 if (!success) 1943 return false; 1944 uint32_t Rt; // the source register 1945 uint32_t imm12; 1946 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1947 1948 bool index; 1949 bool add; 1950 bool wback; 1951 switch (encoding) { 1952 case eEncodingA1: 1953 Rt = Bits32(opcode, 15, 12); 1954 imm12 = Bits32(opcode, 11, 0); 1955 Rn = Bits32 (opcode, 19, 16); 1956 1957 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1958 return false; 1959 1960 index = BitIsSet (opcode, 24); 1961 add = BitIsSet (opcode, 23); 1962 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1963 1964 if (wback && ((Rn == 15) || (Rn == Rt))) 1965 return false; 1966 break; 1967 default: 1968 return false; 1969 } 1970 addr_t offset_addr; 1971 if (add) 1972 offset_addr = sp + imm12; 1973 else 1974 offset_addr = sp - imm12; 1975 1976 addr_t addr; 1977 if (index) 1978 addr = offset_addr; 1979 else 1980 addr = sp; 1981 1982 EmulateInstruction::Context context; 1983 if (conditional) 1984 context.type = EmulateInstruction::eContextRegisterStore; 1985 else 1986 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1987 RegisterInfo sp_reg; 1988 RegisterInfo dwarf_reg; 1989 1990 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1991 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 1992 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 1993 if (Rt != 15) 1994 { 1995 uint32_t reg_value = ReadCoreReg(Rt, &success); 1996 if (!success) 1997 return false; 1998 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1999 return false; 2000 } 2001 else 2002 { 2003 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2004 if (!success) 2005 return false; 2006 if (!MemUWrite (context, addr, pc, addr_byte_size)) 2007 return false; 2008 } 2009 2010 2011 if (wback) 2012 { 2013 context.type = EmulateInstruction::eContextAdjustStackPointer; 2014 context.SetImmediateSigned (addr - sp); 2015 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 2016 return false; 2017 } 2018 } 2019 return true; 2020 } 2021 2022 // Vector Push stores multiple extension registers to the stack. 2023 // It also updates SP to point to the start of the stored data. 2024 bool 2025 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 2026 { 2027 #if 0 2028 // ARM pseudo code... 2029 if (ConditionPassed()) 2030 { 2031 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2032 address = SP - imm32; 2033 SP = SP - imm32; 2034 if single_regs then 2035 for r = 0 to regs-1 2036 MemA[address,4] = S[d+r]; address = address+4; 2037 else 2038 for r = 0 to regs-1 2039 // Store as two word-aligned words in the correct order for current endianness. 2040 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2041 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2042 address = address+8; 2043 } 2044 #endif 2045 2046 bool success = false; 2047 bool conditional = false; 2048 if (ConditionPassed(opcode, &conditional)) 2049 { 2050 const uint32_t addr_byte_size = GetAddressByteSize(); 2051 const addr_t sp = ReadCoreReg (SP_REG, &success); 2052 if (!success) 2053 return false; 2054 bool single_regs; 2055 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2056 uint32_t imm32; // stack offset 2057 uint32_t regs; // number of registers 2058 switch (encoding) { 2059 case eEncodingT1: 2060 case eEncodingA1: 2061 single_regs = false; 2062 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2063 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2064 // If UInt(imm8) is odd, see "FSTMX". 2065 regs = Bits32(opcode, 7, 0) / 2; 2066 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2067 if (regs == 0 || regs > 16 || (d + regs) > 32) 2068 return false; 2069 break; 2070 case eEncodingT2: 2071 case eEncodingA2: 2072 single_regs = true; 2073 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2074 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2075 regs = Bits32(opcode, 7, 0); 2076 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2077 if (regs == 0 || regs > 16 || (d + regs) > 32) 2078 return false; 2079 break; 2080 default: 2081 return false; 2082 } 2083 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2084 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2085 addr_t sp_offset = imm32; 2086 addr_t addr = sp - sp_offset; 2087 uint32_t i; 2088 2089 EmulateInstruction::Context context; 2090 if (conditional) 2091 context.type = EmulateInstruction::eContextRegisterStore; 2092 else 2093 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2094 RegisterInfo dwarf_reg; 2095 RegisterInfo sp_reg; 2096 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2097 for (i=0; i<regs; ++i) 2098 { 2099 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2100 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2101 // uint64_t to accommodate 64-bit registers. 2102 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2103 if (!success) 2104 return false; 2105 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2106 return false; 2107 addr += reg_byte_size; 2108 } 2109 2110 context.type = EmulateInstruction::eContextAdjustStackPointer; 2111 context.SetImmediateSigned (-sp_offset); 2112 2113 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2114 return false; 2115 } 2116 return true; 2117 } 2118 2119 // Vector Pop loads multiple extension registers from the stack. 2120 // It also updates SP to point just above the loaded data. 2121 bool 2122 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2123 { 2124 #if 0 2125 // ARM pseudo code... 2126 if (ConditionPassed()) 2127 { 2128 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2129 address = SP; 2130 SP = SP + imm32; 2131 if single_regs then 2132 for r = 0 to regs-1 2133 S[d+r] = MemA[address,4]; address = address+4; 2134 else 2135 for r = 0 to regs-1 2136 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2137 // Combine the word-aligned words in the correct order for current endianness. 2138 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2139 } 2140 #endif 2141 2142 bool success = false; 2143 bool conditional = false; 2144 if (ConditionPassed(opcode, &conditional)) 2145 { 2146 const uint32_t addr_byte_size = GetAddressByteSize(); 2147 const addr_t sp = ReadCoreReg (SP_REG, &success); 2148 if (!success) 2149 return false; 2150 bool single_regs; 2151 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2152 uint32_t imm32; // stack offset 2153 uint32_t regs; // number of registers 2154 switch (encoding) { 2155 case eEncodingT1: 2156 case eEncodingA1: 2157 single_regs = false; 2158 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2159 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2160 // If UInt(imm8) is odd, see "FLDMX". 2161 regs = Bits32(opcode, 7, 0) / 2; 2162 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2163 if (regs == 0 || regs > 16 || (d + regs) > 32) 2164 return false; 2165 break; 2166 case eEncodingT2: 2167 case eEncodingA2: 2168 single_regs = true; 2169 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2170 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2171 regs = Bits32(opcode, 7, 0); 2172 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2173 if (regs == 0 || regs > 16 || (d + regs) > 32) 2174 return false; 2175 break; 2176 default: 2177 return false; 2178 } 2179 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2180 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2181 addr_t sp_offset = imm32; 2182 addr_t addr = sp; 2183 uint32_t i; 2184 uint64_t data; // uint64_t to accommodate 64-bit registers. 2185 2186 EmulateInstruction::Context context; 2187 if (conditional) 2188 context.type = EmulateInstruction::eContextRegisterLoad; 2189 else 2190 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2191 RegisterInfo dwarf_reg; 2192 RegisterInfo sp_reg; 2193 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2194 for (i=0; i<regs; ++i) 2195 { 2196 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2197 context.SetRegisterPlusOffset (sp_reg, addr - sp); 2198 data = MemARead(context, addr, reg_byte_size, 0, &success); 2199 if (!success) 2200 return false; 2201 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2202 return false; 2203 addr += reg_byte_size; 2204 } 2205 2206 context.type = EmulateInstruction::eContextAdjustStackPointer; 2207 context.SetImmediateSigned (sp_offset); 2208 2209 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2210 return false; 2211 } 2212 return true; 2213 } 2214 2215 // SVC (previously SWI) 2216 bool 2217 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2218 { 2219 #if 0 2220 // ARM pseudo code... 2221 if (ConditionPassed()) 2222 { 2223 EncodingSpecificOperations(); 2224 CallSupervisor(); 2225 } 2226 #endif 2227 2228 bool success = false; 2229 2230 if (ConditionPassed(opcode)) 2231 { 2232 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2233 addr_t lr; // next instruction address 2234 if (!success) 2235 return false; 2236 uint32_t imm32; // the immediate constant 2237 uint32_t mode; // ARM or Thumb mode 2238 switch (encoding) { 2239 case eEncodingT1: 2240 lr = (pc + 2) | 1u; // return address 2241 imm32 = Bits32(opcode, 7, 0); 2242 mode = eModeThumb; 2243 break; 2244 case eEncodingA1: 2245 lr = pc + 4; // return address 2246 imm32 = Bits32(opcode, 23, 0); 2247 mode = eModeARM; 2248 break; 2249 default: 2250 return false; 2251 } 2252 2253 EmulateInstruction::Context context; 2254 context.type = EmulateInstruction::eContextSupervisorCall; 2255 context.SetISAAndImmediate (mode, imm32); 2256 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2257 return false; 2258 } 2259 return true; 2260 } 2261 2262 // If Then makes up to four following instructions (the IT block) conditional. 2263 bool 2264 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2265 { 2266 #if 0 2267 // ARM pseudo code... 2268 EncodingSpecificOperations(); 2269 ITSTATE.IT<7:0> = firstcond:mask; 2270 #endif 2271 2272 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2273 return true; 2274 } 2275 2276 bool 2277 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2278 { 2279 // NOP, nothing to do... 2280 return true; 2281 } 2282 2283 // Branch causes a branch to a target address. 2284 bool 2285 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2286 { 2287 #if 0 2288 // ARM pseudo code... 2289 if (ConditionPassed()) 2290 { 2291 EncodingSpecificOperations(); 2292 BranchWritePC(PC + imm32); 2293 } 2294 #endif 2295 2296 bool success = false; 2297 2298 if (ConditionPassed(opcode)) 2299 { 2300 EmulateInstruction::Context context; 2301 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2302 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2303 if (!success) 2304 return false; 2305 addr_t target; // target address 2306 int32_t imm32; // PC-relative offset 2307 switch (encoding) { 2308 case eEncodingT1: 2309 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2310 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2311 target = pc + imm32; 2312 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2313 break; 2314 case eEncodingT2: 2315 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2316 target = pc + imm32; 2317 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2318 break; 2319 case eEncodingT3: 2320 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2321 { 2322 uint32_t S = Bit32(opcode, 26); 2323 uint32_t imm6 = Bits32(opcode, 21, 16); 2324 uint32_t J1 = Bit32(opcode, 13); 2325 uint32_t J2 = Bit32(opcode, 11); 2326 uint32_t imm11 = Bits32(opcode, 10, 0); 2327 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2328 imm32 = llvm::SignExtend32<21>(imm21); 2329 target = pc + imm32; 2330 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2331 break; 2332 } 2333 case eEncodingT4: 2334 { 2335 uint32_t S = Bit32(opcode, 26); 2336 uint32_t imm10 = Bits32(opcode, 25, 16); 2337 uint32_t J1 = Bit32(opcode, 13); 2338 uint32_t J2 = Bit32(opcode, 11); 2339 uint32_t imm11 = Bits32(opcode, 10, 0); 2340 uint32_t I1 = !(J1 ^ S); 2341 uint32_t I2 = !(J2 ^ S); 2342 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2343 imm32 = llvm::SignExtend32<25>(imm25); 2344 target = pc + imm32; 2345 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2346 break; 2347 } 2348 case eEncodingA1: 2349 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2350 target = pc + imm32; 2351 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2352 break; 2353 default: 2354 return false; 2355 } 2356 if (!BranchWritePC(context, target)) 2357 return false; 2358 } 2359 return true; 2360 } 2361 2362 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2363 // zero and conditionally branch forward a constant value. They do not affect the condition flags. 2364 // CBNZ, CBZ 2365 bool 2366 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2367 { 2368 #if 0 2369 // ARM pseudo code... 2370 EncodingSpecificOperations(); 2371 if nonzero ^ IsZero(R[n]) then 2372 BranchWritePC(PC + imm32); 2373 #endif 2374 2375 bool success = false; 2376 2377 // Read the register value from the operand register Rn. 2378 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2379 if (!success) 2380 return false; 2381 2382 EmulateInstruction::Context context; 2383 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2384 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2385 if (!success) 2386 return false; 2387 2388 addr_t target; // target address 2389 uint32_t imm32; // PC-relative offset to branch forward 2390 bool nonzero; 2391 switch (encoding) { 2392 case eEncodingT1: 2393 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2394 nonzero = BitIsSet(opcode, 11); 2395 target = pc + imm32; 2396 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2397 break; 2398 default: 2399 return false; 2400 } 2401 if (nonzero ^ (reg_val == 0)) 2402 if (!BranchWritePC(context, target)) 2403 return false; 2404 2405 return true; 2406 } 2407 2408 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2409 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2410 // The branch length is twice the value of the byte returned from the table. 2411 // 2412 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2413 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2414 // The branch length is twice the value of the halfword returned from the table. 2415 // TBB, TBH 2416 bool 2417 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2418 { 2419 #if 0 2420 // ARM pseudo code... 2421 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2422 if is_tbh then 2423 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2424 else 2425 halfwords = UInt(MemU[R[n]+R[m], 1]); 2426 BranchWritePC(PC + 2*halfwords); 2427 #endif 2428 2429 bool success = false; 2430 2431 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2432 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2433 bool is_tbh; // true if table branch halfword 2434 switch (encoding) { 2435 case eEncodingT1: 2436 Rn = Bits32(opcode, 19, 16); 2437 Rm = Bits32(opcode, 3, 0); 2438 is_tbh = BitIsSet(opcode, 4); 2439 if (Rn == 13 || BadReg(Rm)) 2440 return false; 2441 if (InITBlock() && !LastInITBlock()) 2442 return false; 2443 break; 2444 default: 2445 return false; 2446 } 2447 2448 // Read the address of the table from the operand register Rn. 2449 // The PC can be used, in which case the table immediately follows this instruction. 2450 uint32_t base = ReadCoreReg(Rm, &success); 2451 if (!success) 2452 return false; 2453 2454 // the table index 2455 uint32_t index = ReadCoreReg(Rm, &success); 2456 if (!success) 2457 return false; 2458 2459 // the offsetted table address 2460 addr_t addr = base + (is_tbh ? index*2 : index); 2461 2462 // PC-relative offset to branch forward 2463 EmulateInstruction::Context context; 2464 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2465 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2466 if (!success) 2467 return false; 2468 2469 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2470 if (!success) 2471 return false; 2472 2473 // target address 2474 addr_t target = pc + offset; 2475 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2476 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2477 2478 if (!BranchWritePC(context, target)) 2479 return false; 2480 2481 return true; 2482 } 2483 2484 // This instruction adds an immediate value to a register value, and writes the result to the destination register. 2485 // It can optionally update the condition flags based on the result. 2486 bool 2487 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2488 { 2489 #if 0 2490 if ConditionPassed() then 2491 EncodingSpecificOperations(); 2492 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2493 R[d] = result; 2494 if setflags then 2495 APSR.N = result<31>; 2496 APSR.Z = IsZeroBit(result); 2497 APSR.C = carry; 2498 APSR.V = overflow; 2499 #endif 2500 2501 bool success = false; 2502 2503 if (ConditionPassed(opcode)) 2504 { 2505 uint32_t d; 2506 uint32_t n; 2507 bool setflags; 2508 uint32_t imm32; 2509 uint32_t carry_out; 2510 2511 //EncodingSpecificOperations(); 2512 switch (encoding) 2513 { 2514 case eEncodingT1: 2515 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2516 d = Bits32 (opcode, 2, 0); 2517 n = Bits32 (opcode, 5, 3); 2518 setflags = !InITBlock(); 2519 imm32 = Bits32 (opcode, 8,6); 2520 2521 break; 2522 2523 case eEncodingT2: 2524 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2525 d = Bits32 (opcode, 10, 8); 2526 n = Bits32 (opcode, 10, 8); 2527 setflags = !InITBlock(); 2528 imm32 = Bits32 (opcode, 7, 0); 2529 2530 break; 2531 2532 case eEncodingT3: 2533 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2534 // if Rn == '1101' then SEE ADD (SP plus immediate); 2535 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2536 d = Bits32 (opcode, 11, 8); 2537 n = Bits32 (opcode, 19, 16); 2538 setflags = BitIsSet (opcode, 20); 2539 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2540 2541 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2542 if (BadReg (d) || (n == 15)) 2543 return false; 2544 2545 break; 2546 2547 case eEncodingT4: 2548 { 2549 // if Rn == '1111' then SEE ADR; 2550 // if Rn == '1101' then SEE ADD (SP plus immediate); 2551 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2552 d = Bits32 (opcode, 11, 8); 2553 n = Bits32 (opcode, 19, 16); 2554 setflags = false; 2555 uint32_t i = Bit32 (opcode, 26); 2556 uint32_t imm3 = Bits32 (opcode, 14, 12); 2557 uint32_t imm8 = Bits32 (opcode, 7, 0); 2558 imm32 = (i << 11) | (imm3 << 8) | imm8; 2559 2560 // if BadReg(d) then UNPREDICTABLE; 2561 if (BadReg (d)) 2562 return false; 2563 2564 break; 2565 } 2566 default: 2567 return false; 2568 } 2569 2570 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2571 if (!success) 2572 return false; 2573 2574 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2575 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2576 2577 RegisterInfo reg_n; 2578 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2579 2580 EmulateInstruction::Context context; 2581 context.type = eContextArithmetic; 2582 context.SetRegisterPlusOffset (reg_n, imm32); 2583 2584 //R[d] = result; 2585 //if setflags then 2586 //APSR.N = result<31>; 2587 //APSR.Z = IsZeroBit(result); 2588 //APSR.C = carry; 2589 //APSR.V = overflow; 2590 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2591 return false; 2592 2593 } 2594 return true; 2595 } 2596 2597 // This instruction adds an immediate value to a register value, and writes the result to the destination 2598 // register. It can optionally update the condition flags based on the result. 2599 bool 2600 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2601 { 2602 #if 0 2603 // ARM pseudo code... 2604 if ConditionPassed() then 2605 EncodingSpecificOperations(); 2606 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2607 if d == 15 then 2608 ALUWritePC(result); // setflags is always FALSE here 2609 else 2610 R[d] = result; 2611 if setflags then 2612 APSR.N = result<31>; 2613 APSR.Z = IsZeroBit(result); 2614 APSR.C = carry; 2615 APSR.V = overflow; 2616 #endif 2617 2618 bool success = false; 2619 2620 if (ConditionPassed(opcode)) 2621 { 2622 uint32_t Rd, Rn; 2623 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2624 bool setflags; 2625 switch (encoding) 2626 { 2627 case eEncodingA1: 2628 Rd = Bits32(opcode, 15, 12); 2629 Rn = Bits32(opcode, 19, 16); 2630 setflags = BitIsSet(opcode, 20); 2631 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2632 break; 2633 default: 2634 return false; 2635 } 2636 2637 // Read the first operand. 2638 uint32_t val1 = ReadCoreReg(Rn, &success); 2639 if (!success) 2640 return false; 2641 2642 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2643 2644 EmulateInstruction::Context context; 2645 context.type = eContextArithmetic; 2646 RegisterInfo dwarf_reg; 2647 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2648 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2649 2650 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2651 return false; 2652 } 2653 return true; 2654 } 2655 2656 // This instruction adds a register value and an optionally-shifted register value, and writes the result 2657 // to the destination register. It can optionally update the condition flags based on the result. 2658 bool 2659 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2660 { 2661 #if 0 2662 // ARM pseudo code... 2663 if ConditionPassed() then 2664 EncodingSpecificOperations(); 2665 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2666 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2667 if d == 15 then 2668 ALUWritePC(result); // setflags is always FALSE here 2669 else 2670 R[d] = result; 2671 if setflags then 2672 APSR.N = result<31>; 2673 APSR.Z = IsZeroBit(result); 2674 APSR.C = carry; 2675 APSR.V = overflow; 2676 #endif 2677 2678 bool success = false; 2679 2680 if (ConditionPassed(opcode)) 2681 { 2682 uint32_t Rd, Rn, Rm; 2683 ARM_ShifterType shift_t; 2684 uint32_t shift_n; // the shift applied to the value read from Rm 2685 bool setflags; 2686 switch (encoding) 2687 { 2688 case eEncodingT1: 2689 Rd = Bits32(opcode, 2, 0); 2690 Rn = Bits32(opcode, 5, 3); 2691 Rm = Bits32(opcode, 8, 6); 2692 setflags = !InITBlock(); 2693 shift_t = SRType_LSL; 2694 shift_n = 0; 2695 break; 2696 case eEncodingT2: 2697 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2698 Rm = Bits32(opcode, 6, 3); 2699 setflags = false; 2700 shift_t = SRType_LSL; 2701 shift_n = 0; 2702 if (Rn == 15 && Rm == 15) 2703 return false; 2704 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2705 return false; 2706 break; 2707 case eEncodingA1: 2708 Rd = Bits32(opcode, 15, 12); 2709 Rn = Bits32(opcode, 19, 16); 2710 Rm = Bits32(opcode, 3, 0); 2711 setflags = BitIsSet(opcode, 20); 2712 shift_n = DecodeImmShiftARM(opcode, shift_t); 2713 break; 2714 default: 2715 return false; 2716 } 2717 2718 // Read the first operand. 2719 uint32_t val1 = ReadCoreReg(Rn, &success); 2720 if (!success) 2721 return false; 2722 2723 // Read the second operand. 2724 uint32_t val2 = ReadCoreReg(Rm, &success); 2725 if (!success) 2726 return false; 2727 2728 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2729 if (!success) 2730 return false; 2731 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2732 2733 EmulateInstruction::Context context; 2734 context.type = eContextArithmetic; 2735 RegisterInfo op1_reg; 2736 RegisterInfo op2_reg; 2737 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2738 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2739 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2740 2741 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2742 return false; 2743 } 2744 return true; 2745 } 2746 2747 // Compare Negative (immediate) adds a register value and an immediate value. 2748 // It updates the condition flags based on the result, and discards the result. 2749 bool 2750 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2751 { 2752 #if 0 2753 // ARM pseudo code... 2754 if ConditionPassed() then 2755 EncodingSpecificOperations(); 2756 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2757 APSR.N = result<31>; 2758 APSR.Z = IsZeroBit(result); 2759 APSR.C = carry; 2760 APSR.V = overflow; 2761 #endif 2762 2763 bool success = false; 2764 2765 uint32_t Rn; // the first operand 2766 uint32_t imm32; // the immediate value to be compared with 2767 switch (encoding) { 2768 case eEncodingT1: 2769 Rn = Bits32(opcode, 19, 16); 2770 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2771 if (Rn == 15) 2772 return false; 2773 break; 2774 case eEncodingA1: 2775 Rn = Bits32(opcode, 19, 16); 2776 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2777 break; 2778 default: 2779 return false; 2780 } 2781 // Read the register value from the operand register Rn. 2782 uint32_t reg_val = ReadCoreReg(Rn, &success); 2783 if (!success) 2784 return false; 2785 2786 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2787 2788 EmulateInstruction::Context context; 2789 context.type = EmulateInstruction::eContextImmediate; 2790 context.SetNoArgs (); 2791 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2792 return false; 2793 2794 return true; 2795 } 2796 2797 // Compare Negative (register) adds a register value and an optionally-shifted register value. 2798 // It updates the condition flags based on the result, and discards the result. 2799 bool 2800 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2801 { 2802 #if 0 2803 // ARM pseudo code... 2804 if ConditionPassed() then 2805 EncodingSpecificOperations(); 2806 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2807 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2808 APSR.N = result<31>; 2809 APSR.Z = IsZeroBit(result); 2810 APSR.C = carry; 2811 APSR.V = overflow; 2812 #endif 2813 2814 bool success = false; 2815 2816 uint32_t Rn; // the first operand 2817 uint32_t Rm; // the second operand 2818 ARM_ShifterType shift_t; 2819 uint32_t shift_n; // the shift applied to the value read from Rm 2820 switch (encoding) { 2821 case eEncodingT1: 2822 Rn = Bits32(opcode, 2, 0); 2823 Rm = Bits32(opcode, 5, 3); 2824 shift_t = SRType_LSL; 2825 shift_n = 0; 2826 break; 2827 case eEncodingT2: 2828 Rn = Bits32(opcode, 19, 16); 2829 Rm = Bits32(opcode, 3, 0); 2830 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2831 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2832 if (Rn == 15 || BadReg(Rm)) 2833 return false; 2834 break; 2835 case eEncodingA1: 2836 Rn = Bits32(opcode, 19, 16); 2837 Rm = Bits32(opcode, 3, 0); 2838 shift_n = DecodeImmShiftARM(opcode, shift_t); 2839 break; 2840 default: 2841 return false; 2842 } 2843 // Read the register value from register Rn. 2844 uint32_t val1 = ReadCoreReg(Rn, &success); 2845 if (!success) 2846 return false; 2847 2848 // Read the register value from register Rm. 2849 uint32_t val2 = ReadCoreReg(Rm, &success); 2850 if (!success) 2851 return false; 2852 2853 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2854 if (!success) 2855 return false; 2856 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2857 2858 EmulateInstruction::Context context; 2859 context.type = EmulateInstruction::eContextImmediate; 2860 context.SetNoArgs(); 2861 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2862 return false; 2863 2864 return true; 2865 } 2866 2867 // Compare (immediate) subtracts an immediate value from a register value. 2868 // It updates the condition flags based on the result, and discards the result. 2869 bool 2870 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2871 { 2872 #if 0 2873 // ARM pseudo code... 2874 if ConditionPassed() then 2875 EncodingSpecificOperations(); 2876 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2877 APSR.N = result<31>; 2878 APSR.Z = IsZeroBit(result); 2879 APSR.C = carry; 2880 APSR.V = overflow; 2881 #endif 2882 2883 bool success = false; 2884 2885 uint32_t Rn; // the first operand 2886 uint32_t imm32; // the immediate value to be compared with 2887 switch (encoding) { 2888 case eEncodingT1: 2889 Rn = Bits32(opcode, 10, 8); 2890 imm32 = Bits32(opcode, 7, 0); 2891 break; 2892 case eEncodingT2: 2893 Rn = Bits32(opcode, 19, 16); 2894 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2895 if (Rn == 15) 2896 return false; 2897 break; 2898 case eEncodingA1: 2899 Rn = Bits32(opcode, 19, 16); 2900 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2901 break; 2902 default: 2903 return false; 2904 } 2905 // Read the register value from the operand register Rn. 2906 uint32_t reg_val = ReadCoreReg(Rn, &success); 2907 if (!success) 2908 return false; 2909 2910 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2911 2912 EmulateInstruction::Context context; 2913 context.type = EmulateInstruction::eContextImmediate; 2914 context.SetNoArgs (); 2915 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2916 return false; 2917 2918 return true; 2919 } 2920 2921 // Compare (register) subtracts an optionally-shifted register value from a register value. 2922 // It updates the condition flags based on the result, and discards the result. 2923 bool 2924 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2925 { 2926 #if 0 2927 // ARM pseudo code... 2928 if ConditionPassed() then 2929 EncodingSpecificOperations(); 2930 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2931 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2932 APSR.N = result<31>; 2933 APSR.Z = IsZeroBit(result); 2934 APSR.C = carry; 2935 APSR.V = overflow; 2936 #endif 2937 2938 bool success = false; 2939 2940 uint32_t Rn; // the first operand 2941 uint32_t Rm; // the second operand 2942 ARM_ShifterType shift_t; 2943 uint32_t shift_n; // the shift applied to the value read from Rm 2944 switch (encoding) { 2945 case eEncodingT1: 2946 Rn = Bits32(opcode, 2, 0); 2947 Rm = Bits32(opcode, 5, 3); 2948 shift_t = SRType_LSL; 2949 shift_n = 0; 2950 break; 2951 case eEncodingT2: 2952 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2953 Rm = Bits32(opcode, 6, 3); 2954 shift_t = SRType_LSL; 2955 shift_n = 0; 2956 if (Rn < 8 && Rm < 8) 2957 return false; 2958 if (Rn == 15 || Rm == 15) 2959 return false; 2960 break; 2961 case eEncodingA1: 2962 Rn = Bits32(opcode, 19, 16); 2963 Rm = Bits32(opcode, 3, 0); 2964 shift_n = DecodeImmShiftARM(opcode, shift_t); 2965 break; 2966 default: 2967 return false; 2968 } 2969 // Read the register value from register Rn. 2970 uint32_t val1 = ReadCoreReg(Rn, &success); 2971 if (!success) 2972 return false; 2973 2974 // Read the register value from register Rm. 2975 uint32_t val2 = ReadCoreReg(Rm, &success); 2976 if (!success) 2977 return false; 2978 2979 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2980 if (!success) 2981 return false; 2982 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 2983 2984 EmulateInstruction::Context context; 2985 context.type = EmulateInstruction::eContextImmediate; 2986 context.SetNoArgs(); 2987 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2988 return false; 2989 2990 return true; 2991 } 2992 2993 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2994 // shifting in copies of its sign bit, and writes the result to the destination register. It can 2995 // optionally update the condition flags based on the result. 2996 bool 2997 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 2998 { 2999 #if 0 3000 // ARM pseudo code... 3001 if ConditionPassed() then 3002 EncodingSpecificOperations(); 3003 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3004 if d == 15 then // Can only occur for ARM encoding 3005 ALUWritePC(result); // setflags is always FALSE here 3006 else 3007 R[d] = result; 3008 if setflags then 3009 APSR.N = result<31>; 3010 APSR.Z = IsZeroBit(result); 3011 APSR.C = carry; 3012 // APSR.V unchanged 3013 #endif 3014 3015 return EmulateShiftImm (opcode, encoding, SRType_ASR); 3016 } 3017 3018 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 3019 // shifting in copies of its sign bit, and writes the result to the destination register. 3020 // The variable number of bits is read from the bottom byte of a register. It can optionally update 3021 // the condition flags based on the result. 3022 bool 3023 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 3024 { 3025 #if 0 3026 // ARM pseudo code... 3027 if ConditionPassed() then 3028 EncodingSpecificOperations(); 3029 shift_n = UInt(R[m]<7:0>); 3030 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3031 R[d] = result; 3032 if setflags then 3033 APSR.N = result<31>; 3034 APSR.Z = IsZeroBit(result); 3035 APSR.C = carry; 3036 // APSR.V unchanged 3037 #endif 3038 3039 return EmulateShiftReg (opcode, encoding, SRType_ASR); 3040 } 3041 3042 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 3043 // shifting in zeros, and writes the result to the destination register. It can optionally 3044 // update the condition flags based on the result. 3045 bool 3046 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 3047 { 3048 #if 0 3049 // ARM pseudo code... 3050 if ConditionPassed() then 3051 EncodingSpecificOperations(); 3052 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3053 if d == 15 then // Can only occur for ARM encoding 3054 ALUWritePC(result); // setflags is always FALSE here 3055 else 3056 R[d] = result; 3057 if setflags then 3058 APSR.N = result<31>; 3059 APSR.Z = IsZeroBit(result); 3060 APSR.C = carry; 3061 // APSR.V unchanged 3062 #endif 3063 3064 return EmulateShiftImm (opcode, encoding, SRType_LSL); 3065 } 3066 3067 // Logical Shift Left (register) shifts a register value left by a variable number of bits, 3068 // shifting in zeros, and writes the result to the destination register. The variable number 3069 // of bits is read from the bottom byte of a register. It can optionally update the condition 3070 // flags based on the result. 3071 bool 3072 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 3073 { 3074 #if 0 3075 // ARM pseudo code... 3076 if ConditionPassed() then 3077 EncodingSpecificOperations(); 3078 shift_n = UInt(R[m]<7:0>); 3079 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3080 R[d] = result; 3081 if setflags then 3082 APSR.N = result<31>; 3083 APSR.Z = IsZeroBit(result); 3084 APSR.C = carry; 3085 // APSR.V unchanged 3086 #endif 3087 3088 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3089 } 3090 3091 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3092 // shifting in zeros, and writes the result to the destination register. It can optionally 3093 // update the condition flags based on the result. 3094 bool 3095 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3096 { 3097 #if 0 3098 // ARM pseudo code... 3099 if ConditionPassed() then 3100 EncodingSpecificOperations(); 3101 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3102 if d == 15 then // Can only occur for ARM encoding 3103 ALUWritePC(result); // setflags is always FALSE here 3104 else 3105 R[d] = result; 3106 if setflags then 3107 APSR.N = result<31>; 3108 APSR.Z = IsZeroBit(result); 3109 APSR.C = carry; 3110 // APSR.V unchanged 3111 #endif 3112 3113 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3114 } 3115 3116 // Logical Shift Right (register) shifts a register value right by a variable number of bits, 3117 // shifting in zeros, and writes the result to the destination register. The variable number 3118 // of bits is read from the bottom byte of a register. It can optionally update the condition 3119 // flags based on the result. 3120 bool 3121 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3122 { 3123 #if 0 3124 // ARM pseudo code... 3125 if ConditionPassed() then 3126 EncodingSpecificOperations(); 3127 shift_n = UInt(R[m]<7:0>); 3128 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3129 R[d] = result; 3130 if setflags then 3131 APSR.N = result<31>; 3132 APSR.Z = IsZeroBit(result); 3133 APSR.C = carry; 3134 // APSR.V unchanged 3135 #endif 3136 3137 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3138 } 3139 3140 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3141 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3142 // It can optionally update the condition flags based on the result. 3143 bool 3144 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3145 { 3146 #if 0 3147 // ARM pseudo code... 3148 if ConditionPassed() then 3149 EncodingSpecificOperations(); 3150 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3151 if d == 15 then // Can only occur for ARM encoding 3152 ALUWritePC(result); // setflags is always FALSE here 3153 else 3154 R[d] = result; 3155 if setflags then 3156 APSR.N = result<31>; 3157 APSR.Z = IsZeroBit(result); 3158 APSR.C = carry; 3159 // APSR.V unchanged 3160 #endif 3161 3162 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3163 } 3164 3165 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3166 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3167 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3168 // flags based on the result. 3169 bool 3170 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3171 { 3172 #if 0 3173 // ARM pseudo code... 3174 if ConditionPassed() then 3175 EncodingSpecificOperations(); 3176 shift_n = UInt(R[m]<7:0>); 3177 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3178 R[d] = result; 3179 if setflags then 3180 APSR.N = result<31>; 3181 APSR.Z = IsZeroBit(result); 3182 APSR.C = carry; 3183 // APSR.V unchanged 3184 #endif 3185 3186 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3187 } 3188 3189 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3190 // with the carry flag shifted into bit [31]. 3191 // 3192 // RRX can optionally update the condition flags based on the result. 3193 // In that case, bit [0] is shifted into the carry flag. 3194 bool 3195 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3196 { 3197 #if 0 3198 // ARM pseudo code... 3199 if ConditionPassed() then 3200 EncodingSpecificOperations(); 3201 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3202 if d == 15 then // Can only occur for ARM encoding 3203 ALUWritePC(result); // setflags is always FALSE here 3204 else 3205 R[d] = result; 3206 if setflags then 3207 APSR.N = result<31>; 3208 APSR.Z = IsZeroBit(result); 3209 APSR.C = carry; 3210 // APSR.V unchanged 3211 #endif 3212 3213 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3214 } 3215 3216 bool 3217 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3218 { 3219 // assert(shift_type == SRType_ASR 3220 // || shift_type == SRType_LSL 3221 // || shift_type == SRType_LSR 3222 // || shift_type == SRType_ROR 3223 // || shift_type == SRType_RRX); 3224 3225 bool success = false; 3226 3227 if (ConditionPassed(opcode)) 3228 { 3229 uint32_t Rd; // the destination register 3230 uint32_t Rm; // the first operand register 3231 uint32_t imm5; // encoding for the shift amount 3232 uint32_t carry; // the carry bit after the shift operation 3233 bool setflags; 3234 3235 // Special case handling! 3236 // A8.6.139 ROR (immediate) -- Encoding T1 3237 ARMEncoding use_encoding = encoding; 3238 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3239 { 3240 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3241 // have the same decoding of bit fields as the other Thumb2 shift operations. 3242 use_encoding = eEncodingT2; 3243 } 3244 3245 switch (use_encoding) { 3246 case eEncodingT1: 3247 // Due to the above special case handling! 3248 if (shift_type == SRType_ROR) 3249 return false; 3250 3251 Rd = Bits32(opcode, 2, 0); 3252 Rm = Bits32(opcode, 5, 3); 3253 setflags = !InITBlock(); 3254 imm5 = Bits32(opcode, 10, 6); 3255 break; 3256 case eEncodingT2: 3257 // A8.6.141 RRX 3258 // There's no imm form of RRX instructions. 3259 if (shift_type == SRType_RRX) 3260 return false; 3261 3262 Rd = Bits32(opcode, 11, 8); 3263 Rm = Bits32(opcode, 3, 0); 3264 setflags = BitIsSet(opcode, 20); 3265 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3266 if (BadReg(Rd) || BadReg(Rm)) 3267 return false; 3268 break; 3269 case eEncodingA1: 3270 Rd = Bits32(opcode, 15, 12); 3271 Rm = Bits32(opcode, 3, 0); 3272 setflags = BitIsSet(opcode, 20); 3273 imm5 = Bits32(opcode, 11, 7); 3274 break; 3275 default: 3276 return false; 3277 } 3278 3279 // A8.6.139 ROR (immediate) 3280 if (shift_type == SRType_ROR && imm5 == 0) 3281 shift_type = SRType_RRX; 3282 3283 // Get the first operand. 3284 uint32_t value = ReadCoreReg (Rm, &success); 3285 if (!success) 3286 return false; 3287 3288 // Decode the shift amount if not RRX. 3289 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3290 3291 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3292 if (!success) 3293 return false; 3294 3295 // The context specifies that an immediate is to be moved into Rd. 3296 EmulateInstruction::Context context; 3297 context.type = EmulateInstruction::eContextImmediate; 3298 context.SetNoArgs (); 3299 3300 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3301 return false; 3302 } 3303 return true; 3304 } 3305 3306 bool 3307 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3308 { 3309 // assert(shift_type == SRType_ASR 3310 // || shift_type == SRType_LSL 3311 // || shift_type == SRType_LSR 3312 // || shift_type == SRType_ROR); 3313 3314 bool success = false; 3315 3316 if (ConditionPassed(opcode)) 3317 { 3318 uint32_t Rd; // the destination register 3319 uint32_t Rn; // the first operand register 3320 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3321 uint32_t carry; // the carry bit after the shift operation 3322 bool setflags; 3323 switch (encoding) { 3324 case eEncodingT1: 3325 Rd = Bits32(opcode, 2, 0); 3326 Rn = Rd; 3327 Rm = Bits32(opcode, 5, 3); 3328 setflags = !InITBlock(); 3329 break; 3330 case eEncodingT2: 3331 Rd = Bits32(opcode, 11, 8); 3332 Rn = Bits32(opcode, 19, 16); 3333 Rm = Bits32(opcode, 3, 0); 3334 setflags = BitIsSet(opcode, 20); 3335 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3336 return false; 3337 break; 3338 case eEncodingA1: 3339 Rd = Bits32(opcode, 15, 12); 3340 Rn = Bits32(opcode, 3, 0); 3341 Rm = Bits32(opcode, 11, 8); 3342 setflags = BitIsSet(opcode, 20); 3343 if (Rd == 15 || Rn == 15 || Rm == 15) 3344 return false; 3345 break; 3346 default: 3347 return false; 3348 } 3349 3350 // Get the first operand. 3351 uint32_t value = ReadCoreReg (Rn, &success); 3352 if (!success) 3353 return false; 3354 // Get the Rm register content. 3355 uint32_t val = ReadCoreReg (Rm, &success); 3356 if (!success) 3357 return false; 3358 3359 // Get the shift amount. 3360 uint32_t amt = Bits32(val, 7, 0); 3361 3362 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3363 if (!success) 3364 return false; 3365 3366 // The context specifies that an immediate is to be moved into Rd. 3367 EmulateInstruction::Context context; 3368 context.type = EmulateInstruction::eContextImmediate; 3369 context.SetNoArgs (); 3370 3371 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3372 return false; 3373 } 3374 return true; 3375 } 3376 3377 // LDM loads multiple registers from consecutive memory locations, using an 3378 // address from a base register. Optionally the address just above the highest of those locations 3379 // can be written back to the base register. 3380 bool 3381 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3382 { 3383 #if 0 3384 // ARM pseudo code... 3385 if ConditionPassed() 3386 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3387 address = R[n]; 3388 3389 for i = 0 to 14 3390 if registers<i> == '1' then 3391 R[i] = MemA[address, 4]; address = address + 4; 3392 if registers<15> == '1' then 3393 LoadWritePC (MemA[address, 4]); 3394 3395 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3396 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3397 3398 #endif 3399 3400 bool success = false; 3401 bool conditional = false; 3402 if (ConditionPassed(opcode, &conditional)) 3403 { 3404 uint32_t n; 3405 uint32_t registers = 0; 3406 bool wback; 3407 const uint32_t addr_byte_size = GetAddressByteSize(); 3408 switch (encoding) 3409 { 3410 case eEncodingT1: 3411 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3412 n = Bits32 (opcode, 10, 8); 3413 registers = Bits32 (opcode, 7, 0); 3414 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3415 wback = BitIsClear (registers, n); 3416 // if BitCount(registers) < 1 then UNPREDICTABLE; 3417 if (BitCount(registers) < 1) 3418 return false; 3419 break; 3420 case eEncodingT2: 3421 // if W == '1' && Rn == '1101' then SEE POP; 3422 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3423 n = Bits32 (opcode, 19, 16); 3424 registers = Bits32 (opcode, 15, 0); 3425 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3426 wback = BitIsSet (opcode, 21); 3427 3428 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3429 if ((n == 15) 3430 || (BitCount (registers) < 2) 3431 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3432 return false; 3433 3434 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3435 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3436 return false; 3437 3438 // if wback && registers<n> == '1' then UNPREDICTABLE; 3439 if (wback 3440 && BitIsSet (registers, n)) 3441 return false; 3442 break; 3443 3444 case eEncodingA1: 3445 n = Bits32 (opcode, 19, 16); 3446 registers = Bits32 (opcode, 15, 0); 3447 wback = BitIsSet (opcode, 21); 3448 if ((n == 15) 3449 || (BitCount (registers) < 1)) 3450 return false; 3451 break; 3452 default: 3453 return false; 3454 } 3455 3456 int32_t offset = 0; 3457 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3458 if (!success) 3459 return false; 3460 3461 EmulateInstruction::Context context; 3462 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3463 RegisterInfo dwarf_reg; 3464 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3465 context.SetRegisterPlusOffset (dwarf_reg, offset); 3466 3467 for (int i = 0; i < 14; ++i) 3468 { 3469 if (BitIsSet (registers, i)) 3470 { 3471 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3472 context.SetRegisterPlusOffset (dwarf_reg, offset); 3473 if (wback && (n == 13)) // Pop Instruction 3474 { 3475 if (conditional) 3476 context.type = EmulateInstruction::eContextRegisterLoad; 3477 else 3478 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3479 } 3480 3481 // R[i] = MemA [address, 4]; address = address + 4; 3482 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3483 if (!success) 3484 return false; 3485 3486 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3487 return false; 3488 3489 offset += addr_byte_size; 3490 } 3491 } 3492 3493 if (BitIsSet (registers, 15)) 3494 { 3495 //LoadWritePC (MemA [address, 4]); 3496 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3497 context.SetRegisterPlusOffset (dwarf_reg, offset); 3498 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3499 if (!success) 3500 return false; 3501 // In ARMv5T and above, this is an interworking branch. 3502 if (!LoadWritePC(context, data)) 3503 return false; 3504 } 3505 3506 if (wback && BitIsClear (registers, n)) 3507 { 3508 // R[n] = R[n] + 4 * BitCount (registers) 3509 int32_t offset = addr_byte_size * BitCount (registers); 3510 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3511 context.SetRegisterPlusOffset (dwarf_reg, offset); 3512 3513 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3514 return false; 3515 } 3516 if (wback && BitIsSet (registers, n)) 3517 // R[n] bits(32) UNKNOWN; 3518 return WriteBits32Unknown (n); 3519 } 3520 return true; 3521 } 3522 3523 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3524 // The consecutive memory locations end at this address and the address just below the lowest of those locations 3525 // can optionally be written back to the base register. 3526 bool 3527 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3528 { 3529 #if 0 3530 // ARM pseudo code... 3531 if ConditionPassed() then 3532 EncodingSpecificOperations(); 3533 address = R[n] - 4*BitCount(registers) + 4; 3534 3535 for i = 0 to 14 3536 if registers<i> == '1' then 3537 R[i] = MemA[address,4]; address = address + 4; 3538 3539 if registers<15> == '1' then 3540 LoadWritePC(MemA[address,4]); 3541 3542 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3543 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3544 #endif 3545 3546 bool success = false; 3547 3548 if (ConditionPassed(opcode)) 3549 { 3550 uint32_t n; 3551 uint32_t registers = 0; 3552 bool wback; 3553 const uint32_t addr_byte_size = GetAddressByteSize(); 3554 3555 // EncodingSpecificOperations(); 3556 switch (encoding) 3557 { 3558 case eEncodingA1: 3559 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3560 n = Bits32 (opcode, 19, 16); 3561 registers = Bits32 (opcode, 15, 0); 3562 wback = BitIsSet (opcode, 21); 3563 3564 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3565 if ((n == 15) || (BitCount (registers) < 1)) 3566 return false; 3567 3568 break; 3569 3570 default: 3571 return false; 3572 } 3573 // address = R[n] - 4*BitCount(registers) + 4; 3574 3575 int32_t offset = 0; 3576 addr_t Rn = ReadCoreReg (n, &success); 3577 3578 if (!success) 3579 return false; 3580 3581 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3582 3583 EmulateInstruction::Context context; 3584 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3585 RegisterInfo dwarf_reg; 3586 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3587 context.SetRegisterPlusOffset (dwarf_reg, offset); 3588 3589 // for i = 0 to 14 3590 for (int i = 0; i < 14; ++i) 3591 { 3592 // if registers<i> == '1' then 3593 if (BitIsSet (registers, i)) 3594 { 3595 // R[i] = MemA[address,4]; address = address + 4; 3596 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3597 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3598 if (!success) 3599 return false; 3600 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3601 return false; 3602 offset += addr_byte_size; 3603 } 3604 } 3605 3606 // if registers<15> == '1' then 3607 // LoadWritePC(MemA[address,4]); 3608 if (BitIsSet (registers, 15)) 3609 { 3610 context.SetRegisterPlusOffset (dwarf_reg, offset); 3611 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3612 if (!success) 3613 return false; 3614 // In ARMv5T and above, this is an interworking branch. 3615 if (!LoadWritePC(context, data)) 3616 return false; 3617 } 3618 3619 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3620 if (wback && BitIsClear (registers, n)) 3621 { 3622 if (!success) 3623 return false; 3624 3625 offset = (addr_byte_size * BitCount (registers)) * -1; 3626 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3627 context.SetImmediateSigned (offset); 3628 addr_t addr = Rn + offset; 3629 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3630 return false; 3631 } 3632 3633 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3634 if (wback && BitIsSet (registers, n)) 3635 return WriteBits32Unknown (n); 3636 } 3637 return true; 3638 } 3639 3640 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3641 // consecutive memory locations end just below this address, and the address of the lowest of those locations can 3642 // be optionally written back to the base register. 3643 bool 3644 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3645 { 3646 #if 0 3647 // ARM pseudo code... 3648 if ConditionPassed() then 3649 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3650 address = R[n] - 4*BitCount(registers); 3651 3652 for i = 0 to 14 3653 if registers<i> == '1' then 3654 R[i] = MemA[address,4]; address = address + 4; 3655 if registers<15> == '1' then 3656 LoadWritePC(MemA[address,4]); 3657 3658 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3659 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3660 #endif 3661 3662 bool success = false; 3663 3664 if (ConditionPassed(opcode)) 3665 { 3666 uint32_t n; 3667 uint32_t registers = 0; 3668 bool wback; 3669 const uint32_t addr_byte_size = GetAddressByteSize(); 3670 switch (encoding) 3671 { 3672 case eEncodingT1: 3673 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3674 n = Bits32 (opcode, 19, 16); 3675 registers = Bits32 (opcode, 15, 0); 3676 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3677 wback = BitIsSet (opcode, 21); 3678 3679 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3680 if ((n == 15) 3681 || (BitCount (registers) < 2) 3682 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3683 return false; 3684 3685 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3686 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3687 return false; 3688 3689 // if wback && registers<n> == '1' then UNPREDICTABLE; 3690 if (wback && BitIsSet (registers, n)) 3691 return false; 3692 3693 break; 3694 3695 case eEncodingA1: 3696 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3697 n = Bits32 (opcode, 19, 16); 3698 registers = Bits32 (opcode, 15, 0); 3699 wback = BitIsSet (opcode, 21); 3700 3701 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3702 if ((n == 15) || (BitCount (registers) < 1)) 3703 return false; 3704 3705 break; 3706 3707 default: 3708 return false; 3709 } 3710 3711 // address = R[n] - 4*BitCount(registers); 3712 3713 int32_t offset = 0; 3714 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3715 3716 if (!success) 3717 return false; 3718 3719 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3720 EmulateInstruction::Context context; 3721 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3722 RegisterInfo dwarf_reg; 3723 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3724 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3725 3726 for (int i = 0; i < 14; ++i) 3727 { 3728 if (BitIsSet (registers, i)) 3729 { 3730 // R[i] = MemA[address,4]; address = address + 4; 3731 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3732 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3733 if (!success) 3734 return false; 3735 3736 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3737 return false; 3738 3739 offset += addr_byte_size; 3740 } 3741 } 3742 3743 // if registers<15> == '1' then 3744 // LoadWritePC(MemA[address,4]); 3745 if (BitIsSet (registers, 15)) 3746 { 3747 context.SetRegisterPlusOffset (dwarf_reg, offset); 3748 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3749 if (!success) 3750 return false; 3751 // In ARMv5T and above, this is an interworking branch. 3752 if (!LoadWritePC(context, data)) 3753 return false; 3754 } 3755 3756 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3757 if (wback && BitIsClear (registers, n)) 3758 { 3759 if (!success) 3760 return false; 3761 3762 offset = (addr_byte_size * BitCount (registers)) * -1; 3763 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3764 context.SetImmediateSigned (offset); 3765 addr_t addr = Rn + offset; 3766 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3767 return false; 3768 } 3769 3770 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3771 if (wback && BitIsSet (registers, n)) 3772 return WriteBits32Unknown (n); 3773 } 3774 return true; 3775 } 3776 3777 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3778 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3779 // optinoally be written back to the base register. 3780 bool 3781 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3782 { 3783 #if 0 3784 if ConditionPassed() then 3785 EncodingSpecificOperations(); 3786 address = R[n] + 4; 3787 3788 for i = 0 to 14 3789 if registers<i> == '1' then 3790 R[i] = MemA[address,4]; address = address + 4; 3791 if registers<15> == '1' then 3792 LoadWritePC(MemA[address,4]); 3793 3794 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3795 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3796 #endif 3797 3798 bool success = false; 3799 3800 if (ConditionPassed(opcode)) 3801 { 3802 uint32_t n; 3803 uint32_t registers = 0; 3804 bool wback; 3805 const uint32_t addr_byte_size = GetAddressByteSize(); 3806 switch (encoding) 3807 { 3808 case eEncodingA1: 3809 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3810 n = Bits32 (opcode, 19, 16); 3811 registers = Bits32 (opcode, 15, 0); 3812 wback = BitIsSet (opcode, 21); 3813 3814 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3815 if ((n == 15) || (BitCount (registers) < 1)) 3816 return false; 3817 3818 break; 3819 default: 3820 return false; 3821 } 3822 // address = R[n] + 4; 3823 3824 int32_t offset = 0; 3825 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3826 3827 if (!success) 3828 return false; 3829 3830 addr_t address = Rn + addr_byte_size; 3831 3832 EmulateInstruction::Context context; 3833 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3834 RegisterInfo dwarf_reg; 3835 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3836 context.SetRegisterPlusOffset (dwarf_reg, offset); 3837 3838 for (int i = 0; i < 14; ++i) 3839 { 3840 if (BitIsSet (registers, i)) 3841 { 3842 // R[i] = MemA[address,4]; address = address + 4; 3843 3844 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3845 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3846 if (!success) 3847 return false; 3848 3849 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3850 return false; 3851 3852 offset += addr_byte_size; 3853 } 3854 } 3855 3856 // if registers<15> == '1' then 3857 // LoadWritePC(MemA[address,4]); 3858 if (BitIsSet (registers, 15)) 3859 { 3860 context.SetRegisterPlusOffset (dwarf_reg, offset); 3861 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3862 if (!success) 3863 return false; 3864 // In ARMv5T and above, this is an interworking branch. 3865 if (!LoadWritePC(context, data)) 3866 return false; 3867 } 3868 3869 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3870 if (wback && BitIsClear (registers, n)) 3871 { 3872 if (!success) 3873 return false; 3874 3875 offset = addr_byte_size * BitCount (registers); 3876 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3877 context.SetImmediateSigned (offset); 3878 addr_t addr = Rn + offset; 3879 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3880 return false; 3881 } 3882 3883 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3884 if (wback && BitIsSet (registers, n)) 3885 return WriteBits32Unknown (n); 3886 } 3887 return true; 3888 } 3889 3890 // Load Register (immediate) calculates an address from a base register value and 3891 // an immediate offset, loads a word from memory, and writes to a register. 3892 // LDR (immediate, Thumb) 3893 bool 3894 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3895 { 3896 #if 0 3897 // ARM pseudo code... 3898 if (ConditionPassed()) 3899 { 3900 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3901 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3902 address = if index then offset_addr else R[n]; 3903 data = MemU[address,4]; 3904 if wback then R[n] = offset_addr; 3905 if t == 15 then 3906 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3907 elsif UnalignedSupport() || address<1:0> = '00' then 3908 R[t] = data; 3909 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3910 } 3911 #endif 3912 3913 bool success = false; 3914 3915 if (ConditionPassed(opcode)) 3916 { 3917 uint32_t Rt; // the destination register 3918 uint32_t Rn; // the base register 3919 uint32_t imm32; // the immediate offset used to form the address 3920 addr_t offset_addr; // the offset address 3921 addr_t address; // the calculated address 3922 uint32_t data; // the literal data value from memory load 3923 bool add, index, wback; 3924 switch (encoding) { 3925 case eEncodingT1: 3926 Rt = Bits32(opcode, 2, 0); 3927 Rn = Bits32(opcode, 5, 3); 3928 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3929 // index = TRUE; add = TRUE; wback = FALSE 3930 add = true; 3931 index = true; 3932 wback = false; 3933 3934 break; 3935 3936 case eEncodingT2: 3937 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3938 Rt = Bits32 (opcode, 10, 8); 3939 Rn = 13; 3940 imm32 = Bits32 (opcode, 7, 0) << 2; 3941 3942 // index = TRUE; add = TRUE; wback = FALSE; 3943 index = true; 3944 add = true; 3945 wback = false; 3946 3947 break; 3948 3949 case eEncodingT3: 3950 // if Rn == '1111' then SEE LDR (literal); 3951 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3952 Rt = Bits32 (opcode, 15, 12); 3953 Rn = Bits32 (opcode, 19, 16); 3954 imm32 = Bits32 (opcode, 11, 0); 3955 3956 // index = TRUE; add = TRUE; wback = FALSE; 3957 index = true; 3958 add = true; 3959 wback = false; 3960 3961 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3962 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3963 return false; 3964 3965 break; 3966 3967 case eEncodingT4: 3968 // if Rn == '1111' then SEE LDR (literal); 3969 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3970 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3971 // if P == '0' && W == '0' then UNDEFINED; 3972 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3973 return false; 3974 3975 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3976 Rt = Bits32 (opcode, 15, 12); 3977 Rn = Bits32 (opcode, 19, 16); 3978 imm32 = Bits32 (opcode, 7, 0); 3979 3980 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3981 index = BitIsSet (opcode, 10); 3982 add = BitIsSet (opcode, 9); 3983 wback = BitIsSet (opcode, 8); 3984 3985 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3986 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3987 return false; 3988 3989 break; 3990 3991 default: 3992 return false; 3993 } 3994 uint32_t base = ReadCoreReg (Rn, &success); 3995 if (!success) 3996 return false; 3997 if (add) 3998 offset_addr = base + imm32; 3999 else 4000 offset_addr = base - imm32; 4001 4002 address = (index ? offset_addr : base); 4003 4004 RegisterInfo base_reg; 4005 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4006 if (wback) 4007 { 4008 EmulateInstruction::Context ctx; 4009 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4010 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4011 4012 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 4013 return false; 4014 } 4015 4016 // Prepare to write to the Rt register. 4017 EmulateInstruction::Context context; 4018 context.type = EmulateInstruction::eContextRegisterLoad; 4019 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4020 4021 // Read memory from the address. 4022 data = MemURead(context, address, 4, 0, &success); 4023 if (!success) 4024 return false; 4025 4026 if (Rt == 15) 4027 { 4028 if (Bits32(address, 1, 0) == 0) 4029 { 4030 if (!LoadWritePC(context, data)) 4031 return false; 4032 } 4033 else 4034 return false; 4035 } 4036 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 4037 { 4038 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 4039 return false; 4040 } 4041 else 4042 WriteBits32Unknown (Rt); 4043 } 4044 return true; 4045 } 4046 4047 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 4048 // from a base register. The consecutive memory locations start at this address, and the address just above the last 4049 // of those locations can optionally be written back to the base register. 4050 bool 4051 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 4052 { 4053 #if 0 4054 if ConditionPassed() then 4055 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4056 address = R[n]; 4057 4058 for i = 0 to 14 4059 if registers<i> == '1' then 4060 if i == n && wback && i != LowestSetBit(registers) then 4061 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4062 else 4063 MemA[address,4] = R[i]; 4064 address = address + 4; 4065 4066 if registers<15> == '1' then // Only possible for encoding A1 4067 MemA[address,4] = PCStoreValue(); 4068 if wback then R[n] = R[n] + 4*BitCount(registers); 4069 #endif 4070 4071 bool success = false; 4072 4073 if (ConditionPassed(opcode)) 4074 { 4075 uint32_t n; 4076 uint32_t registers = 0; 4077 bool wback; 4078 const uint32_t addr_byte_size = GetAddressByteSize(); 4079 4080 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4081 switch (encoding) 4082 { 4083 case eEncodingT1: 4084 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4085 n = Bits32 (opcode, 10, 8); 4086 registers = Bits32 (opcode, 7, 0); 4087 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4088 wback = true; 4089 4090 // if BitCount(registers) < 1 then UNPREDICTABLE; 4091 if (BitCount (registers) < 1) 4092 return false; 4093 4094 break; 4095 4096 case eEncodingT2: 4097 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4098 n = Bits32 (opcode, 19, 16); 4099 registers = Bits32 (opcode, 15, 0); 4100 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4101 wback = BitIsSet (opcode, 21); 4102 4103 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4104 if ((n == 15) || (BitCount (registers) < 2)) 4105 return false; 4106 4107 // if wback && registers<n> == '1' then UNPREDICTABLE; 4108 if (wback && BitIsSet (registers, n)) 4109 return false; 4110 4111 break; 4112 4113 case eEncodingA1: 4114 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4115 n = Bits32 (opcode, 19, 16); 4116 registers = Bits32 (opcode, 15, 0); 4117 wback = BitIsSet (opcode, 21); 4118 4119 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4120 if ((n == 15) || (BitCount (registers) < 1)) 4121 return false; 4122 4123 break; 4124 4125 default: 4126 return false; 4127 } 4128 4129 // address = R[n]; 4130 int32_t offset = 0; 4131 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4132 if (!success) 4133 return false; 4134 4135 EmulateInstruction::Context context; 4136 context.type = EmulateInstruction::eContextRegisterStore; 4137 RegisterInfo base_reg; 4138 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4139 4140 // for i = 0 to 14 4141 uint32_t lowest_set_bit = 14; 4142 for (uint32_t i = 0; i < 14; ++i) 4143 { 4144 // if registers<i> == '1' then 4145 if (BitIsSet (registers, i)) 4146 { 4147 if (i < lowest_set_bit) 4148 lowest_set_bit = i; 4149 // if i == n && wback && i != LowestSetBit(registers) then 4150 if ((i == n) && wback && (i != lowest_set_bit)) 4151 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4152 WriteBits32UnknownToMemory (address + offset); 4153 else 4154 { 4155 // MemA[address,4] = R[i]; 4156 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4157 if (!success) 4158 return false; 4159 4160 RegisterInfo data_reg; 4161 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4162 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4163 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4164 return false; 4165 } 4166 4167 // address = address + 4; 4168 offset += addr_byte_size; 4169 } 4170 } 4171 4172 // if registers<15> == '1' then // Only possible for encoding A1 4173 // MemA[address,4] = PCStoreValue(); 4174 if (BitIsSet (registers, 15)) 4175 { 4176 RegisterInfo pc_reg; 4177 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4178 context.SetRegisterPlusOffset (pc_reg, 8); 4179 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4180 if (!success) 4181 return false; 4182 4183 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4184 return false; 4185 } 4186 4187 // if wback then R[n] = R[n] + 4*BitCount(registers); 4188 if (wback) 4189 { 4190 offset = addr_byte_size * BitCount (registers); 4191 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4192 context.SetImmediateSigned (offset); 4193 addr_t data = address + offset; 4194 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4195 return false; 4196 } 4197 } 4198 return true; 4199 } 4200 4201 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4202 // from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4203 // of those locations can optionally be written back to the base register. 4204 bool 4205 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4206 { 4207 #if 0 4208 if ConditionPassed() then 4209 EncodingSpecificOperations(); 4210 address = R[n] - 4*BitCount(registers) + 4; 4211 4212 for i = 0 to 14 4213 if registers<i> == '1' then 4214 if i == n && wback && i != LowestSetBit(registers) then 4215 MemA[address,4] = bits(32) UNKNOWN; 4216 else 4217 MemA[address,4] = R[i]; 4218 address = address + 4; 4219 4220 if registers<15> == '1' then 4221 MemA[address,4] = PCStoreValue(); 4222 4223 if wback then R[n] = R[n] - 4*BitCount(registers); 4224 #endif 4225 4226 bool success = false; 4227 4228 if (ConditionPassed(opcode)) 4229 { 4230 uint32_t n; 4231 uint32_t registers = 0; 4232 bool wback; 4233 const uint32_t addr_byte_size = GetAddressByteSize(); 4234 4235 // EncodingSpecificOperations(); 4236 switch (encoding) 4237 { 4238 case eEncodingA1: 4239 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4240 n = Bits32 (opcode, 19, 16); 4241 registers = Bits32 (opcode, 15, 0); 4242 wback = BitIsSet (opcode, 21); 4243 4244 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4245 if ((n == 15) || (BitCount (registers) < 1)) 4246 return false; 4247 break; 4248 default: 4249 return false; 4250 } 4251 4252 // address = R[n] - 4*BitCount(registers) + 4; 4253 int32_t offset = 0; 4254 addr_t Rn = ReadCoreReg (n, &success); 4255 if (!success) 4256 return false; 4257 4258 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4259 4260 EmulateInstruction::Context context; 4261 context.type = EmulateInstruction::eContextRegisterStore; 4262 RegisterInfo base_reg; 4263 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4264 4265 // for i = 0 to 14 4266 uint32_t lowest_bit_set = 14; 4267 for (uint32_t i = 0; i < 14; ++i) 4268 { 4269 // if registers<i> == '1' then 4270 if (BitIsSet (registers, i)) 4271 { 4272 if (i < lowest_bit_set) 4273 lowest_bit_set = i; 4274 //if i == n && wback && i != LowestSetBit(registers) then 4275 if ((i == n) && wback && (i != lowest_bit_set)) 4276 // MemA[address,4] = bits(32) UNKNOWN; 4277 WriteBits32UnknownToMemory (address + offset); 4278 else 4279 { 4280 // MemA[address,4] = R[i]; 4281 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4282 if (!success) 4283 return false; 4284 4285 RegisterInfo data_reg; 4286 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4287 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4288 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4289 return false; 4290 } 4291 4292 // address = address + 4; 4293 offset += addr_byte_size; 4294 } 4295 } 4296 4297 // if registers<15> == '1' then 4298 // MemA[address,4] = PCStoreValue(); 4299 if (BitIsSet (registers, 15)) 4300 { 4301 RegisterInfo pc_reg; 4302 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4303 context.SetRegisterPlusOffset (pc_reg, 8); 4304 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4305 if (!success) 4306 return false; 4307 4308 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4309 return false; 4310 } 4311 4312 // if wback then R[n] = R[n] - 4*BitCount(registers); 4313 if (wback) 4314 { 4315 offset = (addr_byte_size * BitCount (registers)) * -1; 4316 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4317 context.SetImmediateSigned (offset); 4318 addr_t data = Rn + offset; 4319 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4320 return false; 4321 } 4322 } 4323 return true; 4324 } 4325 4326 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4327 // from a base register. The consecutive memory locations end just below this address, and the address of the first of 4328 // those locations can optionally be written back to the base register. 4329 bool 4330 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4331 { 4332 #if 0 4333 if ConditionPassed() then 4334 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4335 address = R[n] - 4*BitCount(registers); 4336 4337 for i = 0 to 14 4338 if registers<i> == '1' then 4339 if i == n && wback && i != LowestSetBit(registers) then 4340 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4341 else 4342 MemA[address,4] = R[i]; 4343 address = address + 4; 4344 4345 if registers<15> == '1' then // Only possible for encoding A1 4346 MemA[address,4] = PCStoreValue(); 4347 4348 if wback then R[n] = R[n] - 4*BitCount(registers); 4349 #endif 4350 4351 4352 bool success = false; 4353 4354 if (ConditionPassed(opcode)) 4355 { 4356 uint32_t n; 4357 uint32_t registers = 0; 4358 bool wback; 4359 const uint32_t addr_byte_size = GetAddressByteSize(); 4360 4361 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4362 switch (encoding) 4363 { 4364 case eEncodingT1: 4365 // if W == '1' && Rn == '1101' then SEE PUSH; 4366 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4367 { 4368 // See PUSH 4369 } 4370 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4371 n = Bits32 (opcode, 19, 16); 4372 registers = Bits32 (opcode, 15, 0); 4373 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4374 wback = BitIsSet (opcode, 21); 4375 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4376 if ((n == 15) || BitCount (registers) < 2) 4377 return false; 4378 // if wback && registers<n> == '1' then UNPREDICTABLE; 4379 if (wback && BitIsSet (registers, n)) 4380 return false; 4381 break; 4382 4383 case eEncodingA1: 4384 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH; 4385 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4386 { 4387 // See Push 4388 } 4389 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4390 n = Bits32 (opcode, 19, 16); 4391 registers = Bits32 (opcode, 15, 0); 4392 wback = BitIsSet (opcode, 21); 4393 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4394 if ((n == 15) || BitCount (registers) < 1) 4395 return false; 4396 break; 4397 4398 default: 4399 return false; 4400 } 4401 4402 // address = R[n] - 4*BitCount(registers); 4403 4404 int32_t offset = 0; 4405 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4406 if (!success) 4407 return false; 4408 4409 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4410 4411 EmulateInstruction::Context context; 4412 context.type = EmulateInstruction::eContextRegisterStore; 4413 RegisterInfo base_reg; 4414 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4415 4416 // for i = 0 to 14 4417 uint32_t lowest_set_bit = 14; 4418 for (uint32_t i = 0; i < 14; ++i) 4419 { 4420 // if registers<i> == '1' then 4421 if (BitIsSet (registers, i)) 4422 { 4423 if (i < lowest_set_bit) 4424 lowest_set_bit = i; 4425 // if i == n && wback && i != LowestSetBit(registers) then 4426 if ((i == n) && wback && (i != lowest_set_bit)) 4427 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4428 WriteBits32UnknownToMemory (address + offset); 4429 else 4430 { 4431 // MemA[address,4] = R[i]; 4432 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4433 if (!success) 4434 return false; 4435 4436 RegisterInfo data_reg; 4437 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4438 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4439 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4440 return false; 4441 } 4442 4443 // address = address + 4; 4444 offset += addr_byte_size; 4445 } 4446 } 4447 4448 // if registers<15> == '1' then // Only possible for encoding A1 4449 // MemA[address,4] = PCStoreValue(); 4450 if (BitIsSet (registers, 15)) 4451 { 4452 RegisterInfo pc_reg; 4453 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4454 context.SetRegisterPlusOffset (pc_reg, 8); 4455 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4456 if (!success) 4457 return false; 4458 4459 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4460 return false; 4461 } 4462 4463 // if wback then R[n] = R[n] - 4*BitCount(registers); 4464 if (wback) 4465 { 4466 offset = (addr_byte_size * BitCount (registers)) * -1; 4467 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4468 context.SetImmediateSigned (offset); 4469 addr_t data = Rn + offset; 4470 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4471 return false; 4472 } 4473 } 4474 return true; 4475 } 4476 4477 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4478 // from a base register. The consecutive memory locations start just above this address, and the address of the last 4479 // of those locations can optionally be written back to the base register. 4480 bool 4481 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4482 { 4483 #if 0 4484 if ConditionPassed() then 4485 EncodingSpecificOperations(); 4486 address = R[n] + 4; 4487 4488 for i = 0 to 14 4489 if registers<i> == '1' then 4490 if i == n && wback && i != LowestSetBit(registers) then 4491 MemA[address,4] = bits(32) UNKNOWN; 4492 else 4493 MemA[address,4] = R[i]; 4494 address = address + 4; 4495 4496 if registers<15> == '1' then 4497 MemA[address,4] = PCStoreValue(); 4498 4499 if wback then R[n] = R[n] + 4*BitCount(registers); 4500 #endif 4501 4502 bool success = false; 4503 4504 if (ConditionPassed(opcode)) 4505 { 4506 uint32_t n; 4507 uint32_t registers = 0; 4508 bool wback; 4509 const uint32_t addr_byte_size = GetAddressByteSize(); 4510 4511 // EncodingSpecificOperations(); 4512 switch (encoding) 4513 { 4514 case eEncodingA1: 4515 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4516 n = Bits32 (opcode, 19, 16); 4517 registers = Bits32 (opcode, 15, 0); 4518 wback = BitIsSet (opcode, 21); 4519 4520 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4521 if ((n == 15) && (BitCount (registers) < 1)) 4522 return false; 4523 break; 4524 default: 4525 return false; 4526 } 4527 // address = R[n] + 4; 4528 4529 int32_t offset = 0; 4530 addr_t Rn = ReadCoreReg (n, &success); 4531 if (!success) 4532 return false; 4533 4534 addr_t address = Rn + addr_byte_size; 4535 4536 EmulateInstruction::Context context; 4537 context.type = EmulateInstruction::eContextRegisterStore; 4538 RegisterInfo base_reg; 4539 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4540 4541 uint32_t lowest_set_bit = 14; 4542 // for i = 0 to 14 4543 for (uint32_t i = 0; i < 14; ++i) 4544 { 4545 // if registers<i> == '1' then 4546 if (BitIsSet (registers, i)) 4547 { 4548 if (i < lowest_set_bit) 4549 lowest_set_bit = i; 4550 // if i == n && wback && i != LowestSetBit(registers) then 4551 if ((i == n) && wback && (i != lowest_set_bit)) 4552 // MemA[address,4] = bits(32) UNKNOWN; 4553 WriteBits32UnknownToMemory (address + offset); 4554 // else 4555 else 4556 { 4557 // MemA[address,4] = R[i]; 4558 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4559 if (!success) 4560 return false; 4561 4562 RegisterInfo data_reg; 4563 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4564 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4565 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4566 return false; 4567 } 4568 4569 // address = address + 4; 4570 offset += addr_byte_size; 4571 } 4572 } 4573 4574 // if registers<15> == '1' then 4575 // MemA[address,4] = PCStoreValue(); 4576 if (BitIsSet (registers, 15)) 4577 { 4578 RegisterInfo pc_reg; 4579 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4580 context.SetRegisterPlusOffset (pc_reg, 8); 4581 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4582 if (!success) 4583 return false; 4584 4585 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4586 return false; 4587 } 4588 4589 // if wback then R[n] = R[n] + 4*BitCount(registers); 4590 if (wback) 4591 { 4592 offset = addr_byte_size * BitCount (registers); 4593 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4594 context.SetImmediateSigned (offset); 4595 addr_t data = Rn + offset; 4596 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4597 return false; 4598 } 4599 } 4600 return true; 4601 } 4602 4603 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word 4604 // from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4605 bool 4606 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4607 { 4608 #if 0 4609 if ConditionPassed() then 4610 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4611 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4612 address = if index then offset_addr else R[n]; 4613 if UnalignedSupport() || address<1:0> == '00' then 4614 MemU[address,4] = R[t]; 4615 else // Can only occur before ARMv7 4616 MemU[address,4] = bits(32) UNKNOWN; 4617 if wback then R[n] = offset_addr; 4618 #endif 4619 4620 bool success = false; 4621 4622 if (ConditionPassed(opcode)) 4623 { 4624 const uint32_t addr_byte_size = GetAddressByteSize(); 4625 4626 uint32_t t; 4627 uint32_t n; 4628 uint32_t imm32; 4629 bool index; 4630 bool add; 4631 bool wback; 4632 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4633 switch (encoding) 4634 { 4635 case eEncodingT1: 4636 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4637 t = Bits32 (opcode, 2, 0); 4638 n = Bits32 (opcode, 5, 3); 4639 imm32 = Bits32 (opcode, 10, 6) << 2; 4640 4641 // index = TRUE; add = TRUE; wback = FALSE; 4642 index = true; 4643 add = false; 4644 wback = false; 4645 break; 4646 4647 case eEncodingT2: 4648 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4649 t = Bits32 (opcode, 10, 8); 4650 n = 13; 4651 imm32 = Bits32 (opcode, 7, 0) << 2; 4652 4653 // index = TRUE; add = TRUE; wback = FALSE; 4654 index = true; 4655 add = true; 4656 wback = false; 4657 break; 4658 4659 case eEncodingT3: 4660 // if Rn == '1111' then UNDEFINED; 4661 if (Bits32 (opcode, 19, 16) == 15) 4662 return false; 4663 4664 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4665 t = Bits32 (opcode, 15, 12); 4666 n = Bits32 (opcode, 19, 16); 4667 imm32 = Bits32 (opcode, 11, 0); 4668 4669 // index = TRUE; add = TRUE; wback = FALSE; 4670 index = true; 4671 add = true; 4672 wback = false; 4673 4674 // if t == 15 then UNPREDICTABLE; 4675 if (t == 15) 4676 return false; 4677 break; 4678 4679 case eEncodingT4: 4680 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4681 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4682 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4683 if ((Bits32 (opcode, 19, 16) == 15) 4684 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4685 return false; 4686 4687 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4688 t = Bits32 (opcode, 15, 12); 4689 n = Bits32 (opcode, 19, 16); 4690 imm32 = Bits32 (opcode, 7, 0); 4691 4692 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4693 index = BitIsSet (opcode, 10); 4694 add = BitIsSet (opcode, 9); 4695 wback = BitIsSet (opcode, 8); 4696 4697 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4698 if ((t == 15) || (wback && (n == t))) 4699 return false; 4700 break; 4701 4702 default: 4703 return false; 4704 } 4705 4706 addr_t offset_addr; 4707 addr_t address; 4708 4709 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4710 uint32_t base_address = ReadCoreReg (n, &success); 4711 if (!success) 4712 return false; 4713 4714 if (add) 4715 offset_addr = base_address + imm32; 4716 else 4717 offset_addr = base_address - imm32; 4718 4719 // address = if index then offset_addr else R[n]; 4720 if (index) 4721 address = offset_addr; 4722 else 4723 address = base_address; 4724 4725 EmulateInstruction::Context context; 4726 context.type = eContextRegisterStore; 4727 RegisterInfo base_reg; 4728 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4729 4730 // if UnalignedSupport() || address<1:0> == '00' then 4731 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4732 { 4733 // MemU[address,4] = R[t]; 4734 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4735 if (!success) 4736 return false; 4737 4738 RegisterInfo data_reg; 4739 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4740 int32_t offset = address - base_address; 4741 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4742 if (!MemUWrite (context, address, data, addr_byte_size)) 4743 return false; 4744 } 4745 else 4746 { 4747 // MemU[address,4] = bits(32) UNKNOWN; 4748 WriteBits32UnknownToMemory (address); 4749 } 4750 4751 // if wback then R[n] = offset_addr; 4752 if (wback) 4753 { 4754 context.type = eContextRegisterLoad; 4755 context.SetAddress (offset_addr); 4756 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4757 return false; 4758 } 4759 } 4760 return true; 4761 } 4762 4763 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4764 // word from a register to memory. The offset register value can optionally be shifted. 4765 bool 4766 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4767 { 4768 #if 0 4769 if ConditionPassed() then 4770 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4771 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4772 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4773 address = if index then offset_addr else R[n]; 4774 if t == 15 then // Only possible for encoding A1 4775 data = PCStoreValue(); 4776 else 4777 data = R[t]; 4778 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4779 MemU[address,4] = data; 4780 else // Can only occur before ARMv7 4781 MemU[address,4] = bits(32) UNKNOWN; 4782 if wback then R[n] = offset_addr; 4783 #endif 4784 4785 bool success = false; 4786 4787 if (ConditionPassed(opcode)) 4788 { 4789 const uint32_t addr_byte_size = GetAddressByteSize(); 4790 4791 uint32_t t; 4792 uint32_t n; 4793 uint32_t m; 4794 ARM_ShifterType shift_t; 4795 uint32_t shift_n; 4796 bool index; 4797 bool add; 4798 bool wback; 4799 4800 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4801 switch (encoding) 4802 { 4803 case eEncodingT1: 4804 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4805 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4806 t = Bits32 (opcode, 2, 0); 4807 n = Bits32 (opcode, 5, 3); 4808 m = Bits32 (opcode, 8, 6); 4809 4810 // index = TRUE; add = TRUE; wback = FALSE; 4811 index = true; 4812 add = true; 4813 wback = false; 4814 4815 // (shift_t, shift_n) = (SRType_LSL, 0); 4816 shift_t = SRType_LSL; 4817 shift_n = 0; 4818 break; 4819 4820 case eEncodingT2: 4821 // if Rn == '1111' then UNDEFINED; 4822 if (Bits32 (opcode, 19, 16) == 15) 4823 return false; 4824 4825 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4826 t = Bits32 (opcode, 15, 12); 4827 n = Bits32 (opcode, 19, 16); 4828 m = Bits32 (opcode, 3, 0); 4829 4830 // index = TRUE; add = TRUE; wback = FALSE; 4831 index = true; 4832 add = true; 4833 wback = false; 4834 4835 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4836 shift_t = SRType_LSL; 4837 shift_n = Bits32 (opcode, 5, 4); 4838 4839 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4840 if ((t == 15) || (BadReg (m))) 4841 return false; 4842 break; 4843 4844 case eEncodingA1: 4845 { 4846 // if P == '0' && W == '1' then SEE STRT; 4847 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4848 t = Bits32 (opcode, 15, 12); 4849 n = Bits32 (opcode, 19, 16); 4850 m = Bits32 (opcode, 3, 0); 4851 4852 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4853 index = BitIsSet (opcode, 24); 4854 add = BitIsSet (opcode, 23); 4855 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4856 4857 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4858 uint32_t typ = Bits32 (opcode, 6, 5); 4859 uint32_t imm5 = Bits32 (opcode, 11, 7); 4860 shift_n = DecodeImmShift(typ, imm5, shift_t); 4861 4862 // if m == 15 then UNPREDICTABLE; 4863 if (m == 15) 4864 return false; 4865 4866 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4867 if (wback && ((n == 15) || (n == t))) 4868 return false; 4869 4870 break; 4871 } 4872 default: 4873 return false; 4874 } 4875 4876 addr_t offset_addr; 4877 addr_t address; 4878 int32_t offset = 0; 4879 4880 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4881 if (!success) 4882 return false; 4883 4884 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4885 if (!success) 4886 return false; 4887 4888 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4889 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4890 if (!success) 4891 return false; 4892 4893 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4894 if (add) 4895 offset_addr = base_address + offset; 4896 else 4897 offset_addr = base_address - offset; 4898 4899 // address = if index then offset_addr else R[n]; 4900 if (index) 4901 address = offset_addr; 4902 else 4903 address = base_address; 4904 4905 uint32_t data; 4906 // if t == 15 then // Only possible for encoding A1 4907 if (t == 15) 4908 // data = PCStoreValue(); 4909 data = ReadCoreReg (PC_REG, &success); 4910 else 4911 // data = R[t]; 4912 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4913 4914 if (!success) 4915 return false; 4916 4917 EmulateInstruction::Context context; 4918 context.type = eContextRegisterStore; 4919 4920 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4921 if (UnalignedSupport () 4922 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4923 || CurrentInstrSet() == eModeARM) 4924 { 4925 // MemU[address,4] = data; 4926 4927 RegisterInfo base_reg; 4928 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4929 4930 RegisterInfo data_reg; 4931 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4932 4933 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4934 if (!MemUWrite (context, address, data, addr_byte_size)) 4935 return false; 4936 4937 } 4938 else 4939 // MemU[address,4] = bits(32) UNKNOWN; 4940 WriteBits32UnknownToMemory (address); 4941 4942 // if wback then R[n] = offset_addr; 4943 if (wback) 4944 { 4945 context.type = eContextRegisterLoad; 4946 context.SetAddress (offset_addr); 4947 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4948 return false; 4949 } 4950 4951 } 4952 return true; 4953 } 4954 4955 bool 4956 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 4957 { 4958 #if 0 4959 if ConditionPassed() then 4960 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4961 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4962 address = if index then offset_addr else R[n]; 4963 MemU[address,1] = R[t]<7:0>; 4964 if wback then R[n] = offset_addr; 4965 #endif 4966 4967 4968 bool success = false; 4969 4970 if (ConditionPassed(opcode)) 4971 { 4972 uint32_t t; 4973 uint32_t n; 4974 uint32_t imm32; 4975 bool index; 4976 bool add; 4977 bool wback; 4978 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4979 switch (encoding) 4980 { 4981 case eEncodingT1: 4982 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4983 t = Bits32 (opcode, 2, 0); 4984 n = Bits32 (opcode, 5, 3); 4985 imm32 = Bits32 (opcode, 10, 6); 4986 4987 // index = TRUE; add = TRUE; wback = FALSE; 4988 index = true; 4989 add = true; 4990 wback = false; 4991 break; 4992 4993 case eEncodingT2: 4994 // if Rn == '1111' then UNDEFINED; 4995 if (Bits32 (opcode, 19, 16) == 15) 4996 return false; 4997 4998 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4999 t = Bits32 (opcode, 15, 12); 5000 n = Bits32 (opcode, 19, 16); 5001 imm32 = Bits32 (opcode, 11, 0); 5002 5003 // index = TRUE; add = TRUE; wback = FALSE; 5004 index = true; 5005 add = true; 5006 wback = false; 5007 5008 // if BadReg(t) then UNPREDICTABLE; 5009 if (BadReg (t)) 5010 return false; 5011 break; 5012 5013 case eEncodingT3: 5014 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5015 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5016 if (Bits32 (opcode, 19, 16) == 15) 5017 return false; 5018 5019 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5020 t = Bits32 (opcode, 15, 12); 5021 n = Bits32 (opcode, 19, 16); 5022 imm32 = Bits32 (opcode, 7, 0); 5023 5024 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5025 index = BitIsSet (opcode, 10); 5026 add = BitIsSet (opcode, 9); 5027 wback = BitIsSet (opcode, 8); 5028 5029 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5030 if ((BadReg (t)) || (wback && (n == t))) 5031 return false; 5032 break; 5033 5034 default: 5035 return false; 5036 } 5037 5038 addr_t offset_addr; 5039 addr_t address; 5040 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5041 if (!success) 5042 return false; 5043 5044 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5045 if (add) 5046 offset_addr = base_address + imm32; 5047 else 5048 offset_addr = base_address - imm32; 5049 5050 // address = if index then offset_addr else R[n]; 5051 if (index) 5052 address = offset_addr; 5053 else 5054 address = base_address; 5055 5056 // MemU[address,1] = R[t]<7:0> 5057 RegisterInfo base_reg; 5058 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5059 5060 RegisterInfo data_reg; 5061 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5062 5063 EmulateInstruction::Context context; 5064 context.type = eContextRegisterStore; 5065 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5066 5067 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5068 if (!success) 5069 return false; 5070 5071 data = Bits32 (data, 7, 0); 5072 5073 if (!MemUWrite (context, address, data, 1)) 5074 return false; 5075 5076 // if wback then R[n] = offset_addr; 5077 if (wback) 5078 { 5079 context.type = eContextRegisterLoad; 5080 context.SetAddress (offset_addr); 5081 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5082 return false; 5083 } 5084 5085 } 5086 5087 return true; 5088 } 5089 5090 // STRH (register) calculates an address from a base register value and an offset register value, and stores a 5091 // halfword from a register to memory. The offset register value can be shifted left by 0, 1, 2, or 3 bits. 5092 bool 5093 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5094 { 5095 #if 0 5096 if ConditionPassed() then 5097 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5098 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5099 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5100 address = if index then offset_addr else R[n]; 5101 if UnalignedSupport() || address<0> == '0' then 5102 MemU[address,2] = R[t]<15:0>; 5103 else // Can only occur before ARMv7 5104 MemU[address,2] = bits(16) UNKNOWN; 5105 if wback then R[n] = offset_addr; 5106 #endif 5107 5108 bool success = false; 5109 5110 if (ConditionPassed(opcode)) 5111 { 5112 uint32_t t; 5113 uint32_t n; 5114 uint32_t m; 5115 bool index; 5116 bool add; 5117 bool wback; 5118 ARM_ShifterType shift_t; 5119 uint32_t shift_n; 5120 5121 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5122 switch (encoding) 5123 { 5124 case eEncodingT1: 5125 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5126 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5127 t = Bits32 (opcode, 2, 0); 5128 n = Bits32 (opcode, 5, 3); 5129 m = Bits32 (opcode, 8, 6); 5130 5131 // index = TRUE; add = TRUE; wback = FALSE; 5132 index = true; 5133 add = true; 5134 wback = false; 5135 5136 // (shift_t, shift_n) = (SRType_LSL, 0); 5137 shift_t = SRType_LSL; 5138 shift_n = 0; 5139 5140 break; 5141 5142 case eEncodingT2: 5143 // if Rn == '1111' then UNDEFINED; 5144 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5145 t = Bits32 (opcode, 15, 12); 5146 n = Bits32 (opcode, 19, 16); 5147 m = Bits32 (opcode, 3, 0); 5148 if (n == 15) 5149 return false; 5150 5151 // index = TRUE; add = TRUE; wback = FALSE; 5152 index = true; 5153 add = true; 5154 wback = false; 5155 5156 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5157 shift_t = SRType_LSL; 5158 shift_n = Bits32 (opcode, 5, 4); 5159 5160 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5161 if (BadReg (t) || BadReg (m)) 5162 return false; 5163 5164 break; 5165 5166 case eEncodingA1: 5167 // if P == '0' && W == '1' then SEE STRHT; 5168 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5169 t = Bits32 (opcode, 15, 12); 5170 n = Bits32 (opcode, 19, 16); 5171 m = Bits32 (opcode, 3, 0); 5172 5173 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5174 index = BitIsSet (opcode, 24); 5175 add = BitIsSet (opcode, 23); 5176 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5177 5178 // (shift_t, shift_n) = (SRType_LSL, 0); 5179 shift_t = SRType_LSL; 5180 shift_n = 0; 5181 5182 // if t == 15 || m == 15 then UNPREDICTABLE; 5183 if ((t == 15) || (m == 15)) 5184 return false; 5185 5186 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5187 if (wback && ((n == 15) || (n == t))) 5188 return false; 5189 5190 break; 5191 5192 default: 5193 return false; 5194 } 5195 5196 uint32_t Rm = ReadCoreReg (m, &success); 5197 if (!success) 5198 return false; 5199 5200 uint32_t Rn = ReadCoreReg (n, &success); 5201 if (!success) 5202 return false; 5203 5204 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5205 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5206 if (!success) 5207 return false; 5208 5209 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5210 addr_t offset_addr; 5211 if (add) 5212 offset_addr = Rn + offset; 5213 else 5214 offset_addr = Rn - offset; 5215 5216 // address = if index then offset_addr else R[n]; 5217 addr_t address; 5218 if (index) 5219 address = offset_addr; 5220 else 5221 address = Rn; 5222 5223 EmulateInstruction::Context context; 5224 context.type = eContextRegisterStore; 5225 RegisterInfo base_reg; 5226 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5227 RegisterInfo offset_reg; 5228 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5229 5230 // if UnalignedSupport() || address<0> == '0' then 5231 if (UnalignedSupport() || BitIsClear (address, 0)) 5232 { 5233 // MemU[address,2] = R[t]<15:0>; 5234 uint32_t Rt = ReadCoreReg (t, &success); 5235 if (!success) 5236 return false; 5237 5238 EmulateInstruction::Context context; 5239 context.type = eContextRegisterStore; 5240 RegisterInfo base_reg; 5241 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5242 RegisterInfo offset_reg; 5243 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5244 RegisterInfo data_reg; 5245 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5246 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5247 5248 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5249 return false; 5250 } 5251 else // Can only occur before ARMv7 5252 { 5253 // MemU[address,2] = bits(16) UNKNOWN; 5254 } 5255 5256 // if wback then R[n] = offset_addr; 5257 if (wback) 5258 { 5259 context.type = eContextAdjustBaseRegister; 5260 context.SetAddress (offset_addr); 5261 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5262 return false; 5263 } 5264 } 5265 5266 return true; 5267 } 5268 5269 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5270 // and writes the result to the destination register. It can optionally update the condition flags 5271 // based on the result. 5272 bool 5273 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5274 { 5275 #if 0 5276 // ARM pseudo code... 5277 if ConditionPassed() then 5278 EncodingSpecificOperations(); 5279 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5280 if d == 15 then // Can only occur for ARM encoding 5281 ALUWritePC(result); // setflags is always FALSE here 5282 else 5283 R[d] = result; 5284 if setflags then 5285 APSR.N = result<31>; 5286 APSR.Z = IsZeroBit(result); 5287 APSR.C = carry; 5288 APSR.V = overflow; 5289 #endif 5290 5291 bool success = false; 5292 5293 if (ConditionPassed(opcode)) 5294 { 5295 uint32_t Rd, Rn; 5296 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5297 bool setflags; 5298 switch (encoding) 5299 { 5300 case eEncodingT1: 5301 Rd = Bits32(opcode, 11, 8); 5302 Rn = Bits32(opcode, 19, 16); 5303 setflags = BitIsSet(opcode, 20); 5304 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5305 if (BadReg(Rd) || BadReg(Rn)) 5306 return false; 5307 break; 5308 case eEncodingA1: 5309 Rd = Bits32(opcode, 15, 12); 5310 Rn = Bits32(opcode, 19, 16); 5311 setflags = BitIsSet(opcode, 20); 5312 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5313 5314 if (Rd == 15 && setflags) 5315 return EmulateSUBSPcLrEtc (opcode, encoding); 5316 break; 5317 default: 5318 return false; 5319 } 5320 5321 // Read the first operand. 5322 int32_t val1 = ReadCoreReg(Rn, &success); 5323 if (!success) 5324 return false; 5325 5326 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5327 5328 EmulateInstruction::Context context; 5329 context.type = EmulateInstruction::eContextImmediate; 5330 context.SetNoArgs (); 5331 5332 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5333 return false; 5334 } 5335 return true; 5336 } 5337 5338 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5339 // register value, and writes the result to the destination register. It can optionally update the 5340 // condition flags based on the result. 5341 bool 5342 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5343 { 5344 #if 0 5345 // ARM pseudo code... 5346 if ConditionPassed() then 5347 EncodingSpecificOperations(); 5348 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5349 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5350 if d == 15 then // Can only occur for ARM encoding 5351 ALUWritePC(result); // setflags is always FALSE here 5352 else 5353 R[d] = result; 5354 if setflags then 5355 APSR.N = result<31>; 5356 APSR.Z = IsZeroBit(result); 5357 APSR.C = carry; 5358 APSR.V = overflow; 5359 #endif 5360 5361 bool success = false; 5362 5363 if (ConditionPassed(opcode)) 5364 { 5365 uint32_t Rd, Rn, Rm; 5366 ARM_ShifterType shift_t; 5367 uint32_t shift_n; // the shift applied to the value read from Rm 5368 bool setflags; 5369 switch (encoding) 5370 { 5371 case eEncodingT1: 5372 Rd = Rn = Bits32(opcode, 2, 0); 5373 Rm = Bits32(opcode, 5, 3); 5374 setflags = !InITBlock(); 5375 shift_t = SRType_LSL; 5376 shift_n = 0; 5377 break; 5378 case eEncodingT2: 5379 Rd = Bits32(opcode, 11, 8); 5380 Rn = Bits32(opcode, 19, 16); 5381 Rm = Bits32(opcode, 3, 0); 5382 setflags = BitIsSet(opcode, 20); 5383 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5384 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5385 return false; 5386 break; 5387 case eEncodingA1: 5388 Rd = Bits32(opcode, 15, 12); 5389 Rn = Bits32(opcode, 19, 16); 5390 Rm = Bits32(opcode, 3, 0); 5391 setflags = BitIsSet(opcode, 20); 5392 shift_n = DecodeImmShiftARM(opcode, shift_t); 5393 5394 if (Rd == 15 && setflags) 5395 return EmulateSUBSPcLrEtc (opcode, encoding); 5396 break; 5397 default: 5398 return false; 5399 } 5400 5401 // Read the first operand. 5402 int32_t val1 = ReadCoreReg(Rn, &success); 5403 if (!success) 5404 return false; 5405 5406 // Read the second operand. 5407 int32_t val2 = ReadCoreReg(Rm, &success); 5408 if (!success) 5409 return false; 5410 5411 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5412 if (!success) 5413 return false; 5414 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5415 5416 EmulateInstruction::Context context; 5417 context.type = EmulateInstruction::eContextImmediate; 5418 context.SetNoArgs (); 5419 5420 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5421 return false; 5422 } 5423 return true; 5424 } 5425 5426 // This instruction adds an immediate value to the PC value to form a PC-relative address, 5427 // and writes the result to the destination register. 5428 bool 5429 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5430 { 5431 #if 0 5432 // ARM pseudo code... 5433 if ConditionPassed() then 5434 EncodingSpecificOperations(); 5435 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5436 if d == 15 then // Can only occur for ARM encodings 5437 ALUWritePC(result); 5438 else 5439 R[d] = result; 5440 #endif 5441 5442 bool success = false; 5443 5444 if (ConditionPassed(opcode)) 5445 { 5446 uint32_t Rd; 5447 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5448 bool add; 5449 switch (encoding) 5450 { 5451 case eEncodingT1: 5452 Rd = Bits32(opcode, 10, 8); 5453 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5454 add = true; 5455 break; 5456 case eEncodingT2: 5457 case eEncodingT3: 5458 Rd = Bits32(opcode, 11, 8); 5459 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5460 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5461 if (BadReg(Rd)) 5462 return false; 5463 break; 5464 case eEncodingA1: 5465 case eEncodingA2: 5466 Rd = Bits32(opcode, 15, 12); 5467 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5468 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5469 break; 5470 default: 5471 return false; 5472 } 5473 5474 // Read the PC value. 5475 uint32_t pc = ReadCoreReg(PC_REG, &success); 5476 if (!success) 5477 return false; 5478 5479 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5480 5481 EmulateInstruction::Context context; 5482 context.type = EmulateInstruction::eContextImmediate; 5483 context.SetNoArgs (); 5484 5485 if (!WriteCoreReg(context, result, Rd)) 5486 return false; 5487 } 5488 return true; 5489 } 5490 5491 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5492 // to the destination register. It can optionally update the condition flags based on the result. 5493 bool 5494 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5495 { 5496 #if 0 5497 // ARM pseudo code... 5498 if ConditionPassed() then 5499 EncodingSpecificOperations(); 5500 result = R[n] AND imm32; 5501 if d == 15 then // Can only occur for ARM encoding 5502 ALUWritePC(result); // setflags is always FALSE here 5503 else 5504 R[d] = result; 5505 if setflags then 5506 APSR.N = result<31>; 5507 APSR.Z = IsZeroBit(result); 5508 APSR.C = carry; 5509 // APSR.V unchanged 5510 #endif 5511 5512 bool success = false; 5513 5514 if (ConditionPassed(opcode)) 5515 { 5516 uint32_t Rd, Rn; 5517 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5518 bool setflags; 5519 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5520 switch (encoding) 5521 { 5522 case eEncodingT1: 5523 Rd = Bits32(opcode, 11, 8); 5524 Rn = Bits32(opcode, 19, 16); 5525 setflags = BitIsSet(opcode, 20); 5526 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5527 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5528 if (Rd == 15 && setflags) 5529 return EmulateTSTImm(opcode, eEncodingT1); 5530 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5531 return false; 5532 break; 5533 case eEncodingA1: 5534 Rd = Bits32(opcode, 15, 12); 5535 Rn = Bits32(opcode, 19, 16); 5536 setflags = BitIsSet(opcode, 20); 5537 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5538 5539 if (Rd == 15 && setflags) 5540 return EmulateSUBSPcLrEtc (opcode, encoding); 5541 break; 5542 default: 5543 return false; 5544 } 5545 5546 // Read the first operand. 5547 uint32_t val1 = ReadCoreReg(Rn, &success); 5548 if (!success) 5549 return false; 5550 5551 uint32_t result = val1 & imm32; 5552 5553 EmulateInstruction::Context context; 5554 context.type = EmulateInstruction::eContextImmediate; 5555 context.SetNoArgs (); 5556 5557 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5558 return false; 5559 } 5560 return true; 5561 } 5562 5563 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5564 // and writes the result to the destination register. It can optionally update the condition flags 5565 // based on the result. 5566 bool 5567 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5568 { 5569 #if 0 5570 // ARM pseudo code... 5571 if ConditionPassed() then 5572 EncodingSpecificOperations(); 5573 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5574 result = R[n] AND shifted; 5575 if d == 15 then // Can only occur for ARM encoding 5576 ALUWritePC(result); // setflags is always FALSE here 5577 else 5578 R[d] = result; 5579 if setflags then 5580 APSR.N = result<31>; 5581 APSR.Z = IsZeroBit(result); 5582 APSR.C = carry; 5583 // APSR.V unchanged 5584 #endif 5585 5586 bool success = false; 5587 5588 if (ConditionPassed(opcode)) 5589 { 5590 uint32_t Rd, Rn, Rm; 5591 ARM_ShifterType shift_t; 5592 uint32_t shift_n; // the shift applied to the value read from Rm 5593 bool setflags; 5594 uint32_t carry; 5595 switch (encoding) 5596 { 5597 case eEncodingT1: 5598 Rd = Rn = Bits32(opcode, 2, 0); 5599 Rm = Bits32(opcode, 5, 3); 5600 setflags = !InITBlock(); 5601 shift_t = SRType_LSL; 5602 shift_n = 0; 5603 break; 5604 case eEncodingT2: 5605 Rd = Bits32(opcode, 11, 8); 5606 Rn = Bits32(opcode, 19, 16); 5607 Rm = Bits32(opcode, 3, 0); 5608 setflags = BitIsSet(opcode, 20); 5609 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5610 // if Rd == '1111' && S == '1' then SEE TST (register); 5611 if (Rd == 15 && setflags) 5612 return EmulateTSTReg(opcode, eEncodingT2); 5613 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5614 return false; 5615 break; 5616 case eEncodingA1: 5617 Rd = Bits32(opcode, 15, 12); 5618 Rn = Bits32(opcode, 19, 16); 5619 Rm = Bits32(opcode, 3, 0); 5620 setflags = BitIsSet(opcode, 20); 5621 shift_n = DecodeImmShiftARM(opcode, shift_t); 5622 5623 if (Rd == 15 && setflags) 5624 return EmulateSUBSPcLrEtc (opcode, encoding); 5625 break; 5626 default: 5627 return false; 5628 } 5629 5630 // Read the first operand. 5631 uint32_t val1 = ReadCoreReg(Rn, &success); 5632 if (!success) 5633 return false; 5634 5635 // Read the second operand. 5636 uint32_t val2 = ReadCoreReg(Rm, &success); 5637 if (!success) 5638 return false; 5639 5640 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5641 if (!success) 5642 return false; 5643 uint32_t result = val1 & shifted; 5644 5645 EmulateInstruction::Context context; 5646 context.type = EmulateInstruction::eContextImmediate; 5647 context.SetNoArgs (); 5648 5649 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5650 return false; 5651 } 5652 return true; 5653 } 5654 5655 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5656 // immediate value, and writes the result to the destination register. It can optionally update the 5657 // condition flags based on the result. 5658 bool 5659 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5660 { 5661 #if 0 5662 // ARM pseudo code... 5663 if ConditionPassed() then 5664 EncodingSpecificOperations(); 5665 result = R[n] AND NOT(imm32); 5666 if d == 15 then // Can only occur for ARM encoding 5667 ALUWritePC(result); // setflags is always FALSE here 5668 else 5669 R[d] = result; 5670 if setflags then 5671 APSR.N = result<31>; 5672 APSR.Z = IsZeroBit(result); 5673 APSR.C = carry; 5674 // APSR.V unchanged 5675 #endif 5676 5677 bool success = false; 5678 5679 if (ConditionPassed(opcode)) 5680 { 5681 uint32_t Rd, Rn; 5682 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5683 bool setflags; 5684 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5685 switch (encoding) 5686 { 5687 case eEncodingT1: 5688 Rd = Bits32(opcode, 11, 8); 5689 Rn = Bits32(opcode, 19, 16); 5690 setflags = BitIsSet(opcode, 20); 5691 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5692 if (BadReg(Rd) || BadReg(Rn)) 5693 return false; 5694 break; 5695 case eEncodingA1: 5696 Rd = Bits32(opcode, 15, 12); 5697 Rn = Bits32(opcode, 19, 16); 5698 setflags = BitIsSet(opcode, 20); 5699 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5700 5701 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5702 if (Rd == 15 && setflags) 5703 return EmulateSUBSPcLrEtc (opcode, encoding); 5704 break; 5705 default: 5706 return false; 5707 } 5708 5709 // Read the first operand. 5710 uint32_t val1 = ReadCoreReg(Rn, &success); 5711 if (!success) 5712 return false; 5713 5714 uint32_t result = val1 & ~imm32; 5715 5716 EmulateInstruction::Context context; 5717 context.type = EmulateInstruction::eContextImmediate; 5718 context.SetNoArgs (); 5719 5720 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5721 return false; 5722 } 5723 return true; 5724 } 5725 5726 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5727 // optionally-shifted register value, and writes the result to the destination register. 5728 // It can optionally update the condition flags based on the result. 5729 bool 5730 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5731 { 5732 #if 0 5733 // ARM pseudo code... 5734 if ConditionPassed() then 5735 EncodingSpecificOperations(); 5736 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5737 result = R[n] AND NOT(shifted); 5738 if d == 15 then // Can only occur for ARM encoding 5739 ALUWritePC(result); // setflags is always FALSE here 5740 else 5741 R[d] = result; 5742 if setflags then 5743 APSR.N = result<31>; 5744 APSR.Z = IsZeroBit(result); 5745 APSR.C = carry; 5746 // APSR.V unchanged 5747 #endif 5748 5749 bool success = false; 5750 5751 if (ConditionPassed(opcode)) 5752 { 5753 uint32_t Rd, Rn, Rm; 5754 ARM_ShifterType shift_t; 5755 uint32_t shift_n; // the shift applied to the value read from Rm 5756 bool setflags; 5757 uint32_t carry; 5758 switch (encoding) 5759 { 5760 case eEncodingT1: 5761 Rd = Rn = Bits32(opcode, 2, 0); 5762 Rm = Bits32(opcode, 5, 3); 5763 setflags = !InITBlock(); 5764 shift_t = SRType_LSL; 5765 shift_n = 0; 5766 break; 5767 case eEncodingT2: 5768 Rd = Bits32(opcode, 11, 8); 5769 Rn = Bits32(opcode, 19, 16); 5770 Rm = Bits32(opcode, 3, 0); 5771 setflags = BitIsSet(opcode, 20); 5772 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5773 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5774 return false; 5775 break; 5776 case eEncodingA1: 5777 Rd = Bits32(opcode, 15, 12); 5778 Rn = Bits32(opcode, 19, 16); 5779 Rm = Bits32(opcode, 3, 0); 5780 setflags = BitIsSet(opcode, 20); 5781 shift_n = DecodeImmShiftARM(opcode, shift_t); 5782 5783 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5784 if (Rd == 15 && setflags) 5785 return EmulateSUBSPcLrEtc (opcode, encoding); 5786 break; 5787 default: 5788 return false; 5789 } 5790 5791 // Read the first operand. 5792 uint32_t val1 = ReadCoreReg(Rn, &success); 5793 if (!success) 5794 return false; 5795 5796 // Read the second operand. 5797 uint32_t val2 = ReadCoreReg(Rm, &success); 5798 if (!success) 5799 return false; 5800 5801 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5802 if (!success) 5803 return false; 5804 uint32_t result = val1 & ~shifted; 5805 5806 EmulateInstruction::Context context; 5807 context.type = EmulateInstruction::eContextImmediate; 5808 context.SetNoArgs (); 5809 5810 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5811 return false; 5812 } 5813 return true; 5814 } 5815 5816 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5817 // from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5818 bool 5819 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5820 { 5821 #if 0 5822 if ConditionPassed() then 5823 EncodingSpecificOperations(); 5824 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5825 address = if index then offset_addr else R[n]; 5826 data = MemU[address,4]; 5827 if wback then R[n] = offset_addr; 5828 if t == 15 then 5829 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5830 elsif UnalignedSupport() || address<1:0> = '00' then 5831 R[t] = data; 5832 else // Can only apply before ARMv7 5833 R[t] = ROR(data, 8*UInt(address<1:0>)); 5834 #endif 5835 5836 bool success = false; 5837 5838 if (ConditionPassed(opcode)) 5839 { 5840 const uint32_t addr_byte_size = GetAddressByteSize(); 5841 5842 uint32_t t; 5843 uint32_t n; 5844 uint32_t imm32; 5845 bool index; 5846 bool add; 5847 bool wback; 5848 5849 switch (encoding) 5850 { 5851 case eEncodingA1: 5852 // if Rn == '1111' then SEE LDR (literal); 5853 // if P == '0' && W == '1' then SEE LDRT; 5854 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5855 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5856 t = Bits32 (opcode, 15, 12); 5857 n = Bits32 (opcode, 19, 16); 5858 imm32 = Bits32 (opcode, 11, 0); 5859 5860 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5861 index = BitIsSet (opcode, 24); 5862 add = BitIsSet (opcode, 23); 5863 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5864 5865 // if wback && n == t then UNPREDICTABLE; 5866 if (wback && (n == t)) 5867 return false; 5868 5869 break; 5870 5871 default: 5872 return false; 5873 } 5874 5875 addr_t address; 5876 addr_t offset_addr; 5877 addr_t base_address = ReadCoreReg (n, &success); 5878 if (!success) 5879 return false; 5880 5881 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5882 if (add) 5883 offset_addr = base_address + imm32; 5884 else 5885 offset_addr = base_address - imm32; 5886 5887 // address = if index then offset_addr else R[n]; 5888 if (index) 5889 address = offset_addr; 5890 else 5891 address = base_address; 5892 5893 // data = MemU[address,4]; 5894 5895 RegisterInfo base_reg; 5896 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5897 5898 EmulateInstruction::Context context; 5899 context.type = eContextRegisterLoad; 5900 context.SetRegisterPlusOffset (base_reg, address - base_address); 5901 5902 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5903 if (!success) 5904 return false; 5905 5906 // if wback then R[n] = offset_addr; 5907 if (wback) 5908 { 5909 context.type = eContextAdjustBaseRegister; 5910 context.SetAddress (offset_addr); 5911 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5912 return false; 5913 } 5914 5915 // if t == 15 then 5916 if (t == 15) 5917 { 5918 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5919 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5920 { 5921 // LoadWritePC (data); 5922 context.type = eContextRegisterLoad; 5923 context.SetRegisterPlusOffset (base_reg, address - base_address); 5924 LoadWritePC (context, data); 5925 } 5926 else 5927 return false; 5928 } 5929 // elsif UnalignedSupport() || address<1:0> = '00' then 5930 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5931 { 5932 // R[t] = data; 5933 context.type = eContextRegisterLoad; 5934 context.SetRegisterPlusOffset (base_reg, address - base_address); 5935 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5936 return false; 5937 } 5938 // else // Can only apply before ARMv7 5939 else 5940 { 5941 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5942 data = ROR (data, Bits32 (address, 1, 0), &success); 5943 if (!success) 5944 return false; 5945 context.type = eContextRegisterLoad; 5946 context.SetImmediate (data); 5947 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5948 return false; 5949 } 5950 5951 } 5952 return true; 5953 } 5954 5955 // LDR (register) calculates an address from a base register value and an offset register value, loads a word 5956 // from memory, and writes it to a register. The offset register value can optionally be shifted. 5957 bool 5958 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5959 { 5960 #if 0 5961 if ConditionPassed() then 5962 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5963 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5964 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5965 address = if index then offset_addr else R[n]; 5966 data = MemU[address,4]; 5967 if wback then R[n] = offset_addr; 5968 if t == 15 then 5969 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5970 elsif UnalignedSupport() || address<1:0> = '00' then 5971 R[t] = data; 5972 else // Can only apply before ARMv7 5973 if CurrentInstrSet() == InstrSet_ARM then 5974 R[t] = ROR(data, 8*UInt(address<1:0>)); 5975 else 5976 R[t] = bits(32) UNKNOWN; 5977 #endif 5978 5979 bool success = false; 5980 5981 if (ConditionPassed(opcode)) 5982 { 5983 const uint32_t addr_byte_size = GetAddressByteSize(); 5984 5985 uint32_t t; 5986 uint32_t n; 5987 uint32_t m; 5988 bool index; 5989 bool add; 5990 bool wback; 5991 ARM_ShifterType shift_t; 5992 uint32_t shift_n; 5993 5994 switch (encoding) 5995 { 5996 case eEncodingT1: 5997 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5998 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5999 t = Bits32 (opcode, 2, 0); 6000 n = Bits32 (opcode, 5, 3); 6001 m = Bits32 (opcode, 8, 6); 6002 6003 // index = TRUE; add = TRUE; wback = FALSE; 6004 index = true; 6005 add = true; 6006 wback = false; 6007 6008 // (shift_t, shift_n) = (SRType_LSL, 0); 6009 shift_t = SRType_LSL; 6010 shift_n = 0; 6011 6012 break; 6013 6014 case eEncodingT2: 6015 // if Rn == '1111' then SEE LDR (literal); 6016 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6017 t = Bits32 (opcode, 15, 12); 6018 n = Bits32 (opcode, 19, 16); 6019 m = Bits32 (opcode, 3, 0); 6020 6021 // index = TRUE; add = TRUE; wback = FALSE; 6022 index = true; 6023 add = true; 6024 wback = false; 6025 6026 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6027 shift_t = SRType_LSL; 6028 shift_n = Bits32 (opcode, 5, 4); 6029 6030 // if BadReg(m) then UNPREDICTABLE; 6031 if (BadReg (m)) 6032 return false; 6033 6034 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6035 if ((t == 15) && InITBlock() && !LastInITBlock()) 6036 return false; 6037 6038 break; 6039 6040 case eEncodingA1: 6041 { 6042 // if P == '0' && W == '1' then SEE LDRT; 6043 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6044 t = Bits32 (opcode, 15, 12); 6045 n = Bits32 (opcode, 19, 16); 6046 m = Bits32 (opcode, 3, 0); 6047 6048 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6049 index = BitIsSet (opcode, 24); 6050 add = BitIsSet (opcode, 23); 6051 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6052 6053 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6054 uint32_t type = Bits32 (opcode, 6, 5); 6055 uint32_t imm5 = Bits32 (opcode, 11, 7); 6056 shift_n = DecodeImmShift (type, imm5, shift_t); 6057 6058 // if m == 15 then UNPREDICTABLE; 6059 if (m == 15) 6060 return false; 6061 6062 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6063 if (wback && ((n == 15) || (n == t))) 6064 return false; 6065 } 6066 break; 6067 6068 6069 default: 6070 return false; 6071 } 6072 6073 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6074 if (!success) 6075 return false; 6076 6077 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6078 if (!success) 6079 return false; 6080 6081 addr_t offset_addr; 6082 addr_t address; 6083 6084 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6085 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6086 if (!success) 6087 return false; 6088 6089 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6090 if (add) 6091 offset_addr = Rn + offset; 6092 else 6093 offset_addr = Rn - offset; 6094 6095 // address = if index then offset_addr else R[n]; 6096 if (index) 6097 address = offset_addr; 6098 else 6099 address = Rn; 6100 6101 // data = MemU[address,4]; 6102 RegisterInfo base_reg; 6103 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6104 6105 EmulateInstruction::Context context; 6106 context.type = eContextRegisterLoad; 6107 context.SetRegisterPlusOffset (base_reg, address - Rn); 6108 6109 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6110 if (!success) 6111 return false; 6112 6113 // if wback then R[n] = offset_addr; 6114 if (wback) 6115 { 6116 context.type = eContextAdjustBaseRegister; 6117 context.SetAddress (offset_addr); 6118 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6119 return false; 6120 } 6121 6122 // if t == 15 then 6123 if (t == 15) 6124 { 6125 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6126 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6127 { 6128 context.type = eContextRegisterLoad; 6129 context.SetRegisterPlusOffset (base_reg, address - Rn); 6130 LoadWritePC (context, data); 6131 } 6132 else 6133 return false; 6134 } 6135 // elsif UnalignedSupport() || address<1:0> = '00' then 6136 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6137 { 6138 // R[t] = data; 6139 context.type = eContextRegisterLoad; 6140 context.SetRegisterPlusOffset (base_reg, address - Rn); 6141 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6142 return false; 6143 } 6144 else // Can only apply before ARMv7 6145 { 6146 // if CurrentInstrSet() == InstrSet_ARM then 6147 if (CurrentInstrSet () == eModeARM) 6148 { 6149 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6150 data = ROR (data, Bits32 (address, 1, 0), &success); 6151 if (!success) 6152 return false; 6153 context.type = eContextRegisterLoad; 6154 context.SetImmediate (data); 6155 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6156 return false; 6157 } 6158 else 6159 { 6160 // R[t] = bits(32) UNKNOWN; 6161 WriteBits32Unknown (t); 6162 } 6163 } 6164 } 6165 return true; 6166 } 6167 6168 // LDRB (immediate, Thumb) 6169 bool 6170 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6171 { 6172 #if 0 6173 if ConditionPassed() then 6174 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6175 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6176 address = if index then offset_addr else R[n]; 6177 R[t] = ZeroExtend(MemU[address,1], 32); 6178 if wback then R[n] = offset_addr; 6179 #endif 6180 6181 bool success = false; 6182 6183 if (ConditionPassed(opcode)) 6184 { 6185 uint32_t t; 6186 uint32_t n; 6187 uint32_t imm32; 6188 bool index; 6189 bool add; 6190 bool wback; 6191 6192 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6193 switch (encoding) 6194 { 6195 case eEncodingT1: 6196 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6197 t = Bits32 (opcode, 2, 0); 6198 n = Bits32 (opcode, 5, 3); 6199 imm32 = Bits32 (opcode, 10, 6); 6200 6201 // index = TRUE; add = TRUE; wback = FALSE; 6202 index = true; 6203 add = true; 6204 wback= false; 6205 6206 break; 6207 6208 case eEncodingT2: 6209 // if Rt == '1111' then SEE PLD; 6210 // if Rn == '1111' then SEE LDRB (literal); 6211 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6212 t = Bits32 (opcode, 15, 12); 6213 n = Bits32 (opcode, 19, 16); 6214 imm32 = Bits32 (opcode, 11, 0); 6215 6216 // index = TRUE; add = TRUE; wback = FALSE; 6217 index = true; 6218 add = true; 6219 wback = false; 6220 6221 // if t == 13 then UNPREDICTABLE; 6222 if (t == 13) 6223 return false; 6224 6225 break; 6226 6227 case eEncodingT3: 6228 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6229 // if Rn == '1111' then SEE LDRB (literal); 6230 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6231 // if P == '0' && W == '0' then UNDEFINED; 6232 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6233 return false; 6234 6235 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6236 t = Bits32 (opcode, 15, 12); 6237 n = Bits32 (opcode, 19, 16); 6238 imm32 = Bits32 (opcode, 7, 0); 6239 6240 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6241 index = BitIsSet (opcode, 10); 6242 add = BitIsSet (opcode, 9); 6243 wback = BitIsSet (opcode, 8); 6244 6245 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6246 if (BadReg (t) || (wback && (n == t))) 6247 return false; 6248 6249 break; 6250 6251 default: 6252 return false; 6253 } 6254 6255 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6256 if (!success) 6257 return false; 6258 6259 addr_t address; 6260 addr_t offset_addr; 6261 6262 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6263 if (add) 6264 offset_addr = Rn + imm32; 6265 else 6266 offset_addr = Rn - imm32; 6267 6268 // address = if index then offset_addr else R[n]; 6269 if (index) 6270 address = offset_addr; 6271 else 6272 address = Rn; 6273 6274 // R[t] = ZeroExtend(MemU[address,1], 32); 6275 RegisterInfo base_reg; 6276 RegisterInfo data_reg; 6277 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6278 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6279 6280 EmulateInstruction::Context context; 6281 context.type = eContextRegisterLoad; 6282 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6283 6284 uint64_t data = MemURead (context, address, 1, 0, &success); 6285 if (!success) 6286 return false; 6287 6288 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6289 return false; 6290 6291 // if wback then R[n] = offset_addr; 6292 if (wback) 6293 { 6294 context.type = eContextAdjustBaseRegister; 6295 context.SetAddress (offset_addr); 6296 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6297 return false; 6298 } 6299 } 6300 return true; 6301 } 6302 6303 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6304 // zero-extends it to form a 32-bit word and writes it to a register. 6305 bool 6306 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6307 { 6308 #if 0 6309 if ConditionPassed() then 6310 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6311 base = Align(PC,4); 6312 address = if add then (base + imm32) else (base - imm32); 6313 R[t] = ZeroExtend(MemU[address,1], 32); 6314 #endif 6315 6316 bool success = false; 6317 6318 if (ConditionPassed(opcode)) 6319 { 6320 uint32_t t; 6321 uint32_t imm32; 6322 bool add; 6323 switch (encoding) 6324 { 6325 case eEncodingT1: 6326 // if Rt == '1111' then SEE PLD; 6327 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6328 t = Bits32 (opcode, 15, 12); 6329 imm32 = Bits32 (opcode, 11, 0); 6330 add = BitIsSet (opcode, 23); 6331 6332 // if t == 13 then UNPREDICTABLE; 6333 if (t == 13) 6334 return false; 6335 6336 break; 6337 6338 case eEncodingA1: 6339 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6340 t = Bits32 (opcode, 15, 12); 6341 imm32 = Bits32 (opcode, 11, 0); 6342 add = BitIsSet (opcode, 23); 6343 6344 // if t == 15 then UNPREDICTABLE; 6345 if (t == 15) 6346 return false; 6347 break; 6348 6349 default: 6350 return false; 6351 } 6352 6353 // base = Align(PC,4); 6354 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6355 if (!success) 6356 return false; 6357 6358 uint32_t base = AlignPC (pc_val); 6359 6360 addr_t address; 6361 // address = if add then (base + imm32) else (base - imm32); 6362 if (add) 6363 address = base + imm32; 6364 else 6365 address = base - imm32; 6366 6367 // R[t] = ZeroExtend(MemU[address,1], 32); 6368 EmulateInstruction::Context context; 6369 context.type = eContextRelativeBranchImmediate; 6370 context.SetImmediate (address - base); 6371 6372 uint64_t data = MemURead (context, address, 1, 0, &success); 6373 if (!success) 6374 return false; 6375 6376 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6377 return false; 6378 } 6379 return true; 6380 } 6381 6382 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6383 // memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6384 // optionally be shifted. 6385 bool 6386 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6387 { 6388 #if 0 6389 if ConditionPassed() then 6390 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6391 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6392 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6393 address = if index then offset_addr else R[n]; 6394 R[t] = ZeroExtend(MemU[address,1],32); 6395 if wback then R[n] = offset_addr; 6396 #endif 6397 6398 bool success = false; 6399 6400 if (ConditionPassed(opcode)) 6401 { 6402 uint32_t t; 6403 uint32_t n; 6404 uint32_t m; 6405 bool index; 6406 bool add; 6407 bool wback; 6408 ARM_ShifterType shift_t; 6409 uint32_t shift_n; 6410 6411 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6412 switch (encoding) 6413 { 6414 case eEncodingT1: 6415 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6416 t = Bits32 (opcode, 2, 0); 6417 n = Bits32 (opcode, 5, 3); 6418 m = Bits32 (opcode, 8, 6); 6419 6420 // index = TRUE; add = TRUE; wback = FALSE; 6421 index = true; 6422 add = true; 6423 wback = false; 6424 6425 // (shift_t, shift_n) = (SRType_LSL, 0); 6426 shift_t = SRType_LSL; 6427 shift_n = 0; 6428 break; 6429 6430 case eEncodingT2: 6431 // if Rt == '1111' then SEE PLD; 6432 // if Rn == '1111' then SEE LDRB (literal); 6433 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6434 t = Bits32 (opcode, 15, 12); 6435 n = Bits32 (opcode, 19, 16); 6436 m = Bits32 (opcode, 3, 0); 6437 6438 // index = TRUE; add = TRUE; wback = FALSE; 6439 index = true; 6440 add = true; 6441 wback = false; 6442 6443 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6444 shift_t = SRType_LSL; 6445 shift_n = Bits32 (opcode, 5, 4); 6446 6447 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6448 if ((t == 13) || BadReg (m)) 6449 return false; 6450 break; 6451 6452 case eEncodingA1: 6453 { 6454 // if P == '0' && W == '1' then SEE LDRBT; 6455 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6456 t = Bits32 (opcode, 15, 12); 6457 n = Bits32 (opcode, 19, 16); 6458 m = Bits32 (opcode, 3, 0); 6459 6460 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6461 index = BitIsSet (opcode, 24); 6462 add = BitIsSet (opcode, 23); 6463 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6464 6465 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6466 uint32_t type = Bits32 (opcode, 6, 5); 6467 uint32_t imm5 = Bits32 (opcode, 11, 7); 6468 shift_n = DecodeImmShift (type, imm5, shift_t); 6469 6470 // if t == 15 || m == 15 then UNPREDICTABLE; 6471 if ((t == 15) || (m == 15)) 6472 return false; 6473 6474 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6475 if (wback && ((n == 15) || (n == t))) 6476 return false; 6477 } 6478 break; 6479 6480 default: 6481 return false; 6482 } 6483 6484 addr_t offset_addr; 6485 addr_t address; 6486 6487 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6488 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6489 if (!success) 6490 return false; 6491 6492 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6493 if (!success) 6494 return false; 6495 6496 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6497 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6498 if (!success) 6499 return false; 6500 6501 if (add) 6502 offset_addr = Rn + offset; 6503 else 6504 offset_addr = Rn - offset; 6505 6506 // address = if index then offset_addr else R[n]; 6507 if (index) 6508 address = offset_addr; 6509 else 6510 address = Rn; 6511 6512 // R[t] = ZeroExtend(MemU[address,1],32); 6513 RegisterInfo base_reg; 6514 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6515 6516 EmulateInstruction::Context context; 6517 context.type = eContextRegisterLoad; 6518 context.SetRegisterPlusOffset (base_reg, address - Rn); 6519 6520 uint64_t data = MemURead (context, address, 1, 0, &success); 6521 if (!success) 6522 return false; 6523 6524 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6525 return false; 6526 6527 // if wback then R[n] = offset_addr; 6528 if (wback) 6529 { 6530 context.type = eContextAdjustBaseRegister; 6531 context.SetAddress (offset_addr); 6532 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6533 return false; 6534 } 6535 } 6536 return true; 6537 } 6538 6539 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6540 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6541 // post-indexed, or pre-indexed addressing. 6542 bool 6543 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6544 { 6545 #if 0 6546 if ConditionPassed() then 6547 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6548 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6549 address = if index then offset_addr else R[n]; 6550 data = MemU[address,2]; 6551 if wback then R[n] = offset_addr; 6552 if UnalignedSupport() || address<0> = '0' then 6553 R[t] = ZeroExtend(data, 32); 6554 else // Can only apply before ARMv7 6555 R[t] = bits(32) UNKNOWN; 6556 #endif 6557 6558 6559 bool success = false; 6560 6561 if (ConditionPassed(opcode)) 6562 { 6563 uint32_t t; 6564 uint32_t n; 6565 uint32_t imm32; 6566 bool index; 6567 bool add; 6568 bool wback; 6569 6570 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6571 switch (encoding) 6572 { 6573 case eEncodingT1: 6574 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6575 t = Bits32 (opcode, 2, 0); 6576 n = Bits32 (opcode, 5, 3); 6577 imm32 = Bits32 (opcode, 10, 6) << 1; 6578 6579 // index = TRUE; add = TRUE; wback = FALSE; 6580 index = true; 6581 add = true; 6582 wback = false; 6583 6584 break; 6585 6586 case eEncodingT2: 6587 // if Rt == '1111' then SEE "Unallocated memory hints"; 6588 // if Rn == '1111' then SEE LDRH (literal); 6589 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6590 t = Bits32 (opcode, 15, 12); 6591 n = Bits32 (opcode, 19, 16); 6592 imm32 = Bits32 (opcode, 11, 0); 6593 6594 // index = TRUE; add = TRUE; wback = FALSE; 6595 index = true; 6596 add = true; 6597 wback = false; 6598 6599 // if t == 13 then UNPREDICTABLE; 6600 if (t == 13) 6601 return false; 6602 break; 6603 6604 case eEncodingT3: 6605 // if Rn == '1111' then SEE LDRH (literal); 6606 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6607 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6608 // if P == '0' && W == '0' then UNDEFINED; 6609 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6610 return false; 6611 6612 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6613 t = Bits32 (opcode, 15, 12); 6614 n = Bits32 (opcode, 19, 16); 6615 imm32 = Bits32 (opcode, 7, 0); 6616 6617 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6618 index = BitIsSet (opcode, 10); 6619 add = BitIsSet (opcode, 9); 6620 wback = BitIsSet (opcode, 8); 6621 6622 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6623 if (BadReg (t) || (wback && (n == t))) 6624 return false; 6625 break; 6626 6627 default: 6628 return false; 6629 } 6630 6631 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6632 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6633 if (!success) 6634 return false; 6635 6636 addr_t offset_addr; 6637 addr_t address; 6638 6639 if (add) 6640 offset_addr = Rn + imm32; 6641 else 6642 offset_addr = Rn - imm32; 6643 6644 // address = if index then offset_addr else R[n]; 6645 if (index) 6646 address = offset_addr; 6647 else 6648 address = Rn; 6649 6650 // data = MemU[address,2]; 6651 RegisterInfo base_reg; 6652 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6653 6654 EmulateInstruction::Context context; 6655 context.type = eContextRegisterLoad; 6656 context.SetRegisterPlusOffset (base_reg, address - Rn); 6657 6658 uint64_t data = MemURead (context, address, 2, 0, &success); 6659 if (!success) 6660 return false; 6661 6662 // if wback then R[n] = offset_addr; 6663 if (wback) 6664 { 6665 context.type = eContextAdjustBaseRegister; 6666 context.SetAddress (offset_addr); 6667 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6668 return false; 6669 } 6670 6671 // if UnalignedSupport() || address<0> = '0' then 6672 if (UnalignedSupport () || BitIsClear (address, 0)) 6673 { 6674 // R[t] = ZeroExtend(data, 32); 6675 context.type = eContextRegisterLoad; 6676 context.SetRegisterPlusOffset (base_reg, address - Rn); 6677 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6678 return false; 6679 } 6680 else // Can only apply before ARMv7 6681 { 6682 // R[t] = bits(32) UNKNOWN; 6683 WriteBits32Unknown (t); 6684 } 6685 } 6686 return true; 6687 } 6688 6689 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6690 // zero-extends it to form a 32-bit word, and writes it to a register. 6691 bool 6692 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6693 { 6694 #if 0 6695 if ConditionPassed() then 6696 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6697 base = Align(PC,4); 6698 address = if add then (base + imm32) else (base - imm32); 6699 data = MemU[address,2]; 6700 if UnalignedSupport() || address<0> = '0' then 6701 R[t] = ZeroExtend(data, 32); 6702 else // Can only apply before ARMv7 6703 R[t] = bits(32) UNKNOWN; 6704 #endif 6705 6706 bool success = false; 6707 6708 if (ConditionPassed(opcode)) 6709 { 6710 uint32_t t; 6711 uint32_t imm32; 6712 bool add; 6713 6714 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6715 switch (encoding) 6716 { 6717 case eEncodingT1: 6718 // if Rt == '1111' then SEE "Unallocated memory hints"; 6719 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6720 t = Bits32 (opcode, 15, 12); 6721 imm32 = Bits32 (opcode, 11, 0); 6722 add = BitIsSet (opcode, 23); 6723 6724 // if t == 13 then UNPREDICTABLE; 6725 if (t == 13) 6726 return false; 6727 6728 break; 6729 6730 case eEncodingA1: 6731 { 6732 uint32_t imm4H = Bits32 (opcode, 11, 8); 6733 uint32_t imm4L = Bits32 (opcode, 3, 0); 6734 6735 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6736 t = Bits32 (opcode, 15, 12); 6737 imm32 = (imm4H << 4) | imm4L; 6738 add = BitIsSet (opcode, 23); 6739 6740 // if t == 15 then UNPREDICTABLE; 6741 if (t == 15) 6742 return false; 6743 break; 6744 } 6745 6746 default: 6747 return false; 6748 } 6749 6750 // base = Align(PC,4); 6751 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6752 if (!success) 6753 return false; 6754 6755 addr_t base = AlignPC (pc_value); 6756 addr_t address; 6757 6758 // address = if add then (base + imm32) else (base - imm32); 6759 if (add) 6760 address = base + imm32; 6761 else 6762 address = base - imm32; 6763 6764 // data = MemU[address,2]; 6765 RegisterInfo base_reg; 6766 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6767 6768 EmulateInstruction::Context context; 6769 context.type = eContextRegisterLoad; 6770 context.SetRegisterPlusOffset (base_reg, address - base); 6771 6772 uint64_t data = MemURead (context, address, 2, 0, &success); 6773 if (!success) 6774 return false; 6775 6776 6777 // if UnalignedSupport() || address<0> = '0' then 6778 if (UnalignedSupport () || BitIsClear (address, 0)) 6779 { 6780 // R[t] = ZeroExtend(data, 32); 6781 context.type = eContextRegisterLoad; 6782 context.SetRegisterPlusOffset (base_reg, address - base); 6783 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6784 return false; 6785 6786 } 6787 else // Can only apply before ARMv7 6788 { 6789 // R[t] = bits(32) UNKNOWN; 6790 WriteBits32Unknown (t); 6791 } 6792 } 6793 return true; 6794 } 6795 6796 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6797 // from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6798 // be shifted left by 0, 1, 2, or 3 bits. 6799 bool 6800 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6801 { 6802 #if 0 6803 if ConditionPassed() then 6804 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6805 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6806 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6807 address = if index then offset_addr else R[n]; 6808 data = MemU[address,2]; 6809 if wback then R[n] = offset_addr; 6810 if UnalignedSupport() || address<0> = '0' then 6811 R[t] = ZeroExtend(data, 32); 6812 else // Can only apply before ARMv7 6813 R[t] = bits(32) UNKNOWN; 6814 #endif 6815 6816 bool success = false; 6817 6818 if (ConditionPassed(opcode)) 6819 { 6820 uint32_t t; 6821 uint32_t n; 6822 uint32_t m; 6823 bool index; 6824 bool add; 6825 bool wback; 6826 ARM_ShifterType shift_t; 6827 uint32_t shift_n; 6828 6829 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6830 switch (encoding) 6831 { 6832 case eEncodingT1: 6833 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6834 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6835 t = Bits32 (opcode, 2, 0); 6836 n = Bits32 (opcode, 5, 3); 6837 m = Bits32 (opcode, 8, 6); 6838 6839 // index = TRUE; add = TRUE; wback = FALSE; 6840 index = true; 6841 add = true; 6842 wback = false; 6843 6844 // (shift_t, shift_n) = (SRType_LSL, 0); 6845 shift_t = SRType_LSL; 6846 shift_n = 0; 6847 6848 break; 6849 6850 case eEncodingT2: 6851 // if Rn == '1111' then SEE LDRH (literal); 6852 // if Rt == '1111' then SEE "Unallocated memory hints"; 6853 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6854 t = Bits32 (opcode, 15, 12); 6855 n = Bits32 (opcode, 19, 16); 6856 m = Bits32 (opcode, 3, 0); 6857 6858 // index = TRUE; add = TRUE; wback = FALSE; 6859 index = true; 6860 add = true; 6861 wback = false; 6862 6863 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6864 shift_t = SRType_LSL; 6865 shift_n = Bits32 (opcode, 5, 4); 6866 6867 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6868 if ((t == 13) || BadReg (m)) 6869 return false; 6870 break; 6871 6872 case eEncodingA1: 6873 // if P == '0' && W == '1' then SEE LDRHT; 6874 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6875 t = Bits32 (opcode, 15, 12); 6876 n = Bits32 (opcode, 19, 16); 6877 m = Bits32 (opcode, 3, 0); 6878 6879 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6880 index = BitIsSet (opcode, 24); 6881 add = BitIsSet (opcode, 23); 6882 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6883 6884 // (shift_t, shift_n) = (SRType_LSL, 0); 6885 shift_t = SRType_LSL; 6886 shift_n = 0; 6887 6888 // if t == 15 || m == 15 then UNPREDICTABLE; 6889 if ((t == 15) || (m == 15)) 6890 return false; 6891 6892 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6893 if (wback && ((n == 15) || (n == t))) 6894 return false; 6895 6896 break; 6897 6898 default: 6899 return false; 6900 } 6901 6902 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6903 6904 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6905 if (!success) 6906 return false; 6907 6908 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6909 if (!success) 6910 return false; 6911 6912 addr_t offset_addr; 6913 addr_t address; 6914 6915 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6916 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6917 if (!success) 6918 return false; 6919 6920 if (add) 6921 offset_addr = Rn + offset; 6922 else 6923 offset_addr = Rn - offset; 6924 6925 // address = if index then offset_addr else R[n]; 6926 if (index) 6927 address = offset_addr; 6928 else 6929 address = Rn; 6930 6931 // data = MemU[address,2]; 6932 RegisterInfo base_reg; 6933 RegisterInfo offset_reg; 6934 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6935 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 6936 6937 EmulateInstruction::Context context; 6938 context.type = eContextRegisterLoad; 6939 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6940 uint64_t data = MemURead (context, address, 2, 0, &success); 6941 if (!success) 6942 return false; 6943 6944 // if wback then R[n] = offset_addr; 6945 if (wback) 6946 { 6947 context.type = eContextAdjustBaseRegister; 6948 context.SetAddress (offset_addr); 6949 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6950 return false; 6951 } 6952 6953 // if UnalignedSupport() || address<0> = '0' then 6954 if (UnalignedSupport() || BitIsClear (address, 0)) 6955 { 6956 // R[t] = ZeroExtend(data, 32); 6957 context.type = eContextRegisterLoad; 6958 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6959 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6960 return false; 6961 } 6962 else // Can only apply before ARMv7 6963 { 6964 // R[t] = bits(32) UNKNOWN; 6965 WriteBits32Unknown (t); 6966 } 6967 } 6968 return true; 6969 } 6970 6971 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6972 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6973 // or pre-indexed addressing. 6974 bool 6975 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6976 { 6977 #if 0 6978 if ConditionPassed() then 6979 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6980 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6981 address = if index then offset_addr else R[n]; 6982 R[t] = SignExtend(MemU[address,1], 32); 6983 if wback then R[n] = offset_addr; 6984 #endif 6985 6986 bool success = false; 6987 6988 if (ConditionPassed(opcode)) 6989 { 6990 uint32_t t; 6991 uint32_t n; 6992 uint32_t imm32; 6993 bool index; 6994 bool add; 6995 bool wback; 6996 6997 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6998 switch (encoding) 6999 { 7000 case eEncodingT1: 7001 // if Rt == '1111' then SEE PLI; 7002 // if Rn == '1111' then SEE LDRSB (literal); 7003 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7004 t = Bits32 (opcode, 15, 12); 7005 n = Bits32 (opcode, 19, 16); 7006 imm32 = Bits32 (opcode, 11, 0); 7007 7008 // index = TRUE; add = TRUE; wback = FALSE; 7009 index = true; 7010 add = true; 7011 wback = false; 7012 7013 // if t == 13 then UNPREDICTABLE; 7014 if (t == 13) 7015 return false; 7016 7017 break; 7018 7019 case eEncodingT2: 7020 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7021 // if Rn == '1111' then SEE LDRSB (literal); 7022 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7023 // if P == '0' && W == '0' then UNDEFINED; 7024 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7025 return false; 7026 7027 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7028 t = Bits32 (opcode, 15, 12); 7029 n = Bits32 (opcode, 19, 16); 7030 imm32 = Bits32 (opcode, 7, 0); 7031 7032 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7033 index = BitIsSet (opcode, 10); 7034 add = BitIsSet (opcode, 9); 7035 wback = BitIsSet (opcode, 8); 7036 7037 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7038 if (((t == 13) || ((t == 15) 7039 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 7040 || (wback && (n == t))) 7041 return false; 7042 7043 break; 7044 7045 case eEncodingA1: 7046 { 7047 // if Rn == '1111' then SEE LDRSB (literal); 7048 // if P == '0' && W == '1' then SEE LDRSBT; 7049 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7050 t = Bits32 (opcode, 15, 12); 7051 n = Bits32 (opcode, 19, 16); 7052 7053 uint32_t imm4H = Bits32 (opcode, 11, 8); 7054 uint32_t imm4L = Bits32 (opcode, 3, 0); 7055 imm32 = (imm4H << 4) | imm4L; 7056 7057 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7058 index = BitIsSet (opcode, 24); 7059 add = BitIsSet (opcode, 23); 7060 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7061 7062 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7063 if ((t == 15) || (wback && (n == t))) 7064 return false; 7065 7066 break; 7067 } 7068 7069 default: 7070 return false; 7071 } 7072 7073 uint64_t Rn = ReadCoreReg (n, &success); 7074 if (!success) 7075 return false; 7076 7077 addr_t offset_addr; 7078 addr_t address; 7079 7080 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7081 if (add) 7082 offset_addr = Rn + imm32; 7083 else 7084 offset_addr = Rn - imm32; 7085 7086 // address = if index then offset_addr else R[n]; 7087 if (index) 7088 address = offset_addr; 7089 else 7090 address = Rn; 7091 7092 // R[t] = SignExtend(MemU[address,1], 32); 7093 RegisterInfo base_reg; 7094 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7095 7096 EmulateInstruction::Context context; 7097 context.type = eContextRegisterLoad; 7098 context.SetRegisterPlusOffset (base_reg, address - Rn); 7099 7100 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7101 if (!success) 7102 return false; 7103 7104 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7105 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7106 return false; 7107 7108 // if wback then R[n] = offset_addr; 7109 if (wback) 7110 { 7111 context.type = eContextAdjustBaseRegister; 7112 context.SetAddress (offset_addr); 7113 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7114 return false; 7115 } 7116 } 7117 7118 return true; 7119 } 7120 7121 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7122 // sign-extends it to form a 32-bit word, and writes tit to a register. 7123 bool 7124 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7125 { 7126 #if 0 7127 if ConditionPassed() then 7128 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7129 base = Align(PC,4); 7130 address = if add then (base + imm32) else (base - imm32); 7131 R[t] = SignExtend(MemU[address,1], 32); 7132 #endif 7133 7134 bool success = false; 7135 7136 if (ConditionPassed(opcode)) 7137 { 7138 uint32_t t; 7139 uint32_t imm32; 7140 bool add; 7141 7142 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7143 switch (encoding) 7144 { 7145 case eEncodingT1: 7146 // if Rt == '1111' then SEE PLI; 7147 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7148 t = Bits32 (opcode, 15, 12); 7149 imm32 = Bits32 (opcode, 11, 0); 7150 add = BitIsSet (opcode, 23); 7151 7152 // if t == 13 then UNPREDICTABLE; 7153 if (t == 13) 7154 return false; 7155 7156 break; 7157 7158 case eEncodingA1: 7159 { 7160 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7161 t = Bits32 (opcode, 15, 12); 7162 uint32_t imm4H = Bits32 (opcode, 11, 8); 7163 uint32_t imm4L = Bits32 (opcode, 3, 0); 7164 imm32 = (imm4H << 4) | imm4L; 7165 add = BitIsSet (opcode, 23); 7166 7167 // if t == 15 then UNPREDICTABLE; 7168 if (t == 15) 7169 return false; 7170 7171 break; 7172 } 7173 7174 default: 7175 return false; 7176 } 7177 7178 // base = Align(PC,4); 7179 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7180 if (!success) 7181 return false; 7182 uint64_t base = AlignPC (pc_value); 7183 7184 // address = if add then (base + imm32) else (base - imm32); 7185 addr_t address; 7186 if (add) 7187 address = base + imm32; 7188 else 7189 address = base - imm32; 7190 7191 // R[t] = SignExtend(MemU[address,1], 32); 7192 RegisterInfo base_reg; 7193 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7194 7195 EmulateInstruction::Context context; 7196 context.type = eContextRegisterLoad; 7197 context.SetRegisterPlusOffset (base_reg, address - base); 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 return true; 7208 } 7209 7210 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7211 // memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7212 // shifted left by 0, 1, 2, or 3 bits. 7213 bool 7214 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7215 { 7216 #if 0 7217 if ConditionPassed() then 7218 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7219 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7220 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7221 address = if index then offset_addr else R[n]; 7222 R[t] = SignExtend(MemU[address,1], 32); 7223 if wback then R[n] = offset_addr; 7224 #endif 7225 7226 bool success = false; 7227 7228 if (ConditionPassed(opcode)) 7229 { 7230 uint32_t t; 7231 uint32_t n; 7232 uint32_t m; 7233 bool index; 7234 bool add; 7235 bool wback; 7236 ARM_ShifterType shift_t; 7237 uint32_t shift_n; 7238 7239 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7240 switch (encoding) 7241 { 7242 case eEncodingT1: 7243 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7244 t = Bits32 (opcode, 2, 0); 7245 n = Bits32 (opcode, 5, 3); 7246 m = Bits32 (opcode, 8, 6); 7247 7248 // index = TRUE; add = TRUE; wback = FALSE; 7249 index = true; 7250 add = true; 7251 wback = false; 7252 7253 // (shift_t, shift_n) = (SRType_LSL, 0); 7254 shift_t = SRType_LSL; 7255 shift_n = 0; 7256 7257 break; 7258 7259 case eEncodingT2: 7260 // if Rt == '1111' then SEE PLI; 7261 // if Rn == '1111' then SEE LDRSB (literal); 7262 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7263 t = Bits32 (opcode, 15, 12); 7264 n = Bits32 (opcode, 19, 16); 7265 m = Bits32 (opcode, 3, 0); 7266 7267 // index = TRUE; add = TRUE; wback = FALSE; 7268 index = true; 7269 add = true; 7270 wback = false; 7271 7272 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7273 shift_t = SRType_LSL; 7274 shift_n = Bits32 (opcode, 5, 4); 7275 7276 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7277 if ((t == 13) || BadReg (m)) 7278 return false; 7279 break; 7280 7281 case eEncodingA1: 7282 // if P == '0' && W == '1' then SEE LDRSBT; 7283 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7284 t = Bits32 (opcode, 15, 12); 7285 n = Bits32 (opcode, 19, 16); 7286 m = Bits32 (opcode, 3, 0); 7287 7288 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7289 index = BitIsSet (opcode, 24); 7290 add = BitIsSet (opcode, 23); 7291 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7292 7293 // (shift_t, shift_n) = (SRType_LSL, 0); 7294 shift_t = SRType_LSL; 7295 shift_n = 0; 7296 7297 // if t == 15 || m == 15 then UNPREDICTABLE; 7298 if ((t == 15) || (m == 15)) 7299 return false; 7300 7301 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7302 if (wback && ((n == 15) || (n == t))) 7303 return false; 7304 break; 7305 7306 default: 7307 return false; 7308 } 7309 7310 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7311 if (!success) 7312 return false; 7313 7314 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7315 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7316 if (!success) 7317 return false; 7318 7319 addr_t offset_addr; 7320 addr_t address; 7321 7322 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7323 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7324 if (!success) 7325 return false; 7326 7327 if (add) 7328 offset_addr = Rn + offset; 7329 else 7330 offset_addr = Rn - offset; 7331 7332 // address = if index then offset_addr else R[n]; 7333 if (index) 7334 address = offset_addr; 7335 else 7336 address = Rn; 7337 7338 // R[t] = SignExtend(MemU[address,1], 32); 7339 RegisterInfo base_reg; 7340 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7341 RegisterInfo offset_reg; 7342 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7343 7344 EmulateInstruction::Context context; 7345 context.type = eContextRegisterLoad; 7346 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7347 7348 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7349 if (!success) 7350 return false; 7351 7352 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7353 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7354 return false; 7355 7356 // if wback then R[n] = offset_addr; 7357 if (wback) 7358 { 7359 context.type = eContextAdjustBaseRegister; 7360 context.SetAddress (offset_addr); 7361 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7362 return false; 7363 } 7364 } 7365 return true; 7366 } 7367 7368 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7369 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7370 // pre-indexed addressing. 7371 bool 7372 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7373 { 7374 #if 0 7375 if ConditionPassed() then 7376 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7377 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7378 address = if index then offset_addr else R[n]; 7379 data = MemU[address,2]; 7380 if wback then R[n] = offset_addr; 7381 if UnalignedSupport() || address<0> = '0' then 7382 R[t] = SignExtend(data, 32); 7383 else // Can only apply before ARMv7 7384 R[t] = bits(32) UNKNOWN; 7385 #endif 7386 7387 bool success = false; 7388 7389 if (ConditionPassed(opcode)) 7390 { 7391 uint32_t t; 7392 uint32_t n; 7393 uint32_t imm32; 7394 bool index; 7395 bool add; 7396 bool wback; 7397 7398 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7399 switch (encoding) 7400 { 7401 case eEncodingT1: 7402 // if Rn == '1111' then SEE LDRSH (literal); 7403 // if Rt == '1111' then SEE "Unallocated memory hints"; 7404 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7405 t = Bits32 (opcode, 15, 12); 7406 n = Bits32 (opcode, 19, 16); 7407 imm32 = Bits32 (opcode, 11, 0); 7408 7409 // index = TRUE; add = TRUE; wback = FALSE; 7410 index = true; 7411 add = true; 7412 wback = false; 7413 7414 // if t == 13 then UNPREDICTABLE; 7415 if (t == 13) 7416 return false; 7417 7418 break; 7419 7420 case eEncodingT2: 7421 // if Rn == '1111' then SEE LDRSH (literal); 7422 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7423 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7424 // if P == '0' && W == '0' then UNDEFINED; 7425 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7426 return false; 7427 7428 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7429 t = Bits32 (opcode, 15, 12); 7430 n = Bits32 (opcode, 19, 16); 7431 imm32 = Bits32 (opcode, 7, 0); 7432 7433 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7434 index = BitIsSet (opcode, 10); 7435 add = BitIsSet (opcode, 9); 7436 wback = BitIsSet (opcode, 8); 7437 7438 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7439 if (BadReg (t) || (wback && (n == t))) 7440 return false; 7441 7442 break; 7443 7444 case eEncodingA1: 7445 { 7446 // if Rn == '1111' then SEE LDRSH (literal); 7447 // if P == '0' && W == '1' then SEE LDRSHT; 7448 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7449 t = Bits32 (opcode, 15, 12); 7450 n = Bits32 (opcode, 19, 16); 7451 uint32_t imm4H = Bits32 (opcode, 11,8); 7452 uint32_t imm4L = Bits32 (opcode, 3, 0); 7453 imm32 = (imm4H << 4) | imm4L; 7454 7455 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7456 index = BitIsSet (opcode, 24); 7457 add = BitIsSet (opcode, 23); 7458 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7459 7460 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7461 if ((t == 15) || (wback && (n == t))) 7462 return false; 7463 7464 break; 7465 } 7466 7467 default: 7468 return false; 7469 } 7470 7471 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7472 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7473 if (!success) 7474 return false; 7475 7476 addr_t offset_addr; 7477 if (add) 7478 offset_addr = Rn + imm32; 7479 else 7480 offset_addr = Rn - imm32; 7481 7482 // address = if index then offset_addr else R[n]; 7483 addr_t address; 7484 if (index) 7485 address = offset_addr; 7486 else 7487 address = Rn; 7488 7489 // data = MemU[address,2]; 7490 RegisterInfo base_reg; 7491 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7492 7493 EmulateInstruction::Context context; 7494 context.type = eContextRegisterLoad; 7495 context.SetRegisterPlusOffset (base_reg, address - Rn); 7496 7497 uint64_t data = MemURead (context, address, 2, 0, &success); 7498 if (!success) 7499 return false; 7500 7501 // if wback then R[n] = offset_addr; 7502 if (wback) 7503 { 7504 context.type = eContextAdjustBaseRegister; 7505 context.SetAddress (offset_addr); 7506 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7507 return false; 7508 } 7509 7510 // if UnalignedSupport() || address<0> = '0' then 7511 if (UnalignedSupport() || BitIsClear (address, 0)) 7512 { 7513 // R[t] = SignExtend(data, 32); 7514 int64_t signed_data = llvm::SignExtend64<16>(data); 7515 context.type = eContextRegisterLoad; 7516 context.SetRegisterPlusOffset (base_reg, address - Rn); 7517 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7518 return false; 7519 } 7520 else // Can only apply before ARMv7 7521 { 7522 // R[t] = bits(32) UNKNOWN; 7523 WriteBits32Unknown (t); 7524 } 7525 } 7526 return true; 7527 } 7528 7529 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7530 // sign-extends it to from a 32-bit word, and writes it to a register. 7531 bool 7532 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7533 { 7534 #if 0 7535 if ConditionPassed() then 7536 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7537 base = Align(PC,4); 7538 address = if add then (base + imm32) else (base - imm32); 7539 data = MemU[address,2]; 7540 if UnalignedSupport() || address<0> = '0' then 7541 R[t] = SignExtend(data, 32); 7542 else // Can only apply before ARMv7 7543 R[t] = bits(32) UNKNOWN; 7544 #endif 7545 7546 bool success = false; 7547 7548 if (ConditionPassed(opcode)) 7549 { 7550 uint32_t t; 7551 uint32_t imm32; 7552 bool add; 7553 7554 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7555 switch (encoding) 7556 { 7557 case eEncodingT1: 7558 // if Rt == '1111' then SEE "Unallocated memory hints"; 7559 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7560 t = Bits32 (opcode, 15, 12); 7561 imm32 = Bits32 (opcode, 11, 0); 7562 add = BitIsSet (opcode, 23); 7563 7564 // if t == 13 then UNPREDICTABLE; 7565 if (t == 13) 7566 return false; 7567 7568 break; 7569 7570 case eEncodingA1: 7571 { 7572 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7573 t = Bits32 (opcode, 15, 12); 7574 uint32_t imm4H = Bits32 (opcode, 11, 8); 7575 uint32_t imm4L = Bits32 (opcode, 3, 0); 7576 imm32 = (imm4H << 4) | imm4L; 7577 add = BitIsSet (opcode, 23); 7578 7579 // if t == 15 then UNPREDICTABLE; 7580 if (t == 15) 7581 return false; 7582 7583 break; 7584 } 7585 default: 7586 return false; 7587 } 7588 7589 // base = Align(PC,4); 7590 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7591 if (!success) 7592 return false; 7593 7594 uint64_t base = AlignPC (pc_value); 7595 7596 addr_t address; 7597 // address = if add then (base + imm32) else (base - imm32); 7598 if (add) 7599 address = base + imm32; 7600 else 7601 address = base - imm32; 7602 7603 // data = MemU[address,2]; 7604 RegisterInfo base_reg; 7605 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7606 7607 EmulateInstruction::Context context; 7608 context.type = eContextRegisterLoad; 7609 context.SetRegisterPlusOffset (base_reg, imm32); 7610 7611 uint64_t data = MemURead (context, address, 2, 0, &success); 7612 if (!success) 7613 return false; 7614 7615 // if UnalignedSupport() || address<0> = '0' then 7616 if (UnalignedSupport() || BitIsClear (address, 0)) 7617 { 7618 // R[t] = SignExtend(data, 32); 7619 int64_t signed_data = llvm::SignExtend64<16>(data); 7620 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7621 return false; 7622 } 7623 else // Can only apply before ARMv7 7624 { 7625 // R[t] = bits(32) UNKNOWN; 7626 WriteBits32Unknown (t); 7627 } 7628 } 7629 return true; 7630 } 7631 7632 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7633 // from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7634 // shifted left by 0, 1, 2, or 3 bits. 7635 bool 7636 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7637 { 7638 #if 0 7639 if ConditionPassed() then 7640 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7641 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7642 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7643 address = if index then offset_addr else R[n]; 7644 data = MemU[address,2]; 7645 if wback then R[n] = offset_addr; 7646 if UnalignedSupport() || address<0> = '0' then 7647 R[t] = SignExtend(data, 32); 7648 else // Can only apply before ARMv7 7649 R[t] = bits(32) UNKNOWN; 7650 #endif 7651 7652 bool success = false; 7653 7654 if (ConditionPassed(opcode)) 7655 { 7656 uint32_t t; 7657 uint32_t n; 7658 uint32_t m; 7659 bool index; 7660 bool add; 7661 bool wback; 7662 ARM_ShifterType shift_t; 7663 uint32_t shift_n; 7664 7665 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7666 switch (encoding) 7667 { 7668 case eEncodingT1: 7669 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7670 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7671 t = Bits32 (opcode, 2, 0); 7672 n = Bits32 (opcode, 5, 3); 7673 m = Bits32 (opcode, 8, 6); 7674 7675 // index = TRUE; add = TRUE; wback = FALSE; 7676 index = true; 7677 add = true; 7678 wback = false; 7679 7680 // (shift_t, shift_n) = (SRType_LSL, 0); 7681 shift_t = SRType_LSL; 7682 shift_n = 0; 7683 7684 break; 7685 7686 case eEncodingT2: 7687 // if Rn == '1111' then SEE LDRSH (literal); 7688 // if Rt == '1111' then SEE "Unallocated memory hints"; 7689 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7690 t = Bits32 (opcode, 15, 12); 7691 n = Bits32 (opcode, 19, 16); 7692 m = Bits32 (opcode, 3, 0); 7693 7694 // index = TRUE; add = TRUE; wback = FALSE; 7695 index = true; 7696 add = true; 7697 wback = false; 7698 7699 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7700 shift_t = SRType_LSL; 7701 shift_n = Bits32 (opcode, 5, 4); 7702 7703 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7704 if ((t == 13) || BadReg (m)) 7705 return false; 7706 7707 break; 7708 7709 case eEncodingA1: 7710 // if P == '0' && W == '1' then SEE LDRSHT; 7711 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7712 t = Bits32 (opcode, 15, 12); 7713 n = Bits32 (opcode, 19, 16); 7714 m = Bits32 (opcode, 3, 0); 7715 7716 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7717 index = BitIsSet (opcode, 24); 7718 add = BitIsSet (opcode, 23); 7719 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7720 7721 // (shift_t, shift_n) = (SRType_LSL, 0); 7722 shift_t = SRType_LSL; 7723 shift_n = 0; 7724 7725 // if t == 15 || m == 15 then UNPREDICTABLE; 7726 if ((t == 15) || (m == 15)) 7727 return false; 7728 7729 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7730 if (wback && ((n == 15) || (n == t))) 7731 return false; 7732 7733 break; 7734 7735 default: 7736 return false; 7737 } 7738 7739 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7740 if (!success) 7741 return false; 7742 7743 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7744 if (!success) 7745 return false; 7746 7747 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7748 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7749 if (!success) 7750 return false; 7751 7752 addr_t offset_addr; 7753 addr_t address; 7754 7755 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7756 if (add) 7757 offset_addr = Rn + offset; 7758 else 7759 offset_addr = Rn - offset; 7760 7761 // address = if index then offset_addr else R[n]; 7762 if (index) 7763 address = offset_addr; 7764 else 7765 address = Rn; 7766 7767 // data = MemU[address,2]; 7768 RegisterInfo base_reg; 7769 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7770 7771 RegisterInfo offset_reg; 7772 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7773 7774 EmulateInstruction::Context context; 7775 context.type = eContextRegisterLoad; 7776 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7777 7778 uint64_t data = MemURead (context, address, 2, 0, &success); 7779 if (!success) 7780 return false; 7781 7782 // if wback then R[n] = offset_addr; 7783 if (wback) 7784 { 7785 context.type = eContextAdjustBaseRegister; 7786 context.SetAddress (offset_addr); 7787 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7788 return false; 7789 } 7790 7791 // if UnalignedSupport() || address<0> = '0' then 7792 if (UnalignedSupport() || BitIsClear (address, 0)) 7793 { 7794 // R[t] = SignExtend(data, 32); 7795 context.type = eContextRegisterLoad; 7796 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7797 7798 int64_t signed_data = llvm::SignExtend64<16>(data); 7799 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7800 return false; 7801 } 7802 else // Can only apply before ARMv7 7803 { 7804 // R[t] = bits(32) UNKNOWN; 7805 WriteBits32Unknown (t); 7806 } 7807 } 7808 return true; 7809 } 7810 7811 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7812 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7813 bool 7814 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7815 { 7816 #if 0 7817 if ConditionPassed() then 7818 EncodingSpecificOperations(); 7819 rotated = ROR(R[m], rotation); 7820 R[d] = SignExtend(rotated<7:0>, 32); 7821 #endif 7822 7823 bool success = false; 7824 7825 if (ConditionPassed(opcode)) 7826 { 7827 uint32_t d; 7828 uint32_t m; 7829 uint32_t rotation; 7830 7831 // EncodingSpecificOperations(); 7832 switch (encoding) 7833 { 7834 case eEncodingT1: 7835 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7836 d = Bits32 (opcode, 2, 0); 7837 m = Bits32 (opcode, 5, 3); 7838 rotation = 0; 7839 7840 break; 7841 7842 case eEncodingT2: 7843 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7844 d = Bits32 (opcode, 11, 8); 7845 m = Bits32 (opcode, 3, 0); 7846 rotation = Bits32 (opcode, 5, 4) << 3; 7847 7848 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7849 if (BadReg (d) || BadReg (m)) 7850 return false; 7851 7852 break; 7853 7854 case eEncodingA1: 7855 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7856 d = Bits32 (opcode, 15, 12); 7857 m = Bits32 (opcode, 3, 0); 7858 rotation = Bits32 (opcode, 11, 10) << 3; 7859 7860 // if d == 15 || m == 15 then UNPREDICTABLE; 7861 if ((d == 15) || (m == 15)) 7862 return false; 7863 7864 break; 7865 7866 default: 7867 return false; 7868 } 7869 7870 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7871 if (!success) 7872 return false; 7873 7874 // rotated = ROR(R[m], rotation); 7875 uint64_t rotated = ROR (Rm, rotation, &success); 7876 if (!success) 7877 return false; 7878 7879 // R[d] = SignExtend(rotated<7:0>, 32); 7880 int64_t data = llvm::SignExtend64<8>(rotated); 7881 7882 RegisterInfo source_reg; 7883 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7884 7885 EmulateInstruction::Context context; 7886 context.type = eContextRegisterLoad; 7887 context.SetRegister (source_reg); 7888 7889 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7890 return false; 7891 } 7892 return true; 7893 } 7894 7895 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7896 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7897 bool 7898 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7899 { 7900 #if 0 7901 if ConditionPassed() then 7902 EncodingSpecificOperations(); 7903 rotated = ROR(R[m], rotation); 7904 R[d] = SignExtend(rotated<15:0>, 32); 7905 #endif 7906 7907 bool success = false; 7908 7909 if (ConditionPassed(opcode)) 7910 { 7911 uint32_t d; 7912 uint32_t m; 7913 uint32_t rotation; 7914 7915 // EncodingSpecificOperations(); 7916 switch (encoding) 7917 { 7918 case eEncodingT1: 7919 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7920 d = Bits32 (opcode, 2, 0); 7921 m = Bits32 (opcode, 5, 3); 7922 rotation = 0; 7923 7924 break; 7925 7926 case eEncodingT2: 7927 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7928 d = Bits32 (opcode, 11, 8); 7929 m = Bits32 (opcode, 3, 0); 7930 rotation = Bits32 (opcode, 5, 4) << 3; 7931 7932 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7933 if (BadReg (d) || BadReg (m)) 7934 return false; 7935 7936 break; 7937 7938 case eEncodingA1: 7939 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7940 d = Bits32 (opcode, 15, 12); 7941 m = Bits32 (opcode, 3, 0); 7942 rotation = Bits32 (opcode, 11, 10) << 3; 7943 7944 // if d == 15 || m == 15 then UNPREDICTABLE; 7945 if ((d == 15) || (m == 15)) 7946 return false; 7947 7948 break; 7949 7950 default: 7951 return false; 7952 } 7953 7954 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7955 if (!success) 7956 return false; 7957 7958 // rotated = ROR(R[m], rotation); 7959 uint64_t rotated = ROR (Rm, rotation, &success); 7960 if (!success) 7961 return false; 7962 7963 // R[d] = SignExtend(rotated<15:0>, 32); 7964 RegisterInfo source_reg; 7965 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7966 7967 EmulateInstruction::Context context; 7968 context.type = eContextRegisterLoad; 7969 context.SetRegister (source_reg); 7970 7971 int64_t data = llvm::SignExtend64<16> (rotated); 7972 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7973 return false; 7974 } 7975 7976 return true; 7977 } 7978 7979 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 7980 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7981 bool 7982 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 7983 { 7984 #if 0 7985 if ConditionPassed() then 7986 EncodingSpecificOperations(); 7987 rotated = ROR(R[m], rotation); 7988 R[d] = ZeroExtend(rotated<7:0>, 32); 7989 #endif 7990 7991 bool success = false; 7992 7993 if (ConditionPassed(opcode)) 7994 { 7995 uint32_t d; 7996 uint32_t m; 7997 uint32_t rotation; 7998 7999 // EncodingSpecificOperations(); 8000 switch (encoding) 8001 { 8002 case eEncodingT1: 8003 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8004 d = Bits32 (opcode, 2, 0); 8005 m = Bits32 (opcode, 5, 3); 8006 rotation = 0; 8007 8008 break; 8009 8010 case eEncodingT2: 8011 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8012 d = Bits32 (opcode, 11, 8); 8013 m = Bits32 (opcode, 3, 0); 8014 rotation = Bits32 (opcode, 5, 4) << 3; 8015 8016 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8017 if (BadReg (d) || BadReg (m)) 8018 return false; 8019 8020 break; 8021 8022 case eEncodingA1: 8023 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8024 d = Bits32 (opcode, 15, 12); 8025 m = Bits32 (opcode, 3, 0); 8026 rotation = Bits32 (opcode, 11, 10) << 3; 8027 8028 // if d == 15 || m == 15 then UNPREDICTABLE; 8029 if ((d == 15) || (m == 15)) 8030 return false; 8031 8032 break; 8033 8034 default: 8035 return false; 8036 } 8037 8038 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8039 if (!success) 8040 return false; 8041 8042 // rotated = ROR(R[m], rotation); 8043 uint64_t rotated = ROR (Rm, rotation, &success); 8044 if (!success) 8045 return false; 8046 8047 // R[d] = ZeroExtend(rotated<7:0>, 32); 8048 RegisterInfo source_reg; 8049 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8050 8051 EmulateInstruction::Context context; 8052 context.type = eContextRegisterLoad; 8053 context.SetRegister (source_reg); 8054 8055 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 8056 return false; 8057 } 8058 return true; 8059 } 8060 8061 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 8062 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 8063 bool 8064 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 8065 { 8066 #if 0 8067 if ConditionPassed() then 8068 EncodingSpecificOperations(); 8069 rotated = ROR(R[m], rotation); 8070 R[d] = ZeroExtend(rotated<15:0>, 32); 8071 #endif 8072 8073 bool success = false; 8074 8075 if (ConditionPassed(opcode)) 8076 { 8077 uint32_t d; 8078 uint32_t m; 8079 uint32_t rotation; 8080 8081 switch (encoding) 8082 { 8083 case eEncodingT1: 8084 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8085 d = Bits32 (opcode, 2, 0); 8086 m = Bits32 (opcode, 5, 3); 8087 rotation = 0; 8088 8089 break; 8090 8091 case eEncodingT2: 8092 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8093 d = Bits32 (opcode, 11, 8); 8094 m = Bits32 (opcode, 3, 0); 8095 rotation = Bits32 (opcode, 5, 4) << 3; 8096 8097 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8098 if (BadReg (d) || BadReg (m)) 8099 return false; 8100 8101 break; 8102 8103 case eEncodingA1: 8104 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8105 d = Bits32 (opcode, 15, 12); 8106 m = Bits32 (opcode, 3, 0); 8107 rotation = Bits32 (opcode, 11, 10) << 3; 8108 8109 // if d == 15 || m == 15 then UNPREDICTABLE; 8110 if ((d == 15) || (m == 15)) 8111 return false; 8112 8113 break; 8114 8115 default: 8116 return false; 8117 } 8118 8119 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8120 if (!success) 8121 return false; 8122 8123 // rotated = ROR(R[m], rotation); 8124 uint64_t rotated = ROR (Rm, rotation, &success); 8125 if (!success) 8126 return false; 8127 8128 // R[d] = ZeroExtend(rotated<15:0>, 32); 8129 RegisterInfo source_reg; 8130 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8131 8132 EmulateInstruction::Context context; 8133 context.type = eContextRegisterLoad; 8134 context.SetRegister (source_reg); 8135 8136 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8137 return false; 8138 } 8139 return true; 8140 } 8141 8142 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8143 // word respectively. 8144 bool 8145 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8146 { 8147 #if 0 8148 if ConditionPassed() then 8149 EncodingSpecificOperations(); 8150 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8151 UNPREDICTABLE; 8152 else 8153 address = if increment then R[n] else R[n]-8; 8154 if wordhigher then address = address+4; 8155 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8156 BranchWritePC(MemA[address,4]); 8157 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8158 #endif 8159 8160 bool success = false; 8161 8162 if (ConditionPassed(opcode)) 8163 { 8164 uint32_t n; 8165 bool wback; 8166 bool increment; 8167 bool wordhigher; 8168 8169 // EncodingSpecificOperations(); 8170 switch (encoding) 8171 { 8172 case eEncodingT1: 8173 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8174 n = Bits32 (opcode, 19, 16); 8175 wback = BitIsSet (opcode, 21); 8176 increment = false; 8177 wordhigher = false; 8178 8179 // if n == 15 then UNPREDICTABLE; 8180 if (n == 15) 8181 return false; 8182 8183 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8184 if (InITBlock() && !LastInITBlock()) 8185 return false; 8186 8187 break; 8188 8189 case eEncodingT2: 8190 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8191 n = Bits32 (opcode, 19, 16); 8192 wback = BitIsSet (opcode, 21); 8193 increment = true; 8194 wordhigher = false; 8195 8196 // if n == 15 then UNPREDICTABLE; 8197 if (n == 15) 8198 return false; 8199 8200 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8201 if (InITBlock() && !LastInITBlock()) 8202 return false; 8203 8204 break; 8205 8206 case eEncodingA1: 8207 // n = UInt(Rn); 8208 n = Bits32 (opcode, 19, 16); 8209 8210 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8211 wback = BitIsSet (opcode, 21); 8212 increment = BitIsSet (opcode, 23); 8213 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8214 8215 // if n == 15 then UNPREDICTABLE; 8216 if (n == 15) 8217 return false; 8218 8219 break; 8220 8221 default: 8222 return false; 8223 } 8224 8225 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8226 if (!CurrentModeIsPrivileged ()) 8227 // UNPREDICTABLE; 8228 return false; 8229 else 8230 { 8231 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8232 if (!success) 8233 return false; 8234 8235 addr_t address; 8236 // address = if increment then R[n] else R[n]-8; 8237 if (increment) 8238 address = Rn; 8239 else 8240 address = Rn - 8; 8241 8242 // if wordhigher then address = address+4; 8243 if (wordhigher) 8244 address = address + 4; 8245 8246 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8247 RegisterInfo base_reg; 8248 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8249 8250 EmulateInstruction::Context context; 8251 context.type = eContextReturnFromException; 8252 context.SetRegisterPlusOffset (base_reg, address - Rn); 8253 8254 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8255 if (!success) 8256 return false; 8257 8258 CPSRWriteByInstr (data, 15, true); 8259 8260 // BranchWritePC(MemA[address,4]); 8261 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8262 if (!success) 8263 return false; 8264 8265 BranchWritePC (context, data2); 8266 8267 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8268 if (wback) 8269 { 8270 context.type = eContextAdjustBaseRegister; 8271 if (increment) 8272 { 8273 context.SetOffset (8); 8274 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8275 return false; 8276 } 8277 else 8278 { 8279 context.SetOffset (-8); 8280 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8281 return false; 8282 } 8283 } // if wback 8284 } 8285 } // if ConditionPassed() 8286 return true; 8287 } 8288 8289 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8290 // and writes the result to the destination register. It can optionally update the condition flags based on 8291 // the result. 8292 bool 8293 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8294 { 8295 #if 0 8296 // ARM pseudo code... 8297 if ConditionPassed() then 8298 EncodingSpecificOperations(); 8299 result = R[n] EOR imm32; 8300 if d == 15 then // Can only occur for ARM encoding 8301 ALUWritePC(result); // setflags is always FALSE here 8302 else 8303 R[d] = result; 8304 if setflags then 8305 APSR.N = result<31>; 8306 APSR.Z = IsZeroBit(result); 8307 APSR.C = carry; 8308 // APSR.V unchanged 8309 #endif 8310 8311 bool success = false; 8312 8313 if (ConditionPassed(opcode)) 8314 { 8315 uint32_t Rd, Rn; 8316 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8317 bool setflags; 8318 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8319 switch (encoding) 8320 { 8321 case eEncodingT1: 8322 Rd = Bits32(opcode, 11, 8); 8323 Rn = Bits32(opcode, 19, 16); 8324 setflags = BitIsSet(opcode, 20); 8325 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8326 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8327 if (Rd == 15 && setflags) 8328 return EmulateTEQImm (opcode, eEncodingT1); 8329 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8330 return false; 8331 break; 8332 case eEncodingA1: 8333 Rd = Bits32(opcode, 15, 12); 8334 Rn = Bits32(opcode, 19, 16); 8335 setflags = BitIsSet(opcode, 20); 8336 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8337 8338 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8339 if (Rd == 15 && setflags) 8340 return EmulateSUBSPcLrEtc (opcode, encoding); 8341 break; 8342 default: 8343 return false; 8344 } 8345 8346 // Read the first operand. 8347 uint32_t val1 = ReadCoreReg(Rn, &success); 8348 if (!success) 8349 return false; 8350 8351 uint32_t result = val1 ^ imm32; 8352 8353 EmulateInstruction::Context context; 8354 context.type = EmulateInstruction::eContextImmediate; 8355 context.SetNoArgs (); 8356 8357 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8358 return false; 8359 } 8360 return true; 8361 } 8362 8363 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8364 // optionally-shifted register value, and writes the result to the destination register. 8365 // It can optionally update the condition flags based on the result. 8366 bool 8367 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8368 { 8369 #if 0 8370 // ARM pseudo code... 8371 if ConditionPassed() then 8372 EncodingSpecificOperations(); 8373 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8374 result = R[n] EOR shifted; 8375 if d == 15 then // Can only occur for ARM encoding 8376 ALUWritePC(result); // setflags is always FALSE here 8377 else 8378 R[d] = result; 8379 if setflags then 8380 APSR.N = result<31>; 8381 APSR.Z = IsZeroBit(result); 8382 APSR.C = carry; 8383 // APSR.V unchanged 8384 #endif 8385 8386 bool success = false; 8387 8388 if (ConditionPassed(opcode)) 8389 { 8390 uint32_t Rd, Rn, Rm; 8391 ARM_ShifterType shift_t; 8392 uint32_t shift_n; // the shift applied to the value read from Rm 8393 bool setflags; 8394 uint32_t carry; 8395 switch (encoding) 8396 { 8397 case eEncodingT1: 8398 Rd = Rn = Bits32(opcode, 2, 0); 8399 Rm = Bits32(opcode, 5, 3); 8400 setflags = !InITBlock(); 8401 shift_t = SRType_LSL; 8402 shift_n = 0; 8403 break; 8404 case eEncodingT2: 8405 Rd = Bits32(opcode, 11, 8); 8406 Rn = Bits32(opcode, 19, 16); 8407 Rm = Bits32(opcode, 3, 0); 8408 setflags = BitIsSet(opcode, 20); 8409 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8410 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8411 if (Rd == 15 && setflags) 8412 return EmulateTEQReg (opcode, eEncodingT1); 8413 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8414 return false; 8415 break; 8416 case eEncodingA1: 8417 Rd = Bits32(opcode, 15, 12); 8418 Rn = Bits32(opcode, 19, 16); 8419 Rm = Bits32(opcode, 3, 0); 8420 setflags = BitIsSet(opcode, 20); 8421 shift_n = DecodeImmShiftARM(opcode, shift_t); 8422 8423 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8424 if (Rd == 15 && setflags) 8425 return EmulateSUBSPcLrEtc (opcode, encoding); 8426 break; 8427 default: 8428 return false; 8429 } 8430 8431 // Read the first operand. 8432 uint32_t val1 = ReadCoreReg(Rn, &success); 8433 if (!success) 8434 return false; 8435 8436 // Read the second operand. 8437 uint32_t val2 = ReadCoreReg(Rm, &success); 8438 if (!success) 8439 return false; 8440 8441 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8442 if (!success) 8443 return false; 8444 uint32_t result = val1 ^ shifted; 8445 8446 EmulateInstruction::Context context; 8447 context.type = EmulateInstruction::eContextImmediate; 8448 context.SetNoArgs (); 8449 8450 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8451 return false; 8452 } 8453 return true; 8454 } 8455 8456 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8457 // writes the result to the destination register. It can optionally update the condition flags based 8458 // on the result. 8459 bool 8460 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8461 { 8462 #if 0 8463 // ARM pseudo code... 8464 if ConditionPassed() then 8465 EncodingSpecificOperations(); 8466 result = R[n] OR imm32; 8467 if d == 15 then // Can only occur for ARM encoding 8468 ALUWritePC(result); // setflags is always FALSE here 8469 else 8470 R[d] = result; 8471 if setflags then 8472 APSR.N = result<31>; 8473 APSR.Z = IsZeroBit(result); 8474 APSR.C = carry; 8475 // APSR.V unchanged 8476 #endif 8477 8478 bool success = false; 8479 8480 if (ConditionPassed(opcode)) 8481 { 8482 uint32_t Rd, Rn; 8483 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8484 bool setflags; 8485 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8486 switch (encoding) 8487 { 8488 case eEncodingT1: 8489 Rd = Bits32(opcode, 11, 8); 8490 Rn = Bits32(opcode, 19, 16); 8491 setflags = BitIsSet(opcode, 20); 8492 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8493 // if Rn == '1111' then SEE MOV (immediate); 8494 if (Rn == 15) 8495 return EmulateMOVRdImm (opcode, eEncodingT2); 8496 if (BadReg(Rd) || Rn == 13) 8497 return false; 8498 break; 8499 case eEncodingA1: 8500 Rd = Bits32(opcode, 15, 12); 8501 Rn = Bits32(opcode, 19, 16); 8502 setflags = BitIsSet(opcode, 20); 8503 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8504 8505 if (Rd == 15 && setflags) 8506 return EmulateSUBSPcLrEtc (opcode, encoding); 8507 break; 8508 default: 8509 return false; 8510 } 8511 8512 // Read the first operand. 8513 uint32_t val1 = ReadCoreReg(Rn, &success); 8514 if (!success) 8515 return false; 8516 8517 uint32_t result = val1 | imm32; 8518 8519 EmulateInstruction::Context context; 8520 context.type = EmulateInstruction::eContextImmediate; 8521 context.SetNoArgs (); 8522 8523 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8524 return false; 8525 } 8526 return true; 8527 } 8528 8529 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8530 // value, and writes the result to the destination register. It can optionally update the condition flags based 8531 // on the result. 8532 bool 8533 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8534 { 8535 #if 0 8536 // ARM pseudo code... 8537 if ConditionPassed() then 8538 EncodingSpecificOperations(); 8539 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8540 result = R[n] OR shifted; 8541 if d == 15 then // Can only occur for ARM encoding 8542 ALUWritePC(result); // setflags is always FALSE here 8543 else 8544 R[d] = result; 8545 if setflags then 8546 APSR.N = result<31>; 8547 APSR.Z = IsZeroBit(result); 8548 APSR.C = carry; 8549 // APSR.V unchanged 8550 #endif 8551 8552 bool success = false; 8553 8554 if (ConditionPassed(opcode)) 8555 { 8556 uint32_t Rd, Rn, Rm; 8557 ARM_ShifterType shift_t; 8558 uint32_t shift_n; // the shift applied to the value read from Rm 8559 bool setflags; 8560 uint32_t carry; 8561 switch (encoding) 8562 { 8563 case eEncodingT1: 8564 Rd = Rn = Bits32(opcode, 2, 0); 8565 Rm = Bits32(opcode, 5, 3); 8566 setflags = !InITBlock(); 8567 shift_t = SRType_LSL; 8568 shift_n = 0; 8569 break; 8570 case eEncodingT2: 8571 Rd = Bits32(opcode, 11, 8); 8572 Rn = Bits32(opcode, 19, 16); 8573 Rm = Bits32(opcode, 3, 0); 8574 setflags = BitIsSet(opcode, 20); 8575 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8576 // if Rn == '1111' then SEE MOV (register); 8577 if (Rn == 15) 8578 return EmulateMOVRdRm (opcode, eEncodingT3); 8579 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8580 return false; 8581 break; 8582 case eEncodingA1: 8583 Rd = Bits32(opcode, 15, 12); 8584 Rn = Bits32(opcode, 19, 16); 8585 Rm = Bits32(opcode, 3, 0); 8586 setflags = BitIsSet(opcode, 20); 8587 shift_n = DecodeImmShiftARM(opcode, shift_t); 8588 8589 if (Rd == 15 && setflags) 8590 return EmulateSUBSPcLrEtc (opcode, encoding); 8591 break; 8592 default: 8593 return false; 8594 } 8595 8596 // Read the first operand. 8597 uint32_t val1 = ReadCoreReg(Rn, &success); 8598 if (!success) 8599 return false; 8600 8601 // Read the second operand. 8602 uint32_t val2 = ReadCoreReg(Rm, &success); 8603 if (!success) 8604 return false; 8605 8606 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8607 if (!success) 8608 return false; 8609 uint32_t result = val1 | shifted; 8610 8611 EmulateInstruction::Context context; 8612 context.type = EmulateInstruction::eContextImmediate; 8613 context.SetNoArgs (); 8614 8615 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8616 return false; 8617 } 8618 return true; 8619 } 8620 8621 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8622 // the destination register. It can optionally update the condition flags based on the result. 8623 bool 8624 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8625 { 8626 #if 0 8627 // ARM pseudo code... 8628 if ConditionPassed() then 8629 EncodingSpecificOperations(); 8630 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8631 if d == 15 then // Can only occur for ARM encoding 8632 ALUWritePC(result); // setflags is always FALSE here 8633 else 8634 R[d] = result; 8635 if setflags then 8636 APSR.N = result<31>; 8637 APSR.Z = IsZeroBit(result); 8638 APSR.C = carry; 8639 APSR.V = overflow; 8640 #endif 8641 8642 bool success = false; 8643 8644 uint32_t Rd; // the destination register 8645 uint32_t Rn; // the first operand 8646 bool setflags; 8647 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8648 switch (encoding) { 8649 case eEncodingT1: 8650 Rd = Bits32(opcode, 2, 0); 8651 Rn = Bits32(opcode, 5, 3); 8652 setflags = !InITBlock(); 8653 imm32 = 0; 8654 break; 8655 case eEncodingT2: 8656 Rd = Bits32(opcode, 11, 8); 8657 Rn = Bits32(opcode, 19, 16); 8658 setflags = BitIsSet(opcode, 20); 8659 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8660 if (BadReg(Rd) || BadReg(Rn)) 8661 return false; 8662 break; 8663 case eEncodingA1: 8664 Rd = Bits32(opcode, 15, 12); 8665 Rn = Bits32(opcode, 19, 16); 8666 setflags = BitIsSet(opcode, 20); 8667 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8668 8669 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8670 if (Rd == 15 && setflags) 8671 return EmulateSUBSPcLrEtc (opcode, encoding); 8672 break; 8673 default: 8674 return false; 8675 } 8676 // Read the register value from the operand register Rn. 8677 uint32_t reg_val = ReadCoreReg(Rn, &success); 8678 if (!success) 8679 return false; 8680 8681 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8682 8683 EmulateInstruction::Context context; 8684 context.type = EmulateInstruction::eContextImmediate; 8685 context.SetNoArgs (); 8686 8687 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8688 return false; 8689 8690 return true; 8691 } 8692 8693 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8694 // result to the destination register. It can optionally update the condition flags based on the result. 8695 bool 8696 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8697 { 8698 #if 0 8699 // ARM pseudo code... 8700 if ConditionPassed() then 8701 EncodingSpecificOperations(); 8702 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8703 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8704 if d == 15 then // Can only occur for ARM encoding 8705 ALUWritePC(result); // setflags is always FALSE here 8706 else 8707 R[d] = result; 8708 if setflags then 8709 APSR.N = result<31>; 8710 APSR.Z = IsZeroBit(result); 8711 APSR.C = carry; 8712 APSR.V = overflow; 8713 #endif 8714 8715 bool success = false; 8716 8717 uint32_t Rd; // the destination register 8718 uint32_t Rn; // the first operand 8719 uint32_t Rm; // the second operand 8720 bool setflags; 8721 ARM_ShifterType shift_t; 8722 uint32_t shift_n; // the shift applied to the value read from Rm 8723 switch (encoding) { 8724 case eEncodingT1: 8725 Rd = Bits32(opcode, 11, 8); 8726 Rn = Bits32(opcode, 19, 16); 8727 Rm = Bits32(opcode, 3, 0); 8728 setflags = BitIsSet(opcode, 20); 8729 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8730 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8731 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8732 return false; 8733 break; 8734 case eEncodingA1: 8735 Rd = Bits32(opcode, 15, 12); 8736 Rn = Bits32(opcode, 19, 16); 8737 Rm = Bits32(opcode, 3, 0); 8738 setflags = BitIsSet(opcode, 20); 8739 shift_n = DecodeImmShiftARM(opcode, shift_t); 8740 8741 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8742 if (Rd == 15 && setflags) 8743 return EmulateSUBSPcLrEtc (opcode, encoding); 8744 break; 8745 default: 8746 return false; 8747 } 8748 // Read the register value from register Rn. 8749 uint32_t val1 = ReadCoreReg(Rn, &success); 8750 if (!success) 8751 return false; 8752 8753 // Read the register value from register Rm. 8754 uint32_t val2 = ReadCoreReg(Rm, &success); 8755 if (!success) 8756 return false; 8757 8758 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8759 if (!success) 8760 return false; 8761 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8762 8763 EmulateInstruction::Context context; 8764 context.type = EmulateInstruction::eContextImmediate; 8765 context.SetNoArgs(); 8766 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8767 return false; 8768 8769 return true; 8770 } 8771 8772 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8773 // an immediate value, and writes the result to the destination register. It can optionally update the condition 8774 // flags based on the result. 8775 bool 8776 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8777 { 8778 #if 0 8779 // ARM pseudo code... 8780 if ConditionPassed() then 8781 EncodingSpecificOperations(); 8782 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8783 if d == 15 then 8784 ALUWritePC(result); // setflags is always FALSE here 8785 else 8786 R[d] = result; 8787 if setflags then 8788 APSR.N = result<31>; 8789 APSR.Z = IsZeroBit(result); 8790 APSR.C = carry; 8791 APSR.V = overflow; 8792 #endif 8793 8794 bool success = false; 8795 8796 uint32_t Rd; // the destination register 8797 uint32_t Rn; // the first operand 8798 bool setflags; 8799 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8800 switch (encoding) { 8801 case eEncodingA1: 8802 Rd = Bits32(opcode, 15, 12); 8803 Rn = Bits32(opcode, 19, 16); 8804 setflags = BitIsSet(opcode, 20); 8805 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8806 8807 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8808 if (Rd == 15 && setflags) 8809 return EmulateSUBSPcLrEtc (opcode, encoding); 8810 break; 8811 default: 8812 return false; 8813 } 8814 // Read the register value from the operand register Rn. 8815 uint32_t reg_val = ReadCoreReg(Rn, &success); 8816 if (!success) 8817 return false; 8818 8819 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8820 8821 EmulateInstruction::Context context; 8822 context.type = EmulateInstruction::eContextImmediate; 8823 context.SetNoArgs (); 8824 8825 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8826 return false; 8827 8828 return true; 8829 } 8830 8831 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8832 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8833 // condition flags based on the result. 8834 bool 8835 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8836 { 8837 #if 0 8838 // ARM pseudo code... 8839 if ConditionPassed() then 8840 EncodingSpecificOperations(); 8841 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8842 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8843 if d == 15 then 8844 ALUWritePC(result); // setflags is always FALSE here 8845 else 8846 R[d] = result; 8847 if setflags then 8848 APSR.N = result<31>; 8849 APSR.Z = IsZeroBit(result); 8850 APSR.C = carry; 8851 APSR.V = overflow; 8852 #endif 8853 8854 bool success = false; 8855 8856 uint32_t Rd; // the destination register 8857 uint32_t Rn; // the first operand 8858 uint32_t Rm; // the second operand 8859 bool setflags; 8860 ARM_ShifterType shift_t; 8861 uint32_t shift_n; // the shift applied to the value read from Rm 8862 switch (encoding) { 8863 case eEncodingA1: 8864 Rd = Bits32(opcode, 15, 12); 8865 Rn = Bits32(opcode, 19, 16); 8866 Rm = Bits32(opcode, 3, 0); 8867 setflags = BitIsSet(opcode, 20); 8868 shift_n = DecodeImmShiftARM(opcode, shift_t); 8869 8870 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8871 if (Rd == 15 && setflags) 8872 return EmulateSUBSPcLrEtc (opcode, encoding); 8873 break; 8874 default: 8875 return false; 8876 } 8877 // Read the register value from register Rn. 8878 uint32_t val1 = ReadCoreReg(Rn, &success); 8879 if (!success) 8880 return false; 8881 8882 // Read the register value from register Rm. 8883 uint32_t val2 = ReadCoreReg(Rm, &success); 8884 if (!success) 8885 return false; 8886 8887 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8888 if (!success) 8889 return false; 8890 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8891 8892 EmulateInstruction::Context context; 8893 context.type = EmulateInstruction::eContextImmediate; 8894 context.SetNoArgs(); 8895 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8896 return false; 8897 8898 return true; 8899 } 8900 8901 // Subtract with Carry (immediate) subtracts an immediate value and the value of 8902 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8903 // It can optionally update the condition flags based on the result. 8904 bool 8905 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8906 { 8907 #if 0 8908 // ARM pseudo code... 8909 if ConditionPassed() then 8910 EncodingSpecificOperations(); 8911 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8912 if d == 15 then // Can only occur for ARM encoding 8913 ALUWritePC(result); // setflags is always FALSE here 8914 else 8915 R[d] = result; 8916 if setflags then 8917 APSR.N = result<31>; 8918 APSR.Z = IsZeroBit(result); 8919 APSR.C = carry; 8920 APSR.V = overflow; 8921 #endif 8922 8923 bool success = false; 8924 8925 uint32_t Rd; // the destination register 8926 uint32_t Rn; // the first operand 8927 bool setflags; 8928 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8929 switch (encoding) { 8930 case eEncodingT1: 8931 Rd = Bits32(opcode, 11, 8); 8932 Rn = Bits32(opcode, 19, 16); 8933 setflags = BitIsSet(opcode, 20); 8934 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8935 if (BadReg(Rd) || BadReg(Rn)) 8936 return false; 8937 break; 8938 case eEncodingA1: 8939 Rd = Bits32(opcode, 15, 12); 8940 Rn = Bits32(opcode, 19, 16); 8941 setflags = BitIsSet(opcode, 20); 8942 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8943 8944 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8945 if (Rd == 15 && setflags) 8946 return EmulateSUBSPcLrEtc (opcode, encoding); 8947 break; 8948 default: 8949 return false; 8950 } 8951 // Read the register value from the operand register Rn. 8952 uint32_t reg_val = ReadCoreReg(Rn, &success); 8953 if (!success) 8954 return false; 8955 8956 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 8957 8958 EmulateInstruction::Context context; 8959 context.type = EmulateInstruction::eContextImmediate; 8960 context.SetNoArgs (); 8961 8962 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8963 return false; 8964 8965 return true; 8966 } 8967 8968 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 8969 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8970 // It can optionally update the condition flags based on the result. 8971 bool 8972 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 8973 { 8974 #if 0 8975 // ARM pseudo code... 8976 if ConditionPassed() then 8977 EncodingSpecificOperations(); 8978 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8979 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 8980 if d == 15 then // Can only occur for ARM encoding 8981 ALUWritePC(result); // setflags is always FALSE here 8982 else 8983 R[d] = result; 8984 if setflags then 8985 APSR.N = result<31>; 8986 APSR.Z = IsZeroBit(result); 8987 APSR.C = carry; 8988 APSR.V = overflow; 8989 #endif 8990 8991 bool success = false; 8992 8993 uint32_t Rd; // the destination register 8994 uint32_t Rn; // the first operand 8995 uint32_t Rm; // the second operand 8996 bool setflags; 8997 ARM_ShifterType shift_t; 8998 uint32_t shift_n; // the shift applied to the value read from Rm 8999 switch (encoding) { 9000 case eEncodingT1: 9001 Rd = Rn = Bits32(opcode, 2, 0); 9002 Rm = Bits32(opcode, 5, 3); 9003 setflags = !InITBlock(); 9004 shift_t = SRType_LSL; 9005 shift_n = 0; 9006 break; 9007 case eEncodingT2: 9008 Rd = Bits32(opcode, 11, 8); 9009 Rn = Bits32(opcode, 19, 16); 9010 Rm = Bits32(opcode, 3, 0); 9011 setflags = BitIsSet(opcode, 20); 9012 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9013 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9014 return false; 9015 break; 9016 case eEncodingA1: 9017 Rd = Bits32(opcode, 15, 12); 9018 Rn = Bits32(opcode, 19, 16); 9019 Rm = Bits32(opcode, 3, 0); 9020 setflags = BitIsSet(opcode, 20); 9021 shift_n = DecodeImmShiftARM(opcode, shift_t); 9022 9023 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9024 if (Rd == 15 && setflags) 9025 return EmulateSUBSPcLrEtc (opcode, encoding); 9026 break; 9027 default: 9028 return false; 9029 } 9030 // Read the register value from register Rn. 9031 uint32_t val1 = ReadCoreReg(Rn, &success); 9032 if (!success) 9033 return false; 9034 9035 // Read the register value from register Rm. 9036 uint32_t val2 = ReadCoreReg(Rm, &success); 9037 if (!success) 9038 return false; 9039 9040 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9041 if (!success) 9042 return false; 9043 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9044 9045 EmulateInstruction::Context context; 9046 context.type = EmulateInstruction::eContextImmediate; 9047 context.SetNoArgs(); 9048 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9049 return false; 9050 9051 return true; 9052 } 9053 9054 // This instruction subtracts an immediate value from a register value, and writes the result 9055 // to the destination register. It can optionally update the condition flags based on the result. 9056 bool 9057 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9058 { 9059 #if 0 9060 // ARM pseudo code... 9061 if ConditionPassed() then 9062 EncodingSpecificOperations(); 9063 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9064 R[d] = result; 9065 if setflags then 9066 APSR.N = result<31>; 9067 APSR.Z = IsZeroBit(result); 9068 APSR.C = carry; 9069 APSR.V = overflow; 9070 #endif 9071 9072 bool success = false; 9073 9074 uint32_t Rd; // the destination register 9075 uint32_t Rn; // the first operand 9076 bool setflags; 9077 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9078 switch (encoding) { 9079 case eEncodingT1: 9080 Rd = Bits32(opcode, 2, 0); 9081 Rn = Bits32(opcode, 5, 3); 9082 setflags = !InITBlock(); 9083 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9084 break; 9085 case eEncodingT2: 9086 Rd = Rn = Bits32(opcode, 10, 8); 9087 setflags = !InITBlock(); 9088 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9089 break; 9090 case eEncodingT3: 9091 Rd = Bits32(opcode, 11, 8); 9092 Rn = Bits32(opcode, 19, 16); 9093 setflags = BitIsSet(opcode, 20); 9094 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9095 9096 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9097 if (Rd == 15 && setflags) 9098 return EmulateCMPImm (opcode, eEncodingT2); 9099 9100 // if Rn == '1101' then SEE SUB (SP minus immediate); 9101 if (Rn == 13) 9102 return EmulateSUBSPImm (opcode, eEncodingT2); 9103 9104 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9105 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9106 return false; 9107 break; 9108 case eEncodingT4: 9109 Rd = Bits32(opcode, 11, 8); 9110 Rn = Bits32(opcode, 19, 16); 9111 setflags = BitIsSet(opcode, 20); 9112 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9113 9114 // if Rn == '1111' then SEE ADR; 9115 if (Rn == 15) 9116 return EmulateADR (opcode, eEncodingT2); 9117 9118 // if Rn == '1101' then SEE SUB (SP minus immediate); 9119 if (Rn == 13) 9120 return EmulateSUBSPImm (opcode, eEncodingT3); 9121 9122 if (BadReg(Rd)) 9123 return false; 9124 break; 9125 default: 9126 return false; 9127 } 9128 // Read the register value from the operand register Rn. 9129 uint32_t reg_val = ReadCoreReg(Rn, &success); 9130 if (!success) 9131 return false; 9132 9133 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9134 9135 EmulateInstruction::Context context; 9136 context.type = EmulateInstruction::eContextImmediate; 9137 context.SetNoArgs (); 9138 9139 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9140 return false; 9141 9142 return true; 9143 } 9144 9145 // This instruction subtracts an immediate value from a register value, and writes the result 9146 // to the destination register. It can optionally update the condition flags based on the result. 9147 bool 9148 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9149 { 9150 #if 0 9151 // ARM pseudo code... 9152 if ConditionPassed() then 9153 EncodingSpecificOperations(); 9154 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9155 if d == 15 then 9156 ALUWritePC(result); // setflags is always FALSE here 9157 else 9158 R[d] = result; 9159 if setflags then 9160 APSR.N = result<31>; 9161 APSR.Z = IsZeroBit(result); 9162 APSR.C = carry; 9163 APSR.V = overflow; 9164 #endif 9165 9166 bool success = false; 9167 9168 uint32_t Rd; // the destination register 9169 uint32_t Rn; // the first operand 9170 bool setflags; 9171 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9172 switch (encoding) { 9173 case eEncodingA1: 9174 Rd = Bits32(opcode, 15, 12); 9175 Rn = Bits32(opcode, 19, 16); 9176 setflags = BitIsSet(opcode, 20); 9177 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9178 9179 // if Rn == '1111' && S == '0' then SEE ADR; 9180 if (Rn == 15 && !setflags) 9181 return EmulateADR (opcode, eEncodingA2); 9182 9183 // if Rn == '1101' then SEE SUB (SP minus immediate); 9184 if (Rn == 13) 9185 return EmulateSUBSPImm (opcode, eEncodingA1); 9186 9187 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9188 if (Rd == 15 && setflags) 9189 return EmulateSUBSPcLrEtc (opcode, encoding); 9190 break; 9191 default: 9192 return false; 9193 } 9194 // Read the register value from the operand register Rn. 9195 uint32_t reg_val = ReadCoreReg(Rn, &success); 9196 if (!success) 9197 return false; 9198 9199 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9200 9201 EmulateInstruction::Context context; 9202 context.type = EmulateInstruction::eContextImmediate; 9203 context.SetNoArgs (); 9204 9205 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9206 return false; 9207 9208 return true; 9209 } 9210 9211 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9212 // immediate value. It updates the condition flags based on the result, and discards the result. 9213 bool 9214 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9215 { 9216 #if 0 9217 // ARM pseudo code... 9218 if ConditionPassed() then 9219 EncodingSpecificOperations(); 9220 result = R[n] EOR imm32; 9221 APSR.N = result<31>; 9222 APSR.Z = IsZeroBit(result); 9223 APSR.C = carry; 9224 // APSR.V unchanged 9225 #endif 9226 9227 bool success = false; 9228 9229 if (ConditionPassed(opcode)) 9230 { 9231 uint32_t Rn; 9232 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9233 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9234 switch (encoding) 9235 { 9236 case eEncodingT1: 9237 Rn = Bits32(opcode, 19, 16); 9238 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9239 if (BadReg(Rn)) 9240 return false; 9241 break; 9242 case eEncodingA1: 9243 Rn = Bits32(opcode, 19, 16); 9244 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9245 break; 9246 default: 9247 return false; 9248 } 9249 9250 // Read the first operand. 9251 uint32_t val1 = ReadCoreReg(Rn, &success); 9252 if (!success) 9253 return false; 9254 9255 uint32_t result = val1 ^ imm32; 9256 9257 EmulateInstruction::Context context; 9258 context.type = EmulateInstruction::eContextImmediate; 9259 context.SetNoArgs (); 9260 9261 if (!WriteFlags(context, result, carry)) 9262 return false; 9263 } 9264 return true; 9265 } 9266 9267 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9268 // optionally-shifted register value. It updates the condition flags based on the result, and discards 9269 // the result. 9270 bool 9271 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9272 { 9273 #if 0 9274 // ARM pseudo code... 9275 if ConditionPassed() then 9276 EncodingSpecificOperations(); 9277 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9278 result = R[n] EOR shifted; 9279 APSR.N = result<31>; 9280 APSR.Z = IsZeroBit(result); 9281 APSR.C = carry; 9282 // APSR.V unchanged 9283 #endif 9284 9285 bool success = false; 9286 9287 if (ConditionPassed(opcode)) 9288 { 9289 uint32_t Rn, Rm; 9290 ARM_ShifterType shift_t; 9291 uint32_t shift_n; // the shift applied to the value read from Rm 9292 uint32_t carry; 9293 switch (encoding) 9294 { 9295 case eEncodingT1: 9296 Rn = Bits32(opcode, 19, 16); 9297 Rm = Bits32(opcode, 3, 0); 9298 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9299 if (BadReg(Rn) || BadReg(Rm)) 9300 return false; 9301 break; 9302 case eEncodingA1: 9303 Rn = Bits32(opcode, 19, 16); 9304 Rm = Bits32(opcode, 3, 0); 9305 shift_n = DecodeImmShiftARM(opcode, shift_t); 9306 break; 9307 default: 9308 return false; 9309 } 9310 9311 // Read the first operand. 9312 uint32_t val1 = ReadCoreReg(Rn, &success); 9313 if (!success) 9314 return false; 9315 9316 // Read the second operand. 9317 uint32_t val2 = ReadCoreReg(Rm, &success); 9318 if (!success) 9319 return false; 9320 9321 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9322 if (!success) 9323 return false; 9324 uint32_t result = val1 ^ shifted; 9325 9326 EmulateInstruction::Context context; 9327 context.type = EmulateInstruction::eContextImmediate; 9328 context.SetNoArgs (); 9329 9330 if (!WriteFlags(context, result, carry)) 9331 return false; 9332 } 9333 return true; 9334 } 9335 9336 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9337 // It updates the condition flags based on the result, and discards the result. 9338 bool 9339 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9340 { 9341 #if 0 9342 // ARM pseudo code... 9343 if ConditionPassed() then 9344 EncodingSpecificOperations(); 9345 result = R[n] AND imm32; 9346 APSR.N = result<31>; 9347 APSR.Z = IsZeroBit(result); 9348 APSR.C = carry; 9349 // APSR.V unchanged 9350 #endif 9351 9352 bool success = false; 9353 9354 if (ConditionPassed(opcode)) 9355 { 9356 uint32_t Rn; 9357 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9358 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9359 switch (encoding) 9360 { 9361 case eEncodingT1: 9362 Rn = Bits32(opcode, 19, 16); 9363 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9364 if (BadReg(Rn)) 9365 return false; 9366 break; 9367 case eEncodingA1: 9368 Rn = Bits32(opcode, 19, 16); 9369 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9370 break; 9371 default: 9372 return false; 9373 } 9374 9375 // Read the first operand. 9376 uint32_t val1 = ReadCoreReg(Rn, &success); 9377 if (!success) 9378 return false; 9379 9380 uint32_t result = val1 & imm32; 9381 9382 EmulateInstruction::Context context; 9383 context.type = EmulateInstruction::eContextImmediate; 9384 context.SetNoArgs (); 9385 9386 if (!WriteFlags(context, result, carry)) 9387 return false; 9388 } 9389 return true; 9390 } 9391 9392 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9393 // It updates the condition flags based on the result, and discards the result. 9394 bool 9395 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9396 { 9397 #if 0 9398 // ARM pseudo code... 9399 if ConditionPassed() then 9400 EncodingSpecificOperations(); 9401 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9402 result = R[n] AND shifted; 9403 APSR.N = result<31>; 9404 APSR.Z = IsZeroBit(result); 9405 APSR.C = carry; 9406 // APSR.V unchanged 9407 #endif 9408 9409 bool success = false; 9410 9411 if (ConditionPassed(opcode)) 9412 { 9413 uint32_t Rn, Rm; 9414 ARM_ShifterType shift_t; 9415 uint32_t shift_n; // the shift applied to the value read from Rm 9416 uint32_t carry; 9417 switch (encoding) 9418 { 9419 case eEncodingT1: 9420 Rn = Bits32(opcode, 2, 0); 9421 Rm = Bits32(opcode, 5, 3); 9422 shift_t = SRType_LSL; 9423 shift_n = 0; 9424 break; 9425 case eEncodingT2: 9426 Rn = Bits32(opcode, 19, 16); 9427 Rm = Bits32(opcode, 3, 0); 9428 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9429 if (BadReg(Rn) || BadReg(Rm)) 9430 return false; 9431 break; 9432 case eEncodingA1: 9433 Rn = Bits32(opcode, 19, 16); 9434 Rm = Bits32(opcode, 3, 0); 9435 shift_n = DecodeImmShiftARM(opcode, shift_t); 9436 break; 9437 default: 9438 return false; 9439 } 9440 9441 // Read the first operand. 9442 uint32_t val1 = ReadCoreReg(Rn, &success); 9443 if (!success) 9444 return false; 9445 9446 // Read the second operand. 9447 uint32_t val2 = ReadCoreReg(Rm, &success); 9448 if (!success) 9449 return false; 9450 9451 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9452 if (!success) 9453 return false; 9454 uint32_t result = val1 & shifted; 9455 9456 EmulateInstruction::Context context; 9457 context.type = EmulateInstruction::eContextImmediate; 9458 context.SetNoArgs (); 9459 9460 if (!WriteFlags(context, result, carry)) 9461 return false; 9462 } 9463 return true; 9464 } 9465 9466 // A8.6.216 SUB (SP minus register) 9467 bool 9468 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9469 { 9470 #if 0 9471 if ConditionPassed() then 9472 EncodingSpecificOperations(); 9473 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9474 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9475 if d == 15 then // Can only occur for ARM encoding 9476 ALUWritePC(result); // setflags is always FALSE here 9477 else 9478 R[d] = result; 9479 if setflags then 9480 APSR.N = result<31>; 9481 APSR.Z = IsZeroBit(result); 9482 APSR.C = carry; 9483 APSR.V = overflow; 9484 #endif 9485 9486 bool success = false; 9487 9488 if (ConditionPassed(opcode)) 9489 { 9490 uint32_t d; 9491 uint32_t m; 9492 bool setflags; 9493 ARM_ShifterType shift_t; 9494 uint32_t shift_n; 9495 9496 switch (encoding) 9497 { 9498 case eEncodingT1: 9499 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9500 d = Bits32 (opcode, 11, 8); 9501 m = Bits32 (opcode, 3, 0); 9502 setflags = BitIsSet (opcode, 20); 9503 9504 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9505 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9506 9507 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9508 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9509 return false; 9510 9511 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9512 if ((d == 15) || BadReg (m)) 9513 return false; 9514 break; 9515 9516 case eEncodingA1: 9517 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9518 d = Bits32 (opcode, 15, 12); 9519 m = Bits32 (opcode, 3, 0); 9520 setflags = BitIsSet (opcode, 20); 9521 9522 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9523 if (d == 15 && setflags) 9524 EmulateSUBSPcLrEtc (opcode, encoding); 9525 9526 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9527 shift_n = DecodeImmShiftARM (opcode, shift_t); 9528 break; 9529 9530 default: 9531 return false; 9532 } 9533 9534 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9535 uint32_t Rm = ReadCoreReg (m, &success); 9536 if (!success) 9537 return false; 9538 9539 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9540 if (!success) 9541 return false; 9542 9543 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9544 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9545 if (!success) 9546 return false; 9547 9548 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9549 9550 EmulateInstruction::Context context; 9551 context.type = eContextArithmetic; 9552 RegisterInfo sp_reg; 9553 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9554 RegisterInfo dwarf_reg; 9555 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9556 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9557 9558 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9559 return false; 9560 } 9561 return true; 9562 } 9563 9564 9565 // A8.6.7 ADD (register-shifted register) 9566 bool 9567 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9568 { 9569 #if 0 9570 if ConditionPassed() then 9571 EncodingSpecificOperations(); 9572 shift_n = UInt(R[s]<7:0>); 9573 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9574 (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9575 R[d] = result; 9576 if setflags then 9577 APSR.N = result<31>; 9578 APSR.Z = IsZeroBit(result); 9579 APSR.C = carry; 9580 APSR.V = overflow; 9581 #endif 9582 9583 bool success = false; 9584 9585 if (ConditionPassed(opcode)) 9586 { 9587 uint32_t d; 9588 uint32_t n; 9589 uint32_t m; 9590 uint32_t s; 9591 bool setflags; 9592 ARM_ShifterType shift_t; 9593 9594 switch (encoding) 9595 { 9596 case eEncodingA1: 9597 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9598 d = Bits32 (opcode, 15, 12); 9599 n = Bits32 (opcode, 19, 16); 9600 m = Bits32 (opcode, 3, 0); 9601 s = Bits32 (opcode, 11, 8); 9602 9603 // setflags = (S == �1�); shift_t = DecodeRegShift(type); 9604 setflags = BitIsSet (opcode, 20); 9605 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9606 9607 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9608 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9609 return false; 9610 break; 9611 9612 default: 9613 return false; 9614 } 9615 9616 // shift_n = UInt(R[s]<7:0>); 9617 uint32_t Rs = ReadCoreReg (s, &success); 9618 if (!success) 9619 return false; 9620 9621 uint32_t shift_n = Bits32 (Rs, 7, 0); 9622 9623 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9624 uint32_t Rm = ReadCoreReg (m, &success); 9625 if (!success) 9626 return false; 9627 9628 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9629 if (!success) 9630 return false; 9631 9632 // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9633 uint32_t Rn = ReadCoreReg (n, &success); 9634 if (!success) 9635 return false; 9636 9637 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9638 9639 // R[d] = result; 9640 EmulateInstruction::Context context; 9641 context.type = eContextArithmetic; 9642 RegisterInfo reg_n; 9643 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9644 RegisterInfo reg_m; 9645 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9646 9647 context.SetRegisterRegisterOperands (reg_n, reg_m); 9648 9649 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9650 return false; 9651 9652 // if setflags then 9653 // APSR.N = result<31>; 9654 // APSR.Z = IsZeroBit(result); 9655 // APSR.C = carry; 9656 // APSR.V = overflow; 9657 if (setflags) 9658 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9659 } 9660 return true; 9661 } 9662 9663 // A8.6.213 SUB (register) 9664 bool 9665 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9666 { 9667 #if 0 9668 if ConditionPassed() then 9669 EncodingSpecificOperations(); 9670 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9671 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9672 if d == 15 then // Can only occur for ARM encoding 9673 ALUWritePC(result); // setflags is always FALSE here 9674 else 9675 R[d] = result; 9676 if setflags then 9677 APSR.N = result<31>; 9678 APSR.Z = IsZeroBit(result); 9679 APSR.C = carry; 9680 APSR.V = overflow; 9681 #endif 9682 9683 bool success = false; 9684 9685 if (ConditionPassed(opcode)) 9686 { 9687 uint32_t d; 9688 uint32_t n; 9689 uint32_t m; 9690 bool setflags; 9691 ARM_ShifterType shift_t; 9692 uint32_t shift_n; 9693 9694 switch (encoding) 9695 { 9696 case eEncodingT1: 9697 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9698 d = Bits32 (opcode, 2, 0); 9699 n = Bits32 (opcode, 5, 3); 9700 m = Bits32 (opcode, 8, 6); 9701 setflags = !InITBlock(); 9702 9703 // (shift_t, shift_n) = (SRType_LSL, 0); 9704 shift_t = SRType_LSL; 9705 shift_n = 0; 9706 9707 break; 9708 9709 case eEncodingT2: 9710 // if Rd == �1111� && S == �1� then SEE CMP (register); 9711 // if Rn == �1101� then SEE SUB (SP minus register); 9712 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9713 d = Bits32 (opcode, 11, 8); 9714 n = Bits32 (opcode, 19, 16); 9715 m = Bits32 (opcode, 3, 0); 9716 setflags = BitIsSet (opcode, 20); 9717 9718 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9719 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9720 9721 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9722 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9723 return false; 9724 9725 break; 9726 9727 case eEncodingA1: 9728 // if Rn == �1101� then SEE SUB (SP minus register); 9729 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9730 d = Bits32 (opcode, 15, 12); 9731 n = Bits32 (opcode, 19, 16); 9732 m = Bits32 (opcode, 3, 0); 9733 setflags = BitIsSet (opcode, 20); 9734 9735 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9736 if ((d == 15) && setflags) 9737 EmulateSUBSPcLrEtc (opcode, encoding); 9738 9739 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9740 shift_n = DecodeImmShiftARM (opcode, shift_t); 9741 9742 break; 9743 9744 default: 9745 return false; 9746 } 9747 9748 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9749 uint32_t Rm = ReadCoreReg (m, &success); 9750 if (!success) 9751 return false; 9752 9753 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9754 if (!success) 9755 return false; 9756 9757 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9758 uint32_t Rn = ReadCoreReg (n, &success); 9759 if (!success) 9760 return false; 9761 9762 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9763 9764 // if d == 15 then // Can only occur for ARM encoding 9765 // ALUWritePC(result); // setflags is always FALSE here 9766 // else 9767 // R[d] = result; 9768 // if setflags then 9769 // APSR.N = result<31>; 9770 // APSR.Z = IsZeroBit(result); 9771 // APSR.C = carry; 9772 // APSR.V = overflow; 9773 9774 EmulateInstruction::Context context; 9775 context.type = eContextArithmetic; 9776 RegisterInfo reg_n; 9777 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9778 RegisterInfo reg_m; 9779 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9780 context.SetRegisterRegisterOperands (reg_n, reg_m); 9781 9782 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9783 return false; 9784 } 9785 return true; 9786 } 9787 9788 // A8.6.202 STREX 9789 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9790 // word from a register to memory if the executing processor has exclusive access to the memory addressed. 9791 bool 9792 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9793 { 9794 #if 0 9795 if ConditionPassed() then 9796 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9797 address = R[n] + imm32; 9798 if ExclusiveMonitorsPass(address,4) then 9799 MemA[address,4] = R[t]; 9800 R[d] = 0; 9801 else 9802 R[d] = 1; 9803 #endif 9804 9805 bool success = false; 9806 9807 if (ConditionPassed(opcode)) 9808 { 9809 uint32_t d; 9810 uint32_t t; 9811 uint32_t n; 9812 uint32_t imm32; 9813 const uint32_t addr_byte_size = GetAddressByteSize(); 9814 9815 switch (encoding) 9816 { 9817 case eEncodingT1: 9818 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 9819 d = Bits32 (opcode, 11, 8); 9820 t = Bits32 (opcode, 15, 12); 9821 n = Bits32 (opcode, 19, 16); 9822 imm32 = Bits32 (opcode, 7, 0) << 2; 9823 9824 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9825 if (BadReg (d) || BadReg (t) || (n == 15)) 9826 return false; 9827 9828 // if d == n || d == t then UNPREDICTABLE; 9829 if ((d == n) || (d == t)) 9830 return false; 9831 9832 break; 9833 9834 case eEncodingA1: 9835 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9836 d = Bits32 (opcode, 15, 12); 9837 t = Bits32 (opcode, 3, 0); 9838 n = Bits32 (opcode, 19, 16); 9839 imm32 = 0; 9840 9841 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9842 if ((d == 15) || (t == 15) || (n == 15)) 9843 return false; 9844 9845 // if d == n || d == t then UNPREDICTABLE; 9846 if ((d == n) || (d == t)) 9847 return false; 9848 9849 break; 9850 9851 default: 9852 return false; 9853 } 9854 9855 // address = R[n] + imm32; 9856 uint32_t Rn = ReadCoreReg (n, &success); 9857 if (!success) 9858 return false; 9859 9860 addr_t address = Rn + imm32; 9861 9862 RegisterInfo base_reg; 9863 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9864 RegisterInfo data_reg; 9865 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9866 EmulateInstruction::Context context; 9867 context.type = eContextRegisterStore; 9868 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9869 9870 // if ExclusiveMonitorsPass(address,4) then 9871 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9872 // always return true. 9873 if (true) 9874 { 9875 // MemA[address,4] = R[t]; 9876 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9877 if (!success) 9878 return false; 9879 9880 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9881 return false; 9882 9883 // R[d] = 0; 9884 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9885 return false; 9886 } 9887 #if 0 // unreachable because if true 9888 else 9889 { 9890 // R[d] = 1; 9891 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9892 return false; 9893 } 9894 #endif // unreachable because if true 9895 } 9896 return true; 9897 } 9898 9899 // A8.6.197 STRB (immediate, ARM) 9900 bool 9901 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9902 { 9903 #if 0 9904 if ConditionPassed() then 9905 EncodingSpecificOperations(); 9906 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9907 address = if index then offset_addr else R[n]; 9908 MemU[address,1] = R[t]<7:0>; 9909 if wback then R[n] = offset_addr; 9910 #endif 9911 9912 bool success = false; 9913 9914 if (ConditionPassed(opcode)) 9915 { 9916 uint32_t t; 9917 uint32_t n; 9918 uint32_t imm32; 9919 bool index; 9920 bool add; 9921 bool wback; 9922 9923 switch (encoding) 9924 { 9925 case eEncodingA1: 9926 // if P == �0� && W == �1� then SEE STRBT; 9927 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9928 t = Bits32 (opcode, 15, 12); 9929 n = Bits32 (opcode, 19, 16); 9930 imm32 = Bits32 (opcode, 11, 0); 9931 9932 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9933 index = BitIsSet (opcode, 24); 9934 add = BitIsSet (opcode, 23); 9935 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9936 9937 // if t == 15 then UNPREDICTABLE; 9938 if (t == 15) 9939 return false; 9940 9941 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9942 if (wback && ((n == 15) || (n == t))) 9943 return false; 9944 9945 break; 9946 9947 default: 9948 return false; 9949 } 9950 9951 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9952 uint32_t Rn = ReadCoreReg (n, &success); 9953 if (!success) 9954 return false; 9955 9956 addr_t offset_addr; 9957 if (add) 9958 offset_addr = Rn + imm32; 9959 else 9960 offset_addr = Rn - imm32; 9961 9962 // address = if index then offset_addr else R[n]; 9963 addr_t address; 9964 if (index) 9965 address = offset_addr; 9966 else 9967 address = Rn; 9968 9969 // MemU[address,1] = R[t]<7:0>; 9970 uint32_t Rt = ReadCoreReg (t, &success); 9971 if (!success) 9972 return false; 9973 9974 RegisterInfo base_reg; 9975 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9976 RegisterInfo data_reg; 9977 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9978 EmulateInstruction::Context context; 9979 context.type = eContextRegisterStore; 9980 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9981 9982 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 9983 return false; 9984 9985 // if wback then R[n] = offset_addr; 9986 if (wback) 9987 { 9988 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9989 return false; 9990 } 9991 } 9992 return true; 9993 } 9994 9995 // A8.6.194 STR (immediate, ARM) 9996 bool 9997 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9998 { 9999 #if 0 10000 if ConditionPassed() then 10001 EncodingSpecificOperations(); 10002 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10003 address = if index then offset_addr else R[n]; 10004 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10005 if wback then R[n] = offset_addr; 10006 #endif 10007 10008 bool success = false; 10009 10010 if (ConditionPassed(opcode)) 10011 { 10012 uint32_t t; 10013 uint32_t n; 10014 uint32_t imm32; 10015 bool index; 10016 bool add; 10017 bool wback; 10018 10019 const uint32_t addr_byte_size = GetAddressByteSize(); 10020 10021 switch (encoding) 10022 { 10023 case eEncodingA1: 10024 // if P == �0� && W == �1� then SEE STRT; 10025 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH; 10026 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10027 t = Bits32 (opcode, 15, 12); 10028 n = Bits32 (opcode, 19, 16); 10029 imm32 = Bits32 (opcode, 11, 0); 10030 10031 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10032 index = BitIsSet (opcode, 24); 10033 add = BitIsSet (opcode, 23); 10034 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10035 10036 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10037 if (wback && ((n == 15) || (n == t))) 10038 return false; 10039 10040 break; 10041 10042 default: 10043 return false; 10044 } 10045 10046 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10047 uint32_t Rn = ReadCoreReg (n, &success); 10048 if (!success) 10049 return false; 10050 10051 addr_t offset_addr; 10052 if (add) 10053 offset_addr = Rn + imm32; 10054 else 10055 offset_addr = Rn - imm32; 10056 10057 // address = if index then offset_addr else R[n]; 10058 addr_t address; 10059 if (index) 10060 address = offset_addr; 10061 else 10062 address = Rn; 10063 10064 RegisterInfo base_reg; 10065 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10066 RegisterInfo data_reg; 10067 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10068 EmulateInstruction::Context context; 10069 context.type = eContextRegisterStore; 10070 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10071 10072 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10073 uint32_t Rt = ReadCoreReg (t, &success); 10074 if (!success) 10075 return false; 10076 10077 if (t == 15) 10078 { 10079 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10080 if (!success) 10081 return false; 10082 10083 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10084 return false; 10085 } 10086 else 10087 { 10088 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10089 return false; 10090 } 10091 10092 // if wback then R[n] = offset_addr; 10093 if (wback) 10094 { 10095 context.type = eContextAdjustBaseRegister; 10096 context.SetImmediate (offset_addr); 10097 10098 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10099 return false; 10100 } 10101 } 10102 return true; 10103 } 10104 10105 // A8.6.66 LDRD (immediate) 10106 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10107 // words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10108 bool 10109 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10110 { 10111 #if 0 10112 if ConditionPassed() then 10113 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10114 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10115 address = if index then offset_addr else R[n]; 10116 R[t] = MemA[address,4]; 10117 R[t2] = MemA[address+4,4]; 10118 if wback then R[n] = offset_addr; 10119 #endif 10120 10121 bool success = false; 10122 10123 if (ConditionPassed(opcode)) 10124 { 10125 uint32_t t; 10126 uint32_t t2; 10127 uint32_t n; 10128 uint32_t imm32; 10129 bool index; 10130 bool add; 10131 bool wback; 10132 10133 switch (encoding) 10134 { 10135 case eEncodingT1: 10136 //if P == �0� && W == �0� then SEE �Related encodings�; 10137 //if Rn == �1111� then SEE LDRD (literal); 10138 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10139 t = Bits32 (opcode, 15, 12); 10140 t2 = Bits32 (opcode, 11, 8); 10141 n = Bits32 (opcode, 19, 16); 10142 imm32 = Bits32 (opcode, 7, 0) << 2; 10143 10144 //index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10145 index = BitIsSet (opcode, 24); 10146 add = BitIsSet (opcode, 23); 10147 wback = BitIsSet (opcode, 21); 10148 10149 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10150 if (wback && ((n == t) || (n == t2))) 10151 return false; 10152 10153 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10154 if (BadReg (t) || BadReg (t2) || (t == t2)) 10155 return false; 10156 10157 break; 10158 10159 case eEncodingA1: 10160 //if Rn == �1111� then SEE LDRD (literal); 10161 //if Rt<0> == �1� then UNPREDICTABLE; 10162 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10163 t = Bits32 (opcode, 15, 12); 10164 if (BitIsSet (t, 0)) 10165 return false; 10166 t2 = t + 1; 10167 n = Bits32 (opcode, 19, 16); 10168 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10169 10170 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10171 index = BitIsSet (opcode, 24); 10172 add = BitIsSet (opcode, 23); 10173 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10174 10175 //if P == �0� && W == �1� then UNPREDICTABLE; 10176 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10177 return false; 10178 10179 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10180 if (wback && ((n == t) || (n == t2))) 10181 return false; 10182 10183 //if t2 == 15 then UNPREDICTABLE; 10184 if (t2 == 15) 10185 return false; 10186 10187 break; 10188 10189 default: 10190 return false; 10191 } 10192 10193 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10194 uint32_t Rn = ReadCoreReg (n, &success); 10195 if (!success) 10196 return false; 10197 10198 addr_t offset_addr; 10199 if (add) 10200 offset_addr = Rn + imm32; 10201 else 10202 offset_addr = Rn - imm32; 10203 10204 //address = if index then offset_addr else R[n]; 10205 addr_t address; 10206 if (index) 10207 address = offset_addr; 10208 else 10209 address = Rn; 10210 10211 //R[t] = MemA[address,4]; 10212 RegisterInfo base_reg; 10213 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10214 10215 EmulateInstruction::Context context; 10216 context.type = eContextRegisterLoad; 10217 context.SetRegisterPlusOffset (base_reg, address - Rn); 10218 10219 const uint32_t addr_byte_size = GetAddressByteSize(); 10220 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10221 if (!success) 10222 return false; 10223 10224 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10225 return false; 10226 10227 //R[t2] = MemA[address+4,4]; 10228 10229 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10230 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10231 if (!success) 10232 return false; 10233 10234 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10235 return false; 10236 10237 //if wback then R[n] = offset_addr; 10238 if (wback) 10239 { 10240 context.type = eContextAdjustBaseRegister; 10241 context.SetAddress (offset_addr); 10242 10243 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10244 return false; 10245 } 10246 } 10247 return true; 10248 } 10249 10250 // A8.6.68 LDRD (register) 10251 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10252 // words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10253 bool 10254 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10255 { 10256 #if 0 10257 if ConditionPassed() then 10258 EncodingSpecificOperations(); 10259 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10260 address = if index then offset_addr else R[n]; 10261 R[t] = MemA[address,4]; 10262 R[t2] = MemA[address+4,4]; 10263 if wback then R[n] = offset_addr; 10264 #endif 10265 10266 bool success = false; 10267 10268 if (ConditionPassed(opcode)) 10269 { 10270 uint32_t t; 10271 uint32_t t2; 10272 uint32_t n; 10273 uint32_t m; 10274 bool index; 10275 bool add; 10276 bool wback; 10277 10278 switch (encoding) 10279 { 10280 case eEncodingA1: 10281 // if Rt<0> == �1� then UNPREDICTABLE; 10282 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10283 t = Bits32 (opcode, 15, 12); 10284 if (BitIsSet (t, 0)) 10285 return false; 10286 t2 = t + 1; 10287 n = Bits32 (opcode, 19, 16); 10288 m = Bits32 (opcode, 3, 0); 10289 10290 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10291 index = BitIsSet (opcode, 24); 10292 add = BitIsSet (opcode, 23); 10293 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10294 10295 // if P == �0� && W == �1� then UNPREDICTABLE; 10296 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10297 return false; 10298 10299 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10300 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10301 return false; 10302 10303 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10304 if (wback && ((n == 15) || (n == t) || (n == t2))) 10305 return false; 10306 10307 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10308 if ((ArchVersion() < 6) && wback && (m == n)) 10309 return false; 10310 break; 10311 10312 default: 10313 return false; 10314 } 10315 10316 uint32_t Rn = ReadCoreReg (n, &success); 10317 if (!success) 10318 return false; 10319 RegisterInfo base_reg; 10320 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10321 10322 uint32_t Rm = ReadCoreReg (m, &success); 10323 if (!success) 10324 return false; 10325 RegisterInfo offset_reg; 10326 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10327 10328 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10329 addr_t offset_addr; 10330 if (add) 10331 offset_addr = Rn + Rm; 10332 else 10333 offset_addr = Rn - Rm; 10334 10335 // address = if index then offset_addr else R[n]; 10336 addr_t address; 10337 if (index) 10338 address = offset_addr; 10339 else 10340 address = Rn; 10341 10342 EmulateInstruction::Context context; 10343 context.type = eContextRegisterLoad; 10344 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10345 10346 // R[t] = MemA[address,4]; 10347 const uint32_t addr_byte_size = GetAddressByteSize(); 10348 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10349 if (!success) 10350 return false; 10351 10352 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10353 return false; 10354 10355 // R[t2] = MemA[address+4,4]; 10356 10357 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10358 if (!success) 10359 return false; 10360 10361 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10362 return false; 10363 10364 // if wback then R[n] = offset_addr; 10365 if (wback) 10366 { 10367 context.type = eContextAdjustBaseRegister; 10368 context.SetAddress (offset_addr); 10369 10370 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10371 return false; 10372 } 10373 } 10374 return true; 10375 } 10376 10377 // A8.6.200 STRD (immediate) 10378 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10379 // stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10380 bool 10381 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10382 { 10383 #if 0 10384 if ConditionPassed() then 10385 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10386 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10387 address = if index then offset_addr else R[n]; 10388 MemA[address,4] = R[t]; 10389 MemA[address+4,4] = R[t2]; 10390 if wback then R[n] = offset_addr; 10391 #endif 10392 10393 bool success = false; 10394 10395 if (ConditionPassed(opcode)) 10396 { 10397 uint32_t t; 10398 uint32_t t2; 10399 uint32_t n; 10400 uint32_t imm32; 10401 bool index; 10402 bool add; 10403 bool wback; 10404 10405 switch (encoding) 10406 { 10407 case eEncodingT1: 10408 // if P == �0� && W == �0� then SEE �Related encodings�; 10409 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10410 t = Bits32 (opcode, 15, 12); 10411 t2 = Bits32 (opcode, 11, 8); 10412 n = Bits32 (opcode, 19, 16); 10413 imm32 = Bits32 (opcode, 7, 0) << 2; 10414 10415 // index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10416 index = BitIsSet (opcode, 24); 10417 add = BitIsSet (opcode, 23); 10418 wback = BitIsSet (opcode, 21); 10419 10420 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10421 if (wback && ((n == t) || (n == t2))) 10422 return false; 10423 10424 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10425 if ((n == 15) || BadReg (t) || BadReg (t2)) 10426 return false; 10427 10428 break; 10429 10430 case eEncodingA1: 10431 // if Rt<0> == �1� then UNPREDICTABLE; 10432 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10433 t = Bits32 (opcode, 15, 12); 10434 if (BitIsSet (t, 0)) 10435 return false; 10436 10437 t2 = t + 1; 10438 n = Bits32 (opcode, 19, 16); 10439 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10440 10441 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10442 index = BitIsSet (opcode, 24); 10443 add = BitIsSet (opcode, 23); 10444 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10445 10446 // if P == �0� && W == �1� then UNPREDICTABLE; 10447 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10448 return false; 10449 10450 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10451 if (wback && ((n == 15) || (n == t) || (n == t2))) 10452 return false; 10453 10454 // if t2 == 15 then UNPREDICTABLE; 10455 if (t2 == 15) 10456 return false; 10457 10458 break; 10459 10460 default: 10461 return false; 10462 } 10463 10464 RegisterInfo base_reg; 10465 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10466 10467 uint32_t Rn = ReadCoreReg (n, &success); 10468 if (!success) 10469 return false; 10470 10471 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10472 addr_t offset_addr; 10473 if (add) 10474 offset_addr = Rn + imm32; 10475 else 10476 offset_addr = Rn - imm32; 10477 10478 //address = if index then offset_addr else R[n]; 10479 addr_t address; 10480 if (index) 10481 address = offset_addr; 10482 else 10483 address = Rn; 10484 10485 //MemA[address,4] = R[t]; 10486 RegisterInfo data_reg; 10487 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10488 10489 uint32_t data = ReadCoreReg (t, &success); 10490 if (!success) 10491 return false; 10492 10493 EmulateInstruction::Context context; 10494 context.type = eContextRegisterStore; 10495 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10496 10497 const uint32_t addr_byte_size = GetAddressByteSize(); 10498 10499 if (!MemAWrite (context, address, data, addr_byte_size)) 10500 return false; 10501 10502 //MemA[address+4,4] = R[t2]; 10503 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10504 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10505 10506 data = ReadCoreReg (t2, &success); 10507 if (!success) 10508 return false; 10509 10510 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10511 return false; 10512 10513 //if wback then R[n] = offset_addr; 10514 if (wback) 10515 { 10516 context.type = eContextAdjustBaseRegister; 10517 context.SetAddress (offset_addr); 10518 10519 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10520 return false; 10521 } 10522 } 10523 return true; 10524 } 10525 10526 10527 // A8.6.201 STRD (register) 10528 bool 10529 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10530 { 10531 #if 0 10532 if ConditionPassed() then 10533 EncodingSpecificOperations(); 10534 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10535 address = if index then offset_addr else R[n]; 10536 MemA[address,4] = R[t]; 10537 MemA[address+4,4] = R[t2]; 10538 if wback then R[n] = offset_addr; 10539 #endif 10540 10541 bool success = false; 10542 10543 if (ConditionPassed(opcode)) 10544 { 10545 uint32_t t; 10546 uint32_t t2; 10547 uint32_t n; 10548 uint32_t m; 10549 bool index; 10550 bool add; 10551 bool wback; 10552 10553 switch (encoding) 10554 { 10555 case eEncodingA1: 10556 // if Rt<0> == �1� then UNPREDICTABLE; 10557 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10558 t = Bits32 (opcode, 15, 12); 10559 if (BitIsSet (t, 0)) 10560 return false; 10561 10562 t2 = t+1; 10563 n = Bits32 (opcode, 19, 16); 10564 m = Bits32 (opcode, 3, 0); 10565 10566 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10567 index = BitIsSet (opcode, 24); 10568 add = BitIsSet (opcode, 23); 10569 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10570 10571 // if P == �0� && W == �1� then UNPREDICTABLE; 10572 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10573 return false; 10574 10575 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10576 if ((t2 == 15) || (m == 15)) 10577 return false; 10578 10579 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10580 if (wback && ((n == 15) || (n == t) || (n == t2))) 10581 return false; 10582 10583 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10584 if ((ArchVersion() < 6) && wback && (m == n)) 10585 return false; 10586 10587 break; 10588 10589 default: 10590 return false; 10591 } 10592 10593 RegisterInfo base_reg; 10594 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10595 RegisterInfo offset_reg; 10596 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10597 RegisterInfo data_reg; 10598 10599 uint32_t Rn = ReadCoreReg (n, &success); 10600 if (!success) 10601 return false; 10602 10603 uint32_t Rm = ReadCoreReg (m, &success); 10604 if (!success) 10605 return false; 10606 10607 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10608 addr_t offset_addr; 10609 if (add) 10610 offset_addr = Rn + Rm; 10611 else 10612 offset_addr = Rn - Rm; 10613 10614 // address = if index then offset_addr else R[n]; 10615 addr_t address; 10616 if (index) 10617 address = offset_addr; 10618 else 10619 address = Rn; 10620 // MemA[address,4] = R[t]; 10621 uint32_t Rt = ReadCoreReg (t, &success); 10622 if (!success) 10623 return false; 10624 10625 EmulateInstruction::Context context; 10626 context.type = eContextRegisterStore; 10627 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10628 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10629 10630 const uint32_t addr_byte_size = GetAddressByteSize(); 10631 10632 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10633 return false; 10634 10635 // MemA[address+4,4] = R[t2]; 10636 uint32_t Rt2 = ReadCoreReg (t2, &success); 10637 if (!success) 10638 return false; 10639 10640 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10641 10642 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10643 10644 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10645 return false; 10646 10647 // if wback then R[n] = offset_addr; 10648 if (wback) 10649 { 10650 context.type = eContextAdjustBaseRegister; 10651 context.SetAddress (offset_addr); 10652 10653 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10654 return false; 10655 10656 } 10657 } 10658 return true; 10659 } 10660 10661 // A8.6.319 VLDM 10662 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10663 // an ARM core register. 10664 bool 10665 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10666 { 10667 #if 0 10668 if ConditionPassed() then 10669 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10670 address = if add then R[n] else R[n]-imm32; 10671 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10672 for r = 0 to regs-1 10673 if single_regs then 10674 S[d+r] = MemA[address,4]; address = address+4; 10675 else 10676 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10677 // Combine the word-aligned words in the correct order for current endianness. 10678 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10679 #endif 10680 10681 bool success = false; 10682 10683 if (ConditionPassed(opcode)) 10684 { 10685 bool single_regs; 10686 bool add; 10687 bool wback; 10688 uint32_t d; 10689 uint32_t n; 10690 uint32_t imm32; 10691 uint32_t regs; 10692 10693 switch (encoding) 10694 { 10695 case eEncodingT1: 10696 case eEncodingA1: 10697 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10698 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10699 // if P == �1� && W == �0� then SEE VLDR; 10700 // if P == U && W == �1� then UNDEFINED; 10701 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10702 return false; 10703 10704 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10705 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10706 single_regs = false; 10707 add = BitIsSet (opcode, 23); 10708 wback = BitIsSet (opcode, 21); 10709 10710 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10711 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10712 n = Bits32 (opcode, 19, 16); 10713 imm32 = Bits32 (opcode, 7, 0) << 2; 10714 10715 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�. 10716 regs = Bits32 (opcode, 7, 0) / 2; 10717 10718 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10719 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10720 return false; 10721 10722 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10723 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10724 return false; 10725 10726 break; 10727 10728 case eEncodingT2: 10729 case eEncodingA2: 10730 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10731 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10732 // if P == �1� && W == �0� then SEE VLDR; 10733 // if P == U && W == �1� then UNDEFINED; 10734 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10735 return false; 10736 10737 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10738 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10739 single_regs = true; 10740 add = BitIsSet (opcode, 23); 10741 wback = BitIsSet (opcode, 21); 10742 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10743 n = Bits32 (opcode, 19, 16); 10744 10745 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10746 imm32 = Bits32 (opcode, 7, 0) << 2; 10747 regs = Bits32 (opcode, 7, 0); 10748 10749 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10750 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10751 return false; 10752 10753 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10754 if ((regs == 0) || ((d + regs) > 32)) 10755 return false; 10756 break; 10757 10758 default: 10759 return false; 10760 } 10761 10762 RegisterInfo base_reg; 10763 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10764 10765 uint32_t Rn = ReadCoreReg (n, &success); 10766 if (!success) 10767 return false; 10768 10769 // address = if add then R[n] else R[n]-imm32; 10770 addr_t address; 10771 if (add) 10772 address = Rn; 10773 else 10774 address = Rn - imm32; 10775 10776 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10777 EmulateInstruction::Context context; 10778 10779 if (wback) 10780 { 10781 uint32_t value; 10782 if (add) 10783 value = Rn + imm32; 10784 else 10785 value = Rn - imm32; 10786 10787 context.type = eContextAdjustBaseRegister; 10788 context.SetImmediateSigned (value - Rn); 10789 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10790 return false; 10791 10792 } 10793 10794 const uint32_t addr_byte_size = GetAddressByteSize(); 10795 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10796 10797 context.type = eContextRegisterLoad; 10798 10799 // for r = 0 to regs-1 10800 for (uint32_t r = 0; r < regs; ++r) 10801 { 10802 if (single_regs) 10803 { 10804 // S[d+r] = MemA[address,4]; address = address+4; 10805 context.SetRegisterPlusOffset (base_reg, address - Rn); 10806 10807 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10808 if (!success) 10809 return false; 10810 10811 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10812 return false; 10813 10814 address = address + 4; 10815 } 10816 else 10817 { 10818 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10819 context.SetRegisterPlusOffset (base_reg, address - Rn); 10820 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10821 if (!success) 10822 return false; 10823 10824 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10825 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10826 if (!success) 10827 return false; 10828 10829 address = address + 8; 10830 // // Combine the word-aligned words in the correct order for current endianness. 10831 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10832 uint64_t data; 10833 if (GetByteOrder() == eByteOrderBig) 10834 { 10835 data = word1; 10836 data = (data << 32) | word2; 10837 } 10838 else 10839 { 10840 data = word2; 10841 data = (data << 32) | word1; 10842 } 10843 10844 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10845 return false; 10846 } 10847 } 10848 } 10849 return true; 10850 } 10851 10852 // A8.6.399 VSTM 10853 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10854 // ARM core register. 10855 bool 10856 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10857 { 10858 #if 0 10859 if ConditionPassed() then 10860 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10861 address = if add then R[n] else R[n]-imm32; 10862 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10863 for r = 0 to regs-1 10864 if single_regs then 10865 MemA[address,4] = S[d+r]; address = address+4; 10866 else 10867 // Store as two word-aligned words in the correct order for current endianness. 10868 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10869 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10870 address = address+8; 10871 #endif 10872 10873 bool success = false; 10874 10875 if (ConditionPassed (opcode)) 10876 { 10877 bool single_regs; 10878 bool add; 10879 bool wback; 10880 uint32_t d; 10881 uint32_t n; 10882 uint32_t imm32; 10883 uint32_t regs; 10884 10885 switch (encoding) 10886 { 10887 case eEncodingT1: 10888 case eEncodingA1: 10889 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10890 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10891 // if P == �1� && W == �0� then SEE VSTR; 10892 // if P == U && W == �1� then UNDEFINED; 10893 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10894 return false; 10895 10896 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10897 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10898 single_regs = false; 10899 add = BitIsSet (opcode, 23); 10900 wback = BitIsSet (opcode, 21); 10901 10902 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10903 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10904 n = Bits32 (opcode, 19, 16); 10905 imm32 = Bits32 (opcode, 7, 0) << 2; 10906 10907 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�. 10908 regs = Bits32 (opcode, 7, 0) / 2; 10909 10910 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10911 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10912 return false; 10913 10914 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10915 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10916 return false; 10917 10918 break; 10919 10920 case eEncodingT2: 10921 case eEncodingA2: 10922 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10923 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10924 // if P == �1� && W == �0� then SEE VSTR; 10925 // if P == U && W == �1� then UNDEFINED; 10926 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10927 return false; 10928 10929 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10930 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10931 single_regs = true; 10932 add = BitIsSet (opcode, 23); 10933 wback = BitIsSet (opcode, 21); 10934 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10935 n = Bits32 (opcode, 19, 16); 10936 10937 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10938 imm32 = Bits32 (opcode, 7, 0) << 2; 10939 regs = Bits32 (opcode, 7, 0); 10940 10941 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10942 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 10943 return false; 10944 10945 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10946 if ((regs == 0) || ((d + regs) > 32)) 10947 return false; 10948 10949 break; 10950 10951 default: 10952 return false; 10953 } 10954 10955 RegisterInfo base_reg; 10956 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10957 10958 uint32_t Rn = ReadCoreReg (n, &success); 10959 if (!success) 10960 return false; 10961 10962 // address = if add then R[n] else R[n]-imm32; 10963 addr_t address; 10964 if (add) 10965 address = Rn; 10966 else 10967 address = Rn - imm32; 10968 10969 EmulateInstruction::Context context; 10970 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10971 if (wback) 10972 { 10973 uint32_t value; 10974 if (add) 10975 value = Rn + imm32; 10976 else 10977 value = Rn - imm32; 10978 10979 context.type = eContextAdjustBaseRegister; 10980 context.SetRegisterPlusOffset (base_reg, value - Rn); 10981 10982 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10983 return false; 10984 } 10985 10986 const uint32_t addr_byte_size = GetAddressByteSize(); 10987 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10988 10989 context.type = eContextRegisterStore; 10990 // for r = 0 to regs-1 10991 for (uint32_t r = 0; r < regs; ++r) 10992 { 10993 10994 if (single_regs) 10995 { 10996 // MemA[address,4] = S[d+r]; address = address+4; 10997 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10998 if (!success) 10999 return false; 11000 11001 RegisterInfo data_reg; 11002 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11003 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11004 if (!MemAWrite (context, address, data, addr_byte_size)) 11005 return false; 11006 11007 address = address + 4; 11008 } 11009 else 11010 { 11011 // // Store as two word-aligned words in the correct order for current endianness. 11012 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11013 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11014 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11015 if (!success) 11016 return false; 11017 11018 RegisterInfo data_reg; 11019 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11020 11021 if (GetByteOrder() == eByteOrderBig) 11022 { 11023 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11024 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11025 return false; 11026 11027 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11028 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 11029 return false; 11030 } 11031 else 11032 { 11033 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11034 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11035 return false; 11036 11037 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11038 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11039 return false; 11040 } 11041 // address = address+8; 11042 address = address + 8; 11043 } 11044 } 11045 } 11046 return true; 11047 } 11048 11049 // A8.6.320 11050 // This instruction loads a single extension register from memory, using an address from an ARM core register, with 11051 // an optional offset. 11052 bool 11053 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 11054 { 11055 #if 0 11056 if ConditionPassed() then 11057 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11058 base = if n == 15 then Align(PC,4) else R[n]; 11059 address = if add then (base + imm32) else (base - imm32); 11060 if single_reg then 11061 S[d] = MemA[address,4]; 11062 else 11063 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11064 // Combine the word-aligned words in the correct order for current endianness. 11065 D[d] = if BigEndian() then word1:word2 else word2:word1; 11066 #endif 11067 11068 bool success = false; 11069 11070 if (ConditionPassed (opcode)) 11071 { 11072 bool single_reg; 11073 bool add; 11074 uint32_t imm32; 11075 uint32_t d; 11076 uint32_t n; 11077 11078 switch (encoding) 11079 { 11080 case eEncodingT1: 11081 case eEncodingA1: 11082 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11083 single_reg = false; 11084 add = BitIsSet (opcode, 23); 11085 imm32 = Bits32 (opcode, 7, 0) << 2; 11086 11087 // d = UInt(D:Vd); n = UInt(Rn); 11088 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11089 n = Bits32 (opcode, 19, 16); 11090 11091 break; 11092 11093 case eEncodingT2: 11094 case eEncodingA2: 11095 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11096 single_reg = true; 11097 add = BitIsSet (opcode, 23); 11098 imm32 = Bits32 (opcode, 7, 0) << 2; 11099 11100 // d = UInt(Vd:D); n = UInt(Rn); 11101 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11102 n = Bits32 (opcode, 19, 16); 11103 11104 break; 11105 11106 default: 11107 return false; 11108 } 11109 RegisterInfo base_reg; 11110 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11111 11112 uint32_t Rn = ReadCoreReg (n, &success); 11113 if (!success) 11114 return false; 11115 11116 // base = if n == 15 then Align(PC,4) else R[n]; 11117 uint32_t base; 11118 if (n == 15) 11119 base = AlignPC (Rn); 11120 else 11121 base = Rn; 11122 11123 // address = if add then (base + imm32) else (base - imm32); 11124 addr_t address; 11125 if (add) 11126 address = base + imm32; 11127 else 11128 address = base - imm32; 11129 11130 const uint32_t addr_byte_size = GetAddressByteSize(); 11131 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11132 11133 EmulateInstruction::Context context; 11134 context.type = eContextRegisterLoad; 11135 context.SetRegisterPlusOffset (base_reg, address - base); 11136 11137 if (single_reg) 11138 { 11139 // S[d] = MemA[address,4]; 11140 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11141 if (!success) 11142 return false; 11143 11144 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11145 return false; 11146 } 11147 else 11148 { 11149 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11150 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11151 if (!success) 11152 return false; 11153 11154 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11155 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11156 if (!success) 11157 return false; 11158 // // Combine the word-aligned words in the correct order for current endianness. 11159 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11160 uint64_t data64; 11161 if (GetByteOrder() == eByteOrderBig) 11162 { 11163 data64 = word1; 11164 data64 = (data64 << 32) | word2; 11165 } 11166 else 11167 { 11168 data64 = word2; 11169 data64 = (data64 << 32) | word1; 11170 } 11171 11172 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11173 return false; 11174 } 11175 } 11176 return true; 11177 } 11178 11179 // A8.6.400 VSTR 11180 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11181 // optional offset. 11182 bool 11183 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11184 { 11185 #if 0 11186 if ConditionPassed() then 11187 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11188 address = if add then (R[n] + imm32) else (R[n] - imm32); 11189 if single_reg then 11190 MemA[address,4] = S[d]; 11191 else 11192 // Store as two word-aligned words in the correct order for current endianness. 11193 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11194 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11195 #endif 11196 11197 bool success = false; 11198 11199 if (ConditionPassed (opcode)) 11200 { 11201 bool single_reg; 11202 bool add; 11203 uint32_t imm32; 11204 uint32_t d; 11205 uint32_t n; 11206 11207 switch (encoding) 11208 { 11209 case eEncodingT1: 11210 case eEncodingA1: 11211 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11212 single_reg = false; 11213 add = BitIsSet (opcode, 23); 11214 imm32 = Bits32 (opcode, 7, 0) << 2; 11215 11216 // d = UInt(D:Vd); n = UInt(Rn); 11217 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11218 n = Bits32 (opcode, 19, 16); 11219 11220 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11221 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11222 return false; 11223 11224 break; 11225 11226 case eEncodingT2: 11227 case eEncodingA2: 11228 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11229 single_reg = true; 11230 add = BitIsSet (opcode, 23); 11231 imm32 = Bits32 (opcode, 7, 0) << 2; 11232 11233 // d = UInt(Vd:D); n = UInt(Rn); 11234 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11235 n = Bits32 (opcode, 19, 16); 11236 11237 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11238 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11239 return false; 11240 11241 break; 11242 11243 default: 11244 return false; 11245 } 11246 11247 RegisterInfo base_reg; 11248 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11249 11250 uint32_t Rn = ReadCoreReg (n, &success); 11251 if (!success) 11252 return false; 11253 11254 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11255 addr_t address; 11256 if (add) 11257 address = Rn + imm32; 11258 else 11259 address = Rn - imm32; 11260 11261 const uint32_t addr_byte_size = GetAddressByteSize(); 11262 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11263 11264 RegisterInfo data_reg; 11265 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11266 EmulateInstruction::Context context; 11267 context.type = eContextRegisterStore; 11268 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11269 11270 if (single_reg) 11271 { 11272 // MemA[address,4] = S[d]; 11273 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11274 if (!success) 11275 return false; 11276 11277 if (!MemAWrite (context, address, data, addr_byte_size)) 11278 return false; 11279 } 11280 else 11281 { 11282 // // Store as two word-aligned words in the correct order for current endianness. 11283 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11284 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11285 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11286 if (!success) 11287 return false; 11288 11289 if (GetByteOrder() == eByteOrderBig) 11290 { 11291 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11292 return false; 11293 11294 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11295 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11296 return false; 11297 } 11298 else 11299 { 11300 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11301 return false; 11302 11303 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11304 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11305 return false; 11306 } 11307 } 11308 } 11309 return true; 11310 } 11311 11312 // A8.6.307 VLDI1 (multiple single elements) 11313 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11314 // element of each register is loaded. 11315 bool 11316 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11317 { 11318 #if 0 11319 if ConditionPassed() then 11320 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11321 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11322 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11323 for r = 0 to regs-1 11324 for e = 0 to elements-1 11325 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11326 address = address + ebytes; 11327 #endif 11328 11329 bool success = false; 11330 11331 if (ConditionPassed (opcode)) 11332 { 11333 uint32_t regs; 11334 uint32_t alignment; 11335 uint32_t ebytes; 11336 uint32_t esize; 11337 uint32_t elements; 11338 uint32_t d; 11339 uint32_t n; 11340 uint32_t m; 11341 bool wback; 11342 bool register_index; 11343 11344 switch (encoding) 11345 { 11346 case eEncodingT1: 11347 case eEncodingA1: 11348 { 11349 // case type of 11350 // when �0111� 11351 // regs = 1; if align<1> == �1� then UNDEFINED; 11352 // when �1010� 11353 // regs = 2; if align == �11� then UNDEFINED; 11354 // when �0110� 11355 // regs = 3; if align<1> == �1� then UNDEFINED; 11356 // when �0010� 11357 // regs = 4; 11358 // otherwise 11359 // SEE �Related encodings�; 11360 uint32_t type = Bits32 (opcode, 11, 8); 11361 uint32_t align = Bits32 (opcode, 5, 4); 11362 if (type == 7) // '0111' 11363 { 11364 regs = 1; 11365 if (BitIsSet (align, 1)) 11366 return false; 11367 } 11368 else if (type == 10) // '1010' 11369 { 11370 regs = 2; 11371 if (align == 3) 11372 return false; 11373 11374 } 11375 else if (type == 6) // '0110' 11376 { 11377 regs = 3; 11378 if (BitIsSet (align, 1)) 11379 return false; 11380 } 11381 else if (type == 2) // '0010' 11382 { 11383 regs = 4; 11384 } 11385 else 11386 return false; 11387 11388 // alignment = if align == �00� then 1 else 4 << UInt(align); 11389 if (align == 0) 11390 alignment = 1; 11391 else 11392 alignment = 4 << align; 11393 11394 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11395 ebytes = 1 << Bits32 (opcode, 7, 6); 11396 esize = 8 * ebytes; 11397 elements = 8 / ebytes; 11398 11399 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11400 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11401 n = Bits32 (opcode, 19, 15); 11402 m = Bits32 (opcode, 3, 0); 11403 11404 // wback = (m != 15); register_index = (m != 15 && m != 13); 11405 wback = (m != 15); 11406 register_index = ((m != 15) && (m != 13)); 11407 11408 // if d+regs > 32 then UNPREDICTABLE; 11409 if ((d + regs) > 32) 11410 return false; 11411 } 11412 break; 11413 11414 default: 11415 return false; 11416 } 11417 11418 RegisterInfo base_reg; 11419 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11420 11421 uint32_t Rn = ReadCoreReg (n, &success); 11422 if (!success) 11423 return false; 11424 11425 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11426 addr_t address = Rn; 11427 if ((address % alignment) != 0) 11428 return false; 11429 11430 EmulateInstruction::Context context; 11431 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11432 if (wback) 11433 { 11434 uint32_t Rm = ReadCoreReg (m, &success); 11435 if (!success) 11436 return false; 11437 11438 uint32_t offset; 11439 if (register_index) 11440 offset = Rm; 11441 else 11442 offset = 8 * regs; 11443 11444 uint32_t value = Rn + offset; 11445 context.type = eContextAdjustBaseRegister; 11446 context.SetRegisterPlusOffset (base_reg, offset); 11447 11448 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11449 return false; 11450 11451 } 11452 11453 // for r = 0 to regs-1 11454 for (uint32_t r = 0; r < regs; ++r) 11455 { 11456 // for e = 0 to elements-1 11457 uint64_t assembled_data = 0; 11458 for (uint32_t e = 0; e < elements; ++e) 11459 { 11460 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11461 context.type = eContextRegisterLoad; 11462 context.SetRegisterPlusOffset (base_reg, address - Rn); 11463 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11464 if (!success) 11465 return false; 11466 11467 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11468 11469 // address = address + ebytes; 11470 address = address + ebytes; 11471 } 11472 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11473 return false; 11474 } 11475 } 11476 return true; 11477 } 11478 11479 // A8.6.308 VLD1 (single element to one lane) 11480 // 11481 bool 11482 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11483 { 11484 #if 0 11485 if ConditionPassed() then 11486 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11487 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11488 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11489 Elem[D[d],index,esize] = MemU[address,ebytes]; 11490 #endif 11491 11492 bool success = false; 11493 11494 if (ConditionPassed (opcode)) 11495 { 11496 uint32_t ebytes; 11497 uint32_t esize; 11498 uint32_t index; 11499 uint32_t alignment; 11500 uint32_t d; 11501 uint32_t n; 11502 uint32_t m; 11503 bool wback; 11504 bool register_index; 11505 11506 switch (encoding) 11507 { 11508 case eEncodingT1: 11509 case eEncodingA1: 11510 { 11511 uint32_t size = Bits32 (opcode, 11, 10); 11512 uint32_t index_align = Bits32 (opcode, 7, 4); 11513 // if size == �11� then SEE VLD1 (single element to all lanes); 11514 if (size == 3) 11515 return EmulateVLD1SingleAll (opcode, encoding); 11516 // case size of 11517 if (size == 0) // when '00' 11518 { 11519 // if index_align<0> != �0� then UNDEFINED; 11520 if (BitIsClear (index_align, 0)) 11521 return false; 11522 11523 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11524 ebytes = 1; 11525 esize = 8; 11526 index = Bits32 (index_align, 3, 1); 11527 alignment = 1; 11528 } 11529 else if (size == 1) // when �01� 11530 { 11531 // if index_align<1> != �0� then UNDEFINED; 11532 if (BitIsClear (index_align, 1)) 11533 return false; 11534 11535 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11536 ebytes = 2; 11537 esize = 16; 11538 index = Bits32 (index_align, 3, 2); 11539 11540 // alignment = if index_align<0> == �0� then 1 else 2; 11541 if (BitIsClear (index_align, 0)) 11542 alignment = 1; 11543 else 11544 alignment = 2; 11545 } 11546 else if (size == 2) // when �10� 11547 { 11548 // if index_align<2> != �0� then UNDEFINED; 11549 if (BitIsClear (index_align, 2)) 11550 return false; 11551 11552 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11553 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11554 return false; 11555 11556 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11557 ebytes = 4; 11558 esize = 32; 11559 index = Bit32 (index_align, 3); 11560 11561 // alignment = if index_align<1:0> == �00� then 1 else 4; 11562 if (Bits32 (index_align, 1, 0) == 0) 11563 alignment = 1; 11564 else 11565 alignment = 4; 11566 } 11567 else 11568 { 11569 return false; 11570 } 11571 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11572 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11573 n = Bits32 (opcode, 19, 16); 11574 m = Bits32 (opcode, 3, 0); 11575 11576 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11577 wback = (m != 15); 11578 register_index = ((m != 15) && (m != 13)); 11579 11580 if (n == 15) 11581 return false; 11582 11583 } 11584 break; 11585 11586 default: 11587 return false; 11588 } 11589 11590 RegisterInfo base_reg; 11591 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11592 11593 uint32_t Rn = ReadCoreReg (n, &success); 11594 if (!success) 11595 return false; 11596 11597 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11598 addr_t address = Rn; 11599 if ((address % alignment) != 0) 11600 return false; 11601 11602 EmulateInstruction::Context context; 11603 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11604 if (wback) 11605 { 11606 uint32_t Rm = ReadCoreReg (m, &success); 11607 if (!success) 11608 return false; 11609 11610 uint32_t offset; 11611 if (register_index) 11612 offset = Rm; 11613 else 11614 offset = ebytes; 11615 11616 uint32_t value = Rn + offset; 11617 11618 context.type = eContextAdjustBaseRegister; 11619 context.SetRegisterPlusOffset (base_reg, offset); 11620 11621 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11622 return false; 11623 } 11624 11625 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11626 uint32_t element = MemURead (context, address, esize, 0, &success); 11627 if (!success) 11628 return false; 11629 11630 element = element << (index * esize); 11631 11632 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11633 if (!success) 11634 return false; 11635 11636 uint64_t all_ones = -1; 11637 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11638 // at element & to the right of element. 11639 if (index > 0) 11640 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11641 // now mask should be 0's where element goes & 1's 11642 // everywhere else. 11643 11644 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11645 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11646 11647 context.type = eContextRegisterLoad; 11648 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11649 return false; 11650 } 11651 return true; 11652 } 11653 11654 // A8.6.391 VST1 (multiple single elements) 11655 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without 11656 // interleaving. Every element of each register is stored. 11657 bool 11658 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11659 { 11660 #if 0 11661 if ConditionPassed() then 11662 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11663 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11664 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11665 for r = 0 to regs-1 11666 for e = 0 to elements-1 11667 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11668 address = address + ebytes; 11669 #endif 11670 11671 bool success = false; 11672 11673 if (ConditionPassed (opcode)) 11674 { 11675 uint32_t regs; 11676 uint32_t alignment; 11677 uint32_t ebytes; 11678 uint32_t esize; 11679 uint32_t elements; 11680 uint32_t d; 11681 uint32_t n; 11682 uint32_t m; 11683 bool wback; 11684 bool register_index; 11685 11686 switch (encoding) 11687 { 11688 case eEncodingT1: 11689 case eEncodingA1: 11690 { 11691 uint32_t type = Bits32 (opcode, 11, 8); 11692 uint32_t align = Bits32 (opcode, 5, 4); 11693 11694 // case type of 11695 if (type == 7) // when �0111� 11696 { 11697 // regs = 1; if align<1> == �1� then UNDEFINED; 11698 regs = 1; 11699 if (BitIsSet (align, 1)) 11700 return false; 11701 } 11702 else if (type == 10) // when �1010� 11703 { 11704 // regs = 2; if align == �11� then UNDEFINED; 11705 regs = 2; 11706 if (align == 3) 11707 return false; 11708 } 11709 else if (type == 6) // when �0110� 11710 { 11711 // regs = 3; if align<1> == �1� then UNDEFINED; 11712 regs = 3; 11713 if (BitIsSet (align, 1)) 11714 return false; 11715 } 11716 else if (type == 2) // when �0010� 11717 // regs = 4; 11718 regs = 4; 11719 else // otherwise 11720 // SEE �Related encodings�; 11721 return false; 11722 11723 // alignment = if align == �00� then 1 else 4 << UInt(align); 11724 if (align == 0) 11725 alignment = 1; 11726 else 11727 alignment = 4 << align; 11728 11729 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11730 ebytes = 1 << Bits32 (opcode,7, 6); 11731 esize = 8 * ebytes; 11732 elements = 8 / ebytes; 11733 11734 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11735 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11736 n = Bits32 (opcode, 19, 16); 11737 m = Bits32 (opcode, 3, 0); 11738 11739 // wback = (m != 15); register_index = (m != 15 && m != 13); 11740 wback = (m != 15); 11741 register_index = ((m != 15) && (m != 13)); 11742 11743 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11744 if ((d + regs) > 32) 11745 return false; 11746 11747 if (n == 15) 11748 return false; 11749 11750 } 11751 break; 11752 11753 default: 11754 return false; 11755 } 11756 11757 RegisterInfo base_reg; 11758 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11759 11760 uint32_t Rn = ReadCoreReg (n, &success); 11761 if (!success) 11762 return false; 11763 11764 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11765 addr_t address = Rn; 11766 if ((address % alignment) != 0) 11767 return false; 11768 11769 EmulateInstruction::Context context; 11770 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11771 if (wback) 11772 { 11773 uint32_t Rm = ReadCoreReg (m, &success); 11774 if (!success) 11775 return false; 11776 11777 uint32_t offset; 11778 if (register_index) 11779 offset = Rm; 11780 else 11781 offset = 8 * regs; 11782 11783 context.type = eContextAdjustBaseRegister; 11784 context.SetRegisterPlusOffset (base_reg, offset); 11785 11786 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11787 return false; 11788 } 11789 11790 RegisterInfo data_reg; 11791 context.type = eContextRegisterStore; 11792 // for r = 0 to regs-1 11793 for (uint32_t r = 0; r < regs; ++r) 11794 { 11795 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11796 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11797 if (!success) 11798 return false; 11799 11800 // for e = 0 to elements-1 11801 for (uint32_t e = 0; e < elements; ++e) 11802 { 11803 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11804 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11805 11806 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11807 if (!MemUWrite (context, address, word, ebytes)) 11808 return false; 11809 11810 // address = address + ebytes; 11811 address = address + ebytes; 11812 } 11813 } 11814 } 11815 return true; 11816 } 11817 11818 // A8.6.392 VST1 (single element from one lane) 11819 // This instruction stores one element to memory from one element of a register. 11820 bool 11821 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11822 { 11823 #if 0 11824 if ConditionPassed() then 11825 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11826 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11827 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11828 MemU[address,ebytes] = Elem[D[d],index,esize]; 11829 #endif 11830 11831 bool success = false; 11832 11833 if (ConditionPassed (opcode)) 11834 { 11835 uint32_t ebytes; 11836 uint32_t esize; 11837 uint32_t index; 11838 uint32_t alignment; 11839 uint32_t d; 11840 uint32_t n; 11841 uint32_t m; 11842 bool wback; 11843 bool register_index; 11844 11845 switch (encoding) 11846 { 11847 case eEncodingT1: 11848 case eEncodingA1: 11849 { 11850 uint32_t size = Bits32 (opcode, 11, 10); 11851 uint32_t index_align = Bits32 (opcode, 7, 4); 11852 11853 // if size == �11� then UNDEFINED; 11854 if (size == 3) 11855 return false; 11856 11857 // case size of 11858 if (size == 0) // when �00� 11859 { 11860 // if index_align<0> != �0� then UNDEFINED; 11861 if (BitIsClear (index_align, 0)) 11862 return false; 11863 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11864 ebytes = 1; 11865 esize = 8; 11866 index = Bits32 (index_align, 3, 1); 11867 alignment = 1; 11868 } 11869 else if (size == 1) // when �01� 11870 { 11871 // if index_align<1> != �0� then UNDEFINED; 11872 if (BitIsClear (index_align, 1)) 11873 return false; 11874 11875 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11876 ebytes = 2; 11877 esize = 16; 11878 index = Bits32 (index_align, 3, 2); 11879 11880 // alignment = if index_align<0> == �0� then 1 else 2; 11881 if (BitIsClear (index_align, 0)) 11882 alignment = 1; 11883 else 11884 alignment = 2; 11885 } 11886 else if (size == 2) // when �10� 11887 { 11888 // if index_align<2> != �0� then UNDEFINED; 11889 if (BitIsClear (index_align, 2)) 11890 return false; 11891 11892 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11893 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11894 return false; 11895 11896 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11897 ebytes = 4; 11898 esize = 32; 11899 index = Bit32 (index_align, 3); 11900 11901 // alignment = if index_align<1:0> == �00� then 1 else 4; 11902 if (Bits32 (index_align, 1, 0) == 0) 11903 alignment = 1; 11904 else 11905 alignment = 4; 11906 } 11907 else 11908 { 11909 return false; 11910 } 11911 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11912 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11913 n = Bits32 (opcode, 19, 16); 11914 m = Bits32 (opcode, 3, 0); 11915 11916 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11917 wback = (m != 15); 11918 register_index = ((m != 15) && (m != 13)); 11919 11920 if (n == 15) 11921 return false; 11922 } 11923 break; 11924 11925 default: 11926 return false; 11927 } 11928 11929 RegisterInfo base_reg; 11930 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11931 11932 uint32_t Rn = ReadCoreReg (n, &success); 11933 if (!success) 11934 return false; 11935 11936 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11937 addr_t address = Rn; 11938 if ((address % alignment) != 0) 11939 return false; 11940 11941 EmulateInstruction::Context context; 11942 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11943 if (wback) 11944 { 11945 uint32_t Rm = ReadCoreReg (m, &success); 11946 if (!success) 11947 return false; 11948 11949 uint32_t offset; 11950 if (register_index) 11951 offset = Rm; 11952 else 11953 offset = ebytes; 11954 11955 context.type = eContextAdjustBaseRegister; 11956 context.SetRegisterPlusOffset (base_reg, offset); 11957 11958 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11959 return false; 11960 } 11961 11962 // MemU[address,ebytes] = Elem[D[d],index,esize]; 11963 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11964 if (!success) 11965 return false; 11966 11967 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 11968 11969 RegisterInfo data_reg; 11970 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 11971 context.type = eContextRegisterStore; 11972 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11973 11974 if (!MemUWrite (context, address, word, ebytes)) 11975 return false; 11976 } 11977 return true; 11978 } 11979 11980 // A8.6.309 VLD1 (single element to all lanes) 11981 // This instruction loads one element from memory into every element of one or two vectors. 11982 bool 11983 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 11984 { 11985 #if 0 11986 if ConditionPassed() then 11987 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11988 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11989 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11990 replicated_element = Replicate(MemU[address,ebytes], elements); 11991 for r = 0 to regs-1 11992 D[d+r] = replicated_element; 11993 #endif 11994 11995 bool success = false; 11996 11997 if (ConditionPassed (opcode)) 11998 { 11999 uint32_t ebytes; 12000 uint32_t elements; 12001 uint32_t regs; 12002 uint32_t alignment; 12003 uint32_t d; 12004 uint32_t n; 12005 uint32_t m; 12006 bool wback; 12007 bool register_index; 12008 12009 switch (encoding) 12010 { 12011 case eEncodingT1: 12012 case eEncodingA1: 12013 { 12014 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED; 12015 uint32_t size = Bits32 (opcode, 7, 6); 12016 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 12017 return false; 12018 12019 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2; 12020 ebytes = 1 << size; 12021 elements = 8 / ebytes; 12022 if (BitIsClear (opcode, 5)) 12023 regs = 1; 12024 else 12025 regs = 2; 12026 12027 //alignment = if a == �0� then 1 else ebytes; 12028 if (BitIsClear (opcode, 4)) 12029 alignment = 1; 12030 else 12031 alignment = ebytes; 12032 12033 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12034 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12035 n = Bits32 (opcode, 19, 16); 12036 m = Bits32 (opcode, 3, 0); 12037 12038 //wback = (m != 15); register_index = (m != 15 && m != 13); 12039 wback = (m != 15); 12040 register_index = ((m != 15) && (m != 13)); 12041 12042 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12043 if ((d + regs) > 32) 12044 return false; 12045 12046 if (n == 15) 12047 return false; 12048 } 12049 break; 12050 12051 default: 12052 return false; 12053 } 12054 12055 RegisterInfo base_reg; 12056 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12057 12058 uint32_t Rn = ReadCoreReg (n, &success); 12059 if (!success) 12060 return false; 12061 12062 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12063 addr_t address = Rn; 12064 if ((address % alignment) != 0) 12065 return false; 12066 12067 EmulateInstruction::Context context; 12068 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12069 if (wback) 12070 { 12071 uint32_t Rm = ReadCoreReg (m, &success); 12072 if (!success) 12073 return false; 12074 12075 uint32_t offset; 12076 if (register_index) 12077 offset = Rm; 12078 else 12079 offset = ebytes; 12080 12081 context.type = eContextAdjustBaseRegister; 12082 context.SetRegisterPlusOffset (base_reg, offset); 12083 12084 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12085 return false; 12086 } 12087 12088 // replicated_element = Replicate(MemU[address,ebytes], elements); 12089 12090 context.type = eContextRegisterLoad; 12091 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12092 if (!success) 12093 return false; 12094 12095 uint64_t replicated_element = 0; 12096 uint32_t esize = ebytes * 8; 12097 for (uint32_t e = 0; e < elements; ++e) 12098 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12099 12100 // for r = 0 to regs-1 12101 for (uint32_t r = 0; r < regs; ++r) 12102 { 12103 // D[d+r] = replicated_element; 12104 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12105 return false; 12106 } 12107 } 12108 return true; 12109 } 12110 12111 // B6.2.13 SUBS PC, LR and related instructions 12112 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12113 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12114 bool 12115 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12116 { 12117 #if 0 12118 if ConditionPassed() then 12119 EncodingSpecificOperations(); 12120 if CurrentInstrSet() == InstrSet_ThumbEE then 12121 UNPREDICTABLE; 12122 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12123 case opcode of 12124 when �0000� result = R[n] AND operand2; // AND 12125 when �0001� result = R[n] EOR operand2; // EOR 12126 when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12127 when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12128 when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12129 when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12130 when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12131 when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12132 when �1100� result = R[n] OR operand2; // ORR 12133 when �1101� result = operand2; // MOV 12134 when �1110� result = R[n] AND NOT(operand2); // BIC 12135 when �1111� result = NOT(operand2); // MVN 12136 CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12137 BranchWritePC(result); 12138 #endif 12139 12140 bool success = false; 12141 12142 if (ConditionPassed (opcode)) 12143 { 12144 uint32_t n; 12145 uint32_t m; 12146 uint32_t imm32; 12147 bool register_form; 12148 ARM_ShifterType shift_t; 12149 uint32_t shift_n; 12150 uint32_t code; 12151 12152 switch (encoding) 12153 { 12154 case eEncodingT1: 12155 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12156 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB 12157 n = 14; 12158 imm32 = Bits32 (opcode, 7, 0); 12159 register_form = false; 12160 code = 2; 12161 12162 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12163 if (InITBlock() && !LastInITBlock()) 12164 return false; 12165 12166 break; 12167 12168 case eEncodingA1: 12169 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12170 n = Bits32 (opcode, 19, 16); 12171 imm32 = ARMExpandImm (opcode); 12172 register_form = false; 12173 code = Bits32 (opcode, 24, 21); 12174 12175 break; 12176 12177 case eEncodingA2: 12178 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12179 n = Bits32 (opcode, 19, 16); 12180 m = Bits32 (opcode, 3, 0); 12181 register_form = true; 12182 12183 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12184 shift_n = DecodeImmShiftARM (opcode, shift_t); 12185 12186 break; 12187 12188 default: 12189 return false; 12190 } 12191 12192 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12193 uint32_t operand2; 12194 if (register_form) 12195 { 12196 uint32_t Rm = ReadCoreReg (m, &success); 12197 if (!success) 12198 return false; 12199 12200 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12201 if (!success) 12202 return false; 12203 } 12204 else 12205 { 12206 operand2 = imm32; 12207 } 12208 12209 uint32_t Rn = ReadCoreReg (n, &success); 12210 if (!success) 12211 return false; 12212 12213 AddWithCarryResult result; 12214 12215 // case opcode of 12216 switch (code) 12217 { 12218 case 0: // when �0000� 12219 // result = R[n] AND operand2; // AND 12220 result.result = Rn & operand2; 12221 break; 12222 12223 case 1: // when �0001� 12224 // result = R[n] EOR operand2; // EOR 12225 result.result = Rn ^ operand2; 12226 break; 12227 12228 case 2: // when �0010� 12229 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12230 result = AddWithCarry (Rn, ~(operand2), 1); 12231 break; 12232 12233 case 3: // when �0011� 12234 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12235 result = AddWithCarry (~(Rn), operand2, 1); 12236 break; 12237 12238 case 4: // when �0100� 12239 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12240 result = AddWithCarry (Rn, operand2, 0); 12241 break; 12242 12243 case 5: // when �0101� 12244 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12245 result = AddWithCarry (Rn, operand2, APSR_C); 12246 break; 12247 12248 case 6: // when �0110� 12249 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12250 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12251 break; 12252 12253 case 7: // when �0111� 12254 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12255 result = AddWithCarry (~(Rn), operand2, APSR_C); 12256 break; 12257 12258 case 10: // when �1100� 12259 // result = R[n] OR operand2; // ORR 12260 result.result = Rn | operand2; 12261 break; 12262 12263 case 11: // when �1101� 12264 // result = operand2; // MOV 12265 result.result = operand2; 12266 break; 12267 12268 case 12: // when �1110� 12269 // result = R[n] AND NOT(operand2); // BIC 12270 result.result = Rn & ~(operand2); 12271 break; 12272 12273 case 15: // when �1111� 12274 // result = NOT(operand2); // MVN 12275 result.result = ~(operand2); 12276 break; 12277 12278 default: 12279 return false; 12280 } 12281 // CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12282 12283 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12284 // the best. 12285 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12286 if (!success) 12287 return false; 12288 12289 CPSRWriteByInstr (spsr, 15, true); 12290 12291 // BranchWritePC(result); 12292 EmulateInstruction::Context context; 12293 context.type = eContextAdjustPC; 12294 context.SetImmediate (result.result); 12295 12296 BranchWritePC (context, result.result); 12297 } 12298 return true; 12299 } 12300 12301 EmulateInstructionARM::ARMOpcode* 12302 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12303 { 12304 static ARMOpcode 12305 g_arm_opcodes[] = 12306 { 12307 //---------------------------------------------------------------------- 12308 // Prologue instructions 12309 //---------------------------------------------------------------------- 12310 12311 // push register(s) 12312 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12313 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12314 12315 // set r7 to point to a stack offset 12316 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12317 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12318 // copy the stack pointer to ip 12319 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12320 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12321 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12322 12323 // adjust the stack pointer 12324 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12325 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12326 12327 // push one register 12328 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12329 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12330 12331 // vector push consecutive extension register(s) 12332 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12333 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12334 12335 //---------------------------------------------------------------------- 12336 // Epilogue instructions 12337 //---------------------------------------------------------------------- 12338 12339 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12340 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12341 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12342 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12343 12344 //---------------------------------------------------------------------- 12345 // Supervisor Call (previously Software Interrupt) 12346 //---------------------------------------------------------------------- 12347 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12348 12349 //---------------------------------------------------------------------- 12350 // Branch instructions 12351 //---------------------------------------------------------------------- 12352 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>". 12353 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12354 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12355 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12356 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12357 // for example, "bx lr" 12358 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12359 // bxj 12360 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12361 12362 //---------------------------------------------------------------------- 12363 // Data-processing instructions 12364 //---------------------------------------------------------------------- 12365 // adc (immediate) 12366 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12367 // adc (register) 12368 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12369 // add (immediate) 12370 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12371 // add (register) 12372 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12373 // add (register-shifted register) 12374 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12375 // adr 12376 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12377 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12378 // and (immediate) 12379 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12380 // and (register) 12381 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12382 // bic (immediate) 12383 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12384 // bic (register) 12385 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12386 // eor (immediate) 12387 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12388 // eor (register) 12389 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12390 // orr (immediate) 12391 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12392 // orr (register) 12393 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12394 // rsb (immediate) 12395 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12396 // rsb (register) 12397 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12398 // rsc (immediate) 12399 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12400 // rsc (register) 12401 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12402 // sbc (immediate) 12403 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12404 // sbc (register) 12405 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12406 // sub (immediate, ARM) 12407 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12408 // sub (sp minus immediate) 12409 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12410 // sub (register) 12411 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12412 // teq (immediate) 12413 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12414 // teq (register) 12415 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12416 // tst (immediate) 12417 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12418 // tst (register) 12419 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12420 12421 // mov (immediate) 12422 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12423 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12424 // mov (register) 12425 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12426 // mvn (immediate) 12427 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12428 // mvn (register) 12429 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12430 // cmn (immediate) 12431 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12432 // cmn (register) 12433 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12434 // cmp (immediate) 12435 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12436 // cmp (register) 12437 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12438 // asr (immediate) 12439 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12440 // asr (register) 12441 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12442 // lsl (immediate) 12443 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12444 // lsl (register) 12445 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12446 // lsr (immediate) 12447 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12448 // lsr (register) 12449 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12450 // rrx is a special case encoding of ror (immediate) 12451 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12452 // ror (immediate) 12453 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12454 // ror (register) 12455 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12456 // mul 12457 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12458 12459 // subs pc, lr and related instructions 12460 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12461 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12462 12463 //---------------------------------------------------------------------- 12464 // Load instructions 12465 //---------------------------------------------------------------------- 12466 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12467 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12468 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12469 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12470 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12471 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12472 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12473 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12474 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12475 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12476 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12477 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12478 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12479 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12480 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12481 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12482 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12483 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12484 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12485 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12486 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12487 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12488 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12489 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12490 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12491 12492 //---------------------------------------------------------------------- 12493 // Store instructions 12494 //---------------------------------------------------------------------- 12495 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12496 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12497 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12498 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12499 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12500 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12501 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12502 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12503 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12504 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12505 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12506 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12507 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12508 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12509 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12510 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12511 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12512 12513 //---------------------------------------------------------------------- 12514 // Other instructions 12515 //---------------------------------------------------------------------- 12516 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12517 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12518 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12519 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12520 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12521 12522 }; 12523 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 12524 12525 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12526 { 12527 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12528 (g_arm_opcodes[i].variants & arm_isa) != 0) 12529 return &g_arm_opcodes[i]; 12530 } 12531 return NULL; 12532 } 12533 12534 12535 EmulateInstructionARM::ARMOpcode* 12536 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12537 { 12538 12539 static ARMOpcode 12540 g_thumb_opcodes[] = 12541 { 12542 //---------------------------------------------------------------------- 12543 // Prologue instructions 12544 //---------------------------------------------------------------------- 12545 12546 // push register(s) 12547 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12548 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12549 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12550 12551 // set r7 to point to a stack offset 12552 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12553 // copy the stack pointer to r7 12554 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12555 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12556 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12557 12558 // PC-relative load into register (see also EmulateADDSPRm) 12559 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12560 12561 // adjust the stack pointer 12562 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12563 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12564 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12565 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12566 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12567 12568 // vector push consecutive extension register(s) 12569 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12570 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12571 12572 //---------------------------------------------------------------------- 12573 // Epilogue instructions 12574 //---------------------------------------------------------------------- 12575 12576 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12577 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12578 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12579 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12580 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12581 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12582 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12583 12584 //---------------------------------------------------------------------- 12585 // Supervisor Call (previously Software Interrupt) 12586 //---------------------------------------------------------------------- 12587 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12588 12589 //---------------------------------------------------------------------- 12590 // If Then makes up to four following instructions conditional. 12591 //---------------------------------------------------------------------- 12592 // The next 5 opcode _must_ come before the if then instruction 12593 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12594 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12595 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12596 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12597 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12598 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12599 12600 //---------------------------------------------------------------------- 12601 // Branch instructions 12602 //---------------------------------------------------------------------- 12603 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12604 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12605 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12606 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12607 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12608 // J1 == J2 == 1 12609 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12610 // J1 == J2 == 1 12611 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12612 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12613 // for example, "bx lr" 12614 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12615 // bxj 12616 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12617 // compare and branch 12618 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12619 // table branch byte 12620 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12621 // table branch halfword 12622 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12623 12624 //---------------------------------------------------------------------- 12625 // Data-processing instructions 12626 //---------------------------------------------------------------------- 12627 // adc (immediate) 12628 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12629 // adc (register) 12630 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12631 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12632 // add (register) 12633 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12634 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12635 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12636 // adr 12637 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12638 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12639 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12640 // and (immediate) 12641 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12642 // and (register) 12643 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12644 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12645 // bic (immediate) 12646 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12647 // bic (register) 12648 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12649 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12650 // eor (immediate) 12651 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12652 // eor (register) 12653 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12654 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12655 // orr (immediate) 12656 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12657 // orr (register) 12658 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12659 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12660 // rsb (immediate) 12661 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12662 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12663 // rsb (register) 12664 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12665 // sbc (immediate) 12666 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12667 // sbc (register) 12668 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12669 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12670 // add (immediate, Thumb) 12671 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12672 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12673 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12674 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12675 // sub (immediate, Thumb) 12676 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12677 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12678 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12679 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12680 // sub (sp minus immediate) 12681 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12682 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12683 // sub (register) 12684 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12685 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12686 // teq (immediate) 12687 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12688 // teq (register) 12689 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12690 // tst (immediate) 12691 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12692 // tst (register) 12693 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12694 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12695 12696 12697 // move from high register to high register 12698 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12699 // move from low register to low register 12700 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12701 // mov{s}<c>.w <Rd>, <Rm> 12702 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12703 // move immediate 12704 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12705 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12706 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12707 // mvn (immediate) 12708 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12709 // mvn (register) 12710 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12711 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12712 // cmn (immediate) 12713 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12714 // cmn (register) 12715 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12716 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12717 // cmp (immediate) 12718 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12719 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12720 // cmp (register) (Rn and Rm both from r0-r7) 12721 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12722 // cmp (register) (Rn and Rm not both from r0-r7) 12723 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12724 // asr (immediate) 12725 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12726 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12727 // asr (register) 12728 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12729 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12730 // lsl (immediate) 12731 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12732 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12733 // lsl (register) 12734 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12735 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12736 // lsr (immediate) 12737 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12738 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12739 // lsr (register) 12740 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12741 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12742 // rrx is a special case encoding of ror (immediate) 12743 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12744 // ror (immediate) 12745 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12746 // ror (register) 12747 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12748 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12749 // mul 12750 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12751 // mul 12752 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12753 12754 // subs pc, lr and related instructions 12755 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12756 12757 //---------------------------------------------------------------------- 12758 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12759 // otherwise the wrong instructions will be selected. 12760 //---------------------------------------------------------------------- 12761 12762 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12763 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12764 12765 //---------------------------------------------------------------------- 12766 // Load instructions 12767 //---------------------------------------------------------------------- 12768 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12769 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12770 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12771 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12772 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12773 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12774 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12775 // Thumb2 PC-relative load into register 12776 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12777 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12778 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12779 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12780 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12781 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12782 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12783 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12784 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12785 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12786 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12787 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12788 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12789 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12790 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12791 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12792 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12793 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12794 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12795 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12796 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12797 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12798 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12799 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12800 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12801 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12802 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12803 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12804 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12805 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12806 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12807 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12808 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12809 12810 //---------------------------------------------------------------------- 12811 // Store instructions 12812 //---------------------------------------------------------------------- 12813 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12814 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12815 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12816 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12817 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12818 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12819 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12820 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12821 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12822 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12823 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12824 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12825 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12826 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12827 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12828 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12829 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12830 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12831 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12832 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12833 { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12834 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12835 12836 //---------------------------------------------------------------------- 12837 // Other instructions 12838 //---------------------------------------------------------------------- 12839 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12840 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12841 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12842 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12843 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12844 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12845 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12846 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12847 }; 12848 12849 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 12850 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12851 { 12852 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12853 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12854 return &g_thumb_opcodes[i]; 12855 } 12856 return NULL; 12857 } 12858 12859 bool 12860 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12861 { 12862 m_arch = arch; 12863 m_arm_isa = 0; 12864 const char *arch_cstr = arch.GetArchitectureName (); 12865 if (arch_cstr) 12866 { 12867 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12868 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12869 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12870 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12871 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12872 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12873 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12874 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12875 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12876 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12877 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12878 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12879 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12880 } 12881 return m_arm_isa != 0; 12882 } 12883 12884 bool 12885 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12886 { 12887 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12888 { 12889 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12890 m_opcode_mode = eModeThumb; 12891 else 12892 { 12893 AddressClass addr_class = inst_addr.GetAddressClass(); 12894 12895 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 12896 m_opcode_mode = eModeARM; 12897 else if (addr_class == eAddressClassCodeAlternateISA) 12898 m_opcode_mode = eModeThumb; 12899 else 12900 return false; 12901 } 12902 if (m_opcode_mode == eModeThumb) 12903 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 12904 else 12905 m_opcode_cpsr = CPSR_MODE_USR; 12906 return true; 12907 } 12908 return false; 12909 } 12910 12911 bool 12912 EmulateInstructionARM::ReadInstruction () 12913 { 12914 bool success = false; 12915 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 12916 if (success) 12917 { 12918 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 12919 if (success) 12920 { 12921 Context read_inst_context; 12922 read_inst_context.type = eContextReadOpcode; 12923 read_inst_context.SetNoArgs (); 12924 12925 if (m_opcode_cpsr & MASK_CPSR_T) 12926 { 12927 m_opcode_mode = eModeThumb; 12928 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 12929 12930 if (success) 12931 { 12932 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 12933 { 12934 m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder()); 12935 } 12936 else 12937 { 12938 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder()); 12939 } 12940 } 12941 } 12942 else 12943 { 12944 m_opcode_mode = eModeARM; 12945 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder()); 12946 } 12947 } 12948 } 12949 if (!success) 12950 { 12951 m_opcode_mode = eModeInvalid; 12952 m_addr = LLDB_INVALID_ADDRESS; 12953 } 12954 return success; 12955 } 12956 12957 uint32_t 12958 EmulateInstructionARM::ArchVersion () 12959 { 12960 return m_arm_isa; 12961 } 12962 12963 bool 12964 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) 12965 { 12966 // If we are ignoring conditions, then always return true. 12967 // this allows us to iterate over disassembly code and still 12968 // emulate an instruction even if we don't have all the right 12969 // bits set in the CPSR register... 12970 if (m_ignore_conditions) 12971 return true; 12972 12973 if (is_conditional) 12974 *is_conditional = true; 12975 12976 const uint32_t cond = CurrentCond (opcode); 12977 12978 if (cond == UINT32_MAX) 12979 return false; 12980 12981 bool result = false; 12982 switch (UnsignedBits(cond, 3, 1)) 12983 { 12984 case 0: 12985 if (m_opcode_cpsr == 0) 12986 result = true; 12987 else 12988 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 12989 break; 12990 case 1: 12991 if (m_opcode_cpsr == 0) 12992 result = true; 12993 else 12994 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 12995 break; 12996 case 2: 12997 if (m_opcode_cpsr == 0) 12998 result = true; 12999 else 13000 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13001 break; 13002 case 3: 13003 if (m_opcode_cpsr == 0) 13004 result = true; 13005 else 13006 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13007 break; 13008 case 4: 13009 if (m_opcode_cpsr == 0) 13010 result = true; 13011 else 13012 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13013 break; 13014 case 5: 13015 if (m_opcode_cpsr == 0) 13016 result = true; 13017 else 13018 { 13019 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13020 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13021 result = n == v; 13022 } 13023 break; 13024 case 6: 13025 if (m_opcode_cpsr == 0) 13026 result = true; 13027 else 13028 { 13029 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13030 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13031 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13032 } 13033 break; 13034 case 7: 13035 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13036 // opcodes different meanings, but always means execution happens. 13037 if (is_conditional) 13038 *is_conditional = false; 13039 return true; 13040 } 13041 13042 if (cond & 1) 13043 result = !result; 13044 return result; 13045 } 13046 13047 uint32_t 13048 EmulateInstructionARM::CurrentCond (const uint32_t opcode) 13049 { 13050 switch (m_opcode_mode) 13051 { 13052 case eModeInvalid: 13053 break; 13054 13055 case eModeARM: 13056 return UnsignedBits(opcode, 31, 28); 13057 13058 case eModeThumb: 13059 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13060 // 'cond' field of the encoding. 13061 { 13062 const uint32_t byte_size = m_opcode.GetByteSize(); 13063 if (byte_size == 2) 13064 { 13065 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 13066 return Bits32(opcode, 11, 7); 13067 } 13068 else if (byte_size == 4) 13069 { 13070 if (Bits32(opcode, 31, 27) == 0x1e && 13071 Bits32(opcode, 15, 14) == 0x02 && 13072 Bits32(opcode, 12, 12) == 0x00 && 13073 Bits32(opcode, 25, 22) <= 0x0d) 13074 { 13075 return Bits32(opcode, 25, 22); 13076 } 13077 } 13078 else 13079 // We have an invalid thumb instruction, let's bail out. 13080 break; 13081 13082 return m_it_session.GetCond(); 13083 } 13084 } 13085 return UINT32_MAX; // Return invalid value 13086 } 13087 13088 bool 13089 EmulateInstructionARM::InITBlock() 13090 { 13091 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13092 } 13093 13094 bool 13095 EmulateInstructionARM::LastInITBlock() 13096 { 13097 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13098 } 13099 13100 bool 13101 EmulateInstructionARM::BadMode (uint32_t mode) 13102 { 13103 13104 switch (mode) 13105 { 13106 case 16: return false; // '10000' 13107 case 17: return false; // '10001' 13108 case 18: return false; // '10010' 13109 case 19: return false; // '10011' 13110 case 22: return false; // '10110' 13111 case 23: return false; // '10111' 13112 case 27: return false; // '11011' 13113 case 31: return false; // '11111' 13114 default: return true; 13115 } 13116 return true; 13117 } 13118 13119 bool 13120 EmulateInstructionARM::CurrentModeIsPrivileged () 13121 { 13122 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13123 13124 if (BadMode (mode)) 13125 return false; 13126 13127 if (mode == 16) 13128 return false; 13129 13130 return true; 13131 } 13132 13133 void 13134 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13135 { 13136 bool privileged = CurrentModeIsPrivileged(); 13137 13138 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13139 13140 if (BitIsSet (bytemask, 3)) 13141 { 13142 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13143 if (affect_execstate) 13144 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13145 } 13146 13147 if (BitIsSet (bytemask, 2)) 13148 { 13149 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13150 } 13151 13152 if (BitIsSet (bytemask, 1)) 13153 { 13154 if (affect_execstate) 13155 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13156 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13157 if (privileged) 13158 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13159 } 13160 13161 if (BitIsSet (bytemask, 0)) 13162 { 13163 if (privileged) 13164 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13165 if (affect_execstate) 13166 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13167 if (privileged) 13168 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13169 } 13170 13171 m_opcode_cpsr = tmp_cpsr; 13172 } 13173 13174 13175 bool 13176 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13177 { 13178 addr_t target; 13179 13180 // Check the current instruction set. 13181 if (CurrentInstrSet() == eModeARM) 13182 target = addr & 0xfffffffc; 13183 else 13184 target = addr & 0xfffffffe; 13185 13186 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13187 return false; 13188 13189 return true; 13190 } 13191 13192 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13193 bool 13194 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13195 { 13196 addr_t target; 13197 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13198 // we want to record it and issue a WriteRegister callback so the clients 13199 // can track the mode changes accordingly. 13200 bool cpsr_changed = false; 13201 13202 if (BitIsSet(addr, 0)) 13203 { 13204 if (CurrentInstrSet() != eModeThumb) 13205 { 13206 SelectInstrSet(eModeThumb); 13207 cpsr_changed = true; 13208 } 13209 target = addr & 0xfffffffe; 13210 context.SetISA (eModeThumb); 13211 } 13212 else if (BitIsClear(addr, 1)) 13213 { 13214 if (CurrentInstrSet() != eModeARM) 13215 { 13216 SelectInstrSet(eModeARM); 13217 cpsr_changed = true; 13218 } 13219 target = addr & 0xfffffffc; 13220 context.SetISA (eModeARM); 13221 } 13222 else 13223 return false; // address<1:0> == '10' => UNPREDICTABLE 13224 13225 if (cpsr_changed) 13226 { 13227 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13228 return false; 13229 } 13230 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13231 return false; 13232 13233 return true; 13234 } 13235 13236 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13237 bool 13238 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13239 { 13240 if (ArchVersion() >= ARMv5T) 13241 return BXWritePC(context, addr); 13242 else 13243 return BranchWritePC((const Context)context, addr); 13244 } 13245 13246 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13247 bool 13248 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13249 { 13250 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13251 return BXWritePC(context, addr); 13252 else 13253 return BranchWritePC((const Context)context, addr); 13254 } 13255 13256 EmulateInstructionARM::Mode 13257 EmulateInstructionARM::CurrentInstrSet () 13258 { 13259 return m_opcode_mode; 13260 } 13261 13262 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13263 // ReadInstruction() is performed. This function has a side effect of updating 13264 // the m_new_inst_cpsr member variable if necessary. 13265 bool 13266 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13267 { 13268 m_new_inst_cpsr = m_opcode_cpsr; 13269 switch (arm_or_thumb) 13270 { 13271 default: 13272 return false; 13273 case eModeARM: 13274 // Clear the T bit. 13275 m_new_inst_cpsr &= ~MASK_CPSR_T; 13276 break; 13277 case eModeThumb: 13278 // Set the T bit. 13279 m_new_inst_cpsr |= MASK_CPSR_T; 13280 break; 13281 } 13282 return true; 13283 } 13284 13285 // This function returns TRUE if the processor currently provides support for 13286 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13287 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13288 bool 13289 EmulateInstructionARM::UnalignedSupport() 13290 { 13291 return (ArchVersion() >= ARMv7); 13292 } 13293 13294 // The main addition and subtraction instructions can produce status information 13295 // about both unsigned carry and signed overflow conditions. This status 13296 // information can be used to synthesize multi-word additions and subtractions. 13297 EmulateInstructionARM::AddWithCarryResult 13298 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13299 { 13300 uint32_t result; 13301 uint8_t carry_out; 13302 uint8_t overflow; 13303 13304 uint64_t unsigned_sum = x + y + carry_in; 13305 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13306 13307 result = UnsignedBits(unsigned_sum, 31, 0); 13308 // carry_out = (result == unsigned_sum ? 0 : 1); 13309 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13310 13311 if (carry_in) 13312 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13313 else 13314 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13315 13316 AddWithCarryResult res = { result, carry_out, overflow }; 13317 return res; 13318 } 13319 13320 uint32_t 13321 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13322 { 13323 lldb::RegisterKind reg_kind; 13324 uint32_t reg_num; 13325 switch (num) 13326 { 13327 case SP_REG: 13328 reg_kind = eRegisterKindGeneric; 13329 reg_num = LLDB_REGNUM_GENERIC_SP; 13330 break; 13331 case LR_REG: 13332 reg_kind = eRegisterKindGeneric; 13333 reg_num = LLDB_REGNUM_GENERIC_RA; 13334 break; 13335 case PC_REG: 13336 reg_kind = eRegisterKindGeneric; 13337 reg_num = LLDB_REGNUM_GENERIC_PC; 13338 break; 13339 default: 13340 if (num < SP_REG) 13341 { 13342 reg_kind = eRegisterKindDWARF; 13343 reg_num = dwarf_r0 + num; 13344 } 13345 else 13346 { 13347 //assert(0 && "Invalid register number"); 13348 *success = false; 13349 return UINT32_MAX; 13350 } 13351 break; 13352 } 13353 13354 // Read our register. 13355 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13356 13357 // When executing an ARM instruction , PC reads as the address of the current 13358 // instruction plus 8. 13359 // When executing a Thumb instruction , PC reads as the address of the current 13360 // instruction plus 4. 13361 if (num == 15) 13362 { 13363 if (CurrentInstrSet() == eModeARM) 13364 val += 8; 13365 else 13366 val += 4; 13367 } 13368 13369 return val; 13370 } 13371 13372 // Write the result to the ARM core register Rd, and optionally update the 13373 // condition flags based on the result. 13374 // 13375 // This helper method tries to encapsulate the following pseudocode from the 13376 // ARM Architecture Reference Manual: 13377 // 13378 // if d == 15 then // Can only occur for encoding A1 13379 // ALUWritePC(result); // setflags is always FALSE here 13380 // else 13381 // R[d] = result; 13382 // if setflags then 13383 // APSR.N = result<31>; 13384 // APSR.Z = IsZeroBit(result); 13385 // APSR.C = carry; 13386 // // APSR.V unchanged 13387 // 13388 // In the above case, the API client does not pass in the overflow arg, which 13389 // defaults to ~0u. 13390 bool 13391 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13392 const uint32_t result, 13393 const uint32_t Rd, 13394 bool setflags, 13395 const uint32_t carry, 13396 const uint32_t overflow) 13397 { 13398 if (Rd == 15) 13399 { 13400 if (!ALUWritePC (context, result)) 13401 return false; 13402 } 13403 else 13404 { 13405 lldb::RegisterKind reg_kind; 13406 uint32_t reg_num; 13407 switch (Rd) 13408 { 13409 case SP_REG: 13410 reg_kind = eRegisterKindGeneric; 13411 reg_num = LLDB_REGNUM_GENERIC_SP; 13412 break; 13413 case LR_REG: 13414 reg_kind = eRegisterKindGeneric; 13415 reg_num = LLDB_REGNUM_GENERIC_RA; 13416 break; 13417 default: 13418 reg_kind = eRegisterKindDWARF; 13419 reg_num = dwarf_r0 + Rd; 13420 } 13421 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13422 return false; 13423 if (setflags) 13424 return WriteFlags (context, result, carry, overflow); 13425 } 13426 return true; 13427 } 13428 13429 // This helper method tries to encapsulate the following pseudocode from the 13430 // ARM Architecture Reference Manual: 13431 // 13432 // APSR.N = result<31>; 13433 // APSR.Z = IsZeroBit(result); 13434 // APSR.C = carry; 13435 // APSR.V = overflow 13436 // 13437 // Default arguments can be specified for carry and overflow parameters, which means 13438 // not to update the respective flags. 13439 bool 13440 EmulateInstructionARM::WriteFlags (Context &context, 13441 const uint32_t result, 13442 const uint32_t carry, 13443 const uint32_t overflow) 13444 { 13445 m_new_inst_cpsr = m_opcode_cpsr; 13446 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13447 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13448 if (carry != ~0u) 13449 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13450 if (overflow != ~0u) 13451 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13452 if (m_new_inst_cpsr != m_opcode_cpsr) 13453 { 13454 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13455 return false; 13456 } 13457 return true; 13458 } 13459 13460 bool 13461 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13462 { 13463 // Advance the ITSTATE bits to their values for the next instruction. 13464 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13465 m_it_session.ITAdvance(); 13466 13467 ARMOpcode *opcode_data = NULL; 13468 13469 if (m_opcode_mode == eModeThumb) 13470 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13471 else if (m_opcode_mode == eModeARM) 13472 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13473 13474 if (opcode_data == NULL) 13475 return false; 13476 13477 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13478 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13479 13480 bool success = false; 13481 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13482 { 13483 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13484 dwarf_cpsr, 13485 0, 13486 &success); 13487 } 13488 13489 // Only return false if we are unable to read the CPSR if we care about conditions 13490 if (success == false && m_ignore_conditions == false) 13491 return false; 13492 13493 uint32_t orig_pc_value = 0; 13494 if (auto_advance_pc) 13495 { 13496 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13497 if (!success) 13498 return false; 13499 } 13500 13501 // Call the Emulate... function. 13502 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13503 if (!success) 13504 return false; 13505 13506 if (auto_advance_pc) 13507 { 13508 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13509 if (!success) 13510 return false; 13511 13512 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13513 { 13514 if (opcode_data->size == eSize32) 13515 after_pc_value += 4; 13516 else if (opcode_data->size == eSize16) 13517 after_pc_value += 2; 13518 13519 EmulateInstruction::Context context; 13520 context.type = eContextAdvancePC; 13521 context.SetNoArgs(); 13522 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13523 return false; 13524 13525 } 13526 } 13527 return true; 13528 } 13529 13530 bool 13531 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13532 { 13533 if (!test_data) 13534 { 13535 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13536 return false; 13537 } 13538 13539 static ConstString opcode_key ("opcode"); 13540 static ConstString before_key ("before_state"); 13541 static ConstString after_key ("after_state"); 13542 13543 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13544 13545 uint32_t test_opcode; 13546 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13547 { 13548 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13549 return false; 13550 } 13551 test_opcode = value_sp->GetUInt64Value (); 13552 13553 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13554 { 13555 m_opcode_mode = eModeARM; 13556 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13557 } 13558 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13559 { 13560 m_opcode_mode = eModeThumb; 13561 if (test_opcode < 0x10000) 13562 m_opcode.SetOpcode16 (test_opcode, GetByteOrder()); 13563 else 13564 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13565 13566 } 13567 else 13568 { 13569 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13570 return false; 13571 } 13572 13573 EmulationStateARM before_state; 13574 EmulationStateARM after_state; 13575 13576 value_sp = test_data->GetValueForKey (before_key); 13577 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13578 { 13579 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13580 return false; 13581 } 13582 13583 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13584 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13585 { 13586 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13587 return false; 13588 } 13589 13590 value_sp = test_data->GetValueForKey (after_key); 13591 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13592 { 13593 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13594 return false; 13595 } 13596 13597 state_dictionary = value_sp->GetAsDictionary (); 13598 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13599 { 13600 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13601 return false; 13602 } 13603 13604 SetBaton ((void *) &before_state); 13605 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13606 &EmulationStateARM::WritePseudoMemory, 13607 &EmulationStateARM::ReadPseudoRegister, 13608 &EmulationStateARM::WritePseudoRegister); 13609 13610 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13611 if (!success) 13612 { 13613 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13614 return false; 13615 } 13616 13617 success = before_state.CompareState (after_state); 13618 if (!success) 13619 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13620 13621 return success; 13622 } 13623 // 13624 // 13625 //const char * 13626 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13627 //{ 13628 // if (reg_kind == eRegisterKindGeneric) 13629 // { 13630 // switch (reg_num) 13631 // { 13632 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 13633 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 13634 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 13635 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 13636 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13637 // default: return NULL; 13638 // } 13639 // } 13640 // else if (reg_kind == eRegisterKindDWARF) 13641 // { 13642 // return GetARMDWARFRegisterName (reg_num); 13643 // } 13644 // return NULL; 13645 //} 13646 // 13647 bool 13648 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13649 { 13650 unwind_plan.Clear(); 13651 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13652 13653 UnwindPlan::RowSP row(new UnwindPlan::Row); 13654 13655 // Our previous Call Frame Address is the stack pointer 13656 row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0); 13657 13658 // Our previous PC is in the LR 13659 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true); 13660 unwind_plan.AppendRow (row); 13661 13662 // All other registers are the same. 13663 13664 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13665 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 13666 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 13667 return true; 13668 } 13669