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/Support/MathExtras.h" // for SignExtend32 template function 28 // and countTrailingZeros function 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 // Convenient macro definitions. 34 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 35 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 36 37 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 38 39 //---------------------------------------------------------------------- 40 // 41 // ITSession implementation 42 // 43 //---------------------------------------------------------------------- 44 45 // A8.6.50 46 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 47 static uint32_t 48 CountITSize (uint32_t ITMask) { 49 // First count the trailing zeros of the IT mask. 50 uint32_t TZ = llvm::countTrailingZeros(ITMask); 51 if (TZ > 3) 52 { 53 #ifdef LLDB_CONFIGURATION_DEBUG 54 printf("Encoding error: IT Mask '0000'\n"); 55 #endif 56 return 0; 57 } 58 return (4 - TZ); 59 } 60 61 // Init ITState. Note that at least one bit is always 1 in mask. 62 bool ITSession::InitIT(uint32_t bits7_0) 63 { 64 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 65 if (ITCounter == 0) 66 return false; 67 68 // A8.6.50 IT 69 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 70 if (FirstCond == 0xF) 71 { 72 #ifdef LLDB_CONFIGURATION_DEBUG 73 printf("Encoding error: IT FirstCond '1111'\n"); 74 #endif 75 return false; 76 } 77 if (FirstCond == 0xE && ITCounter != 1) 78 { 79 #ifdef LLDB_CONFIGURATION_DEBUG 80 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 81 #endif 82 return false; 83 } 84 85 ITState = bits7_0; 86 return true; 87 } 88 89 // Update ITState if necessary. 90 void ITSession::ITAdvance() 91 { 92 //assert(ITCounter); 93 --ITCounter; 94 if (ITCounter == 0) 95 ITState = 0; 96 else 97 { 98 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 99 SetBits32(ITState, 4, 0, NewITState4_0); 100 } 101 } 102 103 // Return true if we're inside an IT Block. 104 bool ITSession::InITBlock() 105 { 106 return ITCounter != 0; 107 } 108 109 // Return true if we're the last instruction inside an IT Block. 110 bool ITSession::LastInITBlock() 111 { 112 return ITCounter == 1; 113 } 114 115 // Get condition bits for the current thumb instruction. 116 uint32_t ITSession::GetCond() 117 { 118 if (InITBlock()) 119 return Bits32(ITState, 7, 4); 120 else 121 return COND_AL; 122 } 123 124 // ARM constants used during decoding 125 #define REG_RD 0 126 #define LDM_REGLIST 1 127 #define SP_REG 13 128 #define LR_REG 14 129 #define PC_REG 15 130 #define PC_REGLIST_BIT 0x8000 131 132 #define ARMv4 (1u << 0) 133 #define ARMv4T (1u << 1) 134 #define ARMv5T (1u << 2) 135 #define ARMv5TE (1u << 3) 136 #define ARMv5TEJ (1u << 4) 137 #define ARMv6 (1u << 5) 138 #define ARMv6K (1u << 6) 139 #define ARMv6T2 (1u << 7) 140 #define ARMv7 (1u << 8) 141 #define ARMv7S (1u << 9) 142 #define ARMv8 (1u << 10) 143 #define ARMvAll (0xffffffffu) 144 145 #define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 146 #define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 147 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 148 #define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 149 #define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 150 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8) 151 #define ARMV7_ABOVE (ARMv7|ARMv7S|ARMv8) 152 153 #define No_VFP 0 154 #define VFPv1 (1u << 1) 155 #define VFPv2 (1u << 2) 156 #define VFPv3 (1u << 3) 157 #define AdvancedSIMD (1u << 4) 158 159 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 160 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 161 #define VFPv2v3 (VFPv2 | VFPv3) 162 163 //---------------------------------------------------------------------- 164 // 165 // EmulateInstructionARM implementation 166 // 167 //---------------------------------------------------------------------- 168 169 void 170 EmulateInstructionARM::Initialize () 171 { 172 PluginManager::RegisterPlugin (GetPluginNameStatic (), 173 GetPluginDescriptionStatic (), 174 CreateInstance); 175 } 176 177 void 178 EmulateInstructionARM::Terminate () 179 { 180 PluginManager::UnregisterPlugin (CreateInstance); 181 } 182 183 ConstString 184 EmulateInstructionARM::GetPluginNameStatic () 185 { 186 static ConstString g_name("arm"); 187 return g_name; 188 } 189 190 const char * 191 EmulateInstructionARM::GetPluginDescriptionStatic () 192 { 193 return "Emulate instructions for the ARM architecture."; 194 } 195 196 EmulateInstruction * 197 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) 198 { 199 if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type)) 200 { 201 if (arch.GetTriple().getArch() == llvm::Triple::arm) 202 { 203 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 204 205 if (emulate_insn_ap.get()) 206 return emulate_insn_ap.release(); 207 } 208 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 209 { 210 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 211 212 if (emulate_insn_ap.get()) 213 return emulate_insn_ap.release(); 214 } 215 } 216 217 return NULL; 218 } 219 220 bool 221 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch) 222 { 223 if (arch.GetTriple().getArch () == llvm::Triple::arm) 224 return true; 225 else if (arch.GetTriple().getArch () == llvm::Triple::thumb) 226 return true; 227 228 return false; 229 } 230 231 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 232 bool 233 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 234 { 235 EmulateInstruction::Context context; 236 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 237 context.SetNoArgs (); 238 239 uint32_t random_data = rand (); 240 const uint32_t addr_byte_size = GetAddressByteSize(); 241 242 if (!MemAWrite (context, address, random_data, addr_byte_size)) 243 return false; 244 245 return true; 246 } 247 248 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 249 bool 250 EmulateInstructionARM::WriteBits32Unknown (int n) 251 { 252 EmulateInstruction::Context context; 253 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 254 context.SetNoArgs (); 255 256 bool success; 257 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 258 259 if (!success) 260 return false; 261 262 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 263 return false; 264 265 return true; 266 } 267 268 bool 269 EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo ®_info) 270 { 271 if (reg_kind == eRegisterKindGeneric) 272 { 273 switch (reg_num) 274 { 275 case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break; 276 case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break; 277 case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break; 278 case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break; 279 case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break; 280 default: return false; 281 } 282 } 283 284 if (reg_kind == eRegisterKindDWARF) 285 return GetARMDWARFRegisterInfo(reg_num, reg_info); 286 return false; 287 } 288 289 uint32_t 290 EmulateInstructionARM::GetFramePointerRegisterNumber () const 291 { 292 if (m_opcode_mode == eModeThumb) 293 { 294 switch (m_arch.GetTriple().getOS()) 295 { 296 case llvm::Triple::Darwin: 297 case llvm::Triple::MacOSX: 298 case llvm::Triple::IOS: 299 return 7; 300 default: 301 break; 302 } 303 } 304 return 11; 305 } 306 307 uint32_t 308 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 309 { 310 if (m_opcode_mode == eModeThumb) 311 { 312 switch (m_arch.GetTriple().getOS()) 313 { 314 case llvm::Triple::Darwin: 315 case llvm::Triple::MacOSX: 316 case llvm::Triple::IOS: 317 return dwarf_r7; 318 default: 319 break; 320 } 321 } 322 return dwarf_r11; 323 } 324 325 // Push Multiple Registers stores multiple registers to the stack, storing to 326 // consecutive memory locations ending just below the address in SP, and updates 327 // SP to point to the start of the stored data. 328 bool 329 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 330 { 331 #if 0 332 // ARM pseudo code... 333 if (ConditionPassed()) 334 { 335 EncodingSpecificOperations(); 336 NullCheckIfThumbEE(13); 337 address = SP - 4*BitCount(registers); 338 339 for (i = 0 to 14) 340 { 341 if (registers<i> == '1') 342 { 343 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 344 MemA[address,4] = bits(32) UNKNOWN; 345 else 346 MemA[address,4] = R[i]; 347 address = address + 4; 348 } 349 } 350 351 if (registers<15> == '1') // Only possible for encoding A1 or A2 352 MemA[address,4] = PCStoreValue(); 353 354 SP = SP - 4*BitCount(registers); 355 } 356 #endif 357 358 bool conditional = false; 359 bool success = false; 360 if (ConditionPassed(opcode, &conditional)) 361 { 362 const uint32_t addr_byte_size = GetAddressByteSize(); 363 const addr_t sp = ReadCoreReg (SP_REG, &success); 364 if (!success) 365 return false; 366 uint32_t registers = 0; 367 uint32_t Rt; // the source register 368 switch (encoding) { 369 case eEncodingT1: 370 registers = Bits32(opcode, 7, 0); 371 // The M bit represents LR. 372 if (Bit32(opcode, 8)) 373 registers |= (1u << 14); 374 // if BitCount(registers) < 1 then UNPREDICTABLE; 375 if (BitCount(registers) < 1) 376 return false; 377 break; 378 case eEncodingT2: 379 // Ignore bits 15 & 13. 380 registers = Bits32(opcode, 15, 0) & ~0xa000; 381 // if BitCount(registers) < 2 then UNPREDICTABLE; 382 if (BitCount(registers) < 2) 383 return false; 384 break; 385 case eEncodingT3: 386 Rt = Bits32(opcode, 15, 12); 387 // if BadReg(t) then UNPREDICTABLE; 388 if (BadReg(Rt)) 389 return false; 390 registers = (1u << Rt); 391 break; 392 case eEncodingA1: 393 registers = Bits32(opcode, 15, 0); 394 // Instead of return false, let's handle the following case as well, 395 // which amounts to pushing one reg onto the full descending stacks. 396 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 397 break; 398 case eEncodingA2: 399 Rt = Bits32(opcode, 15, 12); 400 // if t == 13 then UNPREDICTABLE; 401 if (Rt == dwarf_sp) 402 return false; 403 registers = (1u << Rt); 404 break; 405 default: 406 return false; 407 } 408 addr_t sp_offset = addr_byte_size * BitCount (registers); 409 addr_t addr = sp - sp_offset; 410 uint32_t i; 411 412 EmulateInstruction::Context context; 413 if (conditional) 414 context.type = EmulateInstruction::eContextRegisterStore; 415 else 416 context.type = EmulateInstruction::eContextPushRegisterOnStack; 417 RegisterInfo reg_info; 418 RegisterInfo sp_reg; 419 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 420 for (i=0; i<15; ++i) 421 { 422 if (BitIsSet (registers, i)) 423 { 424 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 425 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 426 uint32_t reg_value = ReadCoreReg(i, &success); 427 if (!success) 428 return false; 429 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 430 return false; 431 addr += addr_byte_size; 432 } 433 } 434 435 if (BitIsSet (registers, 15)) 436 { 437 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 438 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 439 const uint32_t pc = ReadCoreReg(PC_REG, &success); 440 if (!success) 441 return false; 442 if (!MemAWrite (context, addr, pc, addr_byte_size)) 443 return false; 444 } 445 446 context.type = EmulateInstruction::eContextAdjustStackPointer; 447 context.SetImmediateSigned (-sp_offset); 448 449 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 450 return false; 451 } 452 return true; 453 } 454 455 // Pop Multiple Registers loads multiple registers from the stack, loading from 456 // consecutive memory locations staring at the address in SP, and updates 457 // SP to point just above the loaded data. 458 bool 459 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 460 { 461 #if 0 462 // ARM pseudo code... 463 if (ConditionPassed()) 464 { 465 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 466 address = SP; 467 for i = 0 to 14 468 if registers<i> == '1' then 469 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 470 if registers<15> == '1' then 471 if UnalignedAllowed then 472 LoadWritePC(MemU[address,4]); 473 else 474 LoadWritePC(MemA[address,4]); 475 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 476 if registers<13> == '1' then SP = bits(32) UNKNOWN; 477 } 478 #endif 479 480 bool success = false; 481 482 bool conditional = false; 483 if (ConditionPassed(opcode, &conditional)) 484 { 485 const uint32_t addr_byte_size = GetAddressByteSize(); 486 const addr_t sp = ReadCoreReg (SP_REG, &success); 487 if (!success) 488 return false; 489 uint32_t registers = 0; 490 uint32_t Rt; // the destination register 491 switch (encoding) { 492 case eEncodingT1: 493 registers = Bits32(opcode, 7, 0); 494 // The P bit represents PC. 495 if (Bit32(opcode, 8)) 496 registers |= (1u << 15); 497 // if BitCount(registers) < 1 then UNPREDICTABLE; 498 if (BitCount(registers) < 1) 499 return false; 500 break; 501 case eEncodingT2: 502 // Ignore bit 13. 503 registers = Bits32(opcode, 15, 0) & ~0x2000; 504 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 505 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 506 return false; 507 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 508 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 509 return false; 510 break; 511 case eEncodingT3: 512 Rt = Bits32(opcode, 15, 12); 513 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 514 if (Rt == 13) 515 return false; 516 if (Rt == 15 && InITBlock() && !LastInITBlock()) 517 return false; 518 registers = (1u << Rt); 519 break; 520 case eEncodingA1: 521 registers = Bits32(opcode, 15, 0); 522 // Instead of return false, let's handle the following case as well, 523 // which amounts to popping one reg from the full descending stacks. 524 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 525 526 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 527 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 528 return false; 529 break; 530 case eEncodingA2: 531 Rt = Bits32(opcode, 15, 12); 532 // if t == 13 then UNPREDICTABLE; 533 if (Rt == dwarf_sp) 534 return false; 535 registers = (1u << Rt); 536 break; 537 default: 538 return false; 539 } 540 addr_t sp_offset = addr_byte_size * BitCount (registers); 541 addr_t addr = sp; 542 uint32_t i, data; 543 544 EmulateInstruction::Context context; 545 if (conditional) 546 context.type = EmulateInstruction::eContextRegisterLoad; 547 else 548 context.type = EmulateInstruction::eContextPopRegisterOffStack; 549 550 RegisterInfo sp_reg; 551 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 552 553 for (i=0; i<15; ++i) 554 { 555 if (BitIsSet (registers, i)) 556 { 557 context.SetRegisterPlusOffset (sp_reg, addr - sp); 558 data = MemARead(context, addr, 4, 0, &success); 559 if (!success) 560 return false; 561 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 562 return false; 563 addr += addr_byte_size; 564 } 565 } 566 567 if (BitIsSet (registers, 15)) 568 { 569 context.SetRegisterPlusOffset (sp_reg, addr - sp); 570 data = MemARead(context, addr, 4, 0, &success); 571 if (!success) 572 return false; 573 // In ARMv5T and above, this is an interworking branch. 574 if (!LoadWritePC(context, data)) 575 return false; 576 //addr += addr_byte_size; 577 } 578 579 context.type = EmulateInstruction::eContextAdjustStackPointer; 580 context.SetImmediateSigned (sp_offset); 581 582 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 583 return false; 584 } 585 return true; 586 } 587 588 // Set r7 or ip to point to saved value residing within the stack. 589 // ADD (SP plus immediate) 590 bool 591 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 592 { 593 #if 0 594 // ARM pseudo code... 595 if (ConditionPassed()) 596 { 597 EncodingSpecificOperations(); 598 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 599 if d == 15 then 600 ALUWritePC(result); // setflags is always FALSE here 601 else 602 R[d] = result; 603 if setflags then 604 APSR.N = result<31>; 605 APSR.Z = IsZeroBit(result); 606 APSR.C = carry; 607 APSR.V = overflow; 608 } 609 #endif 610 611 bool success = false; 612 613 if (ConditionPassed(opcode)) 614 { 615 const addr_t sp = ReadCoreReg (SP_REG, &success); 616 if (!success) 617 return false; 618 uint32_t Rd; // the destination register 619 uint32_t imm32; 620 switch (encoding) { 621 case eEncodingT1: 622 Rd = 7; 623 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 624 break; 625 case eEncodingA1: 626 Rd = Bits32(opcode, 15, 12); 627 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 628 break; 629 default: 630 return false; 631 } 632 addr_t sp_offset = imm32; 633 addr_t addr = sp + sp_offset; // a pointer to the stack area 634 635 EmulateInstruction::Context context; 636 context.type = eContextSetFramePointer; 637 RegisterInfo sp_reg; 638 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 639 context.SetRegisterPlusOffset (sp_reg, sp_offset); 640 641 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 642 return false; 643 } 644 return true; 645 } 646 647 // Set r7 or ip to the current stack pointer. 648 // MOV (register) 649 bool 650 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 651 { 652 #if 0 653 // ARM pseudo code... 654 if (ConditionPassed()) 655 { 656 EncodingSpecificOperations(); 657 result = R[m]; 658 if d == 15 then 659 ALUWritePC(result); // setflags is always FALSE here 660 else 661 R[d] = result; 662 if setflags then 663 APSR.N = result<31>; 664 APSR.Z = IsZeroBit(result); 665 // APSR.C unchanged 666 // APSR.V unchanged 667 } 668 #endif 669 670 bool success = false; 671 672 if (ConditionPassed(opcode)) 673 { 674 const addr_t sp = ReadCoreReg (SP_REG, &success); 675 if (!success) 676 return false; 677 uint32_t Rd; // the destination register 678 switch (encoding) { 679 case eEncodingT1: 680 Rd = 7; 681 break; 682 case eEncodingA1: 683 Rd = 12; 684 break; 685 default: 686 return false; 687 } 688 689 EmulateInstruction::Context context; 690 if (Rd == GetFramePointerRegisterNumber()) 691 context.type = EmulateInstruction::eContextSetFramePointer; 692 else 693 context.type = EmulateInstruction::eContextRegisterPlusOffset; 694 RegisterInfo sp_reg; 695 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 696 context.SetRegisterPlusOffset (sp_reg, 0); 697 698 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 699 return false; 700 } 701 return true; 702 } 703 704 // Move from high register (r8-r15) to low register (r0-r7). 705 // MOV (register) 706 bool 707 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 708 { 709 return EmulateMOVRdRm (opcode, encoding); 710 } 711 712 // Move from register to register. 713 // MOV (register) 714 bool 715 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 716 { 717 #if 0 718 // ARM pseudo code... 719 if (ConditionPassed()) 720 { 721 EncodingSpecificOperations(); 722 result = R[m]; 723 if d == 15 then 724 ALUWritePC(result); // setflags is always FALSE here 725 else 726 R[d] = result; 727 if setflags then 728 APSR.N = result<31>; 729 APSR.Z = IsZeroBit(result); 730 // APSR.C unchanged 731 // APSR.V unchanged 732 } 733 #endif 734 735 bool success = false; 736 737 if (ConditionPassed(opcode)) 738 { 739 uint32_t Rm; // the source register 740 uint32_t Rd; // the destination register 741 bool setflags; 742 switch (encoding) { 743 case eEncodingT1: 744 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 745 Rm = Bits32(opcode, 6, 3); 746 setflags = false; 747 if (Rd == 15 && InITBlock() && !LastInITBlock()) 748 return false; 749 break; 750 case eEncodingT2: 751 Rd = Bits32(opcode, 2, 0); 752 Rm = Bits32(opcode, 5, 3); 753 setflags = true; 754 if (InITBlock()) 755 return false; 756 break; 757 case eEncodingT3: 758 Rd = Bits32(opcode, 11, 8); 759 Rm = Bits32(opcode, 3, 0); 760 setflags = BitIsSet(opcode, 20); 761 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 762 if (setflags && (BadReg(Rd) || BadReg(Rm))) 763 return false; 764 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 765 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 766 return false; 767 break; 768 case eEncodingA1: 769 Rd = Bits32(opcode, 15, 12); 770 Rm = Bits32(opcode, 3, 0); 771 setflags = BitIsSet(opcode, 20); 772 773 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 774 if (Rd == 15 && setflags) 775 return EmulateSUBSPcLrEtc (opcode, encoding); 776 break; 777 default: 778 return false; 779 } 780 uint32_t result = ReadCoreReg(Rm, &success); 781 if (!success) 782 return false; 783 784 // The context specifies that Rm is to be moved into Rd. 785 EmulateInstruction::Context context; 786 context.type = EmulateInstruction::eContextRegisterLoad; 787 RegisterInfo dwarf_reg; 788 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 789 context.SetRegister (dwarf_reg); 790 791 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 792 return false; 793 } 794 return true; 795 } 796 797 // Move (immediate) writes an immediate value to the destination register. It 798 // can optionally update the condition flags based on the value. 799 // MOV (immediate) 800 bool 801 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 802 { 803 #if 0 804 // ARM pseudo code... 805 if (ConditionPassed()) 806 { 807 EncodingSpecificOperations(); 808 result = imm32; 809 if d == 15 then // Can only occur for ARM encoding 810 ALUWritePC(result); // setflags is always FALSE here 811 else 812 R[d] = result; 813 if setflags then 814 APSR.N = result<31>; 815 APSR.Z = IsZeroBit(result); 816 APSR.C = carry; 817 // APSR.V unchanged 818 } 819 #endif 820 821 if (ConditionPassed(opcode)) 822 { 823 uint32_t Rd; // the destination register 824 uint32_t imm32; // the immediate value to be written to Rd 825 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 826 // for setflags == false, this value is a don't care 827 // initialized to 0 to silence the static analyzer 828 bool setflags; 829 switch (encoding) { 830 case eEncodingT1: 831 Rd = Bits32(opcode, 10, 8); 832 setflags = !InITBlock(); 833 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 834 carry = APSR_C; 835 836 break; 837 838 case eEncodingT2: 839 Rd = Bits32(opcode, 11, 8); 840 setflags = BitIsSet(opcode, 20); 841 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 842 if (BadReg(Rd)) 843 return false; 844 845 break; 846 847 case eEncodingT3: 848 { 849 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 850 Rd = Bits32 (opcode, 11, 8); 851 setflags = false; 852 uint32_t imm4 = Bits32 (opcode, 19, 16); 853 uint32_t imm3 = Bits32 (opcode, 14, 12); 854 uint32_t i = Bit32 (opcode, 26); 855 uint32_t imm8 = Bits32 (opcode, 7, 0); 856 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 857 858 // if BadReg(d) then UNPREDICTABLE; 859 if (BadReg (Rd)) 860 return false; 861 } 862 break; 863 864 case eEncodingA1: 865 // d = UInt(Rd); setflags = (S == 1); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 866 Rd = Bits32 (opcode, 15, 12); 867 setflags = BitIsSet (opcode, 20); 868 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 869 870 // if Rd == 1111 && S == 1 then SEE SUBS PC, LR and related instructions; 871 if ((Rd == 15) && setflags) 872 return EmulateSUBSPcLrEtc (opcode, encoding); 873 874 break; 875 876 case eEncodingA2: 877 { 878 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 879 Rd = Bits32 (opcode, 15, 12); 880 setflags = false; 881 uint32_t imm4 = Bits32 (opcode, 19, 16); 882 uint32_t imm12 = Bits32 (opcode, 11, 0); 883 imm32 = (imm4 << 12) | imm12; 884 885 // if d == 15 then UNPREDICTABLE; 886 if (Rd == 15) 887 return false; 888 } 889 break; 890 891 default: 892 return false; 893 } 894 uint32_t result = imm32; 895 896 // The context specifies that an immediate is to be moved into Rd. 897 EmulateInstruction::Context context; 898 context.type = EmulateInstruction::eContextImmediate; 899 context.SetNoArgs (); 900 901 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 902 return false; 903 } 904 return true; 905 } 906 907 // MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 908 // register. These 32 bits do not depend on whether the source register values are considered to be signed values or 909 // unsigned values. 910 // 911 // Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 912 // limited to only a few forms of the instruction. 913 bool 914 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 915 { 916 #if 0 917 if ConditionPassed() then 918 EncodingSpecificOperations(); 919 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 920 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 921 result = operand1 * operand2; 922 R[d] = result<31:0>; 923 if setflags then 924 APSR.N = result<31>; 925 APSR.Z = IsZeroBit(result); 926 if ArchVersion() == 4 then 927 APSR.C = bit UNKNOWN; 928 // else APSR.C unchanged 929 // APSR.V always unchanged 930 #endif 931 932 if (ConditionPassed(opcode)) 933 { 934 uint32_t d; 935 uint32_t n; 936 uint32_t m; 937 bool setflags; 938 939 // EncodingSpecificOperations(); 940 switch (encoding) 941 { 942 case eEncodingT1: 943 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 944 d = Bits32 (opcode, 2, 0); 945 n = Bits32 (opcode, 5, 3); 946 m = Bits32 (opcode, 2, 0); 947 setflags = !InITBlock(); 948 949 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 950 if ((ArchVersion() < ARMv6) && (d == n)) 951 return false; 952 953 break; 954 955 case eEncodingT2: 956 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 957 d = Bits32 (opcode, 11, 8); 958 n = Bits32 (opcode, 19, 16); 959 m = Bits32 (opcode, 3, 0); 960 setflags = false; 961 962 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 963 if (BadReg (d) || BadReg (n) || BadReg (m)) 964 return false; 965 966 break; 967 968 case eEncodingA1: 969 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 970 d = Bits32 (opcode, 19, 16); 971 n = Bits32 (opcode, 3, 0); 972 m = Bits32 (opcode, 11, 8); 973 setflags = BitIsSet (opcode, 20); 974 975 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 976 if ((d == 15) || (n == 15) || (m == 15)) 977 return false; 978 979 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 980 if ((ArchVersion() < ARMv6) && (d == n)) 981 return false; 982 983 break; 984 985 default: 986 return false; 987 } 988 989 bool success = false; 990 991 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 992 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 993 if (!success) 994 return false; 995 996 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 997 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 998 if (!success) 999 return false; 1000 1001 // result = operand1 * operand2; 1002 uint64_t result = operand1 * operand2; 1003 1004 // R[d] = result<31:0>; 1005 RegisterInfo op1_reg; 1006 RegisterInfo op2_reg; 1007 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1008 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1009 1010 EmulateInstruction::Context context; 1011 context.type = eContextArithmetic; 1012 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 1013 1014 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 1015 return false; 1016 1017 // if setflags then 1018 if (setflags) 1019 { 1020 // APSR.N = result<31>; 1021 // APSR.Z = IsZeroBit(result); 1022 m_new_inst_cpsr = m_opcode_cpsr; 1023 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 1024 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1025 if (m_new_inst_cpsr != m_opcode_cpsr) 1026 { 1027 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1028 return false; 1029 } 1030 1031 // if ArchVersion() == 4 then 1032 // APSR.C = bit UNKNOWN; 1033 } 1034 } 1035 return true; 1036 } 1037 1038 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1039 // It can optionally update the condition flags based on the value. 1040 bool 1041 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1042 { 1043 #if 0 1044 // ARM pseudo code... 1045 if (ConditionPassed()) 1046 { 1047 EncodingSpecificOperations(); 1048 result = NOT(imm32); 1049 if d == 15 then // Can only occur for ARM encoding 1050 ALUWritePC(result); // setflags is always FALSE here 1051 else 1052 R[d] = result; 1053 if setflags then 1054 APSR.N = result<31>; 1055 APSR.Z = IsZeroBit(result); 1056 APSR.C = carry; 1057 // APSR.V unchanged 1058 } 1059 #endif 1060 1061 if (ConditionPassed(opcode)) 1062 { 1063 uint32_t Rd; // the destination register 1064 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1065 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1066 bool setflags; 1067 switch (encoding) { 1068 case eEncodingT1: 1069 Rd = Bits32(opcode, 11, 8); 1070 setflags = BitIsSet(opcode, 20); 1071 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1072 break; 1073 case eEncodingA1: 1074 Rd = Bits32(opcode, 15, 12); 1075 setflags = BitIsSet(opcode, 20); 1076 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1077 1078 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1079 if (Rd == 15 && setflags) 1080 return EmulateSUBSPcLrEtc (opcode, encoding); 1081 break; 1082 default: 1083 return false; 1084 } 1085 uint32_t result = ~imm32; 1086 1087 // The context specifies that an immediate is to be moved into Rd. 1088 EmulateInstruction::Context context; 1089 context.type = EmulateInstruction::eContextImmediate; 1090 context.SetNoArgs (); 1091 1092 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1093 return false; 1094 } 1095 return true; 1096 } 1097 1098 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1099 // It can optionally update the condition flags based on the result. 1100 bool 1101 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1102 { 1103 #if 0 1104 // ARM pseudo code... 1105 if (ConditionPassed()) 1106 { 1107 EncodingSpecificOperations(); 1108 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1109 result = NOT(shifted); 1110 if d == 15 then // Can only occur for ARM encoding 1111 ALUWritePC(result); // setflags is always FALSE here 1112 else 1113 R[d] = result; 1114 if setflags then 1115 APSR.N = result<31>; 1116 APSR.Z = IsZeroBit(result); 1117 APSR.C = carry; 1118 // APSR.V unchanged 1119 } 1120 #endif 1121 1122 if (ConditionPassed(opcode)) 1123 { 1124 uint32_t Rm; // the source register 1125 uint32_t Rd; // the destination register 1126 ARM_ShifterType shift_t; 1127 uint32_t shift_n; // the shift applied to the value read from Rm 1128 bool setflags; 1129 uint32_t carry; // the carry bit after the shift operation 1130 switch (encoding) { 1131 case eEncodingT1: 1132 Rd = Bits32(opcode, 2, 0); 1133 Rm = Bits32(opcode, 5, 3); 1134 setflags = !InITBlock(); 1135 shift_t = SRType_LSL; 1136 shift_n = 0; 1137 if (InITBlock()) 1138 return false; 1139 break; 1140 case eEncodingT2: 1141 Rd = Bits32(opcode, 11, 8); 1142 Rm = Bits32(opcode, 3, 0); 1143 setflags = BitIsSet(opcode, 20); 1144 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1145 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1146 if (BadReg(Rd) || BadReg(Rm)) 1147 return false; 1148 break; 1149 case eEncodingA1: 1150 Rd = Bits32(opcode, 15, 12); 1151 Rm = Bits32(opcode, 3, 0); 1152 setflags = BitIsSet(opcode, 20); 1153 shift_n = DecodeImmShiftARM(opcode, shift_t); 1154 break; 1155 default: 1156 return false; 1157 } 1158 bool success = false; 1159 uint32_t value = ReadCoreReg(Rm, &success); 1160 if (!success) 1161 return false; 1162 1163 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1164 if (!success) 1165 return false; 1166 uint32_t result = ~shifted; 1167 1168 // The context specifies that an immediate is to be moved into Rd. 1169 EmulateInstruction::Context context; 1170 context.type = EmulateInstruction::eContextImmediate; 1171 context.SetNoArgs (); 1172 1173 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1174 return false; 1175 } 1176 return true; 1177 } 1178 1179 // PC relative immediate load into register, possibly followed by ADD (SP plus register). 1180 // LDR (literal) 1181 bool 1182 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1183 { 1184 #if 0 1185 // ARM pseudo code... 1186 if (ConditionPassed()) 1187 { 1188 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1189 base = Align(PC,4); 1190 address = if add then (base + imm32) else (base - imm32); 1191 data = MemU[address,4]; 1192 if t == 15 then 1193 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1194 elsif UnalignedSupport() || address<1:0> = '00' then 1195 R[t] = data; 1196 else // Can only apply before ARMv7 1197 if CurrentInstrSet() == InstrSet_ARM then 1198 R[t] = ROR(data, 8*UInt(address<1:0>)); 1199 else 1200 R[t] = bits(32) UNKNOWN; 1201 } 1202 #endif 1203 1204 if (ConditionPassed(opcode)) 1205 { 1206 bool success = false; 1207 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1208 if (!success) 1209 return false; 1210 1211 // PC relative immediate load context 1212 EmulateInstruction::Context context; 1213 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1214 RegisterInfo pc_reg; 1215 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1216 context.SetRegisterPlusOffset (pc_reg, 0); 1217 1218 uint32_t Rt; // the destination register 1219 uint32_t imm32; // immediate offset from the PC 1220 bool add; // +imm32 or -imm32? 1221 addr_t base; // the base address 1222 addr_t address; // the PC relative address 1223 uint32_t data; // the literal data value from the PC relative load 1224 switch (encoding) { 1225 case eEncodingT1: 1226 Rt = Bits32(opcode, 10, 8); 1227 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1228 add = true; 1229 break; 1230 case eEncodingT2: 1231 Rt = Bits32(opcode, 15, 12); 1232 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1233 add = BitIsSet(opcode, 23); 1234 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1235 return false; 1236 break; 1237 default: 1238 return false; 1239 } 1240 1241 base = Align(pc, 4); 1242 if (add) 1243 address = base + imm32; 1244 else 1245 address = base - imm32; 1246 1247 context.SetRegisterPlusOffset(pc_reg, address - base); 1248 data = MemURead(context, address, 4, 0, &success); 1249 if (!success) 1250 return false; 1251 1252 if (Rt == 15) 1253 { 1254 if (Bits32(address, 1, 0) == 0) 1255 { 1256 // In ARMv5T and above, this is an interworking branch. 1257 if (!LoadWritePC(context, data)) 1258 return false; 1259 } 1260 else 1261 return false; 1262 } 1263 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1264 { 1265 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1266 return false; 1267 } 1268 else // We don't handle ARM for now. 1269 return false; 1270 1271 } 1272 return true; 1273 } 1274 1275 // An add operation to adjust the SP. 1276 // ADD (SP plus immediate) 1277 bool 1278 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1279 { 1280 #if 0 1281 // ARM pseudo code... 1282 if (ConditionPassed()) 1283 { 1284 EncodingSpecificOperations(); 1285 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1286 if d == 15 then // Can only occur for ARM encoding 1287 ALUWritePC(result); // setflags is always FALSE here 1288 else 1289 R[d] = result; 1290 if setflags then 1291 APSR.N = result<31>; 1292 APSR.Z = IsZeroBit(result); 1293 APSR.C = carry; 1294 APSR.V = overflow; 1295 } 1296 #endif 1297 1298 bool success = false; 1299 1300 if (ConditionPassed(opcode)) 1301 { 1302 const addr_t sp = ReadCoreReg (SP_REG, &success); 1303 if (!success) 1304 return false; 1305 uint32_t imm32; // the immediate operand 1306 uint32_t d; 1307 //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1 1308 switch (encoding) 1309 { 1310 case eEncodingT1: 1311 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1312 d = Bits32 (opcode, 10, 8); 1313 imm32 = (Bits32 (opcode, 7, 0) << 2); 1314 1315 break; 1316 1317 case eEncodingT2: 1318 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1319 d = 13; 1320 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1321 1322 break; 1323 1324 default: 1325 return false; 1326 } 1327 addr_t sp_offset = imm32; 1328 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1329 1330 EmulateInstruction::Context context; 1331 context.type = EmulateInstruction::eContextAdjustStackPointer; 1332 RegisterInfo sp_reg; 1333 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1334 context.SetRegisterPlusOffset (sp_reg, sp_offset); 1335 1336 if (d == 15) 1337 { 1338 if (!ALUWritePC (context, addr)) 1339 return false; 1340 } 1341 else 1342 { 1343 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr)) 1344 return false; 1345 1346 // Add this back if/when support eEncodingT3 eEncodingA1 1347 //if (setflags) 1348 //{ 1349 // APSR.N = result<31>; 1350 // APSR.Z = IsZeroBit(result); 1351 // APSR.C = carry; 1352 // APSR.V = overflow; 1353 //} 1354 } 1355 } 1356 return true; 1357 } 1358 1359 // An add operation to adjust the SP. 1360 // ADD (SP plus register) 1361 bool 1362 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1363 { 1364 #if 0 1365 // ARM pseudo code... 1366 if (ConditionPassed()) 1367 { 1368 EncodingSpecificOperations(); 1369 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1370 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1371 if d == 15 then 1372 ALUWritePC(result); // setflags is always FALSE here 1373 else 1374 R[d] = result; 1375 if setflags then 1376 APSR.N = result<31>; 1377 APSR.Z = IsZeroBit(result); 1378 APSR.C = carry; 1379 APSR.V = overflow; 1380 } 1381 #endif 1382 1383 bool success = false; 1384 1385 if (ConditionPassed(opcode)) 1386 { 1387 const addr_t sp = ReadCoreReg (SP_REG, &success); 1388 if (!success) 1389 return false; 1390 uint32_t Rm; // the second operand 1391 switch (encoding) { 1392 case eEncodingT2: 1393 Rm = Bits32(opcode, 6, 3); 1394 break; 1395 default: 1396 return false; 1397 } 1398 int32_t reg_value = ReadCoreReg(Rm, &success); 1399 if (!success) 1400 return false; 1401 1402 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1403 1404 EmulateInstruction::Context context; 1405 context.type = eContextArithmetic; 1406 RegisterInfo sp_reg; 1407 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1408 1409 RegisterInfo other_reg; 1410 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1411 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1412 1413 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1414 return false; 1415 } 1416 return true; 1417 } 1418 1419 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1420 // at a PC-relative address, and changes instruction set from ARM to Thumb, or 1421 // from Thumb to ARM. 1422 // BLX (immediate) 1423 bool 1424 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1425 { 1426 #if 0 1427 // ARM pseudo code... 1428 if (ConditionPassed()) 1429 { 1430 EncodingSpecificOperations(); 1431 if CurrentInstrSet() == InstrSet_ARM then 1432 LR = PC - 4; 1433 else 1434 LR = PC<31:1> : '1'; 1435 if targetInstrSet == InstrSet_ARM then 1436 targetAddress = Align(PC,4) + imm32; 1437 else 1438 targetAddress = PC + imm32; 1439 SelectInstrSet(targetInstrSet); 1440 BranchWritePC(targetAddress); 1441 } 1442 #endif 1443 1444 bool success = true; 1445 1446 if (ConditionPassed(opcode)) 1447 { 1448 EmulateInstruction::Context context; 1449 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1450 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1451 if (!success) 1452 return false; 1453 addr_t lr; // next instruction address 1454 addr_t target; // target address 1455 int32_t imm32; // PC-relative offset 1456 switch (encoding) { 1457 case eEncodingT1: 1458 { 1459 lr = pc | 1u; // return address 1460 uint32_t S = Bit32(opcode, 26); 1461 uint32_t imm10 = Bits32(opcode, 25, 16); 1462 uint32_t J1 = Bit32(opcode, 13); 1463 uint32_t J2 = Bit32(opcode, 11); 1464 uint32_t imm11 = Bits32(opcode, 10, 0); 1465 uint32_t I1 = !(J1 ^ S); 1466 uint32_t I2 = !(J2 ^ S); 1467 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1468 imm32 = llvm::SignExtend32<25>(imm25); 1469 target = pc + imm32; 1470 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1471 if (InITBlock() && !LastInITBlock()) 1472 return false; 1473 break; 1474 } 1475 case eEncodingT2: 1476 { 1477 lr = pc | 1u; // return address 1478 uint32_t S = Bit32(opcode, 26); 1479 uint32_t imm10H = Bits32(opcode, 25, 16); 1480 uint32_t J1 = Bit32(opcode, 13); 1481 uint32_t J2 = Bit32(opcode, 11); 1482 uint32_t imm10L = Bits32(opcode, 10, 1); 1483 uint32_t I1 = !(J1 ^ S); 1484 uint32_t I2 = !(J2 ^ S); 1485 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1486 imm32 = llvm::SignExtend32<25>(imm25); 1487 target = Align(pc, 4) + imm32; 1488 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1489 if (InITBlock() && !LastInITBlock()) 1490 return false; 1491 break; 1492 } 1493 case eEncodingA1: 1494 lr = pc - 4; // return address 1495 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1496 target = Align(pc, 4) + imm32; 1497 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1498 break; 1499 case eEncodingA2: 1500 lr = pc - 4; // return address 1501 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1502 target = pc + imm32; 1503 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1504 break; 1505 default: 1506 return false; 1507 } 1508 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1509 return false; 1510 if (!BranchWritePC(context, target)) 1511 return false; 1512 } 1513 return true; 1514 } 1515 1516 // Branch with Link and Exchange (register) calls a subroutine at an address and 1517 // instruction set specified by a register. 1518 // BLX (register) 1519 bool 1520 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1521 { 1522 #if 0 1523 // ARM pseudo code... 1524 if (ConditionPassed()) 1525 { 1526 EncodingSpecificOperations(); 1527 target = R[m]; 1528 if CurrentInstrSet() == InstrSet_ARM then 1529 next_instr_addr = PC - 4; 1530 LR = next_instr_addr; 1531 else 1532 next_instr_addr = PC - 2; 1533 LR = next_instr_addr<31:1> : '1'; 1534 BXWritePC(target); 1535 } 1536 #endif 1537 1538 bool success = false; 1539 1540 if (ConditionPassed(opcode)) 1541 { 1542 EmulateInstruction::Context context; 1543 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1544 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1545 addr_t lr; // next instruction address 1546 if (!success) 1547 return false; 1548 uint32_t Rm; // the register with the target address 1549 switch (encoding) { 1550 case eEncodingT1: 1551 lr = (pc - 2) | 1u; // return address 1552 Rm = Bits32(opcode, 6, 3); 1553 // if m == 15 then UNPREDICTABLE; 1554 if (Rm == 15) 1555 return false; 1556 if (InITBlock() && !LastInITBlock()) 1557 return false; 1558 break; 1559 case eEncodingA1: 1560 lr = pc - 4; // return address 1561 Rm = Bits32(opcode, 3, 0); 1562 // if m == 15 then UNPREDICTABLE; 1563 if (Rm == 15) 1564 return false; 1565 break; 1566 default: 1567 return false; 1568 } 1569 addr_t target = ReadCoreReg (Rm, &success); 1570 if (!success) 1571 return false; 1572 RegisterInfo dwarf_reg; 1573 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1574 context.SetRegister (dwarf_reg); 1575 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1576 return false; 1577 if (!BXWritePC(context, target)) 1578 return false; 1579 } 1580 return true; 1581 } 1582 1583 // Branch and Exchange causes a branch to an address and instruction set specified by a register. 1584 bool 1585 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1586 { 1587 #if 0 1588 // ARM pseudo code... 1589 if (ConditionPassed()) 1590 { 1591 EncodingSpecificOperations(); 1592 BXWritePC(R[m]); 1593 } 1594 #endif 1595 1596 if (ConditionPassed(opcode)) 1597 { 1598 EmulateInstruction::Context context; 1599 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1600 uint32_t Rm; // the register with the target address 1601 switch (encoding) { 1602 case eEncodingT1: 1603 Rm = Bits32(opcode, 6, 3); 1604 if (InITBlock() && !LastInITBlock()) 1605 return false; 1606 break; 1607 case eEncodingA1: 1608 Rm = Bits32(opcode, 3, 0); 1609 break; 1610 default: 1611 return false; 1612 } 1613 bool success = false; 1614 addr_t target = ReadCoreReg (Rm, &success); 1615 if (!success) 1616 return false; 1617 1618 RegisterInfo dwarf_reg; 1619 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1620 context.SetRegister (dwarf_reg); 1621 if (!BXWritePC(context, target)) 1622 return false; 1623 } 1624 return true; 1625 } 1626 1627 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1628 // address and instruction set specified by a register as though it were a BX instruction. 1629 // 1630 // TODO: Emulate Jazelle architecture? 1631 // We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1632 bool 1633 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1634 { 1635 #if 0 1636 // ARM pseudo code... 1637 if (ConditionPassed()) 1638 { 1639 EncodingSpecificOperations(); 1640 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1641 BXWritePC(R[m]); 1642 else 1643 if JazelleAcceptsExecution() then 1644 SwitchToJazelleExecution(); 1645 else 1646 SUBARCHITECTURE_DEFINED handler call; 1647 } 1648 #endif 1649 1650 if (ConditionPassed(opcode)) 1651 { 1652 EmulateInstruction::Context context; 1653 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1654 uint32_t Rm; // the register with the target address 1655 switch (encoding) { 1656 case eEncodingT1: 1657 Rm = Bits32(opcode, 19, 16); 1658 if (BadReg(Rm)) 1659 return false; 1660 if (InITBlock() && !LastInITBlock()) 1661 return false; 1662 break; 1663 case eEncodingA1: 1664 Rm = Bits32(opcode, 3, 0); 1665 if (Rm == 15) 1666 return false; 1667 break; 1668 default: 1669 return false; 1670 } 1671 bool success = false; 1672 addr_t target = ReadCoreReg (Rm, &success); 1673 if (!success) 1674 return false; 1675 1676 RegisterInfo dwarf_reg; 1677 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1678 context.SetRegister (dwarf_reg); 1679 if (!BXWritePC(context, target)) 1680 return false; 1681 } 1682 return true; 1683 } 1684 1685 // Set r7 to point to some ip offset. 1686 // SUB (immediate) 1687 bool 1688 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1689 { 1690 #if 0 1691 // ARM pseudo code... 1692 if (ConditionPassed()) 1693 { 1694 EncodingSpecificOperations(); 1695 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1696 if d == 15 then // Can only occur for ARM encoding 1697 ALUWritePC(result); // setflags is always FALSE here 1698 else 1699 R[d] = result; 1700 if setflags then 1701 APSR.N = result<31>; 1702 APSR.Z = IsZeroBit(result); 1703 APSR.C = carry; 1704 APSR.V = overflow; 1705 } 1706 #endif 1707 1708 if (ConditionPassed(opcode)) 1709 { 1710 bool success = false; 1711 const addr_t ip = ReadCoreReg (12, &success); 1712 if (!success) 1713 return false; 1714 uint32_t imm32; 1715 switch (encoding) { 1716 case eEncodingA1: 1717 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1718 break; 1719 default: 1720 return false; 1721 } 1722 addr_t ip_offset = imm32; 1723 addr_t addr = ip - ip_offset; // the adjusted ip value 1724 1725 EmulateInstruction::Context context; 1726 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1727 RegisterInfo dwarf_reg; 1728 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1729 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1730 1731 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1732 return false; 1733 } 1734 return true; 1735 } 1736 1737 // Set ip to point to some stack offset. 1738 // SUB (SP minus immediate) 1739 bool 1740 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1741 { 1742 #if 0 1743 // ARM pseudo code... 1744 if (ConditionPassed()) 1745 { 1746 EncodingSpecificOperations(); 1747 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1748 if d == 15 then // Can only occur for ARM encoding 1749 ALUWritePC(result); // setflags is always FALSE here 1750 else 1751 R[d] = result; 1752 if setflags then 1753 APSR.N = result<31>; 1754 APSR.Z = IsZeroBit(result); 1755 APSR.C = carry; 1756 APSR.V = overflow; 1757 } 1758 #endif 1759 1760 if (ConditionPassed(opcode)) 1761 { 1762 bool success = false; 1763 const addr_t sp = ReadCoreReg (SP_REG, &success); 1764 if (!success) 1765 return false; 1766 uint32_t imm32; 1767 switch (encoding) { 1768 case eEncodingA1: 1769 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1770 break; 1771 default: 1772 return false; 1773 } 1774 addr_t sp_offset = imm32; 1775 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1776 1777 EmulateInstruction::Context context; 1778 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1779 RegisterInfo dwarf_reg; 1780 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1781 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1782 1783 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1784 return false; 1785 } 1786 return true; 1787 } 1788 1789 // This instruction subtracts an immediate value from the SP value, and writes 1790 // the result to the destination register. 1791 // 1792 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1793 bool 1794 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1795 { 1796 #if 0 1797 // ARM pseudo code... 1798 if (ConditionPassed()) 1799 { 1800 EncodingSpecificOperations(); 1801 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1802 if d == 15 then // Can only occur for ARM encoding 1803 ALUWritePC(result); // setflags is always FALSE here 1804 else 1805 R[d] = result; 1806 if setflags then 1807 APSR.N = result<31>; 1808 APSR.Z = IsZeroBit(result); 1809 APSR.C = carry; 1810 APSR.V = overflow; 1811 } 1812 #endif 1813 1814 bool success = false; 1815 if (ConditionPassed(opcode)) 1816 { 1817 const addr_t sp = ReadCoreReg (SP_REG, &success); 1818 if (!success) 1819 return false; 1820 1821 uint32_t Rd; 1822 bool setflags; 1823 uint32_t imm32; 1824 switch (encoding) { 1825 case eEncodingT1: 1826 Rd = 13; 1827 setflags = false; 1828 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1829 break; 1830 case eEncodingT2: 1831 Rd = Bits32(opcode, 11, 8); 1832 setflags = BitIsSet(opcode, 20); 1833 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1834 if (Rd == 15 && setflags) 1835 return EmulateCMPImm(opcode, eEncodingT2); 1836 if (Rd == 15 && !setflags) 1837 return false; 1838 break; 1839 case eEncodingT3: 1840 Rd = Bits32(opcode, 11, 8); 1841 setflags = false; 1842 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1843 if (Rd == 15) 1844 return false; 1845 break; 1846 case eEncodingA1: 1847 Rd = Bits32(opcode, 15, 12); 1848 setflags = BitIsSet(opcode, 20); 1849 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1850 1851 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1852 if (Rd == 15 && setflags) 1853 return EmulateSUBSPcLrEtc (opcode, encoding); 1854 break; 1855 default: 1856 return false; 1857 } 1858 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1859 1860 EmulateInstruction::Context context; 1861 if (Rd == 13) 1862 { 1863 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1864 // value gets passed down to context.SetImmediateSigned. 1865 context.type = EmulateInstruction::eContextAdjustStackPointer; 1866 context.SetImmediateSigned (-imm64); // the stack pointer offset 1867 } 1868 else 1869 { 1870 context.type = EmulateInstruction::eContextImmediate; 1871 context.SetNoArgs (); 1872 } 1873 1874 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1875 return false; 1876 } 1877 return true; 1878 } 1879 1880 // A store operation to the stack that also updates the SP. 1881 bool 1882 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1883 { 1884 #if 0 1885 // ARM pseudo code... 1886 if (ConditionPassed()) 1887 { 1888 EncodingSpecificOperations(); 1889 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1890 address = if index then offset_addr else R[n]; 1891 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1892 if wback then R[n] = offset_addr; 1893 } 1894 #endif 1895 1896 bool conditional = false; 1897 bool success = false; 1898 if (ConditionPassed(opcode, &conditional)) 1899 { 1900 const uint32_t addr_byte_size = GetAddressByteSize(); 1901 const addr_t sp = ReadCoreReg (SP_REG, &success); 1902 if (!success) 1903 return false; 1904 uint32_t Rt; // the source register 1905 uint32_t imm12; 1906 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1907 1908 bool index; 1909 bool add; 1910 bool wback; 1911 switch (encoding) { 1912 case eEncodingA1: 1913 Rt = Bits32(opcode, 15, 12); 1914 imm12 = Bits32(opcode, 11, 0); 1915 Rn = Bits32 (opcode, 19, 16); 1916 1917 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1918 return false; 1919 1920 index = BitIsSet (opcode, 24); 1921 add = BitIsSet (opcode, 23); 1922 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1923 1924 if (wback && ((Rn == 15) || (Rn == Rt))) 1925 return false; 1926 break; 1927 default: 1928 return false; 1929 } 1930 addr_t offset_addr; 1931 if (add) 1932 offset_addr = sp + imm12; 1933 else 1934 offset_addr = sp - imm12; 1935 1936 addr_t addr; 1937 if (index) 1938 addr = offset_addr; 1939 else 1940 addr = sp; 1941 1942 EmulateInstruction::Context context; 1943 if (conditional) 1944 context.type = EmulateInstruction::eContextRegisterStore; 1945 else 1946 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1947 RegisterInfo sp_reg; 1948 RegisterInfo dwarf_reg; 1949 1950 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1951 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 1952 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 1953 if (Rt != 15) 1954 { 1955 uint32_t reg_value = ReadCoreReg(Rt, &success); 1956 if (!success) 1957 return false; 1958 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1959 return false; 1960 } 1961 else 1962 { 1963 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1964 if (!success) 1965 return false; 1966 if (!MemUWrite (context, addr, pc, addr_byte_size)) 1967 return false; 1968 } 1969 1970 1971 if (wback) 1972 { 1973 context.type = EmulateInstruction::eContextAdjustStackPointer; 1974 context.SetImmediateSigned (addr - sp); 1975 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 1976 return false; 1977 } 1978 } 1979 return true; 1980 } 1981 1982 // Vector Push stores multiple extension registers to the stack. 1983 // It also updates SP to point to the start of the stored data. 1984 bool 1985 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 1986 { 1987 #if 0 1988 // ARM pseudo code... 1989 if (ConditionPassed()) 1990 { 1991 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1992 address = SP - imm32; 1993 SP = SP - imm32; 1994 if single_regs then 1995 for r = 0 to regs-1 1996 MemA[address,4] = S[d+r]; address = address+4; 1997 else 1998 for r = 0 to regs-1 1999 // Store as two word-aligned words in the correct order for current endianness. 2000 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2001 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2002 address = address+8; 2003 } 2004 #endif 2005 2006 bool success = false; 2007 bool conditional = false; 2008 if (ConditionPassed(opcode, &conditional)) 2009 { 2010 const uint32_t addr_byte_size = GetAddressByteSize(); 2011 const addr_t sp = ReadCoreReg (SP_REG, &success); 2012 if (!success) 2013 return false; 2014 bool single_regs; 2015 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2016 uint32_t imm32; // stack offset 2017 uint32_t regs; // number of registers 2018 switch (encoding) { 2019 case eEncodingT1: 2020 case eEncodingA1: 2021 single_regs = false; 2022 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2023 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2024 // If UInt(imm8) is odd, see "FSTMX". 2025 regs = Bits32(opcode, 7, 0) / 2; 2026 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2027 if (regs == 0 || regs > 16 || (d + regs) > 32) 2028 return false; 2029 break; 2030 case eEncodingT2: 2031 case eEncodingA2: 2032 single_regs = true; 2033 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2034 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2035 regs = Bits32(opcode, 7, 0); 2036 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2037 if (regs == 0 || regs > 16 || (d + regs) > 32) 2038 return false; 2039 break; 2040 default: 2041 return false; 2042 } 2043 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2044 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2045 addr_t sp_offset = imm32; 2046 addr_t addr = sp - sp_offset; 2047 uint32_t i; 2048 2049 EmulateInstruction::Context context; 2050 if (conditional) 2051 context.type = EmulateInstruction::eContextRegisterStore; 2052 else 2053 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2054 RegisterInfo dwarf_reg; 2055 RegisterInfo sp_reg; 2056 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2057 for (i=0; i<regs; ++i) 2058 { 2059 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2060 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2061 // uint64_t to accommodate 64-bit registers. 2062 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2063 if (!success) 2064 return false; 2065 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2066 return false; 2067 addr += reg_byte_size; 2068 } 2069 2070 context.type = EmulateInstruction::eContextAdjustStackPointer; 2071 context.SetImmediateSigned (-sp_offset); 2072 2073 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2074 return false; 2075 } 2076 return true; 2077 } 2078 2079 // Vector Pop loads multiple extension registers from the stack. 2080 // It also updates SP to point just above the loaded data. 2081 bool 2082 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2083 { 2084 #if 0 2085 // ARM pseudo code... 2086 if (ConditionPassed()) 2087 { 2088 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2089 address = SP; 2090 SP = SP + imm32; 2091 if single_regs then 2092 for r = 0 to regs-1 2093 S[d+r] = MemA[address,4]; address = address+4; 2094 else 2095 for r = 0 to regs-1 2096 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2097 // Combine the word-aligned words in the correct order for current endianness. 2098 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2099 } 2100 #endif 2101 2102 bool success = false; 2103 bool conditional = false; 2104 if (ConditionPassed(opcode, &conditional)) 2105 { 2106 const uint32_t addr_byte_size = GetAddressByteSize(); 2107 const addr_t sp = ReadCoreReg (SP_REG, &success); 2108 if (!success) 2109 return false; 2110 bool single_regs; 2111 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2112 uint32_t imm32; // stack offset 2113 uint32_t regs; // number of registers 2114 switch (encoding) { 2115 case eEncodingT1: 2116 case eEncodingA1: 2117 single_regs = false; 2118 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2119 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2120 // If UInt(imm8) is odd, see "FLDMX". 2121 regs = Bits32(opcode, 7, 0) / 2; 2122 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2123 if (regs == 0 || regs > 16 || (d + regs) > 32) 2124 return false; 2125 break; 2126 case eEncodingT2: 2127 case eEncodingA2: 2128 single_regs = true; 2129 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2130 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2131 regs = Bits32(opcode, 7, 0); 2132 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2133 if (regs == 0 || regs > 16 || (d + regs) > 32) 2134 return false; 2135 break; 2136 default: 2137 return false; 2138 } 2139 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2140 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2141 addr_t sp_offset = imm32; 2142 addr_t addr = sp; 2143 uint32_t i; 2144 uint64_t data; // uint64_t to accomodate 64-bit registers. 2145 2146 EmulateInstruction::Context context; 2147 if (conditional) 2148 context.type = EmulateInstruction::eContextRegisterLoad; 2149 else 2150 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2151 RegisterInfo dwarf_reg; 2152 RegisterInfo sp_reg; 2153 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2154 for (i=0; i<regs; ++i) 2155 { 2156 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2157 context.SetRegisterPlusOffset (sp_reg, addr - sp); 2158 data = MemARead(context, addr, reg_byte_size, 0, &success); 2159 if (!success) 2160 return false; 2161 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2162 return false; 2163 addr += reg_byte_size; 2164 } 2165 2166 context.type = EmulateInstruction::eContextAdjustStackPointer; 2167 context.SetImmediateSigned (sp_offset); 2168 2169 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2170 return false; 2171 } 2172 return true; 2173 } 2174 2175 // SVC (previously SWI) 2176 bool 2177 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2178 { 2179 #if 0 2180 // ARM pseudo code... 2181 if (ConditionPassed()) 2182 { 2183 EncodingSpecificOperations(); 2184 CallSupervisor(); 2185 } 2186 #endif 2187 2188 bool success = false; 2189 2190 if (ConditionPassed(opcode)) 2191 { 2192 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2193 addr_t lr; // next instruction address 2194 if (!success) 2195 return false; 2196 uint32_t imm32; // the immediate constant 2197 uint32_t mode; // ARM or Thumb mode 2198 switch (encoding) { 2199 case eEncodingT1: 2200 lr = (pc + 2) | 1u; // return address 2201 imm32 = Bits32(opcode, 7, 0); 2202 mode = eModeThumb; 2203 break; 2204 case eEncodingA1: 2205 lr = pc + 4; // return address 2206 imm32 = Bits32(opcode, 23, 0); 2207 mode = eModeARM; 2208 break; 2209 default: 2210 return false; 2211 } 2212 2213 EmulateInstruction::Context context; 2214 context.type = EmulateInstruction::eContextSupervisorCall; 2215 context.SetISAAndImmediate (mode, imm32); 2216 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2217 return false; 2218 } 2219 return true; 2220 } 2221 2222 // If Then makes up to four following instructions (the IT block) conditional. 2223 bool 2224 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2225 { 2226 #if 0 2227 // ARM pseudo code... 2228 EncodingSpecificOperations(); 2229 ITSTATE.IT<7:0> = firstcond:mask; 2230 #endif 2231 2232 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2233 return true; 2234 } 2235 2236 bool 2237 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2238 { 2239 // NOP, nothing to do... 2240 return true; 2241 } 2242 2243 // Branch causes a branch to a target address. 2244 bool 2245 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2246 { 2247 #if 0 2248 // ARM pseudo code... 2249 if (ConditionPassed()) 2250 { 2251 EncodingSpecificOperations(); 2252 BranchWritePC(PC + imm32); 2253 } 2254 #endif 2255 2256 bool success = false; 2257 2258 if (ConditionPassed(opcode)) 2259 { 2260 EmulateInstruction::Context context; 2261 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2262 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2263 if (!success) 2264 return false; 2265 addr_t target; // target address 2266 int32_t imm32; // PC-relative offset 2267 switch (encoding) { 2268 case eEncodingT1: 2269 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2270 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2271 target = pc + imm32; 2272 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2273 break; 2274 case eEncodingT2: 2275 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2276 target = pc + imm32; 2277 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2278 break; 2279 case eEncodingT3: 2280 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2281 { 2282 uint32_t S = Bit32(opcode, 26); 2283 uint32_t imm6 = Bits32(opcode, 21, 16); 2284 uint32_t J1 = Bit32(opcode, 13); 2285 uint32_t J2 = Bit32(opcode, 11); 2286 uint32_t imm11 = Bits32(opcode, 10, 0); 2287 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2288 imm32 = llvm::SignExtend32<21>(imm21); 2289 target = pc + imm32; 2290 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2291 break; 2292 } 2293 case eEncodingT4: 2294 { 2295 uint32_t S = Bit32(opcode, 26); 2296 uint32_t imm10 = Bits32(opcode, 25, 16); 2297 uint32_t J1 = Bit32(opcode, 13); 2298 uint32_t J2 = Bit32(opcode, 11); 2299 uint32_t imm11 = Bits32(opcode, 10, 0); 2300 uint32_t I1 = !(J1 ^ S); 2301 uint32_t I2 = !(J2 ^ S); 2302 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2303 imm32 = llvm::SignExtend32<25>(imm25); 2304 target = pc + imm32; 2305 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2306 break; 2307 } 2308 case eEncodingA1: 2309 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2310 target = pc + imm32; 2311 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2312 break; 2313 default: 2314 return false; 2315 } 2316 if (!BranchWritePC(context, target)) 2317 return false; 2318 } 2319 return true; 2320 } 2321 2322 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2323 // zero and conditionally branch forward a constant value. They do not affect the condition flags. 2324 // CBNZ, CBZ 2325 bool 2326 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2327 { 2328 #if 0 2329 // ARM pseudo code... 2330 EncodingSpecificOperations(); 2331 if nonzero ^ IsZero(R[n]) then 2332 BranchWritePC(PC + imm32); 2333 #endif 2334 2335 bool success = false; 2336 2337 // Read the register value from the operand register Rn. 2338 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2339 if (!success) 2340 return false; 2341 2342 EmulateInstruction::Context context; 2343 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2344 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2345 if (!success) 2346 return false; 2347 2348 addr_t target; // target address 2349 uint32_t imm32; // PC-relative offset to branch forward 2350 bool nonzero; 2351 switch (encoding) { 2352 case eEncodingT1: 2353 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2354 nonzero = BitIsSet(opcode, 11); 2355 target = pc + imm32; 2356 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2357 break; 2358 default: 2359 return false; 2360 } 2361 if (nonzero ^ (reg_val == 0)) 2362 if (!BranchWritePC(context, target)) 2363 return false; 2364 2365 return true; 2366 } 2367 2368 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2369 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2370 // The branch length is twice the value of the byte returned from the table. 2371 // 2372 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2373 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2374 // The branch length is twice the value of the halfword returned from the table. 2375 // TBB, TBH 2376 bool 2377 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2378 { 2379 #if 0 2380 // ARM pseudo code... 2381 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2382 if is_tbh then 2383 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2384 else 2385 halfwords = UInt(MemU[R[n]+R[m], 1]); 2386 BranchWritePC(PC + 2*halfwords); 2387 #endif 2388 2389 bool success = false; 2390 2391 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2392 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2393 bool is_tbh; // true if table branch halfword 2394 switch (encoding) { 2395 case eEncodingT1: 2396 Rn = Bits32(opcode, 19, 16); 2397 Rm = Bits32(opcode, 3, 0); 2398 is_tbh = BitIsSet(opcode, 4); 2399 if (Rn == 13 || BadReg(Rm)) 2400 return false; 2401 if (InITBlock() && !LastInITBlock()) 2402 return false; 2403 break; 2404 default: 2405 return false; 2406 } 2407 2408 // Read the address of the table from the operand register Rn. 2409 // The PC can be used, in which case the table immediately follows this instruction. 2410 uint32_t base = ReadCoreReg(Rm, &success); 2411 if (!success) 2412 return false; 2413 2414 // the table index 2415 uint32_t index = ReadCoreReg(Rm, &success); 2416 if (!success) 2417 return false; 2418 2419 // the offsetted table address 2420 addr_t addr = base + (is_tbh ? index*2 : index); 2421 2422 // PC-relative offset to branch forward 2423 EmulateInstruction::Context context; 2424 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2425 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2426 if (!success) 2427 return false; 2428 2429 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2430 if (!success) 2431 return false; 2432 2433 // target address 2434 addr_t target = pc + offset; 2435 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2436 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2437 2438 if (!BranchWritePC(context, target)) 2439 return false; 2440 2441 return true; 2442 } 2443 2444 // This instruction adds an immediate value to a register value, and writes the result to the destination register. 2445 // It can optionally update the condition flags based on the result. 2446 bool 2447 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2448 { 2449 #if 0 2450 if ConditionPassed() then 2451 EncodingSpecificOperations(); 2452 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2453 R[d] = result; 2454 if setflags then 2455 APSR.N = result<31>; 2456 APSR.Z = IsZeroBit(result); 2457 APSR.C = carry; 2458 APSR.V = overflow; 2459 #endif 2460 2461 bool success = false; 2462 2463 if (ConditionPassed(opcode)) 2464 { 2465 uint32_t d; 2466 uint32_t n; 2467 bool setflags; 2468 uint32_t imm32; 2469 uint32_t carry_out; 2470 2471 //EncodingSpecificOperations(); 2472 switch (encoding) 2473 { 2474 case eEncodingT1: 2475 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2476 d = Bits32 (opcode, 2, 0); 2477 n = Bits32 (opcode, 5, 3); 2478 setflags = !InITBlock(); 2479 imm32 = Bits32 (opcode, 8,6); 2480 2481 break; 2482 2483 case eEncodingT2: 2484 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2485 d = Bits32 (opcode, 10, 8); 2486 n = Bits32 (opcode, 10, 8); 2487 setflags = !InITBlock(); 2488 imm32 = Bits32 (opcode, 7, 0); 2489 2490 break; 2491 2492 case eEncodingT3: 2493 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2494 // if Rn == '1101' then SEE ADD (SP plus immediate); 2495 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2496 d = Bits32 (opcode, 11, 8); 2497 n = Bits32 (opcode, 19, 16); 2498 setflags = BitIsSet (opcode, 20); 2499 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2500 2501 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2502 if (BadReg (d) || (n == 15)) 2503 return false; 2504 2505 break; 2506 2507 case eEncodingT4: 2508 { 2509 // if Rn == '1111' then SEE ADR; 2510 // if Rn == '1101' then SEE ADD (SP plus immediate); 2511 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2512 d = Bits32 (opcode, 11, 8); 2513 n = Bits32 (opcode, 19, 16); 2514 setflags = false; 2515 uint32_t i = Bit32 (opcode, 26); 2516 uint32_t imm3 = Bits32 (opcode, 14, 12); 2517 uint32_t imm8 = Bits32 (opcode, 7, 0); 2518 imm32 = (i << 11) | (imm3 << 8) | imm8; 2519 2520 // if BadReg(d) then UNPREDICTABLE; 2521 if (BadReg (d)) 2522 return false; 2523 2524 break; 2525 } 2526 default: 2527 return false; 2528 } 2529 2530 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2531 if (!success) 2532 return false; 2533 2534 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2535 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2536 2537 RegisterInfo reg_n; 2538 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2539 2540 EmulateInstruction::Context context; 2541 context.type = eContextArithmetic; 2542 context.SetRegisterPlusOffset (reg_n, imm32); 2543 2544 //R[d] = result; 2545 //if setflags then 2546 //APSR.N = result<31>; 2547 //APSR.Z = IsZeroBit(result); 2548 //APSR.C = carry; 2549 //APSR.V = overflow; 2550 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2551 return false; 2552 2553 } 2554 return true; 2555 } 2556 2557 // This instruction adds an immediate value to a register value, and writes the result to the destination 2558 // register. It can optionally update the condition flags based on the result. 2559 bool 2560 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2561 { 2562 #if 0 2563 // ARM pseudo code... 2564 if ConditionPassed() then 2565 EncodingSpecificOperations(); 2566 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2567 if d == 15 then 2568 ALUWritePC(result); // setflags is always FALSE here 2569 else 2570 R[d] = result; 2571 if setflags then 2572 APSR.N = result<31>; 2573 APSR.Z = IsZeroBit(result); 2574 APSR.C = carry; 2575 APSR.V = overflow; 2576 #endif 2577 2578 bool success = false; 2579 2580 if (ConditionPassed(opcode)) 2581 { 2582 uint32_t Rd, Rn; 2583 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2584 bool setflags; 2585 switch (encoding) 2586 { 2587 case eEncodingA1: 2588 Rd = Bits32(opcode, 15, 12); 2589 Rn = Bits32(opcode, 19, 16); 2590 setflags = BitIsSet(opcode, 20); 2591 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2592 break; 2593 default: 2594 return false; 2595 } 2596 2597 // Read the first operand. 2598 uint32_t val1 = ReadCoreReg(Rn, &success); 2599 if (!success) 2600 return false; 2601 2602 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2603 2604 EmulateInstruction::Context context; 2605 context.type = eContextArithmetic; 2606 RegisterInfo dwarf_reg; 2607 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2608 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2609 2610 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2611 return false; 2612 } 2613 return true; 2614 } 2615 2616 // This instruction adds a register value and an optionally-shifted register value, and writes the result 2617 // to the destination register. It can optionally update the condition flags based on the result. 2618 bool 2619 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2620 { 2621 #if 0 2622 // ARM pseudo code... 2623 if ConditionPassed() then 2624 EncodingSpecificOperations(); 2625 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2626 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2627 if d == 15 then 2628 ALUWritePC(result); // setflags is always FALSE here 2629 else 2630 R[d] = result; 2631 if setflags then 2632 APSR.N = result<31>; 2633 APSR.Z = IsZeroBit(result); 2634 APSR.C = carry; 2635 APSR.V = overflow; 2636 #endif 2637 2638 bool success = false; 2639 2640 if (ConditionPassed(opcode)) 2641 { 2642 uint32_t Rd, Rn, Rm; 2643 ARM_ShifterType shift_t; 2644 uint32_t shift_n; // the shift applied to the value read from Rm 2645 bool setflags; 2646 switch (encoding) 2647 { 2648 case eEncodingT1: 2649 Rd = Bits32(opcode, 2, 0); 2650 Rn = Bits32(opcode, 5, 3); 2651 Rm = Bits32(opcode, 8, 6); 2652 setflags = !InITBlock(); 2653 shift_t = SRType_LSL; 2654 shift_n = 0; 2655 break; 2656 case eEncodingT2: 2657 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2658 Rm = Bits32(opcode, 6, 3); 2659 setflags = false; 2660 shift_t = SRType_LSL; 2661 shift_n = 0; 2662 if (Rn == 15 && Rm == 15) 2663 return false; 2664 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2665 return false; 2666 break; 2667 case eEncodingA1: 2668 Rd = Bits32(opcode, 15, 12); 2669 Rn = Bits32(opcode, 19, 16); 2670 Rm = Bits32(opcode, 3, 0); 2671 setflags = BitIsSet(opcode, 20); 2672 shift_n = DecodeImmShiftARM(opcode, shift_t); 2673 break; 2674 default: 2675 return false; 2676 } 2677 2678 // Read the first operand. 2679 uint32_t val1 = ReadCoreReg(Rn, &success); 2680 if (!success) 2681 return false; 2682 2683 // Read the second operand. 2684 uint32_t val2 = ReadCoreReg(Rm, &success); 2685 if (!success) 2686 return false; 2687 2688 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2689 if (!success) 2690 return false; 2691 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2692 2693 EmulateInstruction::Context context; 2694 context.type = eContextArithmetic; 2695 RegisterInfo op1_reg; 2696 RegisterInfo op2_reg; 2697 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2698 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2699 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2700 2701 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2702 return false; 2703 } 2704 return true; 2705 } 2706 2707 // Compare Negative (immediate) adds a register value and an immediate value. 2708 // It updates the condition flags based on the result, and discards the result. 2709 bool 2710 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2711 { 2712 #if 0 2713 // ARM pseudo code... 2714 if ConditionPassed() then 2715 EncodingSpecificOperations(); 2716 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2717 APSR.N = result<31>; 2718 APSR.Z = IsZeroBit(result); 2719 APSR.C = carry; 2720 APSR.V = overflow; 2721 #endif 2722 2723 bool success = false; 2724 2725 uint32_t Rn; // the first operand 2726 uint32_t imm32; // the immediate value to be compared with 2727 switch (encoding) { 2728 case eEncodingT1: 2729 Rn = Bits32(opcode, 19, 16); 2730 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2731 if (Rn == 15) 2732 return false; 2733 break; 2734 case eEncodingA1: 2735 Rn = Bits32(opcode, 19, 16); 2736 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2737 break; 2738 default: 2739 return false; 2740 } 2741 // Read the register value from the operand register Rn. 2742 uint32_t reg_val = ReadCoreReg(Rn, &success); 2743 if (!success) 2744 return false; 2745 2746 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2747 2748 EmulateInstruction::Context context; 2749 context.type = EmulateInstruction::eContextImmediate; 2750 context.SetNoArgs (); 2751 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2752 return false; 2753 2754 return true; 2755 } 2756 2757 // Compare Negative (register) adds a register value and an optionally-shifted register value. 2758 // It updates the condition flags based on the result, and discards the result. 2759 bool 2760 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2761 { 2762 #if 0 2763 // ARM pseudo code... 2764 if ConditionPassed() then 2765 EncodingSpecificOperations(); 2766 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2767 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2768 APSR.N = result<31>; 2769 APSR.Z = IsZeroBit(result); 2770 APSR.C = carry; 2771 APSR.V = overflow; 2772 #endif 2773 2774 bool success = false; 2775 2776 uint32_t Rn; // the first operand 2777 uint32_t Rm; // the second operand 2778 ARM_ShifterType shift_t; 2779 uint32_t shift_n; // the shift applied to the value read from Rm 2780 switch (encoding) { 2781 case eEncodingT1: 2782 Rn = Bits32(opcode, 2, 0); 2783 Rm = Bits32(opcode, 5, 3); 2784 shift_t = SRType_LSL; 2785 shift_n = 0; 2786 break; 2787 case eEncodingT2: 2788 Rn = Bits32(opcode, 19, 16); 2789 Rm = Bits32(opcode, 3, 0); 2790 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2791 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2792 if (Rn == 15 || BadReg(Rm)) 2793 return false; 2794 break; 2795 case eEncodingA1: 2796 Rn = Bits32(opcode, 19, 16); 2797 Rm = Bits32(opcode, 3, 0); 2798 shift_n = DecodeImmShiftARM(opcode, shift_t); 2799 break; 2800 default: 2801 return false; 2802 } 2803 // Read the register value from register Rn. 2804 uint32_t val1 = ReadCoreReg(Rn, &success); 2805 if (!success) 2806 return false; 2807 2808 // Read the register value from register Rm. 2809 uint32_t val2 = ReadCoreReg(Rm, &success); 2810 if (!success) 2811 return false; 2812 2813 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2814 if (!success) 2815 return false; 2816 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2817 2818 EmulateInstruction::Context context; 2819 context.type = EmulateInstruction::eContextImmediate; 2820 context.SetNoArgs(); 2821 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2822 return false; 2823 2824 return true; 2825 } 2826 2827 // Compare (immediate) subtracts an immediate value from a register value. 2828 // It updates the condition flags based on the result, and discards the result. 2829 bool 2830 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2831 { 2832 #if 0 2833 // ARM pseudo code... 2834 if ConditionPassed() then 2835 EncodingSpecificOperations(); 2836 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2837 APSR.N = result<31>; 2838 APSR.Z = IsZeroBit(result); 2839 APSR.C = carry; 2840 APSR.V = overflow; 2841 #endif 2842 2843 bool success = false; 2844 2845 uint32_t Rn; // the first operand 2846 uint32_t imm32; // the immediate value to be compared with 2847 switch (encoding) { 2848 case eEncodingT1: 2849 Rn = Bits32(opcode, 10, 8); 2850 imm32 = Bits32(opcode, 7, 0); 2851 break; 2852 case eEncodingT2: 2853 Rn = Bits32(opcode, 19, 16); 2854 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2855 if (Rn == 15) 2856 return false; 2857 break; 2858 case eEncodingA1: 2859 Rn = Bits32(opcode, 19, 16); 2860 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2861 break; 2862 default: 2863 return false; 2864 } 2865 // Read the register value from the operand register Rn. 2866 uint32_t reg_val = ReadCoreReg(Rn, &success); 2867 if (!success) 2868 return false; 2869 2870 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2871 2872 EmulateInstruction::Context context; 2873 context.type = EmulateInstruction::eContextImmediate; 2874 context.SetNoArgs (); 2875 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2876 return false; 2877 2878 return true; 2879 } 2880 2881 // Compare (register) subtracts an optionally-shifted register value from a register value. 2882 // It updates the condition flags based on the result, and discards the result. 2883 bool 2884 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2885 { 2886 #if 0 2887 // ARM pseudo code... 2888 if ConditionPassed() then 2889 EncodingSpecificOperations(); 2890 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2891 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2892 APSR.N = result<31>; 2893 APSR.Z = IsZeroBit(result); 2894 APSR.C = carry; 2895 APSR.V = overflow; 2896 #endif 2897 2898 bool success = false; 2899 2900 uint32_t Rn; // the first operand 2901 uint32_t Rm; // the second operand 2902 ARM_ShifterType shift_t; 2903 uint32_t shift_n; // the shift applied to the value read from Rm 2904 switch (encoding) { 2905 case eEncodingT1: 2906 Rn = Bits32(opcode, 2, 0); 2907 Rm = Bits32(opcode, 5, 3); 2908 shift_t = SRType_LSL; 2909 shift_n = 0; 2910 break; 2911 case eEncodingT2: 2912 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2913 Rm = Bits32(opcode, 6, 3); 2914 shift_t = SRType_LSL; 2915 shift_n = 0; 2916 if (Rn < 8 && Rm < 8) 2917 return false; 2918 if (Rn == 15 || Rm == 15) 2919 return false; 2920 break; 2921 case eEncodingA1: 2922 Rn = Bits32(opcode, 19, 16); 2923 Rm = Bits32(opcode, 3, 0); 2924 shift_n = DecodeImmShiftARM(opcode, shift_t); 2925 break; 2926 default: 2927 return false; 2928 } 2929 // Read the register value from register Rn. 2930 uint32_t val1 = ReadCoreReg(Rn, &success); 2931 if (!success) 2932 return false; 2933 2934 // Read the register value from register Rm. 2935 uint32_t val2 = ReadCoreReg(Rm, &success); 2936 if (!success) 2937 return false; 2938 2939 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2940 if (!success) 2941 return false; 2942 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 2943 2944 EmulateInstruction::Context context; 2945 context.type = EmulateInstruction::eContextImmediate; 2946 context.SetNoArgs(); 2947 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2948 return false; 2949 2950 return true; 2951 } 2952 2953 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2954 // shifting in copies of its sign bit, and writes the result to the destination register. It can 2955 // optionally update the condition flags based on the result. 2956 bool 2957 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 2958 { 2959 #if 0 2960 // ARM pseudo code... 2961 if ConditionPassed() then 2962 EncodingSpecificOperations(); 2963 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2964 if d == 15 then // Can only occur for ARM encoding 2965 ALUWritePC(result); // setflags is always FALSE here 2966 else 2967 R[d] = result; 2968 if setflags then 2969 APSR.N = result<31>; 2970 APSR.Z = IsZeroBit(result); 2971 APSR.C = carry; 2972 // APSR.V unchanged 2973 #endif 2974 2975 return EmulateShiftImm (opcode, encoding, SRType_ASR); 2976 } 2977 2978 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 2979 // shifting in copies of its sign bit, and writes the result to the destination register. 2980 // The variable number of bits is read from the bottom byte of a register. It can optionally update 2981 // the condition flags based on the result. 2982 bool 2983 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 2984 { 2985 #if 0 2986 // ARM pseudo code... 2987 if ConditionPassed() then 2988 EncodingSpecificOperations(); 2989 shift_n = UInt(R[m]<7:0>); 2990 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2991 R[d] = result; 2992 if setflags then 2993 APSR.N = result<31>; 2994 APSR.Z = IsZeroBit(result); 2995 APSR.C = carry; 2996 // APSR.V unchanged 2997 #endif 2998 2999 return EmulateShiftReg (opcode, encoding, SRType_ASR); 3000 } 3001 3002 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 3003 // shifting in zeros, and writes the result to the destination register. It can optionally 3004 // update the condition flags based on the result. 3005 bool 3006 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 3007 { 3008 #if 0 3009 // ARM pseudo code... 3010 if ConditionPassed() then 3011 EncodingSpecificOperations(); 3012 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3013 if d == 15 then // Can only occur for ARM encoding 3014 ALUWritePC(result); // setflags is always FALSE here 3015 else 3016 R[d] = result; 3017 if setflags then 3018 APSR.N = result<31>; 3019 APSR.Z = IsZeroBit(result); 3020 APSR.C = carry; 3021 // APSR.V unchanged 3022 #endif 3023 3024 return EmulateShiftImm (opcode, encoding, SRType_LSL); 3025 } 3026 3027 // Logical Shift Left (register) shifts a register value left by a variable number of bits, 3028 // shifting in zeros, and writes the result to the destination register. The variable number 3029 // of bits is read from the bottom byte of a register. It can optionally update the condition 3030 // flags based on the result. 3031 bool 3032 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 3033 { 3034 #if 0 3035 // ARM pseudo code... 3036 if ConditionPassed() then 3037 EncodingSpecificOperations(); 3038 shift_n = UInt(R[m]<7:0>); 3039 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3040 R[d] = result; 3041 if setflags then 3042 APSR.N = result<31>; 3043 APSR.Z = IsZeroBit(result); 3044 APSR.C = carry; 3045 // APSR.V unchanged 3046 #endif 3047 3048 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3049 } 3050 3051 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3052 // shifting in zeros, and writes the result to the destination register. It can optionally 3053 // update the condition flags based on the result. 3054 bool 3055 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3056 { 3057 #if 0 3058 // ARM pseudo code... 3059 if ConditionPassed() then 3060 EncodingSpecificOperations(); 3061 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3062 if d == 15 then // Can only occur for ARM encoding 3063 ALUWritePC(result); // setflags is always FALSE here 3064 else 3065 R[d] = result; 3066 if setflags then 3067 APSR.N = result<31>; 3068 APSR.Z = IsZeroBit(result); 3069 APSR.C = carry; 3070 // APSR.V unchanged 3071 #endif 3072 3073 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3074 } 3075 3076 // Logical Shift Right (register) shifts a register value right by a variable number of bits, 3077 // shifting in zeros, and writes the result to the destination register. The variable number 3078 // of bits is read from the bottom byte of a register. It can optionally update the condition 3079 // flags based on the result. 3080 bool 3081 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3082 { 3083 #if 0 3084 // ARM pseudo code... 3085 if ConditionPassed() then 3086 EncodingSpecificOperations(); 3087 shift_n = UInt(R[m]<7:0>); 3088 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3089 R[d] = result; 3090 if setflags then 3091 APSR.N = result<31>; 3092 APSR.Z = IsZeroBit(result); 3093 APSR.C = carry; 3094 // APSR.V unchanged 3095 #endif 3096 3097 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3098 } 3099 3100 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3101 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3102 // It can optionally update the condition flags based on the result. 3103 bool 3104 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3105 { 3106 #if 0 3107 // ARM pseudo code... 3108 if ConditionPassed() then 3109 EncodingSpecificOperations(); 3110 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3111 if d == 15 then // Can only occur for ARM encoding 3112 ALUWritePC(result); // setflags is always FALSE here 3113 else 3114 R[d] = result; 3115 if setflags then 3116 APSR.N = result<31>; 3117 APSR.Z = IsZeroBit(result); 3118 APSR.C = carry; 3119 // APSR.V unchanged 3120 #endif 3121 3122 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3123 } 3124 3125 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3126 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3127 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3128 // flags based on the result. 3129 bool 3130 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3131 { 3132 #if 0 3133 // ARM pseudo code... 3134 if ConditionPassed() then 3135 EncodingSpecificOperations(); 3136 shift_n = UInt(R[m]<7:0>); 3137 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3138 R[d] = result; 3139 if setflags then 3140 APSR.N = result<31>; 3141 APSR.Z = IsZeroBit(result); 3142 APSR.C = carry; 3143 // APSR.V unchanged 3144 #endif 3145 3146 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3147 } 3148 3149 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3150 // with the carry flag shifted into bit [31]. 3151 // 3152 // RRX can optionally update the condition flags based on the result. 3153 // In that case, bit [0] is shifted into the carry flag. 3154 bool 3155 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3156 { 3157 #if 0 3158 // ARM pseudo code... 3159 if ConditionPassed() then 3160 EncodingSpecificOperations(); 3161 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3162 if d == 15 then // Can only occur for ARM encoding 3163 ALUWritePC(result); // setflags is always FALSE here 3164 else 3165 R[d] = result; 3166 if setflags then 3167 APSR.N = result<31>; 3168 APSR.Z = IsZeroBit(result); 3169 APSR.C = carry; 3170 // APSR.V unchanged 3171 #endif 3172 3173 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3174 } 3175 3176 bool 3177 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3178 { 3179 // assert(shift_type == SRType_ASR 3180 // || shift_type == SRType_LSL 3181 // || shift_type == SRType_LSR 3182 // || shift_type == SRType_ROR 3183 // || shift_type == SRType_RRX); 3184 3185 bool success = false; 3186 3187 if (ConditionPassed(opcode)) 3188 { 3189 uint32_t Rd; // the destination register 3190 uint32_t Rm; // the first operand register 3191 uint32_t imm5; // encoding for the shift amount 3192 uint32_t carry; // the carry bit after the shift operation 3193 bool setflags; 3194 3195 // Special case handling! 3196 // A8.6.139 ROR (immediate) -- Encoding T1 3197 ARMEncoding use_encoding = encoding; 3198 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3199 { 3200 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3201 // have the same decoding of bit fields as the other Thumb2 shift operations. 3202 use_encoding = eEncodingT2; 3203 } 3204 3205 switch (use_encoding) { 3206 case eEncodingT1: 3207 // Due to the above special case handling! 3208 if (shift_type == SRType_ROR) 3209 return false; 3210 3211 Rd = Bits32(opcode, 2, 0); 3212 Rm = Bits32(opcode, 5, 3); 3213 setflags = !InITBlock(); 3214 imm5 = Bits32(opcode, 10, 6); 3215 break; 3216 case eEncodingT2: 3217 // A8.6.141 RRX 3218 // There's no imm form of RRX instructions. 3219 if (shift_type == SRType_RRX) 3220 return false; 3221 3222 Rd = Bits32(opcode, 11, 8); 3223 Rm = Bits32(opcode, 3, 0); 3224 setflags = BitIsSet(opcode, 20); 3225 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3226 if (BadReg(Rd) || BadReg(Rm)) 3227 return false; 3228 break; 3229 case eEncodingA1: 3230 Rd = Bits32(opcode, 15, 12); 3231 Rm = Bits32(opcode, 3, 0); 3232 setflags = BitIsSet(opcode, 20); 3233 imm5 = Bits32(opcode, 11, 7); 3234 break; 3235 default: 3236 return false; 3237 } 3238 3239 // A8.6.139 ROR (immediate) 3240 if (shift_type == SRType_ROR && imm5 == 0) 3241 shift_type = SRType_RRX; 3242 3243 // Get the first operand. 3244 uint32_t value = ReadCoreReg (Rm, &success); 3245 if (!success) 3246 return false; 3247 3248 // Decode the shift amount if not RRX. 3249 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3250 3251 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3252 if (!success) 3253 return false; 3254 3255 // The context specifies that an immediate is to be moved into Rd. 3256 EmulateInstruction::Context context; 3257 context.type = EmulateInstruction::eContextImmediate; 3258 context.SetNoArgs (); 3259 3260 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3261 return false; 3262 } 3263 return true; 3264 } 3265 3266 bool 3267 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3268 { 3269 // assert(shift_type == SRType_ASR 3270 // || shift_type == SRType_LSL 3271 // || shift_type == SRType_LSR 3272 // || shift_type == SRType_ROR); 3273 3274 bool success = false; 3275 3276 if (ConditionPassed(opcode)) 3277 { 3278 uint32_t Rd; // the destination register 3279 uint32_t Rn; // the first operand register 3280 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3281 uint32_t carry; // the carry bit after the shift operation 3282 bool setflags; 3283 switch (encoding) { 3284 case eEncodingT1: 3285 Rd = Bits32(opcode, 2, 0); 3286 Rn = Rd; 3287 Rm = Bits32(opcode, 5, 3); 3288 setflags = !InITBlock(); 3289 break; 3290 case eEncodingT2: 3291 Rd = Bits32(opcode, 11, 8); 3292 Rn = Bits32(opcode, 19, 16); 3293 Rm = Bits32(opcode, 3, 0); 3294 setflags = BitIsSet(opcode, 20); 3295 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3296 return false; 3297 break; 3298 case eEncodingA1: 3299 Rd = Bits32(opcode, 15, 12); 3300 Rn = Bits32(opcode, 3, 0); 3301 Rm = Bits32(opcode, 11, 8); 3302 setflags = BitIsSet(opcode, 20); 3303 if (Rd == 15 || Rn == 15 || Rm == 15) 3304 return false; 3305 break; 3306 default: 3307 return false; 3308 } 3309 3310 // Get the first operand. 3311 uint32_t value = ReadCoreReg (Rn, &success); 3312 if (!success) 3313 return false; 3314 // Get the Rm register content. 3315 uint32_t val = ReadCoreReg (Rm, &success); 3316 if (!success) 3317 return false; 3318 3319 // Get the shift amount. 3320 uint32_t amt = Bits32(val, 7, 0); 3321 3322 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3323 if (!success) 3324 return false; 3325 3326 // The context specifies that an immediate is to be moved into Rd. 3327 EmulateInstruction::Context context; 3328 context.type = EmulateInstruction::eContextImmediate; 3329 context.SetNoArgs (); 3330 3331 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3332 return false; 3333 } 3334 return true; 3335 } 3336 3337 // LDM loads multiple registers from consecutive memory locations, using an 3338 // address from a base register. Optionally the address just above the highest of those locations 3339 // can be written back to the base register. 3340 bool 3341 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3342 { 3343 #if 0 3344 // ARM pseudo code... 3345 if ConditionPassed() 3346 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3347 address = R[n]; 3348 3349 for i = 0 to 14 3350 if registers<i> == '1' then 3351 R[i] = MemA[address, 4]; address = address + 4; 3352 if registers<15> == '1' then 3353 LoadWritePC (MemA[address, 4]); 3354 3355 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3356 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3357 3358 #endif 3359 3360 bool success = false; 3361 bool conditional = false; 3362 if (ConditionPassed(opcode, &conditional)) 3363 { 3364 uint32_t n; 3365 uint32_t registers = 0; 3366 bool wback; 3367 const uint32_t addr_byte_size = GetAddressByteSize(); 3368 switch (encoding) 3369 { 3370 case eEncodingT1: 3371 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3372 n = Bits32 (opcode, 10, 8); 3373 registers = Bits32 (opcode, 7, 0); 3374 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3375 wback = BitIsClear (registers, n); 3376 // if BitCount(registers) < 1 then UNPREDICTABLE; 3377 if (BitCount(registers) < 1) 3378 return false; 3379 break; 3380 case eEncodingT2: 3381 // if W == '1' && Rn == '1101' then SEE POP; 3382 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3383 n = Bits32 (opcode, 19, 16); 3384 registers = Bits32 (opcode, 15, 0); 3385 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3386 wback = BitIsSet (opcode, 21); 3387 3388 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3389 if ((n == 15) 3390 || (BitCount (registers) < 2) 3391 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3392 return false; 3393 3394 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3395 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3396 return false; 3397 3398 // if wback && registers<n> == '1' then UNPREDICTABLE; 3399 if (wback 3400 && BitIsSet (registers, n)) 3401 return false; 3402 break; 3403 3404 case eEncodingA1: 3405 n = Bits32 (opcode, 19, 16); 3406 registers = Bits32 (opcode, 15, 0); 3407 wback = BitIsSet (opcode, 21); 3408 if ((n == 15) 3409 || (BitCount (registers) < 1)) 3410 return false; 3411 break; 3412 default: 3413 return false; 3414 } 3415 3416 int32_t offset = 0; 3417 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3418 if (!success) 3419 return false; 3420 3421 EmulateInstruction::Context context; 3422 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3423 RegisterInfo dwarf_reg; 3424 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3425 context.SetRegisterPlusOffset (dwarf_reg, offset); 3426 3427 for (int i = 0; i < 14; ++i) 3428 { 3429 if (BitIsSet (registers, i)) 3430 { 3431 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3432 context.SetRegisterPlusOffset (dwarf_reg, offset); 3433 if (wback && (n == 13)) // Pop Instruction 3434 { 3435 if (conditional) 3436 context.type = EmulateInstruction::eContextRegisterLoad; 3437 else 3438 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3439 } 3440 3441 // R[i] = MemA [address, 4]; address = address + 4; 3442 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3443 if (!success) 3444 return false; 3445 3446 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3447 return false; 3448 3449 offset += addr_byte_size; 3450 } 3451 } 3452 3453 if (BitIsSet (registers, 15)) 3454 { 3455 //LoadWritePC (MemA [address, 4]); 3456 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3457 context.SetRegisterPlusOffset (dwarf_reg, offset); 3458 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3459 if (!success) 3460 return false; 3461 // In ARMv5T and above, this is an interworking branch. 3462 if (!LoadWritePC(context, data)) 3463 return false; 3464 } 3465 3466 if (wback && BitIsClear (registers, n)) 3467 { 3468 // R[n] = R[n] + 4 * BitCount (registers) 3469 int32_t offset = addr_byte_size * BitCount (registers); 3470 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3471 context.SetRegisterPlusOffset (dwarf_reg, offset); 3472 3473 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3474 return false; 3475 } 3476 if (wback && BitIsSet (registers, n)) 3477 // R[n] bits(32) UNKNOWN; 3478 return WriteBits32Unknown (n); 3479 } 3480 return true; 3481 } 3482 3483 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3484 // The consecutive memory locations end at this address and the address just below the lowest of those locations 3485 // can optionally be written back to the base register. 3486 bool 3487 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3488 { 3489 #if 0 3490 // ARM pseudo code... 3491 if ConditionPassed() then 3492 EncodingSpecificOperations(); 3493 address = R[n] - 4*BitCount(registers) + 4; 3494 3495 for i = 0 to 14 3496 if registers<i> == '1' then 3497 R[i] = MemA[address,4]; address = address + 4; 3498 3499 if registers<15> == '1' then 3500 LoadWritePC(MemA[address,4]); 3501 3502 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3503 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3504 #endif 3505 3506 bool success = false; 3507 3508 if (ConditionPassed(opcode)) 3509 { 3510 uint32_t n; 3511 uint32_t registers = 0; 3512 bool wback; 3513 const uint32_t addr_byte_size = GetAddressByteSize(); 3514 3515 // EncodingSpecificOperations(); 3516 switch (encoding) 3517 { 3518 case eEncodingA1: 3519 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3520 n = Bits32 (opcode, 19, 16); 3521 registers = Bits32 (opcode, 15, 0); 3522 wback = BitIsSet (opcode, 21); 3523 3524 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3525 if ((n == 15) || (BitCount (registers) < 1)) 3526 return false; 3527 3528 break; 3529 3530 default: 3531 return false; 3532 } 3533 // address = R[n] - 4*BitCount(registers) + 4; 3534 3535 int32_t offset = 0; 3536 addr_t Rn = ReadCoreReg (n, &success); 3537 3538 if (!success) 3539 return false; 3540 3541 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3542 3543 EmulateInstruction::Context context; 3544 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3545 RegisterInfo dwarf_reg; 3546 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3547 context.SetRegisterPlusOffset (dwarf_reg, offset); 3548 3549 // for i = 0 to 14 3550 for (int i = 0; i < 14; ++i) 3551 { 3552 // if registers<i> == '1' then 3553 if (BitIsSet (registers, i)) 3554 { 3555 // R[i] = MemA[address,4]; address = address + 4; 3556 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3557 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3558 if (!success) 3559 return false; 3560 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3561 return false; 3562 offset += addr_byte_size; 3563 } 3564 } 3565 3566 // if registers<15> == '1' then 3567 // LoadWritePC(MemA[address,4]); 3568 if (BitIsSet (registers, 15)) 3569 { 3570 context.SetRegisterPlusOffset (dwarf_reg, offset); 3571 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3572 if (!success) 3573 return false; 3574 // In ARMv5T and above, this is an interworking branch. 3575 if (!LoadWritePC(context, data)) 3576 return false; 3577 } 3578 3579 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3580 if (wback && BitIsClear (registers, n)) 3581 { 3582 if (!success) 3583 return false; 3584 3585 offset = (addr_byte_size * BitCount (registers)) * -1; 3586 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3587 context.SetImmediateSigned (offset); 3588 addr_t addr = Rn + offset; 3589 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3590 return false; 3591 } 3592 3593 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3594 if (wback && BitIsSet (registers, n)) 3595 return WriteBits32Unknown (n); 3596 } 3597 return true; 3598 } 3599 3600 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3601 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3602 // be optionally written back to the base register. 3603 bool 3604 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3605 { 3606 #if 0 3607 // ARM pseudo code... 3608 if ConditionPassed() then 3609 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3610 address = R[n] - 4*BitCount(registers); 3611 3612 for i = 0 to 14 3613 if registers<i> == '1' then 3614 R[i] = MemA[address,4]; address = address + 4; 3615 if registers<15> == '1' then 3616 LoadWritePC(MemA[address,4]); 3617 3618 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3619 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3620 #endif 3621 3622 bool success = false; 3623 3624 if (ConditionPassed(opcode)) 3625 { 3626 uint32_t n; 3627 uint32_t registers = 0; 3628 bool wback; 3629 const uint32_t addr_byte_size = GetAddressByteSize(); 3630 switch (encoding) 3631 { 3632 case eEncodingT1: 3633 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3634 n = Bits32 (opcode, 19, 16); 3635 registers = Bits32 (opcode, 15, 0); 3636 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3637 wback = BitIsSet (opcode, 21); 3638 3639 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3640 if ((n == 15) 3641 || (BitCount (registers) < 2) 3642 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3643 return false; 3644 3645 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3646 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3647 return false; 3648 3649 // if wback && registers<n> == '1' then UNPREDICTABLE; 3650 if (wback && BitIsSet (registers, n)) 3651 return false; 3652 3653 break; 3654 3655 case eEncodingA1: 3656 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3657 n = Bits32 (opcode, 19, 16); 3658 registers = Bits32 (opcode, 15, 0); 3659 wback = BitIsSet (opcode, 21); 3660 3661 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3662 if ((n == 15) || (BitCount (registers) < 1)) 3663 return false; 3664 3665 break; 3666 3667 default: 3668 return false; 3669 } 3670 3671 // address = R[n] - 4*BitCount(registers); 3672 3673 int32_t offset = 0; 3674 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3675 3676 if (!success) 3677 return false; 3678 3679 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3680 EmulateInstruction::Context context; 3681 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3682 RegisterInfo dwarf_reg; 3683 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3684 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3685 3686 for (int i = 0; i < 14; ++i) 3687 { 3688 if (BitIsSet (registers, i)) 3689 { 3690 // R[i] = MemA[address,4]; address = address + 4; 3691 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3692 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3693 if (!success) 3694 return false; 3695 3696 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3697 return false; 3698 3699 offset += addr_byte_size; 3700 } 3701 } 3702 3703 // if registers<15> == '1' then 3704 // LoadWritePC(MemA[address,4]); 3705 if (BitIsSet (registers, 15)) 3706 { 3707 context.SetRegisterPlusOffset (dwarf_reg, offset); 3708 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3709 if (!success) 3710 return false; 3711 // In ARMv5T and above, this is an interworking branch. 3712 if (!LoadWritePC(context, data)) 3713 return false; 3714 } 3715 3716 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3717 if (wback && BitIsClear (registers, n)) 3718 { 3719 if (!success) 3720 return false; 3721 3722 offset = (addr_byte_size * BitCount (registers)) * -1; 3723 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3724 context.SetImmediateSigned (offset); 3725 addr_t addr = Rn + offset; 3726 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3727 return false; 3728 } 3729 3730 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3731 if (wback && BitIsSet (registers, n)) 3732 return WriteBits32Unknown (n); 3733 } 3734 return true; 3735 } 3736 3737 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3738 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3739 // optinoally be written back to the base register. 3740 bool 3741 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3742 { 3743 #if 0 3744 if ConditionPassed() then 3745 EncodingSpecificOperations(); 3746 address = R[n] + 4; 3747 3748 for i = 0 to 14 3749 if registers<i> == '1' then 3750 R[i] = MemA[address,4]; address = address + 4; 3751 if registers<15> == '1' then 3752 LoadWritePC(MemA[address,4]); 3753 3754 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3755 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3756 #endif 3757 3758 bool success = false; 3759 3760 if (ConditionPassed(opcode)) 3761 { 3762 uint32_t n; 3763 uint32_t registers = 0; 3764 bool wback; 3765 const uint32_t addr_byte_size = GetAddressByteSize(); 3766 switch (encoding) 3767 { 3768 case eEncodingA1: 3769 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3770 n = Bits32 (opcode, 19, 16); 3771 registers = Bits32 (opcode, 15, 0); 3772 wback = BitIsSet (opcode, 21); 3773 3774 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3775 if ((n == 15) || (BitCount (registers) < 1)) 3776 return false; 3777 3778 break; 3779 default: 3780 return false; 3781 } 3782 // address = R[n] + 4; 3783 3784 int32_t offset = 0; 3785 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3786 3787 if (!success) 3788 return false; 3789 3790 addr_t address = Rn + addr_byte_size; 3791 3792 EmulateInstruction::Context context; 3793 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3794 RegisterInfo dwarf_reg; 3795 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3796 context.SetRegisterPlusOffset (dwarf_reg, offset); 3797 3798 for (int i = 0; i < 14; ++i) 3799 { 3800 if (BitIsSet (registers, i)) 3801 { 3802 // R[i] = MemA[address,4]; address = address + 4; 3803 3804 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3805 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3806 if (!success) 3807 return false; 3808 3809 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3810 return false; 3811 3812 offset += addr_byte_size; 3813 } 3814 } 3815 3816 // if registers<15> == '1' then 3817 // LoadWritePC(MemA[address,4]); 3818 if (BitIsSet (registers, 15)) 3819 { 3820 context.SetRegisterPlusOffset (dwarf_reg, offset); 3821 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3822 if (!success) 3823 return false; 3824 // In ARMv5T and above, this is an interworking branch. 3825 if (!LoadWritePC(context, data)) 3826 return false; 3827 } 3828 3829 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3830 if (wback && BitIsClear (registers, n)) 3831 { 3832 if (!success) 3833 return false; 3834 3835 offset = addr_byte_size * BitCount (registers); 3836 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3837 context.SetImmediateSigned (offset); 3838 addr_t addr = Rn + offset; 3839 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3840 return false; 3841 } 3842 3843 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3844 if (wback && BitIsSet (registers, n)) 3845 return WriteBits32Unknown (n); 3846 } 3847 return true; 3848 } 3849 3850 // Load Register (immediate) calculates an address from a base register value and 3851 // an immediate offset, loads a word from memory, and writes to a register. 3852 // LDR (immediate, Thumb) 3853 bool 3854 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3855 { 3856 #if 0 3857 // ARM pseudo code... 3858 if (ConditionPassed()) 3859 { 3860 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3861 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3862 address = if index then offset_addr else R[n]; 3863 data = MemU[address,4]; 3864 if wback then R[n] = offset_addr; 3865 if t == 15 then 3866 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3867 elsif UnalignedSupport() || address<1:0> = '00' then 3868 R[t] = data; 3869 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3870 } 3871 #endif 3872 3873 bool success = false; 3874 3875 if (ConditionPassed(opcode)) 3876 { 3877 uint32_t Rt; // the destination register 3878 uint32_t Rn; // the base register 3879 uint32_t imm32; // the immediate offset used to form the address 3880 addr_t offset_addr; // the offset address 3881 addr_t address; // the calculated address 3882 uint32_t data; // the literal data value from memory load 3883 bool add, index, wback; 3884 switch (encoding) { 3885 case eEncodingT1: 3886 Rt = Bits32(opcode, 2, 0); 3887 Rn = Bits32(opcode, 5, 3); 3888 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3889 // index = TRUE; add = TRUE; wback = FALSE 3890 add = true; 3891 index = true; 3892 wback = false; 3893 3894 break; 3895 3896 case eEncodingT2: 3897 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3898 Rt = Bits32 (opcode, 10, 8); 3899 Rn = 13; 3900 imm32 = Bits32 (opcode, 7, 0) << 2; 3901 3902 // index = TRUE; add = TRUE; wback = FALSE; 3903 index = true; 3904 add = true; 3905 wback = false; 3906 3907 break; 3908 3909 case eEncodingT3: 3910 // if Rn == '1111' then SEE LDR (literal); 3911 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3912 Rt = Bits32 (opcode, 15, 12); 3913 Rn = Bits32 (opcode, 19, 16); 3914 imm32 = Bits32 (opcode, 11, 0); 3915 3916 // index = TRUE; add = TRUE; wback = FALSE; 3917 index = true; 3918 add = true; 3919 wback = false; 3920 3921 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3922 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3923 return false; 3924 3925 break; 3926 3927 case eEncodingT4: 3928 // if Rn == '1111' then SEE LDR (literal); 3929 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3930 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3931 // if P == '0' && W == '0' then UNDEFINED; 3932 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3933 return false; 3934 3935 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3936 Rt = Bits32 (opcode, 15, 12); 3937 Rn = Bits32 (opcode, 19, 16); 3938 imm32 = Bits32 (opcode, 7, 0); 3939 3940 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3941 index = BitIsSet (opcode, 10); 3942 add = BitIsSet (opcode, 9); 3943 wback = BitIsSet (opcode, 8); 3944 3945 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3946 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3947 return false; 3948 3949 break; 3950 3951 default: 3952 return false; 3953 } 3954 uint32_t base = ReadCoreReg (Rn, &success); 3955 if (!success) 3956 return false; 3957 if (add) 3958 offset_addr = base + imm32; 3959 else 3960 offset_addr = base - imm32; 3961 3962 address = (index ? offset_addr : base); 3963 3964 RegisterInfo base_reg; 3965 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 3966 if (wback) 3967 { 3968 EmulateInstruction::Context ctx; 3969 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 3970 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3971 3972 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3973 return false; 3974 } 3975 3976 // Prepare to write to the Rt register. 3977 EmulateInstruction::Context context; 3978 context.type = EmulateInstruction::eContextRegisterLoad; 3979 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3980 3981 // Read memory from the address. 3982 data = MemURead(context, address, 4, 0, &success); 3983 if (!success) 3984 return false; 3985 3986 if (Rt == 15) 3987 { 3988 if (Bits32(address, 1, 0) == 0) 3989 { 3990 if (!LoadWritePC(context, data)) 3991 return false; 3992 } 3993 else 3994 return false; 3995 } 3996 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3997 { 3998 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3999 return false; 4000 } 4001 else 4002 WriteBits32Unknown (Rt); 4003 } 4004 return true; 4005 } 4006 4007 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 4008 // from a base register. The consecutive memory locations start at this address, and teh address just above the last 4009 // of those locations can optionally be written back to the base register. 4010 bool 4011 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 4012 { 4013 #if 0 4014 if ConditionPassed() then 4015 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4016 address = R[n]; 4017 4018 for i = 0 to 14 4019 if registers<i> == '1' then 4020 if i == n && wback && i != LowestSetBit(registers) then 4021 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4022 else 4023 MemA[address,4] = R[i]; 4024 address = address + 4; 4025 4026 if registers<15> == '1' then // Only possible for encoding A1 4027 MemA[address,4] = PCStoreValue(); 4028 if wback then R[n] = R[n] + 4*BitCount(registers); 4029 #endif 4030 4031 bool success = false; 4032 4033 if (ConditionPassed(opcode)) 4034 { 4035 uint32_t n; 4036 uint32_t registers = 0; 4037 bool wback; 4038 const uint32_t addr_byte_size = GetAddressByteSize(); 4039 4040 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4041 switch (encoding) 4042 { 4043 case eEncodingT1: 4044 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4045 n = Bits32 (opcode, 10, 8); 4046 registers = Bits32 (opcode, 7, 0); 4047 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4048 wback = true; 4049 4050 // if BitCount(registers) < 1 then UNPREDICTABLE; 4051 if (BitCount (registers) < 1) 4052 return false; 4053 4054 break; 4055 4056 case eEncodingT2: 4057 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4058 n = Bits32 (opcode, 19, 16); 4059 registers = Bits32 (opcode, 15, 0); 4060 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4061 wback = BitIsSet (opcode, 21); 4062 4063 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4064 if ((n == 15) || (BitCount (registers) < 2)) 4065 return false; 4066 4067 // if wback && registers<n> == '1' then UNPREDICTABLE; 4068 if (wback && BitIsSet (registers, n)) 4069 return false; 4070 4071 break; 4072 4073 case eEncodingA1: 4074 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4075 n = Bits32 (opcode, 19, 16); 4076 registers = Bits32 (opcode, 15, 0); 4077 wback = BitIsSet (opcode, 21); 4078 4079 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4080 if ((n == 15) || (BitCount (registers) < 1)) 4081 return false; 4082 4083 break; 4084 4085 default: 4086 return false; 4087 } 4088 4089 // address = R[n]; 4090 int32_t offset = 0; 4091 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4092 if (!success) 4093 return false; 4094 4095 EmulateInstruction::Context context; 4096 context.type = EmulateInstruction::eContextRegisterStore; 4097 RegisterInfo base_reg; 4098 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4099 4100 // for i = 0 to 14 4101 uint32_t lowest_set_bit = 14; 4102 for (uint32_t i = 0; i < 14; ++i) 4103 { 4104 // if registers<i> == '1' then 4105 if (BitIsSet (registers, i)) 4106 { 4107 if (i < lowest_set_bit) 4108 lowest_set_bit = i; 4109 // if i == n && wback && i != LowestSetBit(registers) then 4110 if ((i == n) && wback && (i != lowest_set_bit)) 4111 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4112 WriteBits32UnknownToMemory (address + offset); 4113 else 4114 { 4115 // MemA[address,4] = R[i]; 4116 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4117 if (!success) 4118 return false; 4119 4120 RegisterInfo data_reg; 4121 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4122 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4123 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4124 return false; 4125 } 4126 4127 // address = address + 4; 4128 offset += addr_byte_size; 4129 } 4130 } 4131 4132 // if registers<15> == '1' then // Only possible for encoding A1 4133 // MemA[address,4] = PCStoreValue(); 4134 if (BitIsSet (registers, 15)) 4135 { 4136 RegisterInfo pc_reg; 4137 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4138 context.SetRegisterPlusOffset (pc_reg, 8); 4139 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4140 if (!success) 4141 return false; 4142 4143 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4144 return false; 4145 } 4146 4147 // if wback then R[n] = R[n] + 4*BitCount(registers); 4148 if (wback) 4149 { 4150 offset = addr_byte_size * BitCount (registers); 4151 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4152 context.SetImmediateSigned (offset); 4153 addr_t data = address + offset; 4154 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4155 return false; 4156 } 4157 } 4158 return true; 4159 } 4160 4161 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4162 // from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4163 // of those locations can optionally be written back to the base register. 4164 bool 4165 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4166 { 4167 #if 0 4168 if ConditionPassed() then 4169 EncodingSpecificOperations(); 4170 address = R[n] - 4*BitCount(registers) + 4; 4171 4172 for i = 0 to 14 4173 if registers<i> == '1' then 4174 if i == n && wback && i != LowestSetBit(registers) then 4175 MemA[address,4] = bits(32) UNKNOWN; 4176 else 4177 MemA[address,4] = R[i]; 4178 address = address + 4; 4179 4180 if registers<15> == '1' then 4181 MemA[address,4] = PCStoreValue(); 4182 4183 if wback then R[n] = R[n] - 4*BitCount(registers); 4184 #endif 4185 4186 bool success = false; 4187 4188 if (ConditionPassed(opcode)) 4189 { 4190 uint32_t n; 4191 uint32_t registers = 0; 4192 bool wback; 4193 const uint32_t addr_byte_size = GetAddressByteSize(); 4194 4195 // EncodingSpecificOperations(); 4196 switch (encoding) 4197 { 4198 case eEncodingA1: 4199 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4200 n = Bits32 (opcode, 19, 16); 4201 registers = Bits32 (opcode, 15, 0); 4202 wback = BitIsSet (opcode, 21); 4203 4204 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4205 if ((n == 15) || (BitCount (registers) < 1)) 4206 return false; 4207 break; 4208 default: 4209 return false; 4210 } 4211 4212 // address = R[n] - 4*BitCount(registers) + 4; 4213 int32_t offset = 0; 4214 addr_t Rn = ReadCoreReg (n, &success); 4215 if (!success) 4216 return false; 4217 4218 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4219 4220 EmulateInstruction::Context context; 4221 context.type = EmulateInstruction::eContextRegisterStore; 4222 RegisterInfo base_reg; 4223 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4224 4225 // for i = 0 to 14 4226 uint32_t lowest_bit_set = 14; 4227 for (uint32_t i = 0; i < 14; ++i) 4228 { 4229 // if registers<i> == '1' then 4230 if (BitIsSet (registers, i)) 4231 { 4232 if (i < lowest_bit_set) 4233 lowest_bit_set = i; 4234 //if i == n && wback && i != LowestSetBit(registers) then 4235 if ((i == n) && wback && (i != lowest_bit_set)) 4236 // MemA[address,4] = bits(32) UNKNOWN; 4237 WriteBits32UnknownToMemory (address + offset); 4238 else 4239 { 4240 // MemA[address,4] = R[i]; 4241 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4242 if (!success) 4243 return false; 4244 4245 RegisterInfo data_reg; 4246 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4247 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4248 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4249 return false; 4250 } 4251 4252 // address = address + 4; 4253 offset += addr_byte_size; 4254 } 4255 } 4256 4257 // if registers<15> == '1' then 4258 // MemA[address,4] = PCStoreValue(); 4259 if (BitIsSet (registers, 15)) 4260 { 4261 RegisterInfo pc_reg; 4262 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4263 context.SetRegisterPlusOffset (pc_reg, 8); 4264 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4265 if (!success) 4266 return false; 4267 4268 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4269 return false; 4270 } 4271 4272 // if wback then R[n] = R[n] - 4*BitCount(registers); 4273 if (wback) 4274 { 4275 offset = (addr_byte_size * BitCount (registers)) * -1; 4276 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4277 context.SetImmediateSigned (offset); 4278 addr_t data = Rn + offset; 4279 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4280 return false; 4281 } 4282 } 4283 return true; 4284 } 4285 4286 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4287 // from a base register. The consecutive memory locations end just below this address, and the address of the first of 4288 // those locations can optionally be written back to the base register. 4289 bool 4290 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4291 { 4292 #if 0 4293 if ConditionPassed() then 4294 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4295 address = R[n] - 4*BitCount(registers); 4296 4297 for i = 0 to 14 4298 if registers<i> == '1' then 4299 if i == n && wback && i != LowestSetBit(registers) then 4300 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4301 else 4302 MemA[address,4] = R[i]; 4303 address = address + 4; 4304 4305 if registers<15> == '1' then // Only possible for encoding A1 4306 MemA[address,4] = PCStoreValue(); 4307 4308 if wback then R[n] = R[n] - 4*BitCount(registers); 4309 #endif 4310 4311 4312 bool success = false; 4313 4314 if (ConditionPassed(opcode)) 4315 { 4316 uint32_t n; 4317 uint32_t registers = 0; 4318 bool wback; 4319 const uint32_t addr_byte_size = GetAddressByteSize(); 4320 4321 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4322 switch (encoding) 4323 { 4324 case eEncodingT1: 4325 // if W == '1' && Rn == '1101' then SEE PUSH; 4326 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4327 { 4328 // See PUSH 4329 } 4330 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4331 n = Bits32 (opcode, 19, 16); 4332 registers = Bits32 (opcode, 15, 0); 4333 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4334 wback = BitIsSet (opcode, 21); 4335 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4336 if ((n == 15) || BitCount (registers) < 2) 4337 return false; 4338 // if wback && registers<n> == '1' then UNPREDICTABLE; 4339 if (wback && BitIsSet (registers, n)) 4340 return false; 4341 break; 4342 4343 case eEncodingA1: 4344 // if W == '1' && Rn == '1101 && BitCount(register_list) >= 2 then SEE PUSH; 4345 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4346 { 4347 // See Push 4348 } 4349 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4350 n = Bits32 (opcode, 19, 16); 4351 registers = Bits32 (opcode, 15, 0); 4352 wback = BitIsSet (opcode, 21); 4353 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4354 if ((n == 15) || BitCount (registers) < 1) 4355 return false; 4356 break; 4357 4358 default: 4359 return false; 4360 } 4361 4362 // address = R[n] - 4*BitCount(registers); 4363 4364 int32_t offset = 0; 4365 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4366 if (!success) 4367 return false; 4368 4369 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4370 4371 EmulateInstruction::Context context; 4372 context.type = EmulateInstruction::eContextRegisterStore; 4373 RegisterInfo base_reg; 4374 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4375 4376 // for i = 0 to 14 4377 uint32_t lowest_set_bit = 14; 4378 for (uint32_t i = 0; i < 14; ++i) 4379 { 4380 // if registers<i> == '1' then 4381 if (BitIsSet (registers, i)) 4382 { 4383 if (i < lowest_set_bit) 4384 lowest_set_bit = i; 4385 // if i == n && wback && i != LowestSetBit(registers) then 4386 if ((i == n) && wback && (i != lowest_set_bit)) 4387 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4388 WriteBits32UnknownToMemory (address + offset); 4389 else 4390 { 4391 // MemA[address,4] = R[i]; 4392 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4393 if (!success) 4394 return false; 4395 4396 RegisterInfo data_reg; 4397 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4398 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4399 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4400 return false; 4401 } 4402 4403 // address = address + 4; 4404 offset += addr_byte_size; 4405 } 4406 } 4407 4408 // if registers<15> == '1' then // Only possible for encoding A1 4409 // MemA[address,4] = PCStoreValue(); 4410 if (BitIsSet (registers, 15)) 4411 { 4412 RegisterInfo pc_reg; 4413 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4414 context.SetRegisterPlusOffset (pc_reg, 8); 4415 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4416 if (!success) 4417 return false; 4418 4419 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4420 return false; 4421 } 4422 4423 // if wback then R[n] = R[n] - 4*BitCount(registers); 4424 if (wback) 4425 { 4426 offset = (addr_byte_size * BitCount (registers)) * -1; 4427 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4428 context.SetImmediateSigned (offset); 4429 addr_t data = Rn + offset; 4430 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4431 return false; 4432 } 4433 } 4434 return true; 4435 } 4436 4437 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4438 // from a base register. The consecutive memory locations start just above this address, and the address of the last 4439 // of those locations can optionally be written back to the base register. 4440 bool 4441 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4442 { 4443 #if 0 4444 if ConditionPassed() then 4445 EncodingSpecificOperations(); 4446 address = R[n] + 4; 4447 4448 for i = 0 to 14 4449 if registers<i> == '1' then 4450 if i == n && wback && i != LowestSetBit(registers) then 4451 MemA[address,4] = bits(32) UNKNOWN; 4452 else 4453 MemA[address,4] = R[i]; 4454 address = address + 4; 4455 4456 if registers<15> == '1' then 4457 MemA[address,4] = PCStoreValue(); 4458 4459 if wback then R[n] = R[n] + 4*BitCount(registers); 4460 #endif 4461 4462 bool success = false; 4463 4464 if (ConditionPassed(opcode)) 4465 { 4466 uint32_t n; 4467 uint32_t registers = 0; 4468 bool wback; 4469 const uint32_t addr_byte_size = GetAddressByteSize(); 4470 4471 // EncodingSpecificOperations(); 4472 switch (encoding) 4473 { 4474 case eEncodingA1: 4475 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4476 n = Bits32 (opcode, 19, 16); 4477 registers = Bits32 (opcode, 15, 0); 4478 wback = BitIsSet (opcode, 21); 4479 4480 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4481 if ((n == 15) && (BitCount (registers) < 1)) 4482 return false; 4483 break; 4484 default: 4485 return false; 4486 } 4487 // address = R[n] + 4; 4488 4489 int32_t offset = 0; 4490 addr_t Rn = ReadCoreReg (n, &success); 4491 if (!success) 4492 return false; 4493 4494 addr_t address = Rn + addr_byte_size; 4495 4496 EmulateInstruction::Context context; 4497 context.type = EmulateInstruction::eContextRegisterStore; 4498 RegisterInfo base_reg; 4499 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4500 4501 uint32_t lowest_set_bit = 14; 4502 // for i = 0 to 14 4503 for (uint32_t i = 0; i < 14; ++i) 4504 { 4505 // if registers<i> == '1' then 4506 if (BitIsSet (registers, i)) 4507 { 4508 if (i < lowest_set_bit) 4509 lowest_set_bit = i; 4510 // if i == n && wback && i != LowestSetBit(registers) then 4511 if ((i == n) && wback && (i != lowest_set_bit)) 4512 // MemA[address,4] = bits(32) UNKNOWN; 4513 WriteBits32UnknownToMemory (address + offset); 4514 // else 4515 else 4516 { 4517 // MemA[address,4] = R[i]; 4518 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4519 if (!success) 4520 return false; 4521 4522 RegisterInfo data_reg; 4523 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4524 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4525 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4526 return false; 4527 } 4528 4529 // address = address + 4; 4530 offset += addr_byte_size; 4531 } 4532 } 4533 4534 // if registers<15> == '1' then 4535 // MemA[address,4] = PCStoreValue(); 4536 if (BitIsSet (registers, 15)) 4537 { 4538 RegisterInfo pc_reg; 4539 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4540 context.SetRegisterPlusOffset (pc_reg, 8); 4541 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4542 if (!success) 4543 return false; 4544 4545 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4546 return false; 4547 } 4548 4549 // if wback then R[n] = R[n] + 4*BitCount(registers); 4550 if (wback) 4551 { 4552 offset = addr_byte_size * BitCount (registers); 4553 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4554 context.SetImmediateSigned (offset); 4555 addr_t data = Rn + offset; 4556 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4557 return false; 4558 } 4559 } 4560 return true; 4561 } 4562 4563 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 4564 // from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4565 bool 4566 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4567 { 4568 #if 0 4569 if ConditionPassed() then 4570 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4571 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4572 address = if index then offset_addr else R[n]; 4573 if UnalignedSupport() || address<1:0> == '00' then 4574 MemU[address,4] = R[t]; 4575 else // Can only occur before ARMv7 4576 MemU[address,4] = bits(32) UNKNOWN; 4577 if wback then R[n] = offset_addr; 4578 #endif 4579 4580 bool success = false; 4581 4582 if (ConditionPassed(opcode)) 4583 { 4584 const uint32_t addr_byte_size = GetAddressByteSize(); 4585 4586 uint32_t t; 4587 uint32_t n; 4588 uint32_t imm32; 4589 bool index; 4590 bool add; 4591 bool wback; 4592 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4593 switch (encoding) 4594 { 4595 case eEncodingT1: 4596 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4597 t = Bits32 (opcode, 2, 0); 4598 n = Bits32 (opcode, 5, 3); 4599 imm32 = Bits32 (opcode, 10, 6) << 2; 4600 4601 // index = TRUE; add = TRUE; wback = FALSE; 4602 index = true; 4603 add = false; 4604 wback = false; 4605 break; 4606 4607 case eEncodingT2: 4608 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4609 t = Bits32 (opcode, 10, 8); 4610 n = 13; 4611 imm32 = Bits32 (opcode, 7, 0) << 2; 4612 4613 // index = TRUE; add = TRUE; wback = FALSE; 4614 index = true; 4615 add = true; 4616 wback = false; 4617 break; 4618 4619 case eEncodingT3: 4620 // if Rn == '1111' then UNDEFINED; 4621 if (Bits32 (opcode, 19, 16) == 15) 4622 return false; 4623 4624 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4625 t = Bits32 (opcode, 15, 12); 4626 n = Bits32 (opcode, 19, 16); 4627 imm32 = Bits32 (opcode, 11, 0); 4628 4629 // index = TRUE; add = TRUE; wback = FALSE; 4630 index = true; 4631 add = true; 4632 wback = false; 4633 4634 // if t == 15 then UNPREDICTABLE; 4635 if (t == 15) 4636 return false; 4637 break; 4638 4639 case eEncodingT4: 4640 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4641 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4642 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4643 if ((Bits32 (opcode, 19, 16) == 15) 4644 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4645 return false; 4646 4647 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4648 t = Bits32 (opcode, 15, 12); 4649 n = Bits32 (opcode, 19, 16); 4650 imm32 = Bits32 (opcode, 7, 0); 4651 4652 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4653 index = BitIsSet (opcode, 10); 4654 add = BitIsSet (opcode, 9); 4655 wback = BitIsSet (opcode, 8); 4656 4657 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4658 if ((t == 15) || (wback && (n == t))) 4659 return false; 4660 break; 4661 4662 default: 4663 return false; 4664 } 4665 4666 addr_t offset_addr; 4667 addr_t address; 4668 4669 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4670 uint32_t base_address = ReadCoreReg (n, &success); 4671 if (!success) 4672 return false; 4673 4674 if (add) 4675 offset_addr = base_address + imm32; 4676 else 4677 offset_addr = base_address - imm32; 4678 4679 // address = if index then offset_addr else R[n]; 4680 if (index) 4681 address = offset_addr; 4682 else 4683 address = base_address; 4684 4685 EmulateInstruction::Context context; 4686 context.type = eContextRegisterStore; 4687 RegisterInfo base_reg; 4688 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4689 4690 // if UnalignedSupport() || address<1:0> == '00' then 4691 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4692 { 4693 // MemU[address,4] = R[t]; 4694 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4695 if (!success) 4696 return false; 4697 4698 RegisterInfo data_reg; 4699 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4700 int32_t offset = address - base_address; 4701 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4702 if (!MemUWrite (context, address, data, addr_byte_size)) 4703 return false; 4704 } 4705 else 4706 { 4707 // MemU[address,4] = bits(32) UNKNOWN; 4708 WriteBits32UnknownToMemory (address); 4709 } 4710 4711 // if wback then R[n] = offset_addr; 4712 if (wback) 4713 { 4714 context.type = eContextRegisterLoad; 4715 context.SetAddress (offset_addr); 4716 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4717 return false; 4718 } 4719 } 4720 return true; 4721 } 4722 4723 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4724 // word from a register to memory. The offset register value can optionally be shifted. 4725 bool 4726 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4727 { 4728 #if 0 4729 if ConditionPassed() then 4730 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4731 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4732 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4733 address = if index then offset_addr else R[n]; 4734 if t == 15 then // Only possible for encoding A1 4735 data = PCStoreValue(); 4736 else 4737 data = R[t]; 4738 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4739 MemU[address,4] = data; 4740 else // Can only occur before ARMv7 4741 MemU[address,4] = bits(32) UNKNOWN; 4742 if wback then R[n] = offset_addr; 4743 #endif 4744 4745 bool success = false; 4746 4747 if (ConditionPassed(opcode)) 4748 { 4749 const uint32_t addr_byte_size = GetAddressByteSize(); 4750 4751 uint32_t t; 4752 uint32_t n; 4753 uint32_t m; 4754 ARM_ShifterType shift_t; 4755 uint32_t shift_n; 4756 bool index; 4757 bool add; 4758 bool wback; 4759 4760 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4761 switch (encoding) 4762 { 4763 case eEncodingT1: 4764 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4765 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4766 t = Bits32 (opcode, 2, 0); 4767 n = Bits32 (opcode, 5, 3); 4768 m = Bits32 (opcode, 8, 6); 4769 4770 // index = TRUE; add = TRUE; wback = FALSE; 4771 index = true; 4772 add = true; 4773 wback = false; 4774 4775 // (shift_t, shift_n) = (SRType_LSL, 0); 4776 shift_t = SRType_LSL; 4777 shift_n = 0; 4778 break; 4779 4780 case eEncodingT2: 4781 // if Rn == '1111' then UNDEFINED; 4782 if (Bits32 (opcode, 19, 16) == 15) 4783 return false; 4784 4785 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4786 t = Bits32 (opcode, 15, 12); 4787 n = Bits32 (opcode, 19, 16); 4788 m = Bits32 (opcode, 3, 0); 4789 4790 // index = TRUE; add = TRUE; wback = FALSE; 4791 index = true; 4792 add = true; 4793 wback = false; 4794 4795 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4796 shift_t = SRType_LSL; 4797 shift_n = Bits32 (opcode, 5, 4); 4798 4799 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4800 if ((t == 15) || (BadReg (m))) 4801 return false; 4802 break; 4803 4804 case eEncodingA1: 4805 { 4806 // if P == '0' && W == '1' then SEE STRT; 4807 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4808 t = Bits32 (opcode, 15, 12); 4809 n = Bits32 (opcode, 19, 16); 4810 m = Bits32 (opcode, 3, 0); 4811 4812 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4813 index = BitIsSet (opcode, 24); 4814 add = BitIsSet (opcode, 23); 4815 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4816 4817 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4818 uint32_t typ = Bits32 (opcode, 6, 5); 4819 uint32_t imm5 = Bits32 (opcode, 11, 7); 4820 shift_n = DecodeImmShift(typ, imm5, shift_t); 4821 4822 // if m == 15 then UNPREDICTABLE; 4823 if (m == 15) 4824 return false; 4825 4826 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4827 if (wback && ((n == 15) || (n == t))) 4828 return false; 4829 4830 break; 4831 } 4832 default: 4833 return false; 4834 } 4835 4836 addr_t offset_addr; 4837 addr_t address; 4838 int32_t offset = 0; 4839 4840 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4841 if (!success) 4842 return false; 4843 4844 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4845 if (!success) 4846 return false; 4847 4848 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4849 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4850 if (!success) 4851 return false; 4852 4853 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4854 if (add) 4855 offset_addr = base_address + offset; 4856 else 4857 offset_addr = base_address - offset; 4858 4859 // address = if index then offset_addr else R[n]; 4860 if (index) 4861 address = offset_addr; 4862 else 4863 address = base_address; 4864 4865 uint32_t data; 4866 // if t == 15 then // Only possible for encoding A1 4867 if (t == 15) 4868 // data = PCStoreValue(); 4869 data = ReadCoreReg (PC_REG, &success); 4870 else 4871 // data = R[t]; 4872 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4873 4874 if (!success) 4875 return false; 4876 4877 EmulateInstruction::Context context; 4878 context.type = eContextRegisterStore; 4879 4880 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4881 if (UnalignedSupport () 4882 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4883 || CurrentInstrSet() == eModeARM) 4884 { 4885 // MemU[address,4] = data; 4886 4887 RegisterInfo base_reg; 4888 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4889 4890 RegisterInfo data_reg; 4891 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4892 4893 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4894 if (!MemUWrite (context, address, data, addr_byte_size)) 4895 return false; 4896 4897 } 4898 else 4899 // MemU[address,4] = bits(32) UNKNOWN; 4900 WriteBits32UnknownToMemory (address); 4901 4902 // if wback then R[n] = offset_addr; 4903 if (wback) 4904 { 4905 context.type = eContextRegisterLoad; 4906 context.SetAddress (offset_addr); 4907 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4908 return false; 4909 } 4910 4911 } 4912 return true; 4913 } 4914 4915 bool 4916 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 4917 { 4918 #if 0 4919 if ConditionPassed() then 4920 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4921 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4922 address = if index then offset_addr else R[n]; 4923 MemU[address,1] = R[t]<7:0>; 4924 if wback then R[n] = offset_addr; 4925 #endif 4926 4927 4928 bool success = false; 4929 4930 if (ConditionPassed(opcode)) 4931 { 4932 uint32_t t; 4933 uint32_t n; 4934 uint32_t imm32; 4935 bool index; 4936 bool add; 4937 bool wback; 4938 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4939 switch (encoding) 4940 { 4941 case eEncodingT1: 4942 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4943 t = Bits32 (opcode, 2, 0); 4944 n = Bits32 (opcode, 5, 3); 4945 imm32 = Bits32 (opcode, 10, 6); 4946 4947 // index = TRUE; add = TRUE; wback = FALSE; 4948 index = true; 4949 add = true; 4950 wback = false; 4951 break; 4952 4953 case eEncodingT2: 4954 // if Rn == '1111' then UNDEFINED; 4955 if (Bits32 (opcode, 19, 16) == 15) 4956 return false; 4957 4958 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4959 t = Bits32 (opcode, 15, 12); 4960 n = Bits32 (opcode, 19, 16); 4961 imm32 = Bits32 (opcode, 11, 0); 4962 4963 // index = TRUE; add = TRUE; wback = FALSE; 4964 index = true; 4965 add = true; 4966 wback = false; 4967 4968 // if BadReg(t) then UNPREDICTABLE; 4969 if (BadReg (t)) 4970 return false; 4971 break; 4972 4973 case eEncodingT3: 4974 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 4975 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4976 if (Bits32 (opcode, 19, 16) == 15) 4977 return false; 4978 4979 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4980 t = Bits32 (opcode, 15, 12); 4981 n = Bits32 (opcode, 19, 16); 4982 imm32 = Bits32 (opcode, 7, 0); 4983 4984 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4985 index = BitIsSet (opcode, 10); 4986 add = BitIsSet (opcode, 9); 4987 wback = BitIsSet (opcode, 8); 4988 4989 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 4990 if ((BadReg (t)) || (wback && (n == t))) 4991 return false; 4992 break; 4993 4994 default: 4995 return false; 4996 } 4997 4998 addr_t offset_addr; 4999 addr_t address; 5000 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5001 if (!success) 5002 return false; 5003 5004 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5005 if (add) 5006 offset_addr = base_address + imm32; 5007 else 5008 offset_addr = base_address - imm32; 5009 5010 // address = if index then offset_addr else R[n]; 5011 if (index) 5012 address = offset_addr; 5013 else 5014 address = base_address; 5015 5016 // MemU[address,1] = R[t]<7:0> 5017 RegisterInfo base_reg; 5018 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5019 5020 RegisterInfo data_reg; 5021 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5022 5023 EmulateInstruction::Context context; 5024 context.type = eContextRegisterStore; 5025 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5026 5027 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5028 if (!success) 5029 return false; 5030 5031 data = Bits32 (data, 7, 0); 5032 5033 if (!MemUWrite (context, address, data, 1)) 5034 return false; 5035 5036 // if wback then R[n] = offset_addr; 5037 if (wback) 5038 { 5039 context.type = eContextRegisterLoad; 5040 context.SetAddress (offset_addr); 5041 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5042 return false; 5043 } 5044 5045 } 5046 5047 return true; 5048 } 5049 5050 // STRH (register) calculates an address from a base register value and an offset register value, and stores a 5051 // halfword from a register to memory. The offset register alue can be shifted left by 0, 1, 2, or 3 bits. 5052 bool 5053 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5054 { 5055 #if 0 5056 if ConditionPassed() then 5057 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5058 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5059 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5060 address = if index then offset_addr else R[n]; 5061 if UnalignedSupport() || address<0> == '0' then 5062 MemU[address,2] = R[t]<15:0>; 5063 else // Can only occur before ARMv7 5064 MemU[address,2] = bits(16) UNKNOWN; 5065 if wback then R[n] = offset_addr; 5066 #endif 5067 5068 bool success = false; 5069 5070 if (ConditionPassed(opcode)) 5071 { 5072 uint32_t t; 5073 uint32_t n; 5074 uint32_t m; 5075 bool index; 5076 bool add; 5077 bool wback; 5078 ARM_ShifterType shift_t; 5079 uint32_t shift_n; 5080 5081 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5082 switch (encoding) 5083 { 5084 case eEncodingT1: 5085 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5086 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5087 t = Bits32 (opcode, 2, 0); 5088 n = Bits32 (opcode, 5, 3); 5089 m = Bits32 (opcode, 8, 6); 5090 5091 // index = TRUE; add = TRUE; wback = FALSE; 5092 index = true; 5093 add = true; 5094 wback = false; 5095 5096 // (shift_t, shift_n) = (SRType_LSL, 0); 5097 shift_t = SRType_LSL; 5098 shift_n = 0; 5099 5100 break; 5101 5102 case eEncodingT2: 5103 // if Rn == '1111' then UNDEFINED; 5104 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5105 t = Bits32 (opcode, 15, 12); 5106 n = Bits32 (opcode, 19, 16); 5107 m = Bits32 (opcode, 3, 0); 5108 if (n == 15) 5109 return false; 5110 5111 // index = TRUE; add = TRUE; wback = FALSE; 5112 index = true; 5113 add = true; 5114 wback = false; 5115 5116 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5117 shift_t = SRType_LSL; 5118 shift_n = Bits32 (opcode, 5, 4); 5119 5120 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5121 if (BadReg (t) || BadReg (m)) 5122 return false; 5123 5124 break; 5125 5126 case eEncodingA1: 5127 // if P == '0' && W == '1' then SEE STRHT; 5128 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5129 t = Bits32 (opcode, 15, 12); 5130 n = Bits32 (opcode, 19, 16); 5131 m = Bits32 (opcode, 3, 0); 5132 5133 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5134 index = BitIsSet (opcode, 24); 5135 add = BitIsSet (opcode, 23); 5136 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5137 5138 // (shift_t, shift_n) = (SRType_LSL, 0); 5139 shift_t = SRType_LSL; 5140 shift_n = 0; 5141 5142 // if t == 15 || m == 15 then UNPREDICTABLE; 5143 if ((t == 15) || (m == 15)) 5144 return false; 5145 5146 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5147 if (wback && ((n == 15) || (n == t))) 5148 return false; 5149 5150 break; 5151 5152 default: 5153 return false; 5154 } 5155 5156 uint32_t Rm = ReadCoreReg (m, &success); 5157 if (!success) 5158 return false; 5159 5160 uint32_t Rn = ReadCoreReg (n, &success); 5161 if (!success) 5162 return false; 5163 5164 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5165 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5166 if (!success) 5167 return false; 5168 5169 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5170 addr_t offset_addr; 5171 if (add) 5172 offset_addr = Rn + offset; 5173 else 5174 offset_addr = Rn - offset; 5175 5176 // address = if index then offset_addr else R[n]; 5177 addr_t address; 5178 if (index) 5179 address = offset_addr; 5180 else 5181 address = Rn; 5182 5183 EmulateInstruction::Context context; 5184 context.type = eContextRegisterStore; 5185 RegisterInfo base_reg; 5186 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5187 RegisterInfo offset_reg; 5188 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5189 5190 // if UnalignedSupport() || address<0> == '0' then 5191 if (UnalignedSupport() || BitIsClear (address, 0)) 5192 { 5193 // MemU[address,2] = R[t]<15:0>; 5194 uint32_t Rt = ReadCoreReg (t, &success); 5195 if (!success) 5196 return false; 5197 5198 EmulateInstruction::Context context; 5199 context.type = eContextRegisterStore; 5200 RegisterInfo base_reg; 5201 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5202 RegisterInfo offset_reg; 5203 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5204 RegisterInfo data_reg; 5205 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5206 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5207 5208 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5209 return false; 5210 } 5211 else // Can only occur before ARMv7 5212 { 5213 // MemU[address,2] = bits(16) UNKNOWN; 5214 } 5215 5216 // if wback then R[n] = offset_addr; 5217 if (wback) 5218 { 5219 context.type = eContextAdjustBaseRegister; 5220 context.SetAddress (offset_addr); 5221 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5222 return false; 5223 } 5224 } 5225 5226 return true; 5227 } 5228 5229 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5230 // and writes the result to the destination register. It can optionally update the condition flags 5231 // based on the result. 5232 bool 5233 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5234 { 5235 #if 0 5236 // ARM pseudo code... 5237 if ConditionPassed() then 5238 EncodingSpecificOperations(); 5239 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5240 if d == 15 then // Can only occur for ARM encoding 5241 ALUWritePC(result); // setflags is always FALSE here 5242 else 5243 R[d] = result; 5244 if setflags then 5245 APSR.N = result<31>; 5246 APSR.Z = IsZeroBit(result); 5247 APSR.C = carry; 5248 APSR.V = overflow; 5249 #endif 5250 5251 bool success = false; 5252 5253 if (ConditionPassed(opcode)) 5254 { 5255 uint32_t Rd, Rn; 5256 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5257 bool setflags; 5258 switch (encoding) 5259 { 5260 case eEncodingT1: 5261 Rd = Bits32(opcode, 11, 8); 5262 Rn = Bits32(opcode, 19, 16); 5263 setflags = BitIsSet(opcode, 20); 5264 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5265 if (BadReg(Rd) || BadReg(Rn)) 5266 return false; 5267 break; 5268 case eEncodingA1: 5269 Rd = Bits32(opcode, 15, 12); 5270 Rn = Bits32(opcode, 19, 16); 5271 setflags = BitIsSet(opcode, 20); 5272 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5273 5274 if (Rd == 15 && setflags) 5275 return EmulateSUBSPcLrEtc (opcode, encoding); 5276 break; 5277 default: 5278 return false; 5279 } 5280 5281 // Read the first operand. 5282 int32_t val1 = ReadCoreReg(Rn, &success); 5283 if (!success) 5284 return false; 5285 5286 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5287 5288 EmulateInstruction::Context context; 5289 context.type = EmulateInstruction::eContextImmediate; 5290 context.SetNoArgs (); 5291 5292 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5293 return false; 5294 } 5295 return true; 5296 } 5297 5298 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5299 // register value, and writes the result to the destination register. It can optionally update the 5300 // condition flags based on the result. 5301 bool 5302 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5303 { 5304 #if 0 5305 // ARM pseudo code... 5306 if ConditionPassed() then 5307 EncodingSpecificOperations(); 5308 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5309 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5310 if d == 15 then // Can only occur for ARM encoding 5311 ALUWritePC(result); // setflags is always FALSE here 5312 else 5313 R[d] = result; 5314 if setflags then 5315 APSR.N = result<31>; 5316 APSR.Z = IsZeroBit(result); 5317 APSR.C = carry; 5318 APSR.V = overflow; 5319 #endif 5320 5321 bool success = false; 5322 5323 if (ConditionPassed(opcode)) 5324 { 5325 uint32_t Rd, Rn, Rm; 5326 ARM_ShifterType shift_t; 5327 uint32_t shift_n; // the shift applied to the value read from Rm 5328 bool setflags; 5329 switch (encoding) 5330 { 5331 case eEncodingT1: 5332 Rd = Rn = Bits32(opcode, 2, 0); 5333 Rm = Bits32(opcode, 5, 3); 5334 setflags = !InITBlock(); 5335 shift_t = SRType_LSL; 5336 shift_n = 0; 5337 break; 5338 case eEncodingT2: 5339 Rd = Bits32(opcode, 11, 8); 5340 Rn = Bits32(opcode, 19, 16); 5341 Rm = Bits32(opcode, 3, 0); 5342 setflags = BitIsSet(opcode, 20); 5343 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5344 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5345 return false; 5346 break; 5347 case eEncodingA1: 5348 Rd = Bits32(opcode, 15, 12); 5349 Rn = Bits32(opcode, 19, 16); 5350 Rm = Bits32(opcode, 3, 0); 5351 setflags = BitIsSet(opcode, 20); 5352 shift_n = DecodeImmShiftARM(opcode, shift_t); 5353 5354 if (Rd == 15 && setflags) 5355 return EmulateSUBSPcLrEtc (opcode, encoding); 5356 break; 5357 default: 5358 return false; 5359 } 5360 5361 // Read the first operand. 5362 int32_t val1 = ReadCoreReg(Rn, &success); 5363 if (!success) 5364 return false; 5365 5366 // Read the second operand. 5367 int32_t val2 = ReadCoreReg(Rm, &success); 5368 if (!success) 5369 return false; 5370 5371 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5372 if (!success) 5373 return false; 5374 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5375 5376 EmulateInstruction::Context context; 5377 context.type = EmulateInstruction::eContextImmediate; 5378 context.SetNoArgs (); 5379 5380 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5381 return false; 5382 } 5383 return true; 5384 } 5385 5386 // This instruction adds an immediate value to the PC value to form a PC-relative address, 5387 // and writes the result to the destination register. 5388 bool 5389 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5390 { 5391 #if 0 5392 // ARM pseudo code... 5393 if ConditionPassed() then 5394 EncodingSpecificOperations(); 5395 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5396 if d == 15 then // Can only occur for ARM encodings 5397 ALUWritePC(result); 5398 else 5399 R[d] = result; 5400 #endif 5401 5402 bool success = false; 5403 5404 if (ConditionPassed(opcode)) 5405 { 5406 uint32_t Rd; 5407 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5408 bool add; 5409 switch (encoding) 5410 { 5411 case eEncodingT1: 5412 Rd = Bits32(opcode, 10, 8); 5413 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5414 add = true; 5415 break; 5416 case eEncodingT2: 5417 case eEncodingT3: 5418 Rd = Bits32(opcode, 11, 8); 5419 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5420 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5421 if (BadReg(Rd)) 5422 return false; 5423 break; 5424 case eEncodingA1: 5425 case eEncodingA2: 5426 Rd = Bits32(opcode, 15, 12); 5427 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5428 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5429 break; 5430 default: 5431 return false; 5432 } 5433 5434 // Read the PC value. 5435 uint32_t pc = ReadCoreReg(PC_REG, &success); 5436 if (!success) 5437 return false; 5438 5439 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5440 5441 EmulateInstruction::Context context; 5442 context.type = EmulateInstruction::eContextImmediate; 5443 context.SetNoArgs (); 5444 5445 if (!WriteCoreReg(context, result, Rd)) 5446 return false; 5447 } 5448 return true; 5449 } 5450 5451 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5452 // to the destination register. It can optionally update the condition flags based on the result. 5453 bool 5454 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5455 { 5456 #if 0 5457 // ARM pseudo code... 5458 if ConditionPassed() then 5459 EncodingSpecificOperations(); 5460 result = R[n] AND imm32; 5461 if d == 15 then // Can only occur for ARM encoding 5462 ALUWritePC(result); // setflags is always FALSE here 5463 else 5464 R[d] = result; 5465 if setflags then 5466 APSR.N = result<31>; 5467 APSR.Z = IsZeroBit(result); 5468 APSR.C = carry; 5469 // APSR.V unchanged 5470 #endif 5471 5472 bool success = false; 5473 5474 if (ConditionPassed(opcode)) 5475 { 5476 uint32_t Rd, Rn; 5477 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5478 bool setflags; 5479 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5480 switch (encoding) 5481 { 5482 case eEncodingT1: 5483 Rd = Bits32(opcode, 11, 8); 5484 Rn = Bits32(opcode, 19, 16); 5485 setflags = BitIsSet(opcode, 20); 5486 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5487 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5488 if (Rd == 15 && setflags) 5489 return EmulateTSTImm(opcode, eEncodingT1); 5490 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5491 return false; 5492 break; 5493 case eEncodingA1: 5494 Rd = Bits32(opcode, 15, 12); 5495 Rn = Bits32(opcode, 19, 16); 5496 setflags = BitIsSet(opcode, 20); 5497 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5498 5499 if (Rd == 15 && setflags) 5500 return EmulateSUBSPcLrEtc (opcode, encoding); 5501 break; 5502 default: 5503 return false; 5504 } 5505 5506 // Read the first operand. 5507 uint32_t val1 = ReadCoreReg(Rn, &success); 5508 if (!success) 5509 return false; 5510 5511 uint32_t result = val1 & imm32; 5512 5513 EmulateInstruction::Context context; 5514 context.type = EmulateInstruction::eContextImmediate; 5515 context.SetNoArgs (); 5516 5517 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5518 return false; 5519 } 5520 return true; 5521 } 5522 5523 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5524 // and writes the result to the destination register. It can optionally update the condition flags 5525 // based on the result. 5526 bool 5527 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5528 { 5529 #if 0 5530 // ARM pseudo code... 5531 if ConditionPassed() then 5532 EncodingSpecificOperations(); 5533 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5534 result = R[n] AND shifted; 5535 if d == 15 then // Can only occur for ARM encoding 5536 ALUWritePC(result); // setflags is always FALSE here 5537 else 5538 R[d] = result; 5539 if setflags then 5540 APSR.N = result<31>; 5541 APSR.Z = IsZeroBit(result); 5542 APSR.C = carry; 5543 // APSR.V unchanged 5544 #endif 5545 5546 bool success = false; 5547 5548 if (ConditionPassed(opcode)) 5549 { 5550 uint32_t Rd, Rn, Rm; 5551 ARM_ShifterType shift_t; 5552 uint32_t shift_n; // the shift applied to the value read from Rm 5553 bool setflags; 5554 uint32_t carry; 5555 switch (encoding) 5556 { 5557 case eEncodingT1: 5558 Rd = Rn = Bits32(opcode, 2, 0); 5559 Rm = Bits32(opcode, 5, 3); 5560 setflags = !InITBlock(); 5561 shift_t = SRType_LSL; 5562 shift_n = 0; 5563 break; 5564 case eEncodingT2: 5565 Rd = Bits32(opcode, 11, 8); 5566 Rn = Bits32(opcode, 19, 16); 5567 Rm = Bits32(opcode, 3, 0); 5568 setflags = BitIsSet(opcode, 20); 5569 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5570 // if Rd == '1111' && S == '1' then SEE TST (register); 5571 if (Rd == 15 && setflags) 5572 return EmulateTSTReg(opcode, eEncodingT2); 5573 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5574 return false; 5575 break; 5576 case eEncodingA1: 5577 Rd = Bits32(opcode, 15, 12); 5578 Rn = Bits32(opcode, 19, 16); 5579 Rm = Bits32(opcode, 3, 0); 5580 setflags = BitIsSet(opcode, 20); 5581 shift_n = DecodeImmShiftARM(opcode, shift_t); 5582 5583 if (Rd == 15 && setflags) 5584 return EmulateSUBSPcLrEtc (opcode, encoding); 5585 break; 5586 default: 5587 return false; 5588 } 5589 5590 // Read the first operand. 5591 uint32_t val1 = ReadCoreReg(Rn, &success); 5592 if (!success) 5593 return false; 5594 5595 // Read the second operand. 5596 uint32_t val2 = ReadCoreReg(Rm, &success); 5597 if (!success) 5598 return false; 5599 5600 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5601 if (!success) 5602 return false; 5603 uint32_t result = val1 & shifted; 5604 5605 EmulateInstruction::Context context; 5606 context.type = EmulateInstruction::eContextImmediate; 5607 context.SetNoArgs (); 5608 5609 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5610 return false; 5611 } 5612 return true; 5613 } 5614 5615 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5616 // immediate value, and writes the result to the destination register. It can optionally update the 5617 // condition flags based on the result. 5618 bool 5619 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5620 { 5621 #if 0 5622 // ARM pseudo code... 5623 if ConditionPassed() then 5624 EncodingSpecificOperations(); 5625 result = R[n] AND NOT(imm32); 5626 if d == 15 then // Can only occur for ARM encoding 5627 ALUWritePC(result); // setflags is always FALSE here 5628 else 5629 R[d] = result; 5630 if setflags then 5631 APSR.N = result<31>; 5632 APSR.Z = IsZeroBit(result); 5633 APSR.C = carry; 5634 // APSR.V unchanged 5635 #endif 5636 5637 bool success = false; 5638 5639 if (ConditionPassed(opcode)) 5640 { 5641 uint32_t Rd, Rn; 5642 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5643 bool setflags; 5644 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5645 switch (encoding) 5646 { 5647 case eEncodingT1: 5648 Rd = Bits32(opcode, 11, 8); 5649 Rn = Bits32(opcode, 19, 16); 5650 setflags = BitIsSet(opcode, 20); 5651 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5652 if (BadReg(Rd) || BadReg(Rn)) 5653 return false; 5654 break; 5655 case eEncodingA1: 5656 Rd = Bits32(opcode, 15, 12); 5657 Rn = Bits32(opcode, 19, 16); 5658 setflags = BitIsSet(opcode, 20); 5659 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5660 5661 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5662 if (Rd == 15 && setflags) 5663 return EmulateSUBSPcLrEtc (opcode, encoding); 5664 break; 5665 default: 5666 return false; 5667 } 5668 5669 // Read the first operand. 5670 uint32_t val1 = ReadCoreReg(Rn, &success); 5671 if (!success) 5672 return false; 5673 5674 uint32_t result = val1 & ~imm32; 5675 5676 EmulateInstruction::Context context; 5677 context.type = EmulateInstruction::eContextImmediate; 5678 context.SetNoArgs (); 5679 5680 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5681 return false; 5682 } 5683 return true; 5684 } 5685 5686 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5687 // optionally-shifted register value, and writes the result to the destination register. 5688 // It can optionally update the condition flags based on the result. 5689 bool 5690 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5691 { 5692 #if 0 5693 // ARM pseudo code... 5694 if ConditionPassed() then 5695 EncodingSpecificOperations(); 5696 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5697 result = R[n] AND NOT(shifted); 5698 if d == 15 then // Can only occur for ARM encoding 5699 ALUWritePC(result); // setflags is always FALSE here 5700 else 5701 R[d] = result; 5702 if setflags then 5703 APSR.N = result<31>; 5704 APSR.Z = IsZeroBit(result); 5705 APSR.C = carry; 5706 // APSR.V unchanged 5707 #endif 5708 5709 bool success = false; 5710 5711 if (ConditionPassed(opcode)) 5712 { 5713 uint32_t Rd, Rn, Rm; 5714 ARM_ShifterType shift_t; 5715 uint32_t shift_n; // the shift applied to the value read from Rm 5716 bool setflags; 5717 uint32_t carry; 5718 switch (encoding) 5719 { 5720 case eEncodingT1: 5721 Rd = Rn = Bits32(opcode, 2, 0); 5722 Rm = Bits32(opcode, 5, 3); 5723 setflags = !InITBlock(); 5724 shift_t = SRType_LSL; 5725 shift_n = 0; 5726 break; 5727 case eEncodingT2: 5728 Rd = Bits32(opcode, 11, 8); 5729 Rn = Bits32(opcode, 19, 16); 5730 Rm = Bits32(opcode, 3, 0); 5731 setflags = BitIsSet(opcode, 20); 5732 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5733 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5734 return false; 5735 break; 5736 case eEncodingA1: 5737 Rd = Bits32(opcode, 15, 12); 5738 Rn = Bits32(opcode, 19, 16); 5739 Rm = Bits32(opcode, 3, 0); 5740 setflags = BitIsSet(opcode, 20); 5741 shift_n = DecodeImmShiftARM(opcode, shift_t); 5742 5743 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5744 if (Rd == 15 && setflags) 5745 return EmulateSUBSPcLrEtc (opcode, encoding); 5746 break; 5747 default: 5748 return false; 5749 } 5750 5751 // Read the first operand. 5752 uint32_t val1 = ReadCoreReg(Rn, &success); 5753 if (!success) 5754 return false; 5755 5756 // Read the second operand. 5757 uint32_t val2 = ReadCoreReg(Rm, &success); 5758 if (!success) 5759 return false; 5760 5761 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5762 if (!success) 5763 return false; 5764 uint32_t result = val1 & ~shifted; 5765 5766 EmulateInstruction::Context context; 5767 context.type = EmulateInstruction::eContextImmediate; 5768 context.SetNoArgs (); 5769 5770 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5771 return false; 5772 } 5773 return true; 5774 } 5775 5776 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5777 // from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5778 bool 5779 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5780 { 5781 #if 0 5782 if ConditionPassed() then 5783 EncodingSpecificOperations(); 5784 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5785 address = if index then offset_addr else R[n]; 5786 data = MemU[address,4]; 5787 if wback then R[n] = offset_addr; 5788 if t == 15 then 5789 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5790 elsif UnalignedSupport() || address<1:0> = '00' then 5791 R[t] = data; 5792 else // Can only apply before ARMv7 5793 R[t] = ROR(data, 8*UInt(address<1:0>)); 5794 #endif 5795 5796 bool success = false; 5797 5798 if (ConditionPassed(opcode)) 5799 { 5800 const uint32_t addr_byte_size = GetAddressByteSize(); 5801 5802 uint32_t t; 5803 uint32_t n; 5804 uint32_t imm32; 5805 bool index; 5806 bool add; 5807 bool wback; 5808 5809 switch (encoding) 5810 { 5811 case eEncodingA1: 5812 // if Rn == '1111' then SEE LDR (literal); 5813 // if P == '0' && W == '1' then SEE LDRT; 5814 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5815 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5816 t = Bits32 (opcode, 15, 12); 5817 n = Bits32 (opcode, 19, 16); 5818 imm32 = Bits32 (opcode, 11, 0); 5819 5820 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5821 index = BitIsSet (opcode, 24); 5822 add = BitIsSet (opcode, 23); 5823 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5824 5825 // if wback && n == t then UNPREDICTABLE; 5826 if (wback && (n == t)) 5827 return false; 5828 5829 break; 5830 5831 default: 5832 return false; 5833 } 5834 5835 addr_t address; 5836 addr_t offset_addr; 5837 addr_t base_address = ReadCoreReg (n, &success); 5838 if (!success) 5839 return false; 5840 5841 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5842 if (add) 5843 offset_addr = base_address + imm32; 5844 else 5845 offset_addr = base_address - imm32; 5846 5847 // address = if index then offset_addr else R[n]; 5848 if (index) 5849 address = offset_addr; 5850 else 5851 address = base_address; 5852 5853 // data = MemU[address,4]; 5854 5855 RegisterInfo base_reg; 5856 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5857 5858 EmulateInstruction::Context context; 5859 context.type = eContextRegisterLoad; 5860 context.SetRegisterPlusOffset (base_reg, address - base_address); 5861 5862 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5863 if (!success) 5864 return false; 5865 5866 // if wback then R[n] = offset_addr; 5867 if (wback) 5868 { 5869 context.type = eContextAdjustBaseRegister; 5870 context.SetAddress (offset_addr); 5871 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5872 return false; 5873 } 5874 5875 // if t == 15 then 5876 if (t == 15) 5877 { 5878 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5879 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5880 { 5881 // LoadWritePC (data); 5882 context.type = eContextRegisterLoad; 5883 context.SetRegisterPlusOffset (base_reg, address - base_address); 5884 LoadWritePC (context, data); 5885 } 5886 else 5887 return false; 5888 } 5889 // elsif UnalignedSupport() || address<1:0> = '00' then 5890 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5891 { 5892 // R[t] = data; 5893 context.type = eContextRegisterLoad; 5894 context.SetRegisterPlusOffset (base_reg, address - base_address); 5895 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5896 return false; 5897 } 5898 // else // Can only apply before ARMv7 5899 else 5900 { 5901 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5902 data = ROR (data, Bits32 (address, 1, 0), &success); 5903 if (!success) 5904 return false; 5905 context.type = eContextRegisterLoad; 5906 context.SetImmediate (data); 5907 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5908 return false; 5909 } 5910 5911 } 5912 return true; 5913 } 5914 5915 // LDR (register) calculates an address from a base register value and an offset register value, loads a word 5916 // from memory, and writes it to a resgister. The offset register value can optionally be shifted. 5917 bool 5918 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5919 { 5920 #if 0 5921 if ConditionPassed() then 5922 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5923 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5924 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5925 address = if index then offset_addr else R[n]; 5926 data = MemU[address,4]; 5927 if wback then R[n] = offset_addr; 5928 if t == 15 then 5929 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5930 elsif UnalignedSupport() || address<1:0> = '00' then 5931 R[t] = data; 5932 else // Can only apply before ARMv7 5933 if CurrentInstrSet() == InstrSet_ARM then 5934 R[t] = ROR(data, 8*UInt(address<1:0>)); 5935 else 5936 R[t] = bits(32) UNKNOWN; 5937 #endif 5938 5939 bool success = false; 5940 5941 if (ConditionPassed(opcode)) 5942 { 5943 const uint32_t addr_byte_size = GetAddressByteSize(); 5944 5945 uint32_t t; 5946 uint32_t n; 5947 uint32_t m; 5948 bool index; 5949 bool add; 5950 bool wback; 5951 ARM_ShifterType shift_t; 5952 uint32_t shift_n; 5953 5954 switch (encoding) 5955 { 5956 case eEncodingT1: 5957 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5958 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5959 t = Bits32 (opcode, 2, 0); 5960 n = Bits32 (opcode, 5, 3); 5961 m = Bits32 (opcode, 8, 6); 5962 5963 // index = TRUE; add = TRUE; wback = FALSE; 5964 index = true; 5965 add = true; 5966 wback = false; 5967 5968 // (shift_t, shift_n) = (SRType_LSL, 0); 5969 shift_t = SRType_LSL; 5970 shift_n = 0; 5971 5972 break; 5973 5974 case eEncodingT2: 5975 // if Rn == '1111' then SEE LDR (literal); 5976 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5977 t = Bits32 (opcode, 15, 12); 5978 n = Bits32 (opcode, 19, 16); 5979 m = Bits32 (opcode, 3, 0); 5980 5981 // index = TRUE; add = TRUE; wback = FALSE; 5982 index = true; 5983 add = true; 5984 wback = false; 5985 5986 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5987 shift_t = SRType_LSL; 5988 shift_n = Bits32 (opcode, 5, 4); 5989 5990 // if BadReg(m) then UNPREDICTABLE; 5991 if (BadReg (m)) 5992 return false; 5993 5994 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5995 if ((t == 15) && InITBlock() && !LastInITBlock()) 5996 return false; 5997 5998 break; 5999 6000 case eEncodingA1: 6001 { 6002 // if P == '0' && W == '1' then SEE LDRT; 6003 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6004 t = Bits32 (opcode, 15, 12); 6005 n = Bits32 (opcode, 19, 16); 6006 m = Bits32 (opcode, 3, 0); 6007 6008 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6009 index = BitIsSet (opcode, 24); 6010 add = BitIsSet (opcode, 23); 6011 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6012 6013 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6014 uint32_t type = Bits32 (opcode, 6, 5); 6015 uint32_t imm5 = Bits32 (opcode, 11, 7); 6016 shift_n = DecodeImmShift (type, imm5, shift_t); 6017 6018 // if m == 15 then UNPREDICTABLE; 6019 if (m == 15) 6020 return false; 6021 6022 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6023 if (wback && ((n == 15) || (n == t))) 6024 return false; 6025 } 6026 break; 6027 6028 6029 default: 6030 return false; 6031 } 6032 6033 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6034 if (!success) 6035 return false; 6036 6037 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6038 if (!success) 6039 return false; 6040 6041 addr_t offset_addr; 6042 addr_t address; 6043 6044 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6045 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6046 if (!success) 6047 return false; 6048 6049 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6050 if (add) 6051 offset_addr = Rn + offset; 6052 else 6053 offset_addr = Rn - offset; 6054 6055 // address = if index then offset_addr else R[n]; 6056 if (index) 6057 address = offset_addr; 6058 else 6059 address = Rn; 6060 6061 // data = MemU[address,4]; 6062 RegisterInfo base_reg; 6063 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6064 6065 EmulateInstruction::Context context; 6066 context.type = eContextRegisterLoad; 6067 context.SetRegisterPlusOffset (base_reg, address - Rn); 6068 6069 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6070 if (!success) 6071 return false; 6072 6073 // if wback then R[n] = offset_addr; 6074 if (wback) 6075 { 6076 context.type = eContextAdjustBaseRegister; 6077 context.SetAddress (offset_addr); 6078 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6079 return false; 6080 } 6081 6082 // if t == 15 then 6083 if (t == 15) 6084 { 6085 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6086 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6087 { 6088 context.type = eContextRegisterLoad; 6089 context.SetRegisterPlusOffset (base_reg, address - Rn); 6090 LoadWritePC (context, data); 6091 } 6092 else 6093 return false; 6094 } 6095 // elsif UnalignedSupport() || address<1:0> = '00' then 6096 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6097 { 6098 // R[t] = data; 6099 context.type = eContextRegisterLoad; 6100 context.SetRegisterPlusOffset (base_reg, address - Rn); 6101 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6102 return false; 6103 } 6104 else // Can only apply before ARMv7 6105 { 6106 // if CurrentInstrSet() == InstrSet_ARM then 6107 if (CurrentInstrSet () == eModeARM) 6108 { 6109 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6110 data = ROR (data, Bits32 (address, 1, 0), &success); 6111 if (!success) 6112 return false; 6113 context.type = eContextRegisterLoad; 6114 context.SetImmediate (data); 6115 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6116 return false; 6117 } 6118 else 6119 { 6120 // R[t] = bits(32) UNKNOWN; 6121 WriteBits32Unknown (t); 6122 } 6123 } 6124 } 6125 return true; 6126 } 6127 6128 // LDRB (immediate, Thumb) 6129 bool 6130 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6131 { 6132 #if 0 6133 if ConditionPassed() then 6134 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6135 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6136 address = if index then offset_addr else R[n]; 6137 R[t] = ZeroExtend(MemU[address,1], 32); 6138 if wback then R[n] = offset_addr; 6139 #endif 6140 6141 bool success = false; 6142 6143 if (ConditionPassed(opcode)) 6144 { 6145 uint32_t t; 6146 uint32_t n; 6147 uint32_t imm32; 6148 bool index; 6149 bool add; 6150 bool wback; 6151 6152 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6153 switch (encoding) 6154 { 6155 case eEncodingT1: 6156 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6157 t = Bits32 (opcode, 2, 0); 6158 n = Bits32 (opcode, 5, 3); 6159 imm32 = Bits32 (opcode, 10, 6); 6160 6161 // index = TRUE; add = TRUE; wback = FALSE; 6162 index = true; 6163 add = true; 6164 wback= false; 6165 6166 break; 6167 6168 case eEncodingT2: 6169 // if Rt == '1111' then SEE PLD; 6170 // if Rn == '1111' then SEE LDRB (literal); 6171 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6172 t = Bits32 (opcode, 15, 12); 6173 n = Bits32 (opcode, 19, 16); 6174 imm32 = Bits32 (opcode, 11, 0); 6175 6176 // index = TRUE; add = TRUE; wback = FALSE; 6177 index = true; 6178 add = true; 6179 wback = false; 6180 6181 // if t == 13 then UNPREDICTABLE; 6182 if (t == 13) 6183 return false; 6184 6185 break; 6186 6187