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/Symbol/UnwindPlan.h" 20 21 #include "Plugins/Process/Utility/ARMDefines.h" 22 #include "Plugins/Process/Utility/ARMUtils.h" 23 #include "Utility/ARM_DWARF_Registers.h" 24 25 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function 26 // and CountTrailingZeros_32 function 27 28 using namespace lldb; 29 using namespace lldb_private; 30 31 // Convenient macro definitions. 32 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 33 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 34 35 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 36 37 //---------------------------------------------------------------------- 38 // 39 // ITSession implementation 40 // 41 //---------------------------------------------------------------------- 42 43 // A8.6.50 44 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 45 static uint32_t 46 CountITSize (uint32_t ITMask) { 47 // First count the trailing zeros of the IT mask. 48 uint32_t TZ = llvm::CountTrailingZeros_32(ITMask); 49 if (TZ > 3) 50 { 51 printf("Encoding error: IT Mask '0000'\n"); 52 return 0; 53 } 54 return (4 - TZ); 55 } 56 57 // Init ITState. Note that at least one bit is always 1 in mask. 58 bool ITSession::InitIT(uint32_t bits7_0) 59 { 60 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 61 if (ITCounter == 0) 62 return false; 63 64 // A8.6.50 IT 65 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 66 if (FirstCond == 0xF) 67 { 68 printf("Encoding error: IT FirstCond '1111'\n"); 69 return false; 70 } 71 if (FirstCond == 0xE && ITCounter != 1) 72 { 73 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 74 return false; 75 } 76 77 ITState = bits7_0; 78 return true; 79 } 80 81 // Update ITState if necessary. 82 void ITSession::ITAdvance() 83 { 84 //assert(ITCounter); 85 --ITCounter; 86 if (ITCounter == 0) 87 ITState = 0; 88 else 89 { 90 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 91 SetBits32(ITState, 4, 0, NewITState4_0); 92 } 93 } 94 95 // Return true if we're inside an IT Block. 96 bool ITSession::InITBlock() 97 { 98 return ITCounter != 0; 99 } 100 101 // Return true if we're the last instruction inside an IT Block. 102 bool ITSession::LastInITBlock() 103 { 104 return ITCounter == 1; 105 } 106 107 // Get condition bits for the current thumb instruction. 108 uint32_t ITSession::GetCond() 109 { 110 if (InITBlock()) 111 return Bits32(ITState, 7, 4); 112 else 113 return COND_AL; 114 } 115 116 // ARM constants used during decoding 117 #define REG_RD 0 118 #define LDM_REGLIST 1 119 #define SP_REG 13 120 #define LR_REG 14 121 #define PC_REG 15 122 #define PC_REGLIST_BIT 0x8000 123 124 #define ARMv4 (1u << 0) 125 #define ARMv4T (1u << 1) 126 #define ARMv5T (1u << 2) 127 #define ARMv5TE (1u << 3) 128 #define ARMv5TEJ (1u << 4) 129 #define ARMv6 (1u << 5) 130 #define ARMv6K (1u << 6) 131 #define ARMv6T2 (1u << 7) 132 #define ARMv7 (1u << 8) 133 #define ARMv7S (1u << 9) 134 #define ARMv8 (1u << 10) 135 #define ARMvAll (0xffffffffu) 136 137 #define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 138 #define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 139 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 140 #define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 141 #define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 142 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8) 143 #define ARMV7_ABOVE (ARMv7|ARMv7S|ARMv8) 144 145 #define No_VFP 0 146 #define VFPv1 (1u << 1) 147 #define VFPv2 (1u << 2) 148 #define VFPv3 (1u << 3) 149 #define AdvancedSIMD (1u << 4) 150 151 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 152 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 153 #define VFPv2v3 (VFPv2 | VFPv3) 154 155 //---------------------------------------------------------------------- 156 // 157 // EmulateInstructionARM implementation 158 // 159 //---------------------------------------------------------------------- 160 161 void 162 EmulateInstructionARM::Initialize () 163 { 164 PluginManager::RegisterPlugin (GetPluginNameStatic (), 165 GetPluginDescriptionStatic (), 166 CreateInstance); 167 } 168 169 void 170 EmulateInstructionARM::Terminate () 171 { 172 PluginManager::UnregisterPlugin (CreateInstance); 173 } 174 175 const char * 176 EmulateInstructionARM::GetPluginNameStatic () 177 { 178 return "lldb.emulate-instruction.arm"; 179 } 180 181 const char * 182 EmulateInstructionARM::GetPluginDescriptionStatic () 183 { 184 return "Emulate instructions for the ARM architecture."; 185 } 186 187 EmulateInstruction * 188 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) 189 { 190 if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type)) 191 { 192 if (arch.GetTriple().getArch() == llvm::Triple::arm) 193 { 194 std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 195 196 if (emulate_insn_ap.get()) 197 return emulate_insn_ap.release(); 198 } 199 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 200 { 201 std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 202 203 if (emulate_insn_ap.get()) 204 return emulate_insn_ap.release(); 205 } 206 } 207 208 return NULL; 209 } 210 211 bool 212 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch) 213 { 214 if (arch.GetTriple().getArch () == llvm::Triple::arm) 215 return true; 216 else if (arch.GetTriple().getArch () == llvm::Triple::thumb) 217 return true; 218 219 return false; 220 } 221 222 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 223 bool 224 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 225 { 226 EmulateInstruction::Context context; 227 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 228 context.SetNoArgs (); 229 230 uint32_t random_data = rand (); 231 const uint32_t addr_byte_size = GetAddressByteSize(); 232 233 if (!MemAWrite (context, address, random_data, addr_byte_size)) 234 return false; 235 236 return true; 237 } 238 239 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 240 bool 241 EmulateInstructionARM::WriteBits32Unknown (int n) 242 { 243 EmulateInstruction::Context context; 244 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 245 context.SetNoArgs (); 246 247 bool success; 248 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 249 250 if (!success) 251 return false; 252 253 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 254 return false; 255 256 return true; 257 } 258 259 bool 260 EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo ®_info) 261 { 262 if (reg_kind == eRegisterKindGeneric) 263 { 264 switch (reg_num) 265 { 266 case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break; 267 case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break; 268 case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break; 269 case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break; 270 case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break; 271 default: return false; 272 } 273 } 274 275 if (reg_kind == eRegisterKindDWARF) 276 return GetARMDWARFRegisterInfo(reg_num, reg_info); 277 return false; 278 } 279 280 uint32_t 281 EmulateInstructionARM::GetFramePointerRegisterNumber () const 282 { 283 if (m_opcode_mode == eModeThumb) 284 { 285 switch (m_arch.GetTriple().getOS()) 286 { 287 case llvm::Triple::Darwin: 288 case llvm::Triple::MacOSX: 289 case llvm::Triple::IOS: 290 return 7; 291 default: 292 break; 293 } 294 } 295 return 11; 296 } 297 298 uint32_t 299 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 300 { 301 if (m_opcode_mode == eModeThumb) 302 { 303 switch (m_arch.GetTriple().getOS()) 304 { 305 case llvm::Triple::Darwin: 306 case llvm::Triple::MacOSX: 307 case llvm::Triple::IOS: 308 return dwarf_r7; 309 default: 310 break; 311 } 312 } 313 return dwarf_r11; 314 } 315 316 // Push Multiple Registers stores multiple registers to the stack, storing to 317 // consecutive memory locations ending just below the address in SP, and updates 318 // SP to point to the start of the stored data. 319 bool 320 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 321 { 322 #if 0 323 // ARM pseudo code... 324 if (ConditionPassed()) 325 { 326 EncodingSpecificOperations(); 327 NullCheckIfThumbEE(13); 328 address = SP - 4*BitCount(registers); 329 330 for (i = 0 to 14) 331 { 332 if (registers<i> == '1') 333 { 334 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 335 MemA[address,4] = bits(32) UNKNOWN; 336 else 337 MemA[address,4] = R[i]; 338 address = address + 4; 339 } 340 } 341 342 if (registers<15> == '1') // Only possible for encoding A1 or A2 343 MemA[address,4] = PCStoreValue(); 344 345 SP = SP - 4*BitCount(registers); 346 } 347 #endif 348 349 bool conditional = false; 350 bool success = false; 351 if (ConditionPassed(opcode, &conditional)) 352 { 353 const uint32_t addr_byte_size = GetAddressByteSize(); 354 const addr_t sp = ReadCoreReg (SP_REG, &success); 355 if (!success) 356 return false; 357 uint32_t registers = 0; 358 uint32_t Rt; // the source register 359 switch (encoding) { 360 case eEncodingT1: 361 registers = Bits32(opcode, 7, 0); 362 // The M bit represents LR. 363 if (Bit32(opcode, 8)) 364 registers |= (1u << 14); 365 // if BitCount(registers) < 1 then UNPREDICTABLE; 366 if (BitCount(registers) < 1) 367 return false; 368 break; 369 case eEncodingT2: 370 // Ignore bits 15 & 13. 371 registers = Bits32(opcode, 15, 0) & ~0xa000; 372 // if BitCount(registers) < 2 then UNPREDICTABLE; 373 if (BitCount(registers) < 2) 374 return false; 375 break; 376 case eEncodingT3: 377 Rt = Bits32(opcode, 15, 12); 378 // if BadReg(t) then UNPREDICTABLE; 379 if (BadReg(Rt)) 380 return false; 381 registers = (1u << Rt); 382 break; 383 case eEncodingA1: 384 registers = Bits32(opcode, 15, 0); 385 // Instead of return false, let's handle the following case as well, 386 // which amounts to pushing one reg onto the full descending stacks. 387 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 388 break; 389 case eEncodingA2: 390 Rt = Bits32(opcode, 15, 12); 391 // if t == 13 then UNPREDICTABLE; 392 if (Rt == dwarf_sp) 393 return false; 394 registers = (1u << Rt); 395 break; 396 default: 397 return false; 398 } 399 addr_t sp_offset = addr_byte_size * BitCount (registers); 400 addr_t addr = sp - sp_offset; 401 uint32_t i; 402 403 EmulateInstruction::Context context; 404 if (conditional) 405 context.type = EmulateInstruction::eContextRegisterStore; 406 else 407 context.type = EmulateInstruction::eContextPushRegisterOnStack; 408 RegisterInfo reg_info; 409 RegisterInfo sp_reg; 410 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 411 for (i=0; i<15; ++i) 412 { 413 if (BitIsSet (registers, i)) 414 { 415 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 416 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 417 uint32_t reg_value = ReadCoreReg(i, &success); 418 if (!success) 419 return false; 420 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 421 return false; 422 addr += addr_byte_size; 423 } 424 } 425 426 if (BitIsSet (registers, 15)) 427 { 428 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 429 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 430 const uint32_t pc = ReadCoreReg(PC_REG, &success); 431 if (!success) 432 return false; 433 if (!MemAWrite (context, addr, pc, addr_byte_size)) 434 return false; 435 } 436 437 context.type = EmulateInstruction::eContextAdjustStackPointer; 438 context.SetImmediateSigned (-sp_offset); 439 440 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 441 return false; 442 } 443 return true; 444 } 445 446 // Pop Multiple Registers loads multiple registers from the stack, loading from 447 // consecutive memory locations staring at the address in SP, and updates 448 // SP to point just above the loaded data. 449 bool 450 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 451 { 452 #if 0 453 // ARM pseudo code... 454 if (ConditionPassed()) 455 { 456 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 457 address = SP; 458 for i = 0 to 14 459 if registers<i> == '1' then 460 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 461 if registers<15> == '1' then 462 if UnalignedAllowed then 463 LoadWritePC(MemU[address,4]); 464 else 465 LoadWritePC(MemA[address,4]); 466 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 467 if registers<13> == '1' then SP = bits(32) UNKNOWN; 468 } 469 #endif 470 471 bool success = false; 472 473 bool conditional = false; 474 if (ConditionPassed(opcode, &conditional)) 475 { 476 const uint32_t addr_byte_size = GetAddressByteSize(); 477 const addr_t sp = ReadCoreReg (SP_REG, &success); 478 if (!success) 479 return false; 480 uint32_t registers = 0; 481 uint32_t Rt; // the destination register 482 switch (encoding) { 483 case eEncodingT1: 484 registers = Bits32(opcode, 7, 0); 485 // The P bit represents PC. 486 if (Bit32(opcode, 8)) 487 registers |= (1u << 15); 488 // if BitCount(registers) < 1 then UNPREDICTABLE; 489 if (BitCount(registers) < 1) 490 return false; 491 break; 492 case eEncodingT2: 493 // Ignore bit 13. 494 registers = Bits32(opcode, 15, 0) & ~0x2000; 495 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 496 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 497 return false; 498 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 499 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 500 return false; 501 break; 502 case eEncodingT3: 503 Rt = Bits32(opcode, 15, 12); 504 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 505 if (Rt == 13) 506 return false; 507 if (Rt == 15 && InITBlock() && !LastInITBlock()) 508 return false; 509 registers = (1u << Rt); 510 break; 511 case eEncodingA1: 512 registers = Bits32(opcode, 15, 0); 513 // Instead of return false, let's handle the following case as well, 514 // which amounts to popping one reg from the full descending stacks. 515 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 516 517 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 518 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 519 return false; 520 break; 521 case eEncodingA2: 522 Rt = Bits32(opcode, 15, 12); 523 // if t == 13 then UNPREDICTABLE; 524 if (Rt == dwarf_sp) 525 return false; 526 registers = (1u << Rt); 527 break; 528 default: 529 return false; 530 } 531 addr_t sp_offset = addr_byte_size * BitCount (registers); 532 addr_t addr = sp; 533 uint32_t i, data; 534 535 EmulateInstruction::Context context; 536 if (conditional) 537 context.type = EmulateInstruction::eContextRegisterLoad; 538 else 539 context.type = EmulateInstruction::eContextPopRegisterOffStack; 540 541 RegisterInfo sp_reg; 542 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 543 544 for (i=0; i<15; ++i) 545 { 546 if (BitIsSet (registers, i)) 547 { 548 context.SetRegisterPlusOffset (sp_reg, addr - sp); 549 data = MemARead(context, addr, 4, 0, &success); 550 if (!success) 551 return false; 552 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 553 return false; 554 addr += addr_byte_size; 555 } 556 } 557 558 if (BitIsSet (registers, 15)) 559 { 560 context.SetRegisterPlusOffset (sp_reg, addr - sp); 561 data = MemARead(context, addr, 4, 0, &success); 562 if (!success) 563 return false; 564 // In ARMv5T and above, this is an interworking branch. 565 if (!LoadWritePC(context, data)) 566 return false; 567 //addr += addr_byte_size; 568 } 569 570 context.type = EmulateInstruction::eContextAdjustStackPointer; 571 context.SetImmediateSigned (sp_offset); 572 573 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 574 return false; 575 } 576 return true; 577 } 578 579 // Set r7 or ip to point to saved value residing within the stack. 580 // ADD (SP plus immediate) 581 bool 582 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 583 { 584 #if 0 585 // ARM pseudo code... 586 if (ConditionPassed()) 587 { 588 EncodingSpecificOperations(); 589 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 590 if d == 15 then 591 ALUWritePC(result); // setflags is always FALSE here 592 else 593 R[d] = result; 594 if setflags then 595 APSR.N = result<31>; 596 APSR.Z = IsZeroBit(result); 597 APSR.C = carry; 598 APSR.V = overflow; 599 } 600 #endif 601 602 bool success = false; 603 604 if (ConditionPassed(opcode)) 605 { 606 const addr_t sp = ReadCoreReg (SP_REG, &success); 607 if (!success) 608 return false; 609 uint32_t Rd; // the destination register 610 uint32_t imm32; 611 switch (encoding) { 612 case eEncodingT1: 613 Rd = 7; 614 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 615 break; 616 case eEncodingA1: 617 Rd = Bits32(opcode, 15, 12); 618 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 619 break; 620 default: 621 return false; 622 } 623 addr_t sp_offset = imm32; 624 addr_t addr = sp + sp_offset; // a pointer to the stack area 625 626 EmulateInstruction::Context context; 627 context.type = eContextSetFramePointer; 628 RegisterInfo sp_reg; 629 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 630 context.SetRegisterPlusOffset (sp_reg, sp_offset); 631 632 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 633 return false; 634 } 635 return true; 636 } 637 638 // Set r7 or ip to the current stack pointer. 639 // MOV (register) 640 bool 641 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 642 { 643 #if 0 644 // ARM pseudo code... 645 if (ConditionPassed()) 646 { 647 EncodingSpecificOperations(); 648 result = R[m]; 649 if d == 15 then 650 ALUWritePC(result); // setflags is always FALSE here 651 else 652 R[d] = result; 653 if setflags then 654 APSR.N = result<31>; 655 APSR.Z = IsZeroBit(result); 656 // APSR.C unchanged 657 // APSR.V unchanged 658 } 659 #endif 660 661 bool success = false; 662 663 if (ConditionPassed(opcode)) 664 { 665 const addr_t sp = ReadCoreReg (SP_REG, &success); 666 if (!success) 667 return false; 668 uint32_t Rd; // the destination register 669 switch (encoding) { 670 case eEncodingT1: 671 Rd = 7; 672 break; 673 case eEncodingA1: 674 Rd = 12; 675 break; 676 default: 677 return false; 678 } 679 680 EmulateInstruction::Context context; 681 if (Rd == GetFramePointerRegisterNumber()) 682 context.type = EmulateInstruction::eContextSetFramePointer; 683 else 684 context.type = EmulateInstruction::eContextRegisterPlusOffset; 685 RegisterInfo sp_reg; 686 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 687 context.SetRegisterPlusOffset (sp_reg, 0); 688 689 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 690 return false; 691 } 692 return true; 693 } 694 695 // Move from high register (r8-r15) to low register (r0-r7). 696 // MOV (register) 697 bool 698 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 699 { 700 return EmulateMOVRdRm (opcode, encoding); 701 } 702 703 // Move from register to register. 704 // MOV (register) 705 bool 706 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 707 { 708 #if 0 709 // ARM pseudo code... 710 if (ConditionPassed()) 711 { 712 EncodingSpecificOperations(); 713 result = R[m]; 714 if d == 15 then 715 ALUWritePC(result); // setflags is always FALSE here 716 else 717 R[d] = result; 718 if setflags then 719 APSR.N = result<31>; 720 APSR.Z = IsZeroBit(result); 721 // APSR.C unchanged 722 // APSR.V unchanged 723 } 724 #endif 725 726 bool success = false; 727 728 if (ConditionPassed(opcode)) 729 { 730 uint32_t Rm; // the source register 731 uint32_t Rd; // the destination register 732 bool setflags; 733 switch (encoding) { 734 case eEncodingT1: 735 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 736 Rm = Bits32(opcode, 6, 3); 737 setflags = false; 738 if (Rd == 15 && InITBlock() && !LastInITBlock()) 739 return false; 740 break; 741 case eEncodingT2: 742 Rd = Bits32(opcode, 2, 0); 743 Rm = Bits32(opcode, 5, 3); 744 setflags = true; 745 if (InITBlock()) 746 return false; 747 break; 748 case eEncodingT3: 749 Rd = Bits32(opcode, 11, 8); 750 Rm = Bits32(opcode, 3, 0); 751 setflags = BitIsSet(opcode, 20); 752 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 753 if (setflags && (BadReg(Rd) || BadReg(Rm))) 754 return false; 755 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 756 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 757 return false; 758 break; 759 case eEncodingA1: 760 Rd = Bits32(opcode, 15, 12); 761 Rm = Bits32(opcode, 3, 0); 762 setflags = BitIsSet(opcode, 20); 763 764 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 765 if (Rd == 15 && setflags) 766 return EmulateSUBSPcLrEtc (opcode, encoding); 767 break; 768 default: 769 return false; 770 } 771 uint32_t result = ReadCoreReg(Rm, &success); 772 if (!success) 773 return false; 774 775 // The context specifies that Rm is to be moved into Rd. 776 EmulateInstruction::Context context; 777 context.type = EmulateInstruction::eContextRegisterLoad; 778 RegisterInfo dwarf_reg; 779 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 780 context.SetRegister (dwarf_reg); 781 782 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 783 return false; 784 } 785 return true; 786 } 787 788 // Move (immediate) writes an immediate value to the destination register. It 789 // can optionally update the condition flags based on the value. 790 // MOV (immediate) 791 bool 792 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 793 { 794 #if 0 795 // ARM pseudo code... 796 if (ConditionPassed()) 797 { 798 EncodingSpecificOperations(); 799 result = imm32; 800 if d == 15 then // Can only occur for ARM encoding 801 ALUWritePC(result); // setflags is always FALSE here 802 else 803 R[d] = result; 804 if setflags then 805 APSR.N = result<31>; 806 APSR.Z = IsZeroBit(result); 807 APSR.C = carry; 808 // APSR.V unchanged 809 } 810 #endif 811 812 if (ConditionPassed(opcode)) 813 { 814 uint32_t Rd; // the destination register 815 uint32_t imm32; // the immediate value to be written to Rd 816 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 817 // for setflags == false, this value is a don't care 818 // initialized to 0 to silence the static analyzer 819 bool setflags; 820 switch (encoding) { 821 case eEncodingT1: 822 Rd = Bits32(opcode, 10, 8); 823 setflags = !InITBlock(); 824 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 825 carry = APSR_C; 826 827 break; 828 829 case eEncodingT2: 830 Rd = Bits32(opcode, 11, 8); 831 setflags = BitIsSet(opcode, 20); 832 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 833 if (BadReg(Rd)) 834 return false; 835 836 break; 837 838 case eEncodingT3: 839 { 840 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 841 Rd = Bits32 (opcode, 11, 8); 842 setflags = false; 843 uint32_t imm4 = Bits32 (opcode, 19, 16); 844 uint32_t imm3 = Bits32 (opcode, 14, 12); 845 uint32_t i = Bit32 (opcode, 26); 846 uint32_t imm8 = Bits32 (opcode, 7, 0); 847 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 848 849 // if BadReg(d) then UNPREDICTABLE; 850 if (BadReg (Rd)) 851 return false; 852 } 853 break; 854 855 case eEncodingA1: 856 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 857 Rd = Bits32 (opcode, 15, 12); 858 setflags = BitIsSet (opcode, 20); 859 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 860 861 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 862 if ((Rd == 15) && setflags) 863 return EmulateSUBSPcLrEtc (opcode, encoding); 864 865 break; 866 867 case eEncodingA2: 868 { 869 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 870 Rd = Bits32 (opcode, 15, 12); 871 setflags = false; 872 uint32_t imm4 = Bits32 (opcode, 19, 16); 873 uint32_t imm12 = Bits32 (opcode, 11, 0); 874 imm32 = (imm4 << 12) | imm12; 875 876 // if d == 15 then UNPREDICTABLE; 877 if (Rd == 15) 878 return false; 879 } 880 break; 881 882 default: 883 return false; 884 } 885 uint32_t result = imm32; 886 887 // The context specifies that an immediate is to be moved into Rd. 888 EmulateInstruction::Context context; 889 context.type = EmulateInstruction::eContextImmediate; 890 context.SetNoArgs (); 891 892 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 893 return false; 894 } 895 return true; 896 } 897 898 // MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 899 // register. These 32 bits do not depend on whether the source register values are considered to be signed values or 900 // unsigned values. 901 // 902 // Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 903 // limited to only a few forms of the instruction. 904 bool 905 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 906 { 907 #if 0 908 if ConditionPassed() then 909 EncodingSpecificOperations(); 910 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 911 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 912 result = operand1 * operand2; 913 R[d] = result<31:0>; 914 if setflags then 915 APSR.N = result<31>; 916 APSR.Z = IsZeroBit(result); 917 if ArchVersion() == 4 then 918 APSR.C = bit UNKNOWN; 919 // else APSR.C unchanged 920 // APSR.V always unchanged 921 #endif 922 923 if (ConditionPassed(opcode)) 924 { 925 uint32_t d; 926 uint32_t n; 927 uint32_t m; 928 bool setflags; 929 930 // EncodingSpecificOperations(); 931 switch (encoding) 932 { 933 case eEncodingT1: 934 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 935 d = Bits32 (opcode, 2, 0); 936 n = Bits32 (opcode, 5, 3); 937 m = Bits32 (opcode, 2, 0); 938 setflags = !InITBlock(); 939 940 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 941 if ((ArchVersion() < ARMv6) && (d == n)) 942 return false; 943 944 break; 945 946 case eEncodingT2: 947 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 948 d = Bits32 (opcode, 11, 8); 949 n = Bits32 (opcode, 19, 16); 950 m = Bits32 (opcode, 3, 0); 951 setflags = false; 952 953 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 954 if (BadReg (d) || BadReg (n) || BadReg (m)) 955 return false; 956 957 break; 958 959 case eEncodingA1: 960 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 961 d = Bits32 (opcode, 19, 16); 962 n = Bits32 (opcode, 3, 0); 963 m = Bits32 (opcode, 11, 8); 964 setflags = BitIsSet (opcode, 20); 965 966 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 967 if ((d == 15) || (n == 15) || (m == 15)) 968 return false; 969 970 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 971 if ((ArchVersion() < ARMv6) && (d == n)) 972 return false; 973 974 break; 975 976 default: 977 return false; 978 } 979 980 bool success = false; 981 982 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 983 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 984 if (!success) 985 return false; 986 987 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 988 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 989 if (!success) 990 return false; 991 992 // result = operand1 * operand2; 993 uint64_t result = operand1 * operand2; 994 995 // R[d] = result<31:0>; 996 RegisterInfo op1_reg; 997 RegisterInfo op2_reg; 998 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 999 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1000 1001 EmulateInstruction::Context context; 1002 context.type = eContextArithmetic; 1003 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 1004 1005 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 1006 return false; 1007 1008 // if setflags then 1009 if (setflags) 1010 { 1011 // APSR.N = result<31>; 1012 // APSR.Z = IsZeroBit(result); 1013 m_new_inst_cpsr = m_opcode_cpsr; 1014 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 1015 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1016 if (m_new_inst_cpsr != m_opcode_cpsr) 1017 { 1018 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1019 return false; 1020 } 1021 1022 // if ArchVersion() == 4 then 1023 // APSR.C = bit UNKNOWN; 1024 } 1025 } 1026 return true; 1027 } 1028 1029 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1030 // It can optionally update the condition flags based on the value. 1031 bool 1032 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1033 { 1034 #if 0 1035 // ARM pseudo code... 1036 if (ConditionPassed()) 1037 { 1038 EncodingSpecificOperations(); 1039 result = NOT(imm32); 1040 if d == 15 then // Can only occur for ARM encoding 1041 ALUWritePC(result); // setflags is always FALSE here 1042 else 1043 R[d] = result; 1044 if setflags then 1045 APSR.N = result<31>; 1046 APSR.Z = IsZeroBit(result); 1047 APSR.C = carry; 1048 // APSR.V unchanged 1049 } 1050 #endif 1051 1052 if (ConditionPassed(opcode)) 1053 { 1054 uint32_t Rd; // the destination register 1055 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1056 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1057 bool setflags; 1058 switch (encoding) { 1059 case eEncodingT1: 1060 Rd = Bits32(opcode, 11, 8); 1061 setflags = BitIsSet(opcode, 20); 1062 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1063 break; 1064 case eEncodingA1: 1065 Rd = Bits32(opcode, 15, 12); 1066 setflags = BitIsSet(opcode, 20); 1067 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1068 1069 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1070 if (Rd == 15 && setflags) 1071 return EmulateSUBSPcLrEtc (opcode, encoding); 1072 break; 1073 default: 1074 return false; 1075 } 1076 uint32_t result = ~imm32; 1077 1078 // The context specifies that an immediate is to be moved into Rd. 1079 EmulateInstruction::Context context; 1080 context.type = EmulateInstruction::eContextImmediate; 1081 context.SetNoArgs (); 1082 1083 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1084 return false; 1085 } 1086 return true; 1087 } 1088 1089 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1090 // It can optionally update the condition flags based on the result. 1091 bool 1092 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1093 { 1094 #if 0 1095 // ARM pseudo code... 1096 if (ConditionPassed()) 1097 { 1098 EncodingSpecificOperations(); 1099 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1100 result = NOT(shifted); 1101 if d == 15 then // Can only occur for ARM encoding 1102 ALUWritePC(result); // setflags is always FALSE here 1103 else 1104 R[d] = result; 1105 if setflags then 1106 APSR.N = result<31>; 1107 APSR.Z = IsZeroBit(result); 1108 APSR.C = carry; 1109 // APSR.V unchanged 1110 } 1111 #endif 1112 1113 if (ConditionPassed(opcode)) 1114 { 1115 uint32_t Rm; // the source register 1116 uint32_t Rd; // the destination register 1117 ARM_ShifterType shift_t; 1118 uint32_t shift_n; // the shift applied to the value read from Rm 1119 bool setflags; 1120 uint32_t carry; // the carry bit after the shift operation 1121 switch (encoding) { 1122 case eEncodingT1: 1123 Rd = Bits32(opcode, 2, 0); 1124 Rm = Bits32(opcode, 5, 3); 1125 setflags = !InITBlock(); 1126 shift_t = SRType_LSL; 1127 shift_n = 0; 1128 if (InITBlock()) 1129 return false; 1130 break; 1131 case eEncodingT2: 1132 Rd = Bits32(opcode, 11, 8); 1133 Rm = Bits32(opcode, 3, 0); 1134 setflags = BitIsSet(opcode, 20); 1135 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1136 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1137 if (BadReg(Rd) || BadReg(Rm)) 1138 return false; 1139 break; 1140 case eEncodingA1: 1141 Rd = Bits32(opcode, 15, 12); 1142 Rm = Bits32(opcode, 3, 0); 1143 setflags = BitIsSet(opcode, 20); 1144 shift_n = DecodeImmShiftARM(opcode, shift_t); 1145 break; 1146 default: 1147 return false; 1148 } 1149 bool success = false; 1150 uint32_t value = ReadCoreReg(Rm, &success); 1151 if (!success) 1152 return false; 1153 1154 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1155 if (!success) 1156 return false; 1157 uint32_t result = ~shifted; 1158 1159 // The context specifies that an immediate is to be moved into Rd. 1160 EmulateInstruction::Context context; 1161 context.type = EmulateInstruction::eContextImmediate; 1162 context.SetNoArgs (); 1163 1164 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1165 return false; 1166 } 1167 return true; 1168 } 1169 1170 // PC relative immediate load into register, possibly followed by ADD (SP plus register). 1171 // LDR (literal) 1172 bool 1173 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1174 { 1175 #if 0 1176 // ARM pseudo code... 1177 if (ConditionPassed()) 1178 { 1179 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1180 base = Align(PC,4); 1181 address = if add then (base + imm32) else (base - imm32); 1182 data = MemU[address,4]; 1183 if t == 15 then 1184 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1185 elsif UnalignedSupport() || address<1:0> = '00' then 1186 R[t] = data; 1187 else // Can only apply before ARMv7 1188 if CurrentInstrSet() == InstrSet_ARM then 1189 R[t] = ROR(data, 8*UInt(address<1:0>)); 1190 else 1191 R[t] = bits(32) UNKNOWN; 1192 } 1193 #endif 1194 1195 if (ConditionPassed(opcode)) 1196 { 1197 bool success = false; 1198 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1199 if (!success) 1200 return false; 1201 1202 // PC relative immediate load context 1203 EmulateInstruction::Context context; 1204 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1205 RegisterInfo pc_reg; 1206 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1207 context.SetRegisterPlusOffset (pc_reg, 0); 1208 1209 uint32_t Rt; // the destination register 1210 uint32_t imm32; // immediate offset from the PC 1211 bool add; // +imm32 or -imm32? 1212 addr_t base; // the base address 1213 addr_t address; // the PC relative address 1214 uint32_t data; // the literal data value from the PC relative load 1215 switch (encoding) { 1216 case eEncodingT1: 1217 Rt = Bits32(opcode, 10, 8); 1218 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1219 add = true; 1220 break; 1221 case eEncodingT2: 1222 Rt = Bits32(opcode, 15, 12); 1223 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1224 add = BitIsSet(opcode, 23); 1225 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1226 return false; 1227 break; 1228 default: 1229 return false; 1230 } 1231 1232 base = Align(pc, 4); 1233 if (add) 1234 address = base + imm32; 1235 else 1236 address = base - imm32; 1237 1238 context.SetRegisterPlusOffset(pc_reg, address - base); 1239 data = MemURead(context, address, 4, 0, &success); 1240 if (!success) 1241 return false; 1242 1243 if (Rt == 15) 1244 { 1245 if (Bits32(address, 1, 0) == 0) 1246 { 1247 // In ARMv5T and above, this is an interworking branch. 1248 if (!LoadWritePC(context, data)) 1249 return false; 1250 } 1251 else 1252 return false; 1253 } 1254 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1255 { 1256 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1257 return false; 1258 } 1259 else // We don't handle ARM for now. 1260 return false; 1261 1262 } 1263 return true; 1264 } 1265 1266 // An add operation to adjust the SP. 1267 // ADD (SP plus immediate) 1268 bool 1269 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1270 { 1271 #if 0 1272 // ARM pseudo code... 1273 if (ConditionPassed()) 1274 { 1275 EncodingSpecificOperations(); 1276 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1277 if d == 15 then // Can only occur for ARM encoding 1278 ALUWritePC(result); // setflags is always FALSE here 1279 else 1280 R[d] = result; 1281 if setflags then 1282 APSR.N = result<31>; 1283 APSR.Z = IsZeroBit(result); 1284 APSR.C = carry; 1285 APSR.V = overflow; 1286 } 1287 #endif 1288 1289 bool success = false; 1290 1291 if (ConditionPassed(opcode)) 1292 { 1293 const addr_t sp = ReadCoreReg (SP_REG, &success); 1294 if (!success) 1295 return false; 1296 uint32_t imm32; // the immediate operand 1297 uint32_t d; 1298 //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1 1299 switch (encoding) 1300 { 1301 case eEncodingT1: 1302 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1303 d = Bits32 (opcode, 10, 8); 1304 imm32 = (Bits32 (opcode, 7, 0) << 2); 1305 1306 break; 1307 1308 case eEncodingT2: 1309 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1310 d = 13; 1311 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1312 1313 break; 1314 1315 default: 1316 return false; 1317 } 1318 addr_t sp_offset = imm32; 1319 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1320 1321 EmulateInstruction::Context context; 1322 context.type = EmulateInstruction::eContextAdjustStackPointer; 1323 RegisterInfo sp_reg; 1324 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1325 context.SetRegisterPlusOffset (sp_reg, sp_offset); 1326 1327 if (d == 15) 1328 { 1329 if (!ALUWritePC (context, addr)) 1330 return false; 1331 } 1332 else 1333 { 1334 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr)) 1335 return false; 1336 1337 // Add this back if/when support eEncodingT3 eEncodingA1 1338 //if (setflags) 1339 //{ 1340 // APSR.N = result<31>; 1341 // APSR.Z = IsZeroBit(result); 1342 // APSR.C = carry; 1343 // APSR.V = overflow; 1344 //} 1345 } 1346 } 1347 return true; 1348 } 1349 1350 // An add operation to adjust the SP. 1351 // ADD (SP plus register) 1352 bool 1353 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1354 { 1355 #if 0 1356 // ARM pseudo code... 1357 if (ConditionPassed()) 1358 { 1359 EncodingSpecificOperations(); 1360 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1361 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1362 if d == 15 then 1363 ALUWritePC(result); // setflags is always FALSE here 1364 else 1365 R[d] = result; 1366 if setflags then 1367 APSR.N = result<31>; 1368 APSR.Z = IsZeroBit(result); 1369 APSR.C = carry; 1370 APSR.V = overflow; 1371 } 1372 #endif 1373 1374 bool success = false; 1375 1376 if (ConditionPassed(opcode)) 1377 { 1378 const addr_t sp = ReadCoreReg (SP_REG, &success); 1379 if (!success) 1380 return false; 1381 uint32_t Rm; // the second operand 1382 switch (encoding) { 1383 case eEncodingT2: 1384 Rm = Bits32(opcode, 6, 3); 1385 break; 1386 default: 1387 return false; 1388 } 1389 int32_t reg_value = ReadCoreReg(Rm, &success); 1390 if (!success) 1391 return false; 1392 1393 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1394 1395 EmulateInstruction::Context context; 1396 context.type = eContextArithmetic; 1397 RegisterInfo sp_reg; 1398 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1399 1400 RegisterInfo other_reg; 1401 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1402 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1403 1404 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1405 return false; 1406 } 1407 return true; 1408 } 1409 1410 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1411 // at a PC-relative address, and changes instruction set from ARM to Thumb, or 1412 // from Thumb to ARM. 1413 // BLX (immediate) 1414 bool 1415 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1416 { 1417 #if 0 1418 // ARM pseudo code... 1419 if (ConditionPassed()) 1420 { 1421 EncodingSpecificOperations(); 1422 if CurrentInstrSet() == InstrSet_ARM then 1423 LR = PC - 4; 1424 else 1425 LR = PC<31:1> : '1'; 1426 if targetInstrSet == InstrSet_ARM then 1427 targetAddress = Align(PC,4) + imm32; 1428 else 1429 targetAddress = PC + imm32; 1430 SelectInstrSet(targetInstrSet); 1431 BranchWritePC(targetAddress); 1432 } 1433 #endif 1434 1435 bool success = true; 1436 1437 if (ConditionPassed(opcode)) 1438 { 1439 EmulateInstruction::Context context; 1440 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1441 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1442 if (!success) 1443 return false; 1444 addr_t lr; // next instruction address 1445 addr_t target; // target address 1446 int32_t imm32; // PC-relative offset 1447 switch (encoding) { 1448 case eEncodingT1: 1449 { 1450 lr = pc | 1u; // return address 1451 uint32_t S = Bit32(opcode, 26); 1452 uint32_t imm10 = Bits32(opcode, 25, 16); 1453 uint32_t J1 = Bit32(opcode, 13); 1454 uint32_t J2 = Bit32(opcode, 11); 1455 uint32_t imm11 = Bits32(opcode, 10, 0); 1456 uint32_t I1 = !(J1 ^ S); 1457 uint32_t I2 = !(J2 ^ S); 1458 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1459 imm32 = llvm::SignExtend32<25>(imm25); 1460 target = pc + imm32; 1461 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1462 if (InITBlock() && !LastInITBlock()) 1463 return false; 1464 break; 1465 } 1466 case eEncodingT2: 1467 { 1468 lr = pc | 1u; // return address 1469 uint32_t S = Bit32(opcode, 26); 1470 uint32_t imm10H = Bits32(opcode, 25, 16); 1471 uint32_t J1 = Bit32(opcode, 13); 1472 uint32_t J2 = Bit32(opcode, 11); 1473 uint32_t imm10L = Bits32(opcode, 10, 1); 1474 uint32_t I1 = !(J1 ^ S); 1475 uint32_t I2 = !(J2 ^ S); 1476 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1477 imm32 = llvm::SignExtend32<25>(imm25); 1478 target = Align(pc, 4) + imm32; 1479 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1480 if (InITBlock() && !LastInITBlock()) 1481 return false; 1482 break; 1483 } 1484 case eEncodingA1: 1485 lr = pc - 4; // return address 1486 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1487 target = Align(pc, 4) + imm32; 1488 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1489 break; 1490 case eEncodingA2: 1491 lr = pc - 4; // return address 1492 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1493 target = pc + imm32; 1494 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1495 break; 1496 default: 1497 return false; 1498 } 1499 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1500 return false; 1501 if (!BranchWritePC(context, target)) 1502 return false; 1503 } 1504 return true; 1505 } 1506 1507 // Branch with Link and Exchange (register) calls a subroutine at an address and 1508 // instruction set specified by a register. 1509 // BLX (register) 1510 bool 1511 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1512 { 1513 #if 0 1514 // ARM pseudo code... 1515 if (ConditionPassed()) 1516 { 1517 EncodingSpecificOperations(); 1518 target = R[m]; 1519 if CurrentInstrSet() == InstrSet_ARM then 1520 next_instr_addr = PC - 4; 1521 LR = next_instr_addr; 1522 else 1523 next_instr_addr = PC - 2; 1524 LR = next_instr_addr<31:1> : '1'; 1525 BXWritePC(target); 1526 } 1527 #endif 1528 1529 bool success = false; 1530 1531 if (ConditionPassed(opcode)) 1532 { 1533 EmulateInstruction::Context context; 1534 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1535 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1536 addr_t lr; // next instruction address 1537 if (!success) 1538 return false; 1539 uint32_t Rm; // the register with the target address 1540 switch (encoding) { 1541 case eEncodingT1: 1542 lr = (pc - 2) | 1u; // return address 1543 Rm = Bits32(opcode, 6, 3); 1544 // if m == 15 then UNPREDICTABLE; 1545 if (Rm == 15) 1546 return false; 1547 if (InITBlock() && !LastInITBlock()) 1548 return false; 1549 break; 1550 case eEncodingA1: 1551 lr = pc - 4; // return address 1552 Rm = Bits32(opcode, 3, 0); 1553 // if m == 15 then UNPREDICTABLE; 1554 if (Rm == 15) 1555 return false; 1556 break; 1557 default: 1558 return false; 1559 } 1560 addr_t target = ReadCoreReg (Rm, &success); 1561 if (!success) 1562 return false; 1563 RegisterInfo dwarf_reg; 1564 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1565 context.SetRegister (dwarf_reg); 1566 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1567 return false; 1568 if (!BXWritePC(context, target)) 1569 return false; 1570 } 1571 return true; 1572 } 1573 1574 // Branch and Exchange causes a branch to an address and instruction set specified by a register. 1575 bool 1576 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1577 { 1578 #if 0 1579 // ARM pseudo code... 1580 if (ConditionPassed()) 1581 { 1582 EncodingSpecificOperations(); 1583 BXWritePC(R[m]); 1584 } 1585 #endif 1586 1587 if (ConditionPassed(opcode)) 1588 { 1589 EmulateInstruction::Context context; 1590 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1591 uint32_t Rm; // the register with the target address 1592 switch (encoding) { 1593 case eEncodingT1: 1594 Rm = Bits32(opcode, 6, 3); 1595 if (InITBlock() && !LastInITBlock()) 1596 return false; 1597 break; 1598 case eEncodingA1: 1599 Rm = Bits32(opcode, 3, 0); 1600 break; 1601 default: 1602 return false; 1603 } 1604 bool success = false; 1605 addr_t target = ReadCoreReg (Rm, &success); 1606 if (!success) 1607 return false; 1608 1609 RegisterInfo dwarf_reg; 1610 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1611 context.SetRegister (dwarf_reg); 1612 if (!BXWritePC(context, target)) 1613 return false; 1614 } 1615 return true; 1616 } 1617 1618 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1619 // address and instruction set specified by a register as though it were a BX instruction. 1620 // 1621 // TODO: Emulate Jazelle architecture? 1622 // We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1623 bool 1624 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1625 { 1626 #if 0 1627 // ARM pseudo code... 1628 if (ConditionPassed()) 1629 { 1630 EncodingSpecificOperations(); 1631 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1632 BXWritePC(R[m]); 1633 else 1634 if JazelleAcceptsExecution() then 1635 SwitchToJazelleExecution(); 1636 else 1637 SUBARCHITECTURE_DEFINED handler call; 1638 } 1639 #endif 1640 1641 if (ConditionPassed(opcode)) 1642 { 1643 EmulateInstruction::Context context; 1644 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1645 uint32_t Rm; // the register with the target address 1646 switch (encoding) { 1647 case eEncodingT1: 1648 Rm = Bits32(opcode, 19, 16); 1649 if (BadReg(Rm)) 1650 return false; 1651 if (InITBlock() && !LastInITBlock()) 1652 return false; 1653 break; 1654 case eEncodingA1: 1655 Rm = Bits32(opcode, 3, 0); 1656 if (Rm == 15) 1657 return false; 1658 break; 1659 default: 1660 return false; 1661 } 1662 bool success = false; 1663 addr_t target = ReadCoreReg (Rm, &success); 1664 if (!success) 1665 return false; 1666 1667 RegisterInfo dwarf_reg; 1668 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1669 context.SetRegister (dwarf_reg); 1670 if (!BXWritePC(context, target)) 1671 return false; 1672 } 1673 return true; 1674 } 1675 1676 // Set r7 to point to some ip offset. 1677 // SUB (immediate) 1678 bool 1679 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1680 { 1681 #if 0 1682 // ARM pseudo code... 1683 if (ConditionPassed()) 1684 { 1685 EncodingSpecificOperations(); 1686 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1687 if d == 15 then // Can only occur for ARM encoding 1688 ALUWritePC(result); // setflags is always FALSE here 1689 else 1690 R[d] = result; 1691 if setflags then 1692 APSR.N = result<31>; 1693 APSR.Z = IsZeroBit(result); 1694 APSR.C = carry; 1695 APSR.V = overflow; 1696 } 1697 #endif 1698 1699 if (ConditionPassed(opcode)) 1700 { 1701 bool success = false; 1702 const addr_t ip = ReadCoreReg (12, &success); 1703 if (!success) 1704 return false; 1705 uint32_t imm32; 1706 switch (encoding) { 1707 case eEncodingA1: 1708 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1709 break; 1710 default: 1711 return false; 1712 } 1713 addr_t ip_offset = imm32; 1714 addr_t addr = ip - ip_offset; // the adjusted ip value 1715 1716 EmulateInstruction::Context context; 1717 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1718 RegisterInfo dwarf_reg; 1719 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1720 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1721 1722 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1723 return false; 1724 } 1725 return true; 1726 } 1727 1728 // Set ip to point to some stack offset. 1729 // SUB (SP minus immediate) 1730 bool 1731 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1732 { 1733 #if 0 1734 // ARM pseudo code... 1735 if (ConditionPassed()) 1736 { 1737 EncodingSpecificOperations(); 1738 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1739 if d == 15 then // Can only occur for ARM encoding 1740 ALUWritePC(result); // setflags is always FALSE here 1741 else 1742 R[d] = result; 1743 if setflags then 1744 APSR.N = result<31>; 1745 APSR.Z = IsZeroBit(result); 1746 APSR.C = carry; 1747 APSR.V = overflow; 1748 } 1749 #endif 1750 1751 if (ConditionPassed(opcode)) 1752 { 1753 bool success = false; 1754 const addr_t sp = ReadCoreReg (SP_REG, &success); 1755 if (!success) 1756 return false; 1757 uint32_t imm32; 1758 switch (encoding) { 1759 case eEncodingA1: 1760 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1761 break; 1762 default: 1763 return false; 1764 } 1765 addr_t sp_offset = imm32; 1766 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1767 1768 EmulateInstruction::Context context; 1769 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1770 RegisterInfo dwarf_reg; 1771 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1772 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1773 1774 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1775 return false; 1776 } 1777 return true; 1778 } 1779 1780 // This instruction subtracts an immediate value from the SP value, and writes 1781 // the result to the destination register. 1782 // 1783 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1784 bool 1785 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1786 { 1787 #if 0 1788 // ARM pseudo code... 1789 if (ConditionPassed()) 1790 { 1791 EncodingSpecificOperations(); 1792 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1793 if d == 15 then // Can only occur for ARM encoding 1794 ALUWritePC(result); // setflags is always FALSE here 1795 else 1796 R[d] = result; 1797 if setflags then 1798 APSR.N = result<31>; 1799 APSR.Z = IsZeroBit(result); 1800 APSR.C = carry; 1801 APSR.V = overflow; 1802 } 1803 #endif 1804 1805 bool success = false; 1806 if (ConditionPassed(opcode)) 1807 { 1808 const addr_t sp = ReadCoreReg (SP_REG, &success); 1809 if (!success) 1810 return false; 1811 1812 uint32_t Rd; 1813 bool setflags; 1814 uint32_t imm32; 1815 switch (encoding) { 1816 case eEncodingT1: 1817 Rd = 13; 1818 setflags = false; 1819 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1820 break; 1821 case eEncodingT2: 1822 Rd = Bits32(opcode, 11, 8); 1823 setflags = BitIsSet(opcode, 20); 1824 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1825 if (Rd == 15 && setflags) 1826 return EmulateCMPImm(opcode, eEncodingT2); 1827 if (Rd == 15 && !setflags) 1828 return false; 1829 break; 1830 case eEncodingT3: 1831 Rd = Bits32(opcode, 11, 8); 1832 setflags = false; 1833 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1834 if (Rd == 15) 1835 return false; 1836 break; 1837 case eEncodingA1: 1838 Rd = Bits32(opcode, 15, 12); 1839 setflags = BitIsSet(opcode, 20); 1840 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1841 1842 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1843 if (Rd == 15 && setflags) 1844 return EmulateSUBSPcLrEtc (opcode, encoding); 1845 break; 1846 default: 1847 return false; 1848 } 1849 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1850 1851 EmulateInstruction::Context context; 1852 if (Rd == 13) 1853 { 1854 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1855 // value gets passed down to context.SetImmediateSigned. 1856 context.type = EmulateInstruction::eContextAdjustStackPointer; 1857 context.SetImmediateSigned (-imm64); // the stack pointer offset 1858 } 1859 else 1860 { 1861 context.type = EmulateInstruction::eContextImmediate; 1862 context.SetNoArgs (); 1863 } 1864 1865 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1866 return false; 1867 } 1868 return true; 1869 } 1870 1871 // A store operation to the stack that also updates the SP. 1872 bool 1873 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1874 { 1875 #if 0 1876 // ARM pseudo code... 1877 if (ConditionPassed()) 1878 { 1879 EncodingSpecificOperations(); 1880 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1881 address = if index then offset_addr else R[n]; 1882 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1883 if wback then R[n] = offset_addr; 1884 } 1885 #endif 1886 1887 bool conditional = false; 1888 bool success = false; 1889 if (ConditionPassed(opcode, &conditional)) 1890 { 1891 const uint32_t addr_byte_size = GetAddressByteSize(); 1892 const addr_t sp = ReadCoreReg (SP_REG, &success); 1893 if (!success) 1894 return false; 1895 uint32_t Rt; // the source register 1896 uint32_t imm12; 1897 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1898 1899 bool index; 1900 bool add; 1901 bool wback; 1902 switch (encoding) { 1903 case eEncodingA1: 1904 Rt = Bits32(opcode, 15, 12); 1905 imm12 = Bits32(opcode, 11, 0); 1906 Rn = Bits32 (opcode, 19, 16); 1907 1908 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1909 return false; 1910 1911 index = BitIsSet (opcode, 24); 1912 add = BitIsSet (opcode, 23); 1913 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1914 1915 if (wback && ((Rn == 15) || (Rn == Rt))) 1916 return false; 1917 break; 1918 default: 1919 return false; 1920 } 1921 addr_t offset_addr; 1922 if (add) 1923 offset_addr = sp + imm12; 1924 else 1925 offset_addr = sp - imm12; 1926 1927 addr_t addr; 1928 if (index) 1929 addr = offset_addr; 1930 else 1931 addr = sp; 1932 1933 EmulateInstruction::Context context; 1934 if (conditional) 1935 context.type = EmulateInstruction::eContextRegisterStore; 1936 else 1937 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1938 RegisterInfo sp_reg; 1939 RegisterInfo dwarf_reg; 1940 1941 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1942 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 1943 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 1944 if (Rt != 15) 1945 { 1946 uint32_t reg_value = ReadCoreReg(Rt, &success); 1947 if (!success) 1948 return false; 1949 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1950 return false; 1951 } 1952 else 1953 { 1954 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1955 if (!success) 1956 return false; 1957 if (!MemUWrite (context, addr, pc, addr_byte_size)) 1958 return false; 1959 } 1960 1961 1962 if (wback) 1963 { 1964 context.type = EmulateInstruction::eContextAdjustStackPointer; 1965 context.SetImmediateSigned (addr - sp); 1966 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 1967 return false; 1968 } 1969 } 1970 return true; 1971 } 1972 1973 // Vector Push stores multiple extension registers to the stack. 1974 // It also updates SP to point to the start of the stored data. 1975 bool 1976 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 1977 { 1978 #if 0 1979 // ARM pseudo code... 1980 if (ConditionPassed()) 1981 { 1982 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1983 address = SP - imm32; 1984 SP = SP - imm32; 1985 if single_regs then 1986 for r = 0 to regs-1 1987 MemA[address,4] = S[d+r]; address = address+4; 1988 else 1989 for r = 0 to regs-1 1990 // Store as two word-aligned words in the correct order for current endianness. 1991 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1992 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1993 address = address+8; 1994 } 1995 #endif 1996 1997 bool success = false; 1998 bool conditional = false; 1999 if (ConditionPassed(opcode, &conditional)) 2000 { 2001 const uint32_t addr_byte_size = GetAddressByteSize(); 2002 const addr_t sp = ReadCoreReg (SP_REG, &success); 2003 if (!success) 2004 return false; 2005 bool single_regs; 2006 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2007 uint32_t imm32; // stack offset 2008 uint32_t regs; // number of registers 2009 switch (encoding) { 2010 case eEncodingT1: 2011 case eEncodingA1: 2012 single_regs = false; 2013 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2014 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2015 // If UInt(imm8) is odd, see "FSTMX". 2016 regs = Bits32(opcode, 7, 0) / 2; 2017 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2018 if (regs == 0 || regs > 16 || (d + regs) > 32) 2019 return false; 2020 break; 2021 case eEncodingT2: 2022 case eEncodingA2: 2023 single_regs = true; 2024 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2025 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2026 regs = Bits32(opcode, 7, 0); 2027 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2028 if (regs == 0 || regs > 16 || (d + regs) > 32) 2029 return false; 2030 break; 2031 default: 2032 return false; 2033 } 2034 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2035 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2036 addr_t sp_offset = imm32; 2037 addr_t addr = sp - sp_offset; 2038 uint32_t i; 2039 2040 EmulateInstruction::Context context; 2041 if (conditional) 2042 context.type = EmulateInstruction::eContextRegisterStore; 2043 else 2044 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2045 RegisterInfo dwarf_reg; 2046 RegisterInfo sp_reg; 2047 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2048 for (i=0; i<regs; ++i) 2049 { 2050 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2051 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2052 // uint64_t to accommodate 64-bit registers. 2053 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2054 if (!success) 2055 return false; 2056 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2057 return false; 2058 addr += reg_byte_size; 2059 } 2060 2061 context.type = EmulateInstruction::eContextAdjustStackPointer; 2062 context.SetImmediateSigned (-sp_offset); 2063 2064 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2065 return false; 2066 } 2067 return true; 2068 } 2069 2070 // Vector Pop loads multiple extension registers from the stack. 2071 // It also updates SP to point just above the loaded data. 2072 bool 2073 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2074 { 2075 #if 0 2076 // ARM pseudo code... 2077 if (ConditionPassed()) 2078 { 2079 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2080 address = SP; 2081 SP = SP + imm32; 2082 if single_regs then 2083 for r = 0 to regs-1 2084 S[d+r] = MemA[address,4]; address = address+4; 2085 else 2086 for r = 0 to regs-1 2087 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2088 // Combine the word-aligned words in the correct order for current endianness. 2089 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2090 } 2091 #endif 2092 2093 bool success = false; 2094 bool conditional = false; 2095 if (ConditionPassed(opcode, &conditional)) 2096 { 2097 const uint32_t addr_byte_size = GetAddressByteSize(); 2098 const addr_t sp = ReadCoreReg (SP_REG, &success); 2099 if (!success) 2100 return false; 2101 bool single_regs; 2102 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2103 uint32_t imm32; // stack offset 2104 uint32_t regs; // number of registers 2105 switch (encoding) { 2106 case eEncodingT1: 2107 case eEncodingA1: 2108 single_regs = false; 2109 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2110 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2111 // If UInt(imm8) is odd, see "FLDMX". 2112 regs = Bits32(opcode, 7, 0) / 2; 2113 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2114 if (regs == 0 || regs > 16 || (d + regs) > 32) 2115 return false; 2116 break; 2117 case eEncodingT2: 2118 case eEncodingA2: 2119 single_regs = true; 2120 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2121 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2122 regs = Bits32(opcode, 7, 0); 2123 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2124 if (regs == 0 || regs > 16 || (d + regs) > 32) 2125 return false; 2126 break; 2127 default: 2128 return false; 2129 } 2130 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2131 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2132 addr_t sp_offset = imm32; 2133 addr_t addr = sp; 2134 uint32_t i; 2135 uint64_t data; // uint64_t to accomodate 64-bit registers. 2136 2137 EmulateInstruction::Context context; 2138 if (conditional) 2139 context.type = EmulateInstruction::eContextRegisterLoad; 2140 else 2141 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2142 RegisterInfo dwarf_reg; 2143 RegisterInfo sp_reg; 2144 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2145 for (i=0; i<regs; ++i) 2146 { 2147 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2148 context.SetRegisterPlusOffset (sp_reg, addr - sp); 2149 data = MemARead(context, addr, reg_byte_size, 0, &success); 2150 if (!success) 2151 return false; 2152 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2153 return false; 2154 addr += reg_byte_size; 2155 } 2156 2157 context.type = EmulateInstruction::eContextAdjustStackPointer; 2158 context.SetImmediateSigned (sp_offset); 2159 2160 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2161 return false; 2162 } 2163 return true; 2164 } 2165 2166 // SVC (previously SWI) 2167 bool 2168 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2169 { 2170 #if 0 2171 // ARM pseudo code... 2172 if (ConditionPassed()) 2173 { 2174 EncodingSpecificOperations(); 2175 CallSupervisor(); 2176 } 2177 #endif 2178 2179 bool success = false; 2180 2181 if (ConditionPassed(opcode)) 2182 { 2183 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2184 addr_t lr; // next instruction address 2185 if (!success) 2186 return false; 2187 uint32_t imm32; // the immediate constant 2188 uint32_t mode; // ARM or Thumb mode 2189 switch (encoding) { 2190 case eEncodingT1: 2191 lr = (pc + 2) | 1u; // return address 2192 imm32 = Bits32(opcode, 7, 0); 2193 mode = eModeThumb; 2194 break; 2195 case eEncodingA1: 2196 lr = pc + 4; // return address 2197 imm32 = Bits32(opcode, 23, 0); 2198 mode = eModeARM; 2199 break; 2200 default: 2201 return false; 2202 } 2203 2204 EmulateInstruction::Context context; 2205 context.type = EmulateInstruction::eContextSupervisorCall; 2206 context.SetISAAndImmediate (mode, imm32); 2207 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2208 return false; 2209 } 2210 return true; 2211 } 2212 2213 // If Then makes up to four following instructions (the IT block) conditional. 2214 bool 2215 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2216 { 2217 #if 0 2218 // ARM pseudo code... 2219 EncodingSpecificOperations(); 2220 ITSTATE.IT<7:0> = firstcond:mask; 2221 #endif 2222 2223 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2224 return true; 2225 } 2226 2227 bool 2228 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2229 { 2230 // NOP, nothing to do... 2231 return true; 2232 } 2233 2234 // Branch causes a branch to a target address. 2235 bool 2236 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2237 { 2238 #if 0 2239 // ARM pseudo code... 2240 if (ConditionPassed()) 2241 { 2242 EncodingSpecificOperations(); 2243 BranchWritePC(PC + imm32); 2244 } 2245 #endif 2246 2247 bool success = false; 2248 2249 if (ConditionPassed(opcode)) 2250 { 2251 EmulateInstruction::Context context; 2252 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2253 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2254 if (!success) 2255 return false; 2256 addr_t target; // target address 2257 int32_t imm32; // PC-relative offset 2258 switch (encoding) { 2259 case eEncodingT1: 2260 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2261 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2262 target = pc + imm32; 2263 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2264 break; 2265 case eEncodingT2: 2266 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2267 target = pc + imm32; 2268 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2269 break; 2270 case eEncodingT3: 2271 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2272 { 2273 uint32_t S = Bit32(opcode, 26); 2274 uint32_t imm6 = Bits32(opcode, 21, 16); 2275 uint32_t J1 = Bit32(opcode, 13); 2276 uint32_t J2 = Bit32(opcode, 11); 2277 uint32_t imm11 = Bits32(opcode, 10, 0); 2278 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2279 imm32 = llvm::SignExtend32<21>(imm21); 2280 target = pc + imm32; 2281 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2282 break; 2283 } 2284 case eEncodingT4: 2285 { 2286 uint32_t S = Bit32(opcode, 26); 2287 uint32_t imm10 = Bits32(opcode, 25, 16); 2288 uint32_t J1 = Bit32(opcode, 13); 2289 uint32_t J2 = Bit32(opcode, 11); 2290 uint32_t imm11 = Bits32(opcode, 10, 0); 2291 uint32_t I1 = !(J1 ^ S); 2292 uint32_t I2 = !(J2 ^ S); 2293 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2294 imm32 = llvm::SignExtend32<25>(imm25); 2295 target = pc + imm32; 2296 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2297 break; 2298 } 2299 case eEncodingA1: 2300 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2301 target = pc + imm32; 2302 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2303 break; 2304 default: 2305 return false; 2306 } 2307 if (!BranchWritePC(context, target)) 2308 return false; 2309 } 2310 return true; 2311 } 2312 2313 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2314 // zero and conditionally branch forward a constant value. They do not affect the condition flags. 2315 // CBNZ, CBZ 2316 bool 2317 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2318 { 2319 #if 0 2320 // ARM pseudo code... 2321 EncodingSpecificOperations(); 2322 if nonzero ^ IsZero(R[n]) then 2323 BranchWritePC(PC + imm32); 2324 #endif 2325 2326 bool success = false; 2327 2328 // Read the register value from the operand register Rn. 2329 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2330 if (!success) 2331 return false; 2332 2333 EmulateInstruction::Context context; 2334 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2335 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2336 if (!success) 2337 return false; 2338 2339 addr_t target; // target address 2340 uint32_t imm32; // PC-relative offset to branch forward 2341 bool nonzero; 2342 switch (encoding) { 2343 case eEncodingT1: 2344 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2345 nonzero = BitIsSet(opcode, 11); 2346 target = pc + imm32; 2347 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2348 break; 2349 default: 2350 return false; 2351 } 2352 if (nonzero ^ (reg_val == 0)) 2353 if (!BranchWritePC(context, target)) 2354 return false; 2355 2356 return true; 2357 } 2358 2359 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2360 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2361 // The branch length is twice the value of the byte returned from the table. 2362 // 2363 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2364 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2365 // The branch length is twice the value of the halfword returned from the table. 2366 // TBB, TBH 2367 bool 2368 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2369 { 2370 #if 0 2371 // ARM pseudo code... 2372 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2373 if is_tbh then 2374 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2375 else 2376 halfwords = UInt(MemU[R[n]+R[m], 1]); 2377 BranchWritePC(PC + 2*halfwords); 2378 #endif 2379 2380 bool success = false; 2381 2382 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2383 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2384 bool is_tbh; // true if table branch halfword 2385 switch (encoding) { 2386 case eEncodingT1: 2387 Rn = Bits32(opcode, 19, 16); 2388 Rm = Bits32(opcode, 3, 0); 2389 is_tbh = BitIsSet(opcode, 4); 2390 if (Rn == 13 || BadReg(Rm)) 2391 return false; 2392 if (InITBlock() && !LastInITBlock()) 2393 return false; 2394 break; 2395 default: 2396 return false; 2397 } 2398 2399 // Read the address of the table from the operand register Rn. 2400 // The PC can be used, in which case the table immediately follows this instruction. 2401 uint32_t base = ReadCoreReg(Rm, &success); 2402 if (!success) 2403 return false; 2404 2405 // the table index 2406 uint32_t index = ReadCoreReg(Rm, &success); 2407 if (!success) 2408 return false; 2409 2410 // the offsetted table address 2411 addr_t addr = base + (is_tbh ? index*2 : index); 2412 2413 // PC-relative offset to branch forward 2414 EmulateInstruction::Context context; 2415 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2416 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2417 if (!success) 2418 return false; 2419 2420 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2421 if (!success) 2422 return false; 2423 2424 // target address 2425 addr_t target = pc + offset; 2426 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2427 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2428 2429 if (!BranchWritePC(context, target)) 2430 return false; 2431 2432 return true; 2433 } 2434 2435 // This instruction adds an immediate value to a register value, and writes the result to the destination register. 2436 // It can optionally update the condition flags based on the result. 2437 bool 2438 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2439 { 2440 #if 0 2441 if ConditionPassed() then 2442 EncodingSpecificOperations(); 2443 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2444 R[d] = result; 2445 if setflags then 2446 APSR.N = result<31>; 2447 APSR.Z = IsZeroBit(result); 2448 APSR.C = carry; 2449 APSR.V = overflow; 2450 #endif 2451 2452 bool success = false; 2453 2454 if (ConditionPassed(opcode)) 2455 { 2456 uint32_t d; 2457 uint32_t n; 2458 bool setflags; 2459 uint32_t imm32; 2460 uint32_t carry_out; 2461 2462 //EncodingSpecificOperations(); 2463 switch (encoding) 2464 { 2465 case eEncodingT1: 2466 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2467 d = Bits32 (opcode, 2, 0); 2468 n = Bits32 (opcode, 5, 3); 2469 setflags = !InITBlock(); 2470 imm32 = Bits32 (opcode, 8,6); 2471 2472 break; 2473 2474 case eEncodingT2: 2475 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2476 d = Bits32 (opcode, 10, 8); 2477 n = Bits32 (opcode, 10, 8); 2478 setflags = !InITBlock(); 2479 imm32 = Bits32 (opcode, 7, 0); 2480 2481 break; 2482 2483 case eEncodingT3: 2484 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2485 // if Rn == '1101' then SEE ADD (SP plus immediate); 2486 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2487 d = Bits32 (opcode, 11, 8); 2488 n = Bits32 (opcode, 19, 16); 2489 setflags = BitIsSet (opcode, 20); 2490 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2491 2492 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2493 if (BadReg (d) || (n == 15)) 2494 return false; 2495 2496 break; 2497 2498 case eEncodingT4: 2499 { 2500 // if Rn == '1111' then SEE ADR; 2501 // if Rn == '1101' then SEE ADD (SP plus immediate); 2502 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2503 d = Bits32 (opcode, 11, 8); 2504 n = Bits32 (opcode, 19, 16); 2505 setflags = false; 2506 uint32_t i = Bit32 (opcode, 26); 2507 uint32_t imm3 = Bits32 (opcode, 14, 12); 2508 uint32_t imm8 = Bits32 (opcode, 7, 0); 2509 imm32 = (i << 11) | (imm3 << 8) | imm8; 2510 2511 // if BadReg(d) then UNPREDICTABLE; 2512 if (BadReg (d)) 2513 return false; 2514 2515 break; 2516 } 2517 default: 2518 return false; 2519 } 2520 2521 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2522 if (!success) 2523 return false; 2524 2525 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2526 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2527 2528 RegisterInfo reg_n; 2529 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2530 2531 EmulateInstruction::Context context; 2532 context.type = eContextArithmetic; 2533 context.SetRegisterPlusOffset (reg_n, imm32); 2534 2535 //R[d] = result; 2536 //if setflags then 2537 //APSR.N = result<31>; 2538 //APSR.Z = IsZeroBit(result); 2539 //APSR.C = carry; 2540 //APSR.V = overflow; 2541 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2542 return false; 2543 2544 } 2545 return true; 2546 } 2547 2548 // This instruction adds an immediate value to a register value, and writes the result to the destination 2549 // register. It can optionally update the condition flags based on the result. 2550 bool 2551 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2552 { 2553 #if 0 2554 // ARM pseudo code... 2555 if ConditionPassed() then 2556 EncodingSpecificOperations(); 2557 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2558 if d == 15 then 2559 ALUWritePC(result); // setflags is always FALSE here 2560 else 2561 R[d] = result; 2562 if setflags then 2563 APSR.N = result<31>; 2564 APSR.Z = IsZeroBit(result); 2565 APSR.C = carry; 2566 APSR.V = overflow; 2567 #endif 2568 2569 bool success = false; 2570 2571 if (ConditionPassed(opcode)) 2572 { 2573 uint32_t Rd, Rn; 2574 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2575 bool setflags; 2576 switch (encoding) 2577 { 2578 case eEncodingA1: 2579 Rd = Bits32(opcode, 15, 12); 2580 Rn = Bits32(opcode, 19, 16); 2581 setflags = BitIsSet(opcode, 20); 2582 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2583 break; 2584 default: 2585 return false; 2586 } 2587 2588 // Read the first operand. 2589 uint32_t val1 = ReadCoreReg(Rn, &success); 2590 if (!success) 2591 return false; 2592 2593 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2594 2595 EmulateInstruction::Context context; 2596 context.type = eContextArithmetic; 2597 RegisterInfo dwarf_reg; 2598 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2599 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2600 2601 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2602 return false; 2603 } 2604 return true; 2605 } 2606 2607 // This instruction adds a register value and an optionally-shifted register value, and writes the result 2608 // to the destination register. It can optionally update the condition flags based on the result. 2609 bool 2610 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2611 { 2612 #if 0 2613 // ARM pseudo code... 2614 if ConditionPassed() then 2615 EncodingSpecificOperations(); 2616 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2617 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2618 if d == 15 then 2619 ALUWritePC(result); // setflags is always FALSE here 2620 else 2621 R[d] = result; 2622 if setflags then 2623 APSR.N = result<31>; 2624 APSR.Z = IsZeroBit(result); 2625 APSR.C = carry; 2626 APSR.V = overflow; 2627 #endif 2628 2629 bool success = false; 2630 2631 if (ConditionPassed(opcode)) 2632 { 2633 uint32_t Rd, Rn, Rm; 2634 ARM_ShifterType shift_t; 2635 uint32_t shift_n; // the shift applied to the value read from Rm 2636 bool setflags; 2637 switch (encoding) 2638 { 2639 case eEncodingT1: 2640 Rd = Bits32(opcode, 2, 0); 2641 Rn = Bits32(opcode, 5, 3); 2642 Rm = Bits32(opcode, 8, 6); 2643 setflags = !InITBlock(); 2644 shift_t = SRType_LSL; 2645 shift_n = 0; 2646 break; 2647 case eEncodingT2: 2648 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2649 Rm = Bits32(opcode, 6, 3); 2650 setflags = false; 2651 shift_t = SRType_LSL; 2652 shift_n = 0; 2653 if (Rn == 15 && Rm == 15) 2654 return false; 2655 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2656 return false; 2657 break; 2658 case eEncodingA1: 2659 Rd = Bits32(opcode, 15, 12); 2660 Rn = Bits32(opcode, 19, 16); 2661 Rm = Bits32(opcode, 3, 0); 2662 setflags = BitIsSet(opcode, 20); 2663 shift_n = DecodeImmShiftARM(opcode, shift_t); 2664 break; 2665 default: 2666 return false; 2667 } 2668 2669 // Read the first operand. 2670 uint32_t val1 = ReadCoreReg(Rn, &success); 2671 if (!success) 2672 return false; 2673 2674 // Read the second operand. 2675 uint32_t val2 = ReadCoreReg(Rm, &success); 2676 if (!success) 2677 return false; 2678 2679 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2680 if (!success) 2681 return false; 2682 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2683 2684 EmulateInstruction::Context context; 2685 context.type = eContextArithmetic; 2686 RegisterInfo op1_reg; 2687 RegisterInfo op2_reg; 2688 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2689 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2690 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2691 2692 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2693 return false; 2694 } 2695 return true; 2696 } 2697 2698 // Compare Negative (immediate) adds a register value and an immediate value. 2699 // It updates the condition flags based on the result, and discards the result. 2700 bool 2701 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2702 { 2703 #if 0 2704 // ARM pseudo code... 2705 if ConditionPassed() then 2706 EncodingSpecificOperations(); 2707 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2708 APSR.N = result<31>; 2709 APSR.Z = IsZeroBit(result); 2710 APSR.C = carry; 2711 APSR.V = overflow; 2712 #endif 2713 2714 bool success = false; 2715 2716 uint32_t Rn; // the first operand 2717 uint32_t imm32; // the immediate value to be compared with 2718 switch (encoding) { 2719 case eEncodingT1: 2720 Rn = Bits32(opcode, 19, 16); 2721 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2722 if (Rn == 15) 2723 return false; 2724 break; 2725 case eEncodingA1: 2726 Rn = Bits32(opcode, 19, 16); 2727 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2728 break; 2729 default: 2730 return false; 2731 } 2732 // Read the register value from the operand register Rn. 2733 uint32_t reg_val = ReadCoreReg(Rn, &success); 2734 if (!success) 2735 return false; 2736 2737 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2738 2739 EmulateInstruction::Context context; 2740 context.type = EmulateInstruction::eContextImmediate; 2741 context.SetNoArgs (); 2742 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2743 return false; 2744 2745 return true; 2746 } 2747 2748 // Compare Negative (register) adds a register value and an optionally-shifted register value. 2749 // It updates the condition flags based on the result, and discards the result. 2750 bool 2751 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2752 { 2753 #if 0 2754 // ARM pseudo code... 2755 if ConditionPassed() then 2756 EncodingSpecificOperations(); 2757 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2758 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2759 APSR.N = result<31>; 2760 APSR.Z = IsZeroBit(result); 2761 APSR.C = carry; 2762 APSR.V = overflow; 2763 #endif 2764 2765 bool success = false; 2766 2767 uint32_t Rn; // the first operand 2768 uint32_t Rm; // the second operand 2769 ARM_ShifterType shift_t; 2770 uint32_t shift_n; // the shift applied to the value read from Rm 2771 switch (encoding) { 2772 case eEncodingT1: 2773 Rn = Bits32(opcode, 2, 0); 2774 Rm = Bits32(opcode, 5, 3); 2775 shift_t = SRType_LSL; 2776 shift_n = 0; 2777 break; 2778 case eEncodingT2: 2779 Rn = Bits32(opcode, 19, 16); 2780 Rm = Bits32(opcode, 3, 0); 2781 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2782 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2783 if (Rn == 15 || BadReg(Rm)) 2784 return false; 2785 break; 2786 case eEncodingA1: 2787 Rn = Bits32(opcode, 19, 16); 2788 Rm = Bits32(opcode, 3, 0); 2789 shift_n = DecodeImmShiftARM(opcode, shift_t); 2790 break; 2791 default: 2792 return false; 2793 } 2794 // Read the register value from register Rn. 2795 uint32_t val1 = ReadCoreReg(Rn, &success); 2796 if (!success) 2797 return false; 2798 2799 // Read the register value from register Rm. 2800 uint32_t val2 = ReadCoreReg(Rm, &success); 2801 if (!success) 2802 return false; 2803 2804 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2805 if (!success) 2806 return false; 2807 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2808 2809 EmulateInstruction::Context context; 2810 context.type = EmulateInstruction::eContextImmediate; 2811 context.SetNoArgs(); 2812 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2813 return false; 2814 2815 return true; 2816 } 2817 2818 // Compare (immediate) subtracts an immediate value from a register value. 2819 // It updates the condition flags based on the result, and discards the result. 2820 bool 2821 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2822 { 2823 #if 0 2824 // ARM pseudo code... 2825 if ConditionPassed() then 2826 EncodingSpecificOperations(); 2827 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2828 APSR.N = result<31>; 2829 APSR.Z = IsZeroBit(result); 2830 APSR.C = carry; 2831 APSR.V = overflow; 2832 #endif 2833 2834 bool success = false; 2835 2836 uint32_t Rn; // the first operand 2837 uint32_t imm32; // the immediate value to be compared with 2838 switch (encoding) { 2839 case eEncodingT1: 2840 Rn = Bits32(opcode, 10, 8); 2841 imm32 = Bits32(opcode, 7, 0); 2842 break; 2843 case eEncodingT2: 2844 Rn = Bits32(opcode, 19, 16); 2845 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2846 if (Rn == 15) 2847 return false; 2848 break; 2849 case eEncodingA1: 2850 Rn = Bits32(opcode, 19, 16); 2851 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2852 break; 2853 default: 2854 return false; 2855 } 2856 // Read the register value from the operand register Rn. 2857 uint32_t reg_val = ReadCoreReg(Rn, &success); 2858 if (!success) 2859 return false; 2860 2861 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2862 2863 EmulateInstruction::Context context; 2864 context.type = EmulateInstruction::eContextImmediate; 2865 context.SetNoArgs (); 2866 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2867 return false; 2868 2869 return true; 2870 } 2871 2872 // Compare (register) subtracts an optionally-shifted register value from a register value. 2873 // It updates the condition flags based on the result, and discards the result. 2874 bool 2875 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2876 { 2877 #if 0 2878 // ARM pseudo code... 2879 if ConditionPassed() then 2880 EncodingSpecificOperations(); 2881 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2882 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2883 APSR.N = result<31>; 2884 APSR.Z = IsZeroBit(result); 2885 APSR.C = carry; 2886 APSR.V = overflow; 2887 #endif 2888 2889 bool success = false; 2890 2891 uint32_t Rn; // the first operand 2892 uint32_t Rm; // the second operand 2893 ARM_ShifterType shift_t; 2894 uint32_t shift_n; // the shift applied to the value read from Rm 2895 switch (encoding) { 2896 case eEncodingT1: 2897 Rn = Bits32(opcode, 2, 0); 2898 Rm = Bits32(opcode, 5, 3); 2899 shift_t = SRType_LSL; 2900 shift_n = 0; 2901 break; 2902 case eEncodingT2: 2903 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2904 Rm = Bits32(opcode, 6, 3); 2905 shift_t = SRType_LSL; 2906 shift_n = 0; 2907 if (Rn < 8 && Rm < 8) 2908 return false; 2909 if (Rn == 15 || Rm == 15) 2910 return false; 2911 break; 2912 case eEncodingA1: 2913 Rn = Bits32(opcode, 19, 16); 2914 Rm = Bits32(opcode, 3, 0); 2915 shift_n = DecodeImmShiftARM(opcode, shift_t); 2916 break; 2917 default: 2918 return false; 2919 } 2920 // Read the register value from register Rn. 2921 uint32_t val1 = ReadCoreReg(Rn, &success); 2922 if (!success) 2923 return false; 2924 2925 // Read the register value from register Rm. 2926 uint32_t val2 = ReadCoreReg(Rm, &success); 2927 if (!success) 2928 return false; 2929 2930 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2931 if (!success) 2932 return false; 2933 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 2934 2935 EmulateInstruction::Context context; 2936 context.type = EmulateInstruction::eContextImmediate; 2937 context.SetNoArgs(); 2938 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2939 return false; 2940 2941 return true; 2942 } 2943 2944 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2945 // shifting in copies of its sign bit, and writes the result to the destination register. It can 2946 // optionally update the condition flags based on the result. 2947 bool 2948 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 2949 { 2950 #if 0 2951 // ARM pseudo code... 2952 if ConditionPassed() then 2953 EncodingSpecificOperations(); 2954 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2955 if d == 15 then // Can only occur for ARM encoding 2956 ALUWritePC(result); // setflags is always FALSE here 2957 else 2958 R[d] = result; 2959 if setflags then 2960 APSR.N = result<31>; 2961 APSR.Z = IsZeroBit(result); 2962 APSR.C = carry; 2963 // APSR.V unchanged 2964 #endif 2965 2966 return EmulateShiftImm (opcode, encoding, SRType_ASR); 2967 } 2968 2969 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 2970 // shifting in copies of its sign bit, and writes the result to the destination register. 2971 // The variable number of bits is read from the bottom byte of a register. It can optionally update 2972 // the condition flags based on the result. 2973 bool 2974 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 2975 { 2976 #if 0 2977 // ARM pseudo code... 2978 if ConditionPassed() then 2979 EncodingSpecificOperations(); 2980 shift_n = UInt(R[m]<7:0>); 2981 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2982 R[d] = result; 2983 if setflags then 2984 APSR.N = result<31>; 2985 APSR.Z = IsZeroBit(result); 2986 APSR.C = carry; 2987 // APSR.V unchanged 2988 #endif 2989 2990 return EmulateShiftReg (opcode, encoding, SRType_ASR); 2991 } 2992 2993 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 2994 // shifting in zeros, and writes the result to the destination register. It can optionally 2995 // update the condition flags based on the result. 2996 bool 2997 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 2998 { 2999 #if 0 3000 // ARM pseudo code... 3001 if ConditionPassed() then 3002 EncodingSpecificOperations(); 3003 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3004 if d == 15 then // Can only occur for ARM encoding 3005 ALUWritePC(result); // setflags is always FALSE here 3006 else 3007 R[d] = result; 3008 if setflags then 3009 APSR.N = result<31>; 3010 APSR.Z = IsZeroBit(result); 3011 APSR.C = carry; 3012 // APSR.V unchanged 3013 #endif 3014 3015 return EmulateShiftImm (opcode, encoding, SRType_LSL); 3016 } 3017 3018 // Logical Shift Left (register) shifts a register value left by a variable number of bits, 3019 // shifting in zeros, and writes the result to the destination register. The variable number 3020 // of bits is read from the bottom byte of a register. It can optionally update the condition 3021 // flags based on the result. 3022 bool 3023 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 3024 { 3025 #if 0 3026 // ARM pseudo code... 3027 if ConditionPassed() then 3028 EncodingSpecificOperations(); 3029 shift_n = UInt(R[m]<7:0>); 3030 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3031 R[d] = result; 3032 if setflags then 3033 APSR.N = result<31>; 3034 APSR.Z = IsZeroBit(result); 3035 APSR.C = carry; 3036 // APSR.V unchanged 3037 #endif 3038 3039 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3040 } 3041 3042 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3043 // shifting in zeros, and writes the result to the destination register. It can optionally 3044 // update the condition flags based on the result. 3045 bool 3046 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3047 { 3048 #if 0 3049 // ARM pseudo code... 3050 if ConditionPassed() then 3051 EncodingSpecificOperations(); 3052 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3053 if d == 15 then // Can only occur for ARM encoding 3054 ALUWritePC(result); // setflags is always FALSE here 3055 else 3056 R[d] = result; 3057 if setflags then 3058 APSR.N = result<31>; 3059 APSR.Z = IsZeroBit(result); 3060 APSR.C = carry; 3061 // APSR.V unchanged 3062 #endif 3063 3064 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3065 } 3066 3067 // Logical Shift Right (register) shifts a register value right by a variable number of bits, 3068 // shifting in zeros, and writes the result to the destination register. The variable number 3069 // of bits is read from the bottom byte of a register. It can optionally update the condition 3070 // flags based on the result. 3071 bool 3072 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3073 { 3074 #if 0 3075 // ARM pseudo code... 3076 if ConditionPassed() then 3077 EncodingSpecificOperations(); 3078 shift_n = UInt(R[m]<7:0>); 3079 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3080 R[d] = result; 3081 if setflags then 3082 APSR.N = result<31>; 3083 APSR.Z = IsZeroBit(result); 3084 APSR.C = carry; 3085 // APSR.V unchanged 3086 #endif 3087 3088 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3089 } 3090 3091 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3092 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3093 // It can optionally update the condition flags based on the result. 3094 bool 3095 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3096 { 3097 #if 0 3098 // ARM pseudo code... 3099 if ConditionPassed() then 3100 EncodingSpecificOperations(); 3101 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3102 if d == 15 then // Can only occur for ARM encoding 3103 ALUWritePC(result); // setflags is always FALSE here 3104 else 3105 R[d] = result; 3106 if setflags then 3107 APSR.N = result<31>; 3108 APSR.Z = IsZeroBit(result); 3109 APSR.C = carry; 3110 // APSR.V unchanged 3111 #endif 3112 3113 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3114 } 3115 3116 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3117 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3118 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3119 // flags based on the result. 3120 bool 3121 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3122 { 3123 #if 0 3124 // ARM pseudo code... 3125 if ConditionPassed() then 3126 EncodingSpecificOperations(); 3127 shift_n = UInt(R[m]<7:0>); 3128 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3129 R[d] = result; 3130 if setflags then 3131 APSR.N = result<31>; 3132 APSR.Z = IsZeroBit(result); 3133 APSR.C = carry; 3134 // APSR.V unchanged 3135 #endif 3136 3137 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3138 } 3139 3140 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3141 // with the carry flag shifted into bit [31]. 3142 // 3143 // RRX can optionally update the condition flags based on the result. 3144 // In that case, bit [0] is shifted into the carry flag. 3145 bool 3146 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3147 { 3148 #if 0 3149 // ARM pseudo code... 3150 if ConditionPassed() then 3151 EncodingSpecificOperations(); 3152 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3153 if d == 15 then // Can only occur for ARM encoding 3154 ALUWritePC(result); // setflags is always FALSE here 3155 else 3156 R[d] = result; 3157 if setflags then 3158 APSR.N = result<31>; 3159 APSR.Z = IsZeroBit(result); 3160 APSR.C = carry; 3161 // APSR.V unchanged 3162 #endif 3163 3164 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3165 } 3166 3167 bool 3168 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3169 { 3170 // assert(shift_type == SRType_ASR 3171 // || shift_type == SRType_LSL 3172 // || shift_type == SRType_LSR 3173 // || shift_type == SRType_ROR 3174 // || shift_type == SRType_RRX); 3175 3176 bool success = false; 3177 3178 if (ConditionPassed(opcode)) 3179 { 3180 uint32_t Rd; // the destination register 3181 uint32_t Rm; // the first operand register 3182 uint32_t imm5; // encoding for the shift amount 3183 uint32_t carry; // the carry bit after the shift operation 3184 bool setflags; 3185 3186 // Special case handling! 3187 // A8.6.139 ROR (immediate) -- Encoding T1 3188 ARMEncoding use_encoding = encoding; 3189 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3190 { 3191 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3192 // have the same decoding of bit fields as the other Thumb2 shift operations. 3193 use_encoding = eEncodingT2; 3194 } 3195 3196 switch (use_encoding) { 3197 case eEncodingT1: 3198 // Due to the above special case handling! 3199 if (shift_type == SRType_ROR) 3200 return false; 3201 3202 Rd = Bits32(opcode, 2, 0); 3203 Rm = Bits32(opcode, 5, 3); 3204 setflags = !InITBlock(); 3205 imm5 = Bits32(opcode, 10, 6); 3206 break; 3207 case eEncodingT2: 3208 // A8.6.141 RRX 3209 // There's no imm form of RRX instructions. 3210 if (shift_type == SRType_RRX) 3211 return false; 3212 3213 Rd = Bits32(opcode, 11, 8); 3214 Rm = Bits32(opcode, 3, 0); 3215 setflags = BitIsSet(opcode, 20); 3216 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3217 if (BadReg(Rd) || BadReg(Rm)) 3218 return false; 3219 break; 3220 case eEncodingA1: 3221 Rd = Bits32(opcode, 15, 12); 3222 Rm = Bits32(opcode, 3, 0); 3223 setflags = BitIsSet(opcode, 20); 3224 imm5 = Bits32(opcode, 11, 7); 3225 break; 3226 default: 3227 return false; 3228 } 3229 3230 // A8.6.139 ROR (immediate) 3231 if (shift_type == SRType_ROR && imm5 == 0) 3232 shift_type = SRType_RRX; 3233 3234 // Get the first operand. 3235 uint32_t value = ReadCoreReg (Rm, &success); 3236 if (!success) 3237 return false; 3238 3239 // Decode the shift amount if not RRX. 3240 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3241 3242 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3243 if (!success) 3244 return false; 3245 3246 // The context specifies that an immediate is to be moved into Rd. 3247 EmulateInstruction::Context context; 3248 context.type = EmulateInstruction::eContextImmediate; 3249 context.SetNoArgs (); 3250 3251 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3252 return false; 3253 } 3254 return true; 3255 } 3256 3257 bool 3258 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3259 { 3260 // assert(shift_type == SRType_ASR 3261 // || shift_type == SRType_LSL 3262 // || shift_type == SRType_LSR 3263 // || shift_type == SRType_ROR); 3264 3265 bool success = false; 3266 3267 if (ConditionPassed(opcode)) 3268 { 3269 uint32_t Rd; // the destination register 3270 uint32_t Rn; // the first operand register 3271 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3272 uint32_t carry; // the carry bit after the shift operation 3273 bool setflags; 3274 switch (encoding) { 3275 case eEncodingT1: 3276 Rd = Bits32(opcode, 2, 0); 3277 Rn = Rd; 3278 Rm = Bits32(opcode, 5, 3); 3279 setflags = !InITBlock(); 3280 break; 3281 case eEncodingT2: 3282 Rd = Bits32(opcode, 11, 8); 3283 Rn = Bits32(opcode, 19, 16); 3284 Rm = Bits32(opcode, 3, 0); 3285 setflags = BitIsSet(opcode, 20); 3286 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3287 return false; 3288 break; 3289 case eEncodingA1: 3290 Rd = Bits32(opcode, 15, 12); 3291 Rn = Bits32(opcode, 3, 0); 3292 Rm = Bits32(opcode, 11, 8); 3293 setflags = BitIsSet(opcode, 20); 3294 if (Rd == 15 || Rn == 15 || Rm == 15) 3295 return false; 3296 break; 3297 default: 3298 return false; 3299 } 3300 3301 // Get the first operand. 3302 uint32_t value = ReadCoreReg (Rn, &success); 3303 if (!success) 3304 return false; 3305 // Get the Rm register content. 3306 uint32_t val = ReadCoreReg (Rm, &success); 3307 if (!success) 3308 return false; 3309 3310 // Get the shift amount. 3311 uint32_t amt = Bits32(val, 7, 0); 3312 3313 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3314 if (!success) 3315 return false; 3316 3317 // The context specifies that an immediate is to be moved into Rd. 3318 EmulateInstruction::Context context; 3319 context.type = EmulateInstruction::eContextImmediate; 3320 context.SetNoArgs (); 3321 3322 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3323 return false; 3324 } 3325 return true; 3326 } 3327 3328 // LDM loads multiple registers from consecutive memory locations, using an 3329 // address from a base register. Optionally the address just above the highest of those locations 3330 // can be written back to the base register. 3331 bool 3332 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3333 { 3334 #if 0 3335 // ARM pseudo code... 3336 if ConditionPassed() 3337 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3338 address = R[n]; 3339 3340 for i = 0 to 14 3341 if registers<i> == '1' then 3342 R[i] = MemA[address, 4]; address = address + 4; 3343 if registers<15> == '1' then 3344 LoadWritePC (MemA[address, 4]); 3345 3346 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3347 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3348 3349 #endif 3350 3351 bool success = false; 3352 bool conditional = false; 3353 if (ConditionPassed(opcode, &conditional)) 3354 { 3355 uint32_t n; 3356 uint32_t registers = 0; 3357 bool wback; 3358 const uint32_t addr_byte_size = GetAddressByteSize(); 3359 switch (encoding) 3360 { 3361 case eEncodingT1: 3362 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3363 n = Bits32 (opcode, 10, 8); 3364 registers = Bits32 (opcode, 7, 0); 3365 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3366 wback = BitIsClear (registers, n); 3367 // if BitCount(registers) < 1 then UNPREDICTABLE; 3368 if (BitCount(registers) < 1) 3369 return false; 3370 break; 3371 case eEncodingT2: 3372 // if W == '1' && Rn == '1101' then SEE POP; 3373 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3374 n = Bits32 (opcode, 19, 16); 3375 registers = Bits32 (opcode, 15, 0); 3376 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3377 wback = BitIsSet (opcode, 21); 3378 3379 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3380 if ((n == 15) 3381 || (BitCount (registers) < 2) 3382 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3383 return false; 3384 3385 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3386 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3387 return false; 3388 3389 // if wback && registers<n> == '1' then UNPREDICTABLE; 3390 if (wback 3391 && BitIsSet (registers, n)) 3392 return false; 3393 break; 3394 3395 case eEncodingA1: 3396 n = Bits32 (opcode, 19, 16); 3397 registers = Bits32 (opcode, 15, 0); 3398 wback = BitIsSet (opcode, 21); 3399 if ((n == 15) 3400 || (BitCount (registers) < 1)) 3401 return false; 3402 break; 3403 default: 3404 return false; 3405 } 3406 3407 int32_t offset = 0; 3408 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3409 if (!success) 3410 return false; 3411 3412 EmulateInstruction::Context context; 3413 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3414 RegisterInfo dwarf_reg; 3415 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3416 context.SetRegisterPlusOffset (dwarf_reg, offset); 3417 3418 for (int i = 0; i < 14; ++i) 3419 { 3420 if (BitIsSet (registers, i)) 3421 { 3422 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3423 context.SetRegisterPlusOffset (dwarf_reg, offset); 3424 if (wback && (n == 13)) // Pop Instruction 3425 { 3426 if (conditional) 3427 context.type = EmulateInstruction::eContextRegisterLoad; 3428 else 3429 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3430 } 3431 3432 // R[i] = MemA [address, 4]; address = address + 4; 3433 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3434 if (!success) 3435 return false; 3436 3437 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3438 return false; 3439 3440 offset += addr_byte_size; 3441 } 3442 } 3443 3444 if (BitIsSet (registers, 15)) 3445 { 3446 //LoadWritePC (MemA [address, 4]); 3447 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3448 context.SetRegisterPlusOffset (dwarf_reg, offset); 3449 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3450 if (!success) 3451 return false; 3452 // In ARMv5T and above, this is an interworking branch. 3453 if (!LoadWritePC(context, data)) 3454 return false; 3455 } 3456 3457 if (wback && BitIsClear (registers, n)) 3458 { 3459 // R[n] = R[n] + 4 * BitCount (registers) 3460 int32_t offset = addr_byte_size * BitCount (registers); 3461 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3462 context.SetRegisterPlusOffset (dwarf_reg, offset); 3463 3464 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3465 return false; 3466 } 3467 if (wback && BitIsSet (registers, n)) 3468 // R[n] bits(32) UNKNOWN; 3469 return WriteBits32Unknown (n); 3470 } 3471 return true; 3472 } 3473 3474 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3475 // The consecutive memory locations end at this address and the address just below the lowest of those locations 3476 // can optionally be written back to the base register. 3477 bool 3478 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3479 { 3480 #if 0 3481 // ARM pseudo code... 3482 if ConditionPassed() then 3483 EncodingSpecificOperations(); 3484 address = R[n] - 4*BitCount(registers) + 4; 3485 3486 for i = 0 to 14 3487 if registers<i> == '1' then 3488 R[i] = MemA[address,4]; address = address + 4; 3489 3490 if registers<15> == '1' then 3491 LoadWritePC(MemA[address,4]); 3492 3493 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3494 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3495 #endif 3496 3497 bool success = false; 3498 3499 if (ConditionPassed(opcode)) 3500 { 3501 uint32_t n; 3502 uint32_t registers = 0; 3503 bool wback; 3504 const uint32_t addr_byte_size = GetAddressByteSize(); 3505 3506 // EncodingSpecificOperations(); 3507 switch (encoding) 3508 { 3509 case eEncodingA1: 3510 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3511 n = Bits32 (opcode, 19, 16); 3512 registers = Bits32 (opcode, 15, 0); 3513 wback = BitIsSet (opcode, 21); 3514 3515 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3516 if ((n == 15) || (BitCount (registers) < 1)) 3517 return false; 3518 3519 break; 3520 3521 default: 3522 return false; 3523 } 3524 // address = R[n] - 4*BitCount(registers) + 4; 3525 3526 int32_t offset = 0; 3527 addr_t Rn = ReadCoreReg (n, &success); 3528 3529 if (!success) 3530 return false; 3531 3532 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3533 3534 EmulateInstruction::Context context; 3535 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3536 RegisterInfo dwarf_reg; 3537 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3538 context.SetRegisterPlusOffset (dwarf_reg, offset); 3539 3540 // for i = 0 to 14 3541 for (int i = 0; i < 14; ++i) 3542 { 3543 // if registers<i> == '1' then 3544 if (BitIsSet (registers, i)) 3545 { 3546 // R[i] = MemA[address,4]; address = address + 4; 3547 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3548 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3549 if (!success) 3550 return false; 3551 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3552 return false; 3553 offset += addr_byte_size; 3554 } 3555 } 3556 3557 // if registers<15> == '1' then 3558 // LoadWritePC(MemA[address,4]); 3559 if (BitIsSet (registers, 15)) 3560 { 3561 context.SetRegisterPlusOffset (dwarf_reg, offset); 3562 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3563 if (!success) 3564 return false; 3565 // In ARMv5T and above, this is an interworking branch. 3566 if (!LoadWritePC(context, data)) 3567 return false; 3568 } 3569 3570 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3571 if (wback && BitIsClear (registers, n)) 3572 { 3573 if (!success) 3574 return false; 3575 3576 offset = (addr_byte_size * BitCount (registers)) * -1; 3577 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3578 context.SetImmediateSigned (offset); 3579 addr_t addr = Rn + offset; 3580 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3581 return false; 3582 } 3583 3584 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3585 if (wback && BitIsSet (registers, n)) 3586 return WriteBits32Unknown (n); 3587 } 3588 return true; 3589 } 3590 3591 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3592 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3593 // be optionally written back to the base register. 3594 bool 3595 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3596 { 3597 #if 0 3598 // ARM pseudo code... 3599 if ConditionPassed() then 3600 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3601 address = R[n] - 4*BitCount(registers); 3602 3603 for i = 0 to 14 3604 if registers<i> == '1' then 3605 R[i] = MemA[address,4]; address = address + 4; 3606 if registers<15> == '1' then 3607 LoadWritePC(MemA[address,4]); 3608 3609 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3610 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3611 #endif 3612 3613 bool success = false; 3614 3615 if (ConditionPassed(opcode)) 3616 { 3617 uint32_t n; 3618 uint32_t registers = 0; 3619 bool wback; 3620 const uint32_t addr_byte_size = GetAddressByteSize(); 3621 switch (encoding) 3622 { 3623 case eEncodingT1: 3624 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3625 n = Bits32 (opcode, 19, 16); 3626 registers = Bits32 (opcode, 15, 0); 3627 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3628 wback = BitIsSet (opcode, 21); 3629 3630 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3631 if ((n == 15) 3632 || (BitCount (registers) < 2) 3633 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3634 return false; 3635 3636 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3637 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3638 return false; 3639 3640 // if wback && registers<n> == '1' then UNPREDICTABLE; 3641 if (wback && BitIsSet (registers, n)) 3642 return false; 3643 3644 break; 3645 3646 case eEncodingA1: 3647 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3648 n = Bits32 (opcode, 19, 16); 3649 registers = Bits32 (opcode, 15, 0); 3650 wback = BitIsSet (opcode, 21); 3651 3652 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3653 if ((n == 15) || (BitCount (registers) < 1)) 3654 return false; 3655 3656 break; 3657 3658 default: 3659 return false; 3660 } 3661 3662 // address = R[n] - 4*BitCount(registers); 3663 3664 int32_t offset = 0; 3665 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3666 3667 if (!success) 3668 return false; 3669 3670 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3671 EmulateInstruction::Context context; 3672 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3673 RegisterInfo dwarf_reg; 3674 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3675 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3676 3677 for (int i = 0; i < 14; ++i) 3678 { 3679 if (BitIsSet (registers, i)) 3680 { 3681 // R[i] = MemA[address,4]; address = address + 4; 3682 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3683 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3684 if (!success) 3685 return false; 3686 3687 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3688 return false; 3689 3690 offset += addr_byte_size; 3691 } 3692 } 3693 3694 // if registers<15> == '1' then 3695 // LoadWritePC(MemA[address,4]); 3696 if (BitIsSet (registers, 15)) 3697 { 3698 context.SetRegisterPlusOffset (dwarf_reg, offset); 3699 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3700 if (!success) 3701 return false; 3702 // In ARMv5T and above, this is an interworking branch. 3703 if (!LoadWritePC(context, data)) 3704 return false; 3705 } 3706 3707 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3708 if (wback && BitIsClear (registers, n)) 3709 { 3710 if (!success) 3711 return false; 3712 3713 offset = (addr_byte_size * BitCount (registers)) * -1; 3714 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3715 context.SetImmediateSigned (offset); 3716 addr_t addr = Rn + offset; 3717 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3718 return false; 3719 } 3720 3721 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3722 if (wback && BitIsSet (registers, n)) 3723 return WriteBits32Unknown (n); 3724 } 3725 return true; 3726 } 3727 3728 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3729 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3730 // optinoally be written back to the base register. 3731 bool 3732 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3733 { 3734 #if 0 3735 if ConditionPassed() then 3736 EncodingSpecificOperations(); 3737 address = R[n] + 4; 3738 3739 for i = 0 to 14 3740 if registers<i> == '1' then 3741 R[i] = MemA[address,4]; address = address + 4; 3742 if registers<15> == '1' then 3743 LoadWritePC(MemA[address,4]); 3744 3745 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3746 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3747 #endif 3748 3749 bool success = false; 3750 3751 if (ConditionPassed(opcode)) 3752 { 3753 uint32_t n; 3754 uint32_t registers = 0; 3755 bool wback; 3756 const uint32_t addr_byte_size = GetAddressByteSize(); 3757 switch (encoding) 3758 { 3759 case eEncodingA1: 3760 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3761 n = Bits32 (opcode, 19, 16); 3762 registers = Bits32 (opcode, 15, 0); 3763 wback = BitIsSet (opcode, 21); 3764 3765 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3766 if ((n == 15) || (BitCount (registers) < 1)) 3767 return false; 3768 3769 break; 3770 default: 3771 return false; 3772 } 3773 // address = R[n] + 4; 3774 3775 int32_t offset = 0; 3776 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3777 3778 if (!success) 3779 return false; 3780 3781 addr_t address = Rn + addr_byte_size; 3782 3783 EmulateInstruction::Context context; 3784 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3785 RegisterInfo dwarf_reg; 3786 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3787 context.SetRegisterPlusOffset (dwarf_reg, offset); 3788 3789 for (int i = 0; i < 14; ++i) 3790 { 3791 if (BitIsSet (registers, i)) 3792 { 3793 // R[i] = MemA[address,4]; address = address + 4; 3794 3795 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3796 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3797 if (!success) 3798 return false; 3799 3800 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3801 return false; 3802 3803 offset += addr_byte_size; 3804 } 3805 } 3806 3807 // if registers<15> == '1' then 3808 // LoadWritePC(MemA[address,4]); 3809 if (BitIsSet (registers, 15)) 3810 { 3811 context.SetRegisterPlusOffset (dwarf_reg, offset); 3812 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3813 if (!success) 3814 return false; 3815 // In ARMv5T and above, this is an interworking branch. 3816 if (!LoadWritePC(context, data)) 3817 return false; 3818 } 3819 3820 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3821 if (wback && BitIsClear (registers, n)) 3822 { 3823 if (!success) 3824 return false; 3825 3826 offset = addr_byte_size * BitCount (registers); 3827 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3828 context.SetImmediateSigned (offset); 3829 addr_t addr = Rn + offset; 3830 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3831 return false; 3832 } 3833 3834 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3835 if (wback && BitIsSet (registers, n)) 3836 return WriteBits32Unknown (n); 3837 } 3838 return true; 3839 } 3840 3841 // Load Register (immediate) calculates an address from a base register value and 3842 // an immediate offset, loads a word from memory, and writes to a register. 3843 // LDR (immediate, Thumb) 3844 bool 3845 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3846 { 3847 #if 0 3848 // ARM pseudo code... 3849 if (ConditionPassed()) 3850 { 3851 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3852 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3853 address = if index then offset_addr else R[n]; 3854 data = MemU[address,4]; 3855 if wback then R[n] = offset_addr; 3856 if t == 15 then 3857 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3858 elsif UnalignedSupport() || address<1:0> = '00' then 3859 R[t] = data; 3860 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3861 } 3862 #endif 3863 3864 bool success = false; 3865 3866 if (ConditionPassed(opcode)) 3867 { 3868 uint32_t Rt; // the destination register 3869 uint32_t Rn; // the base register 3870 uint32_t imm32; // the immediate offset used to form the address 3871 addr_t offset_addr; // the offset address 3872 addr_t address; // the calculated address 3873 uint32_t data; // the literal data value from memory load 3874 bool add, index, wback; 3875 switch (encoding) { 3876 case eEncodingT1: 3877 Rt = Bits32(opcode, 2, 0); 3878 Rn = Bits32(opcode, 5, 3); 3879 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3880 // index = TRUE; add = TRUE; wback = FALSE 3881 add = true; 3882 index = true; 3883 wback = false; 3884 3885 break; 3886 3887 case eEncodingT2: 3888 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3889 Rt = Bits32 (opcode, 10, 8); 3890 Rn = 13; 3891 imm32 = Bits32 (opcode, 7, 0) << 2; 3892 3893 // index = TRUE; add = TRUE; wback = FALSE; 3894 index = true; 3895 add = true; 3896 wback = false; 3897 3898 break; 3899 3900 case eEncodingT3: 3901 // if Rn == '1111' then SEE LDR (literal); 3902 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3903 Rt = Bits32 (opcode, 15, 12); 3904 Rn = Bits32 (opcode, 19, 16); 3905 imm32 = Bits32 (opcode, 11, 0); 3906 3907 // index = TRUE; add = TRUE; wback = FALSE; 3908 index = true; 3909 add = true; 3910 wback = false; 3911 3912 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3913 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3914 return false; 3915 3916 break; 3917 3918 case eEncodingT4: 3919 // if Rn == '1111' then SEE LDR (literal); 3920 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3921 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3922 // if P == '0' && W == '0' then UNDEFINED; 3923 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3924 return false; 3925 3926 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3927 Rt = Bits32 (opcode, 15, 12); 3928 Rn = Bits32 (opcode, 19, 16); 3929 imm32 = Bits32 (opcode, 7, 0); 3930 3931 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3932 index = BitIsSet (opcode, 10); 3933 add = BitIsSet (opcode, 9); 3934 wback = BitIsSet (opcode, 8); 3935 3936 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3937 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3938 return false; 3939 3940 break; 3941 3942 default: 3943 return false; 3944 } 3945 uint32_t base = ReadCoreReg (Rn, &success); 3946 if (!success) 3947 return false; 3948 if (add) 3949 offset_addr = base + imm32; 3950 else 3951 offset_addr = base - imm32; 3952 3953 address = (index ? offset_addr : base); 3954 3955 RegisterInfo base_reg; 3956 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 3957 if (wback) 3958 { 3959 EmulateInstruction::Context ctx; 3960 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 3961 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3962 3963 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3964 return false; 3965 } 3966 3967 // Prepare to write to the Rt register. 3968 EmulateInstruction::Context context; 3969 context.type = EmulateInstruction::eContextRegisterLoad; 3970 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3971 3972 // Read memory from the address. 3973 data = MemURead(context, address, 4, 0, &success); 3974 if (!success) 3975 return false; 3976 3977 if (Rt == 15) 3978 { 3979 if (Bits32(address, 1, 0) == 0) 3980 { 3981 if (!LoadWritePC(context, data)) 3982 return false; 3983 } 3984 else 3985 return false; 3986 } 3987 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3988 { 3989 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3990 return false; 3991 } 3992 else 3993 WriteBits32Unknown (Rt); 3994 } 3995 return true; 3996 } 3997 3998 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 3999 // from a base register. The consecutive memory locations start at this address, and teh address just above the last 4000 // of those locations can optionally be written back to the base register. 4001 bool 4002 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 4003 { 4004 #if 0 4005 if ConditionPassed() then 4006 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4007 address = R[n]; 4008 4009 for i = 0 to 14 4010 if registers<i> == '1' then 4011 if i == n && wback && i != LowestSetBit(registers) then 4012 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4013 else 4014 MemA[address,4] = R[i]; 4015 address = address + 4; 4016 4017 if registers<15> == '1' then // Only possible for encoding A1 4018 MemA[address,4] = PCStoreValue(); 4019 if wback then R[n] = R[n] + 4*BitCount(registers); 4020 #endif 4021 4022 bool success = false; 4023 4024 if (ConditionPassed(opcode)) 4025 { 4026 uint32_t n; 4027 uint32_t registers = 0; 4028 bool wback; 4029 const uint32_t addr_byte_size = GetAddressByteSize(); 4030 4031 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4032 switch (encoding) 4033 { 4034 case eEncodingT1: 4035 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4036 n = Bits32 (opcode, 10, 8); 4037 registers = Bits32 (opcode, 7, 0); 4038 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4039 wback = true; 4040 4041 // if BitCount(registers) < 1 then UNPREDICTABLE; 4042 if (BitCount (registers) < 1) 4043 return false; 4044 4045 break; 4046 4047 case eEncodingT2: 4048 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4049 n = Bits32 (opcode, 19, 16); 4050 registers = Bits32 (opcode, 15, 0); 4051 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4052 wback = BitIsSet (opcode, 21); 4053 4054 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4055 if ((n == 15) || (BitCount (registers) < 2)) 4056 return false; 4057 4058 // if wback && registers<n> == '1' then UNPREDICTABLE; 4059 if (wback && BitIsSet (registers, n)) 4060 return false; 4061 4062 break; 4063 4064 case eEncodingA1: 4065 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4066 n = Bits32 (opcode, 19, 16); 4067 registers = Bits32 (opcode, 15, 0); 4068 wback = BitIsSet (opcode, 21); 4069 4070 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4071 if ((n == 15) || (BitCount (registers) < 1)) 4072 return false; 4073 4074 break; 4075 4076 default: 4077 return false; 4078 } 4079 4080 // address = R[n]; 4081 int32_t offset = 0; 4082 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4083 if (!success) 4084 return false; 4085 4086 EmulateInstruction::Context context; 4087 context.type = EmulateInstruction::eContextRegisterStore; 4088 RegisterInfo base_reg; 4089 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4090 4091 // for i = 0 to 14 4092 int lowest_set_bit = 14; 4093 for (int i = 0; i < 14; ++i) 4094 { 4095 // if registers<i> == '1' then 4096 if (BitIsSet (registers, i)) 4097 { 4098 if (i < lowest_set_bit) 4099 lowest_set_bit = i; 4100 // if i == n && wback && i != LowestSetBit(registers) then 4101 if ((i == n) && wback && (i != lowest_set_bit)) 4102 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4103 WriteBits32UnknownToMemory (address + offset); 4104 else 4105 { 4106 // MemA[address,4] = R[i]; 4107 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4108 if (!success) 4109 return false; 4110 4111 RegisterInfo data_reg; 4112 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4113 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4114 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4115 return false; 4116 } 4117 4118 // address = address + 4; 4119 offset += addr_byte_size; 4120 } 4121 } 4122 4123 // if registers<15> == '1' then // Only possible for encoding A1 4124 // MemA[address,4] = PCStoreValue(); 4125 if (BitIsSet (registers, 15)) 4126 { 4127 RegisterInfo pc_reg; 4128 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4129 context.SetRegisterPlusOffset (pc_reg, 8); 4130 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4131 if (!success) 4132 return false; 4133 4134 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4135 return false; 4136 } 4137 4138 // if wback then R[n] = R[n] + 4*BitCount(registers); 4139 if (wback) 4140 { 4141 offset = addr_byte_size * BitCount (registers); 4142 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4143 context.SetImmediateSigned (offset); 4144 addr_t data = address + offset; 4145 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4146 return false; 4147 } 4148 } 4149 return true; 4150 } 4151 4152 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4153 // from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4154 // of those locations can optionally be written back to the base register. 4155 bool 4156 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4157 { 4158 #if 0 4159 if ConditionPassed() then 4160 EncodingSpecificOperations(); 4161 address = R[n] - 4*BitCount(registers) + 4; 4162 4163 for i = 0 to 14 4164 if registers<i> == '1' then 4165 if i == n && wback && i != LowestSetBit(registers) then 4166 MemA[address,4] = bits(32) UNKNOWN; 4167 else 4168 MemA[address,4] = R[i]; 4169 address = address + 4; 4170 4171 if registers<15> == '1' then 4172 MemA[address,4] = PCStoreValue(); 4173 4174 if wback then R[n] = R[n] - 4*BitCount(registers); 4175 #endif 4176 4177 bool success = false; 4178 4179 if (ConditionPassed(opcode)) 4180 { 4181 uint32_t n; 4182 uint32_t registers = 0; 4183 bool wback; 4184 const uint32_t addr_byte_size = GetAddressByteSize(); 4185 4186 // EncodingSpecificOperations(); 4187 switch (encoding) 4188 { 4189 case eEncodingA1: 4190 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4191 n = Bits32 (opcode, 19, 16); 4192 registers = Bits32 (opcode, 15, 0); 4193 wback = BitIsSet (opcode, 21); 4194 4195 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4196 if ((n == 15) || (BitCount (registers) < 1)) 4197 return false; 4198 break; 4199 default: 4200 return false; 4201 } 4202 4203 // address = R[n] - 4*BitCount(registers) + 4; 4204 int32_t offset = 0; 4205 addr_t Rn = ReadCoreReg (n, &success); 4206 if (!success) 4207 return false; 4208 4209 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4210 4211 EmulateInstruction::Context context; 4212 context.type = EmulateInstruction::eContextRegisterStore; 4213 RegisterInfo base_reg; 4214 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4215 4216 // for i = 0 to 14 4217 int lowest_bit_set = 14; 4218 for (int i = 0; i < 14; ++i) 4219 { 4220 // if registers<i> == '1' then 4221 if (BitIsSet (registers, i)) 4222 { 4223 if (i < lowest_bit_set) 4224 lowest_bit_set = i; 4225 //if i == n && wback && i != LowestSetBit(registers) then 4226 if ((i == n) && wback && (i != lowest_bit_set)) 4227 // MemA[address,4] = bits(32) UNKNOWN; 4228 WriteBits32UnknownToMemory (address + offset); 4229 else 4230 { 4231 // MemA[address,4] = R[i]; 4232 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4233 if (!success) 4234 return false; 4235 4236 RegisterInfo data_reg; 4237 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4238 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4239 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4240 return false; 4241 } 4242 4243 // address = address + 4; 4244 offset += addr_byte_size; 4245 } 4246 } 4247 4248 // if registers<15> == '1' then 4249 // MemA[address,4] = PCStoreValue(); 4250 if (BitIsSet (registers, 15)) 4251 { 4252 RegisterInfo pc_reg; 4253 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4254 context.SetRegisterPlusOffset (pc_reg, 8); 4255 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4256 if (!success) 4257 return false; 4258 4259 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4260 return false; 4261 } 4262 4263 // if wback then R[n] = R[n] - 4*BitCount(registers); 4264 if (wback) 4265 { 4266 offset = (addr_byte_size * BitCount (registers)) * -1; 4267 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4268 context.SetImmediateSigned (offset); 4269 addr_t data = Rn + offset; 4270 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4271 return false; 4272 } 4273 } 4274 return true; 4275 } 4276 4277 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4278 // from a base register. The consecutive memory locations end just below this address, and the address of the first of 4279 // those locations can optionally be written back to the base register. 4280 bool 4281 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4282 { 4283 #if 0 4284 if ConditionPassed() then 4285 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4286 address = R[n] - 4*BitCount(registers); 4287 4288 for i = 0 to 14 4289 if registers<i> == '1' then 4290 if i == n && wback && i != LowestSetBit(registers) then 4291 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4292 else 4293 MemA[address,4] = R[i]; 4294 address = address + 4; 4295 4296 if registers<15> == '1' then // Only possible for encoding A1 4297 MemA[address,4] = PCStoreValue(); 4298 4299 if wback then R[n] = R[n] - 4*BitCount(registers); 4300 #endif 4301 4302 4303 bool success = false; 4304 4305 if (ConditionPassed(opcode)) 4306 { 4307 uint32_t n; 4308 uint32_t registers = 0; 4309 bool wback; 4310 const uint32_t addr_byte_size = GetAddressByteSize(); 4311 4312 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4313 switch (encoding) 4314 { 4315 case eEncodingT1: 4316 // if W == '1' && Rn == '1101' then SEE PUSH; 4317 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4318 { 4319 // See PUSH 4320 } 4321 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4322 n = Bits32 (opcode, 19, 16); 4323 registers = Bits32 (opcode, 15, 0); 4324 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4325 wback = BitIsSet (opcode, 21); 4326 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4327 if ((n == 15) || BitCount (registers) < 2) 4328 return false; 4329 // if wback && registers<n> == '1' then UNPREDICTABLE; 4330 if (wback && BitIsSet (registers, n)) 4331 return false; 4332 break; 4333 4334 case eEncodingA1: 4335 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH; 4336 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4337 { 4338 // See Push 4339 } 4340 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4341 n = Bits32 (opcode, 19, 16); 4342 registers = Bits32 (opcode, 15, 0); 4343 wback = BitIsSet (opcode, 21); 4344 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4345 if ((n == 15) || BitCount (registers) < 1) 4346 return false; 4347 break; 4348 4349 default: 4350 return false; 4351 } 4352 4353 // address = R[n] - 4*BitCount(registers); 4354 4355 int32_t offset = 0; 4356 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4357 if (!success) 4358 return false; 4359 4360 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4361 4362 EmulateInstruction::Context context; 4363 context.type = EmulateInstruction::eContextRegisterStore; 4364 RegisterInfo base_reg; 4365 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4366 4367 // for i = 0 to 14 4368 uint32_t lowest_set_bit = 14; 4369 for (int i = 0; i < 14; ++i) 4370 { 4371 // if registers<i> == '1' then 4372 if (BitIsSet (registers, i)) 4373 { 4374 if (i < lowest_set_bit) 4375 lowest_set_bit = i; 4376 // if i == n && wback && i != LowestSetBit(registers) then 4377 if ((i == n) && wback && (i != lowest_set_bit)) 4378 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4379 WriteBits32UnknownToMemory (address + offset); 4380 else 4381 { 4382 // MemA[address,4] = R[i]; 4383 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4384 if (!success) 4385 return false; 4386 4387 RegisterInfo data_reg; 4388 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4389 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4390 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4391 return false; 4392 } 4393 4394 // address = address + 4; 4395 offset += addr_byte_size; 4396 } 4397 } 4398 4399 // if registers<15> == '1' then // Only possible for encoding A1 4400 // MemA[address,4] = PCStoreValue(); 4401 if (BitIsSet (registers, 15)) 4402 { 4403 RegisterInfo pc_reg; 4404 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4405 context.SetRegisterPlusOffset (pc_reg, 8); 4406 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4407 if (!success) 4408 return false; 4409 4410 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4411 return false; 4412 } 4413 4414 // if wback then R[n] = R[n] - 4*BitCount(registers); 4415 if (wback) 4416 { 4417 offset = (addr_byte_size * BitCount (registers)) * -1; 4418 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4419 context.SetImmediateSigned (offset); 4420 addr_t data = Rn + offset; 4421 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4422 return false; 4423 } 4424 } 4425 return true; 4426 } 4427 4428 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4429 // from a base register. The consecutive memory locations start just above this address, and the address of the last 4430 // of those locations can optionally be written back to the base register. 4431 bool 4432 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4433 { 4434 #if 0 4435 if ConditionPassed() then 4436 EncodingSpecificOperations(); 4437 address = R[n] + 4; 4438 4439 for i = 0 to 14 4440 if registers<i> == '1' then 4441 if i == n && wback && i != LowestSetBit(registers) then 4442 MemA[address,4] = bits(32) UNKNOWN; 4443 else 4444 MemA[address,4] = R[i]; 4445 address = address + 4; 4446 4447 if registers<15> == '1' then 4448 MemA[address,4] = PCStoreValue(); 4449 4450 if wback then R[n] = R[n] + 4*BitCount(registers); 4451 #endif 4452 4453 bool success = false; 4454 4455 if (ConditionPassed(opcode)) 4456 { 4457 uint32_t n; 4458 uint32_t registers = 0; 4459 bool wback; 4460 const uint32_t addr_byte_size = GetAddressByteSize(); 4461 4462 // EncodingSpecificOperations(); 4463 switch (encoding) 4464 { 4465 case eEncodingA1: 4466 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4467 n = Bits32 (opcode, 19, 16); 4468 registers = Bits32 (opcode, 15, 0); 4469 wback = BitIsSet (opcode, 21); 4470 4471 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4472 if ((n == 15) && (BitCount (registers) < 1)) 4473 return false; 4474 break; 4475 default: 4476 return false; 4477 } 4478 // address = R[n] + 4; 4479 4480 int32_t offset = 0; 4481 addr_t Rn = ReadCoreReg (n, &success); 4482 if (!success) 4483 return false; 4484 4485 addr_t address = Rn + addr_byte_size; 4486 4487 EmulateInstruction::Context context; 4488 context.type = EmulateInstruction::eContextRegisterStore; 4489 RegisterInfo base_reg; 4490 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4491 4492 uint32_t lowest_set_bit = 14; 4493 // for i = 0 to 14 4494 for (int i = 0; i < 14; ++i) 4495 { 4496 // if registers<i> == '1' then 4497 if (BitIsSet (registers, i)) 4498 { 4499 if (i < lowest_set_bit) 4500 lowest_set_bit = i; 4501 // if i == n && wback && i != LowestSetBit(registers) then 4502 if ((i == n) && wback && (i != lowest_set_bit)) 4503 // MemA[address,4] = bits(32) UNKNOWN; 4504 WriteBits32UnknownToMemory (address + offset); 4505 // else 4506 else 4507 { 4508 // MemA[address,4] = R[i]; 4509 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4510 if (!success) 4511 return false; 4512 4513 RegisterInfo data_reg; 4514 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4515 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4516 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4517 return false; 4518 } 4519 4520 // address = address + 4; 4521 offset += addr_byte_size; 4522 } 4523 } 4524 4525 // if registers<15> == '1' then 4526 // MemA[address,4] = PCStoreValue(); 4527 if (BitIsSet (registers, 15)) 4528 { 4529 RegisterInfo pc_reg; 4530 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4531 context.SetRegisterPlusOffset (pc_reg, 8); 4532 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4533 if (!success) 4534 return false; 4535 4536 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4537 return false; 4538 } 4539 4540 // if wback then R[n] = R[n] + 4*BitCount(registers); 4541 if (wback) 4542 { 4543 offset = addr_byte_size * BitCount (registers); 4544 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4545 context.SetImmediateSigned (offset); 4546 addr_t data = Rn + offset; 4547 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4548 return false; 4549 } 4550 } 4551 return true; 4552 } 4553 4554 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 4555 // from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4556 bool 4557 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4558 { 4559 #if 0 4560 if ConditionPassed() then 4561 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4562 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4563 address = if index then offset_addr else R[n]; 4564 if UnalignedSupport() || address<1:0> == '00' then 4565 MemU[address,4] = R[t]; 4566 else // Can only occur before ARMv7 4567 MemU[address,4] = bits(32) UNKNOWN; 4568 if wback then R[n] = offset_addr; 4569 #endif 4570 4571 bool success = false; 4572 4573 if (ConditionPassed(opcode)) 4574 { 4575 const uint32_t addr_byte_size = GetAddressByteSize(); 4576 4577 uint32_t t; 4578 uint32_t n; 4579 uint32_t imm32; 4580 bool index; 4581 bool add; 4582 bool wback; 4583 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4584 switch (encoding) 4585 { 4586 case eEncodingT1: 4587 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4588 t = Bits32 (opcode, 2, 0); 4589 n = Bits32 (opcode, 5, 3); 4590 imm32 = Bits32 (opcode, 10, 6) << 2; 4591 4592 // index = TRUE; add = TRUE; wback = FALSE; 4593 index = true; 4594 add = false; 4595 wback = false; 4596 break; 4597 4598 case eEncodingT2: 4599 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4600 t = Bits32 (opcode, 10, 8); 4601 n = 13; 4602 imm32 = Bits32 (opcode, 7, 0) << 2; 4603 4604 // index = TRUE; add = TRUE; wback = FALSE; 4605 index = true; 4606 add = true; 4607 wback = false; 4608 break; 4609 4610 case eEncodingT3: 4611 // if Rn == '1111' then UNDEFINED; 4612 if (Bits32 (opcode, 19, 16) == 15) 4613 return false; 4614 4615 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4616 t = Bits32 (opcode, 15, 12); 4617 n = Bits32 (opcode, 19, 16); 4618 imm32 = Bits32 (opcode, 11, 0); 4619 4620 // index = TRUE; add = TRUE; wback = FALSE; 4621 index = true; 4622 add = true; 4623 wback = false; 4624 4625 // if t == 15 then UNPREDICTABLE; 4626 if (t == 15) 4627 return false; 4628 break; 4629 4630 case eEncodingT4: 4631 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4632 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4633 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4634 if ((Bits32 (opcode, 19, 16) == 15) 4635 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4636 return false; 4637 4638 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4639 t = Bits32 (opcode, 15, 12); 4640 n = Bits32 (opcode, 19, 16); 4641 imm32 = Bits32 (opcode, 7, 0); 4642 4643 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4644 index = BitIsSet (opcode, 10); 4645 add = BitIsSet (opcode, 9); 4646 wback = BitIsSet (opcode, 8); 4647 4648 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4649 if ((t == 15) || (wback && (n == t))) 4650 return false; 4651 break; 4652 4653 default: 4654 return false; 4655 } 4656 4657 addr_t offset_addr; 4658 addr_t address; 4659 4660 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4661 uint32_t base_address = ReadCoreReg (n, &success); 4662 if (!success) 4663 return false; 4664 4665 if (add) 4666 offset_addr = base_address + imm32; 4667 else 4668 offset_addr = base_address - imm32; 4669 4670 // address = if index then offset_addr else R[n]; 4671 if (index) 4672 address = offset_addr; 4673 else 4674 address = base_address; 4675 4676 EmulateInstruction::Context context; 4677 context.type = eContextRegisterStore; 4678 RegisterInfo base_reg; 4679 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4680 4681 // if UnalignedSupport() || address<1:0> == '00' then 4682 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4683 { 4684 // MemU[address,4] = R[t]; 4685 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4686 if (!success) 4687 return false; 4688 4689 RegisterInfo data_reg; 4690 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4691 int32_t offset = address - base_address; 4692 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4693 if (!MemUWrite (context, address, data, addr_byte_size)) 4694 return false; 4695 } 4696 else 4697 { 4698 // MemU[address,4] = bits(32) UNKNOWN; 4699 WriteBits32UnknownToMemory (address); 4700 } 4701 4702 // if wback then R[n] = offset_addr; 4703 if (wback) 4704 { 4705 context.type = eContextRegisterLoad; 4706 context.SetAddress (offset_addr); 4707 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4708 return false; 4709 } 4710 } 4711 return true; 4712 } 4713 4714 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4715 // word from a register to memory. The offset register value can optionally be shifted. 4716 bool 4717 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4718 { 4719 #if 0 4720 if ConditionPassed() then 4721 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4722 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4723 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4724 address = if index then offset_addr else R[n]; 4725 if t == 15 then // Only possible for encoding A1 4726 data = PCStoreValue(); 4727 else 4728 data = R[t]; 4729 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4730 MemU[address,4] = data; 4731 else // Can only occur before ARMv7 4732 MemU[address,4] = bits(32) UNKNOWN; 4733 if wback then R[n] = offset_addr; 4734 #endif 4735 4736 bool success = false; 4737 4738 if (ConditionPassed(opcode)) 4739 { 4740 const uint32_t addr_byte_size = GetAddressByteSize(); 4741 4742 uint32_t t; 4743 uint32_t n; 4744 uint32_t m; 4745 ARM_ShifterType shift_t; 4746 uint32_t shift_n; 4747 bool index; 4748 bool add; 4749 bool wback; 4750 4751 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4752 switch (encoding) 4753 { 4754 case eEncodingT1: 4755 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4756 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4757 t = Bits32 (opcode, 2, 0); 4758 n = Bits32 (opcode, 5, 3); 4759 m = Bits32 (opcode, 8, 6); 4760 4761 // index = TRUE; add = TRUE; wback = FALSE; 4762 index = true; 4763 add = true; 4764 wback = false; 4765 4766 // (shift_t, shift_n) = (SRType_LSL, 0); 4767 shift_t = SRType_LSL; 4768 shift_n = 0; 4769 break; 4770 4771 case eEncodingT2: 4772 // if Rn == '1111' then UNDEFINED; 4773 if (Bits32 (opcode, 19, 16) == 15) 4774 return false; 4775 4776 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4777 t = Bits32 (opcode, 15, 12); 4778 n = Bits32 (opcode, 19, 16); 4779 m = Bits32 (opcode, 3, 0); 4780 4781 // index = TRUE; add = TRUE; wback = FALSE; 4782 index = true; 4783 add = true; 4784 wback = false; 4785 4786 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4787 shift_t = SRType_LSL; 4788 shift_n = Bits32 (opcode, 5, 4); 4789 4790 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4791 if ((t == 15) || (BadReg (m))) 4792 return false; 4793 break; 4794 4795 case eEncodingA1: 4796 { 4797 // if P == '0' && W == '1' then SEE STRT; 4798 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4799 t = Bits32 (opcode, 15, 12); 4800 n = Bits32 (opcode, 19, 16); 4801 m = Bits32 (opcode, 3, 0); 4802 4803 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4804 index = BitIsSet (opcode, 24); 4805 add = BitIsSet (opcode, 23); 4806 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4807 4808 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4809 uint32_t typ = Bits32 (opcode, 6, 5); 4810 uint32_t imm5 = Bits32 (opcode, 11, 7); 4811 shift_n = DecodeImmShift(typ, imm5, shift_t); 4812 4813 // if m == 15 then UNPREDICTABLE; 4814 if (m == 15) 4815 return false; 4816 4817 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4818 if (wback && ((n == 15) || (n == t))) 4819 return false; 4820 4821 break; 4822 } 4823 default: 4824 return false; 4825 } 4826 4827 addr_t offset_addr; 4828 addr_t address; 4829 int32_t offset = 0; 4830 4831 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4832 if (!success) 4833 return false; 4834 4835 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4836 if (!success) 4837 return false; 4838 4839 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4840 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4841 if (!success) 4842 return false; 4843 4844 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4845 if (add) 4846 offset_addr = base_address + offset; 4847 else 4848 offset_addr = base_address - offset; 4849 4850 // address = if index then offset_addr else R[n]; 4851 if (index) 4852 address = offset_addr; 4853 else 4854 address = base_address; 4855 4856 uint32_t data; 4857 // if t == 15 then // Only possible for encoding A1 4858 if (t == 15) 4859 // data = PCStoreValue(); 4860 data = ReadCoreReg (PC_REG, &success); 4861 else 4862 // data = R[t]; 4863 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4864 4865 if (!success) 4866 return false; 4867 4868 EmulateInstruction::Context context; 4869 context.type = eContextRegisterStore; 4870 4871 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4872 if (UnalignedSupport () 4873 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4874 || CurrentInstrSet() == eModeARM) 4875 { 4876 // MemU[address,4] = data; 4877 4878 RegisterInfo base_reg; 4879 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4880 4881 RegisterInfo data_reg; 4882 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4883 4884 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4885 if (!MemUWrite (context, address, data, addr_byte_size)) 4886 return false; 4887 4888 } 4889 else 4890 // MemU[address,4] = bits(32) UNKNOWN; 4891 WriteBits32UnknownToMemory (address); 4892 4893 // if wback then R[n] = offset_addr; 4894 if (wback) 4895 { 4896 context.type = eContextRegisterLoad; 4897 context.SetAddress (offset_addr); 4898 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4899 return false; 4900 } 4901 4902 } 4903 return true; 4904 } 4905 4906 bool 4907 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 4908 { 4909 #if 0 4910 if ConditionPassed() then 4911 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4912 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4913 address = if index then offset_addr else R[n]; 4914 MemU[address,1] = R[t]<7:0>; 4915 if wback then R[n] = offset_addr; 4916 #endif 4917 4918 4919 bool success = false; 4920 4921 if (ConditionPassed(opcode)) 4922 { 4923 uint32_t t; 4924 uint32_t n; 4925 uint32_t imm32; 4926 bool index; 4927 bool add; 4928 bool wback; 4929 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4930 switch (encoding) 4931 { 4932 case eEncodingT1: 4933 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4934 t = Bits32 (opcode, 2, 0); 4935 n = Bits32 (opcode, 5, 3); 4936 imm32 = Bits32 (opcode, 10, 6); 4937 4938 // index = TRUE; add = TRUE; wback = FALSE; 4939 index = true; 4940 add = true; 4941 wback = false; 4942 break; 4943 4944 case eEncodingT2: 4945 // if Rn == '1111' then UNDEFINED; 4946 if (Bits32 (opcode, 19, 16) == 15) 4947 return false; 4948 4949 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4950 t = Bits32 (opcode, 15, 12); 4951 n = Bits32 (opcode, 19, 16); 4952 imm32 = Bits32 (opcode, 11, 0); 4953 4954 // index = TRUE; add = TRUE; wback = FALSE; 4955 index = true; 4956 add = true; 4957 wback = false; 4958 4959 // if BadReg(t) then UNPREDICTABLE; 4960 if (BadReg (t)) 4961 return false; 4962 break; 4963 4964 case eEncodingT3: 4965 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 4966 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4967 if (Bits32 (opcode, 19, 16) == 15) 4968 return false; 4969 4970 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4971 t = Bits32 (opcode, 15, 12); 4972 n = Bits32 (opcode, 19, 16); 4973 imm32 = Bits32 (opcode, 7, 0); 4974 4975 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4976 index = BitIsSet (opcode, 10); 4977 add = BitIsSet (opcode, 9); 4978 wback = BitIsSet (opcode, 8); 4979 4980 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 4981 if ((BadReg (t)) || (wback && (n == t))) 4982 return false; 4983 break; 4984 4985 default: 4986 return false; 4987 } 4988 4989 addr_t offset_addr; 4990 addr_t address; 4991 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4992 if (!success) 4993 return false; 4994 4995 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4996 if (add) 4997 offset_addr = base_address + imm32; 4998 else 4999 offset_addr = base_address - imm32; 5000 5001 // address = if index then offset_addr else R[n]; 5002 if (index) 5003 address = offset_addr; 5004 else 5005 address = base_address; 5006 5007 // MemU[address,1] = R[t]<7:0> 5008 RegisterInfo base_reg; 5009 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5010 5011 RegisterInfo data_reg; 5012 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5013 5014 EmulateInstruction::Context context; 5015 context.type = eContextRegisterStore; 5016 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5017 5018 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5019 if (!success) 5020 return false; 5021 5022 data = Bits32 (data, 7, 0); 5023 5024 if (!MemUWrite (context, address, data, 1)) 5025 return false; 5026 5027 // if wback then R[n] = offset_addr; 5028 if (wback) 5029 { 5030 context.type = eContextRegisterLoad; 5031 context.SetAddress (offset_addr); 5032 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5033 return false; 5034 } 5035 5036 } 5037 5038 return true; 5039 } 5040 5041 // STRH (register) calculates an address from a base register value and an offset register value, and stores a 5042 // halfword from a register to memory. The offset register alue can be shifted left by 0, 1, 2, or 3 bits. 5043 bool 5044 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5045 { 5046 #if 0 5047 if ConditionPassed() then 5048 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5049 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5050 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5051 address = if index then offset_addr else R[n]; 5052 if UnalignedSupport() || address<0> == '0' then 5053 MemU[address,2] = R[t]<15:0>; 5054 else // Can only occur before ARMv7 5055 MemU[address,2] = bits(16) UNKNOWN; 5056 if wback then R[n] = offset_addr; 5057 #endif 5058 5059 bool success = false; 5060 5061 if (ConditionPassed(opcode)) 5062 { 5063 uint32_t t; 5064 uint32_t n; 5065 uint32_t m; 5066 bool index; 5067 bool add; 5068 bool wback; 5069 ARM_ShifterType shift_t; 5070 uint32_t shift_n; 5071 5072 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5073 switch (encoding) 5074 { 5075 case eEncodingT1: 5076 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5077 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5078 t = Bits32 (opcode, 2, 0); 5079 n = Bits32 (opcode, 5, 3); 5080 m = Bits32 (opcode, 8, 6); 5081 5082 // index = TRUE; add = TRUE; wback = FALSE; 5083 index = true; 5084 add = true; 5085 wback = false; 5086 5087 // (shift_t, shift_n) = (SRType_LSL, 0); 5088 shift_t = SRType_LSL; 5089 shift_n = 0; 5090 5091 break; 5092 5093 case eEncodingT2: 5094 // if Rn == '1111' then UNDEFINED; 5095 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5096 t = Bits32 (opcode, 15, 12); 5097 n = Bits32 (opcode, 19, 16); 5098 m = Bits32 (opcode, 3, 0); 5099 if (n == 15) 5100 return false; 5101 5102 // index = TRUE; add = TRUE; wback = FALSE; 5103 index = true; 5104 add = true; 5105 wback = false; 5106 5107 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5108 shift_t = SRType_LSL; 5109 shift_n = Bits32 (opcode, 5, 4); 5110 5111 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5112 if (BadReg (t) || BadReg (m)) 5113 return false; 5114 5115 break; 5116 5117 case eEncodingA1: 5118 // if P == '0' && W == '1' then SEE STRHT; 5119 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5120 t = Bits32 (opcode, 15, 12); 5121 n = Bits32 (opcode, 19, 16); 5122 m = Bits32 (opcode, 3, 0); 5123 5124 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5125 index = BitIsSet (opcode, 24); 5126 add = BitIsSet (opcode, 23); 5127 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5128 5129 // (shift_t, shift_n) = (SRType_LSL, 0); 5130 shift_t = SRType_LSL; 5131 shift_n = 0; 5132 5133 // if t == 15 || m == 15 then UNPREDICTABLE; 5134 if ((t == 15) || (m == 15)) 5135 return false; 5136 5137 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5138 if (wback && ((n == 15) || (n == t))) 5139 return false; 5140 5141 break; 5142 5143 default: 5144 return false; 5145 } 5146 5147 uint32_t Rm = ReadCoreReg (m, &success); 5148 if (!success) 5149 return false; 5150 5151 uint32_t Rn = ReadCoreReg (n, &success); 5152 if (!success) 5153 return false; 5154 5155 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5156 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5157 if (!success) 5158 return false; 5159 5160 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5161 addr_t offset_addr; 5162 if (add) 5163 offset_addr = Rn + offset; 5164 else 5165 offset_addr = Rn - offset; 5166 5167 // address = if index then offset_addr else R[n]; 5168 addr_t address; 5169 if (index) 5170 address = offset_addr; 5171 else 5172 address = Rn; 5173 5174 EmulateInstruction::Context context; 5175 context.type = eContextRegisterStore; 5176 RegisterInfo base_reg; 5177 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5178 RegisterInfo offset_reg; 5179 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5180 5181 // if UnalignedSupport() || address<0> == '0' then 5182 if (UnalignedSupport() || BitIsClear (address, 0)) 5183 { 5184 // MemU[address,2] = R[t]<15:0>; 5185 uint32_t Rt = ReadCoreReg (t, &success); 5186 if (!success) 5187 return false; 5188 5189 EmulateInstruction::Context context; 5190 context.type = eContextRegisterStore; 5191 RegisterInfo base_reg; 5192 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5193 RegisterInfo offset_reg; 5194 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5195 RegisterInfo data_reg; 5196 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5197 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5198 5199 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5200 return false; 5201 } 5202 else // Can only occur before ARMv7 5203 { 5204 // MemU[address,2] = bits(16) UNKNOWN; 5205 } 5206 5207 // if wback then R[n] = offset_addr; 5208 if (wback) 5209 { 5210 context.type = eContextAdjustBaseRegister; 5211 context.SetAddress (offset_addr); 5212 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5213 return false; 5214 } 5215 } 5216 5217 return true; 5218 } 5219 5220 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5221 // and writes the result to the destination register. It can optionally update the condition flags 5222 // based on the result. 5223 bool 5224 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5225 { 5226 #if 0 5227 // ARM pseudo code... 5228 if ConditionPassed() then 5229 EncodingSpecificOperations(); 5230 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5231 if d == 15 then // Can only occur for ARM encoding 5232 ALUWritePC(result); // setflags is always FALSE here 5233 else 5234 R[d] = result; 5235 if setflags then 5236 APSR.N = result<31>; 5237 APSR.Z = IsZeroBit(result); 5238 APSR.C = carry; 5239 APSR.V = overflow; 5240 #endif 5241 5242 bool success = false; 5243 5244 if (ConditionPassed(opcode)) 5245 { 5246 uint32_t Rd, Rn; 5247 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5248 bool setflags; 5249 switch (encoding) 5250 { 5251 case eEncodingT1: 5252 Rd = Bits32(opcode, 11, 8); 5253 Rn = Bits32(opcode, 19, 16); 5254 setflags = BitIsSet(opcode, 20); 5255 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5256 if (BadReg(Rd) || BadReg(Rn)) 5257 return false; 5258 break; 5259 case eEncodingA1: 5260 Rd = Bits32(opcode, 15, 12); 5261 Rn = Bits32(opcode, 19, 16); 5262 setflags = BitIsSet(opcode, 20); 5263 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5264 5265 if (Rd == 15 && setflags) 5266 return EmulateSUBSPcLrEtc (opcode, encoding); 5267 break; 5268 default: 5269 return false; 5270 } 5271 5272 // Read the first operand. 5273 int32_t val1 = ReadCoreReg(Rn, &success); 5274 if (!success) 5275 return false; 5276 5277 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5278 5279 EmulateInstruction::Context context; 5280 context.type = EmulateInstruction::eContextImmediate; 5281 context.SetNoArgs (); 5282 5283 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5284 return false; 5285 } 5286 return true; 5287 } 5288 5289 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5290 // register value, and writes the result to the destination register. It can optionally update the 5291 // condition flags based on the result. 5292 bool 5293 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5294 { 5295 #if 0 5296 // ARM pseudo code... 5297 if ConditionPassed() then 5298 EncodingSpecificOperations(); 5299 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5300 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5301 if d == 15 then // Can only occur for ARM encoding 5302 ALUWritePC(result); // setflags is always FALSE here 5303 else 5304 R[d] = result; 5305 if setflags then 5306 APSR.N = result<31>; 5307 APSR.Z = IsZeroBit(result); 5308 APSR.C = carry; 5309 APSR.V = overflow; 5310 #endif 5311 5312 bool success = false; 5313 5314 if (ConditionPassed(opcode)) 5315 { 5316 uint32_t Rd, Rn, Rm; 5317 ARM_ShifterType shift_t; 5318 uint32_t shift_n; // the shift applied to the value read from Rm 5319 bool setflags; 5320 switch (encoding) 5321 { 5322 case eEncodingT1: 5323 Rd = Rn = Bits32(opcode, 2, 0); 5324 Rm = Bits32(opcode, 5, 3); 5325 setflags = !InITBlock(); 5326 shift_t = SRType_LSL; 5327 shift_n = 0; 5328 break; 5329 case eEncodingT2: 5330 Rd = Bits32(opcode, 11, 8); 5331 Rn = Bits32(opcode, 19, 16); 5332 Rm = Bits32(opcode, 3, 0); 5333 setflags = BitIsSet(opcode, 20); 5334 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5335 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5336 return false; 5337 break; 5338 case eEncodingA1: 5339 Rd = Bits32(opcode, 15, 12); 5340 Rn = Bits32(opcode, 19, 16); 5341 Rm = Bits32(opcode, 3, 0); 5342 setflags = BitIsSet(opcode, 20); 5343 shift_n = DecodeImmShiftARM(opcode, shift_t); 5344 5345 if (Rd == 15 && setflags) 5346 return EmulateSUBSPcLrEtc (opcode, encoding); 5347 break; 5348 default: 5349 return false; 5350 } 5351 5352 // Read the first operand. 5353 int32_t val1 = ReadCoreReg(Rn, &success); 5354 if (!success) 5355 return false; 5356 5357 // Read the second operand. 5358 int32_t val2 = ReadCoreReg(Rm, &success); 5359 if (!success) 5360 return false; 5361 5362 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5363 if (!success) 5364 return false; 5365 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5366 5367 EmulateInstruction::Context context; 5368 context.type = EmulateInstruction::eContextImmediate; 5369 context.SetNoArgs (); 5370 5371 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5372 return false; 5373 } 5374 return true; 5375 } 5376 5377 // This instruction adds an immediate value to the PC value to form a PC-relative address, 5378 // and writes the result to the destination register. 5379 bool 5380 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5381 { 5382 #if 0 5383 // ARM pseudo code... 5384 if ConditionPassed() then 5385 EncodingSpecificOperations(); 5386 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5387 if d == 15 then // Can only occur for ARM encodings 5388 ALUWritePC(result); 5389 else 5390 R[d] = result; 5391 #endif 5392 5393 bool success = false; 5394 5395 if (ConditionPassed(opcode)) 5396 { 5397 uint32_t Rd; 5398 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5399 bool add; 5400 switch (encoding) 5401 { 5402 case eEncodingT1: 5403 Rd = Bits32(opcode, 10, 8); 5404 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5405 add = true; 5406 break; 5407 case eEncodingT2: 5408 case eEncodingT3: 5409 Rd = Bits32(opcode, 11, 8); 5410 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5411 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5412 if (BadReg(Rd)) 5413 return false; 5414 break; 5415 case eEncodingA1: 5416 case eEncodingA2: 5417 Rd = Bits32(opcode, 15, 12); 5418 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5419 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5420 break; 5421 default: 5422 return false; 5423 } 5424 5425 // Read the PC value. 5426 uint32_t pc = ReadCoreReg(PC_REG, &success); 5427 if (!success) 5428 return false; 5429 5430 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5431 5432 EmulateInstruction::Context context; 5433 context.type = EmulateInstruction::eContextImmediate; 5434 context.SetNoArgs (); 5435 5436 if (!WriteCoreReg(context, result, Rd)) 5437 return false; 5438 } 5439 return true; 5440 } 5441 5442 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5443 // to the destination register. It can optionally update the condition flags based on the result. 5444 bool 5445 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5446 { 5447 #if 0 5448 // ARM pseudo code... 5449 if ConditionPassed() then 5450 EncodingSpecificOperations(); 5451 result = R[n] AND imm32; 5452 if d == 15 then // Can only occur for ARM encoding 5453 ALUWritePC(result); // setflags is always FALSE here 5454 else 5455 R[d] = result; 5456 if setflags then 5457 APSR.N = result<31>; 5458 APSR.Z = IsZeroBit(result); 5459 APSR.C = carry; 5460 // APSR.V unchanged 5461 #endif 5462 5463 bool success = false; 5464 5465 if (ConditionPassed(opcode)) 5466 { 5467 uint32_t Rd, Rn; 5468 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5469 bool setflags; 5470 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5471 switch (encoding) 5472 { 5473 case eEncodingT1: 5474 Rd = Bits32(opcode, 11, 8); 5475 Rn = Bits32(opcode, 19, 16); 5476 setflags = BitIsSet(opcode, 20); 5477 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5478 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5479 if (Rd == 15 && setflags) 5480 return EmulateTSTImm(opcode, eEncodingT1); 5481 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5482 return false; 5483 break; 5484 case eEncodingA1: 5485 Rd = Bits32(opcode, 15, 12); 5486 Rn = Bits32(opcode, 19, 16); 5487 setflags = BitIsSet(opcode, 20); 5488 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5489 5490 if (Rd == 15 && setflags) 5491 return EmulateSUBSPcLrEtc (opcode, encoding); 5492 break; 5493 default: 5494 return false; 5495 } 5496 5497 // Read the first operand. 5498 uint32_t val1 = ReadCoreReg(Rn, &success); 5499 if (!success) 5500 return false; 5501 5502 uint32_t result = val1 & imm32; 5503 5504 EmulateInstruction::Context context; 5505 context.type = EmulateInstruction::eContextImmediate; 5506 context.SetNoArgs (); 5507 5508 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5509 return false; 5510 } 5511 return true; 5512 } 5513 5514 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5515 // and writes the result to the destination register. It can optionally update the condition flags 5516 // based on the result. 5517 bool 5518 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5519 { 5520 #if 0 5521 // ARM pseudo code... 5522 if ConditionPassed() then 5523 EncodingSpecificOperations(); 5524 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5525 result = R[n] AND shifted; 5526 if d == 15 then // Can only occur for ARM encoding 5527 ALUWritePC(result); // setflags is always FALSE here 5528 else 5529 R[d] = result; 5530 if setflags then 5531 APSR.N = result<31>; 5532 APSR.Z = IsZeroBit(result); 5533 APSR.C = carry; 5534 // APSR.V unchanged 5535 #endif 5536 5537 bool success = false; 5538 5539 if (ConditionPassed(opcode)) 5540 { 5541 uint32_t Rd, Rn, Rm; 5542 ARM_ShifterType shift_t; 5543 uint32_t shift_n; // the shift applied to the value read from Rm 5544 bool setflags; 5545 uint32_t carry; 5546 switch (encoding) 5547 { 5548 case eEncodingT1: 5549 Rd = Rn = Bits32(opcode, 2, 0); 5550 Rm = Bits32(opcode, 5, 3); 5551 setflags = !InITBlock(); 5552 shift_t = SRType_LSL; 5553 shift_n = 0; 5554 break; 5555 case eEncodingT2: 5556 Rd = Bits32(opcode, 11, 8); 5557 Rn = Bits32(opcode, 19, 16); 5558 Rm = Bits32(opcode, 3, 0); 5559 setflags = BitIsSet(opcode, 20); 5560 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5561 // if Rd == '1111' && S == '1' then SEE TST (register); 5562 if (Rd == 15 && setflags) 5563 return EmulateTSTReg(opcode, eEncodingT2); 5564 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5565 return false; 5566 break; 5567 case eEncodingA1: 5568 Rd = Bits32(opcode, 15, 12); 5569 Rn = Bits32(opcode, 19, 16); 5570 Rm = Bits32(opcode, 3, 0); 5571 setflags = BitIsSet(opcode, 20); 5572 shift_n = DecodeImmShiftARM(opcode, shift_t); 5573 5574 if (Rd == 15 && setflags) 5575 return EmulateSUBSPcLrEtc (opcode, encoding); 5576 break; 5577 default: 5578 return false; 5579 } 5580 5581 // Read the first operand. 5582 uint32_t val1 = ReadCoreReg(Rn, &success); 5583 if (!success) 5584 return false; 5585 5586 // Read the second operand. 5587 uint32_t val2 = ReadCoreReg(Rm, &success); 5588 if (!success) 5589 return false; 5590 5591 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5592 if (!success) 5593 return false; 5594 uint32_t result = val1 & shifted; 5595 5596 EmulateInstruction::Context context; 5597 context.type = EmulateInstruction::eContextImmediate; 5598 context.SetNoArgs (); 5599 5600 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5601 return false; 5602 } 5603 return true; 5604 } 5605 5606 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5607 // immediate value, and writes the result to the destination register. It can optionally update the 5608 // condition flags based on the result. 5609 bool 5610 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5611 { 5612 #if 0 5613 // ARM pseudo code... 5614 if ConditionPassed() then 5615 EncodingSpecificOperations(); 5616 result = R[n] AND NOT(imm32); 5617 if d == 15 then // Can only occur for ARM encoding 5618 ALUWritePC(result); // setflags is always FALSE here 5619 else 5620 R[d] = result; 5621 if setflags then 5622 APSR.N = result<31>; 5623 APSR.Z = IsZeroBit(result); 5624 APSR.C = carry; 5625 // APSR.V unchanged 5626 #endif 5627 5628 bool success = false; 5629 5630 if (ConditionPassed(opcode)) 5631 { 5632 uint32_t Rd, Rn; 5633 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5634 bool setflags; 5635 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5636 switch (encoding) 5637 { 5638 case eEncodingT1: 5639 Rd = Bits32(opcode, 11, 8); 5640 Rn = Bits32(opcode, 19, 16); 5641 setflags = BitIsSet(opcode, 20); 5642 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5643 if (BadReg(Rd) || BadReg(Rn)) 5644 return false; 5645 break; 5646 case eEncodingA1: 5647 Rd = Bits32(opcode, 15, 12); 5648 Rn = Bits32(opcode, 19, 16); 5649 setflags = BitIsSet(opcode, 20); 5650 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5651 5652 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5653 if (Rd == 15 && setflags) 5654 return EmulateSUBSPcLrEtc (opcode, encoding); 5655 break; 5656 default: 5657 return false; 5658 } 5659 5660 // Read the first operand. 5661 uint32_t val1 = ReadCoreReg(Rn, &success); 5662 if (!success) 5663 return false; 5664 5665 uint32_t result = val1 & ~imm32; 5666 5667 EmulateInstruction::Context context; 5668 context.type = EmulateInstruction::eContextImmediate; 5669 context.SetNoArgs (); 5670 5671 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5672 return false; 5673 } 5674 return true; 5675 } 5676 5677 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5678 // optionally-shifted register value, and writes the result to the destination register. 5679 // It can optionally update the condition flags based on the result. 5680 bool 5681 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5682 { 5683 #if 0 5684 // ARM pseudo code... 5685 if ConditionPassed() then 5686 EncodingSpecificOperations(); 5687 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5688 result = R[n] AND NOT(shifted); 5689 if d == 15 then // Can only occur for ARM encoding 5690 ALUWritePC(result); // setflags is always FALSE here 5691 else 5692 R[d] = result; 5693 if setflags then 5694 APSR.N = result<31>; 5695 APSR.Z = IsZeroBit(result); 5696 APSR.C = carry; 5697 // APSR.V unchanged 5698 #endif 5699 5700 bool success = false; 5701 5702 if (ConditionPassed(opcode)) 5703 { 5704 uint32_t Rd, Rn, Rm; 5705 ARM_ShifterType shift_t; 5706 uint32_t shift_n; // the shift applied to the value read from Rm 5707 bool setflags; 5708 uint32_t carry; 5709 switch (encoding) 5710 { 5711 case eEncodingT1: 5712 Rd = Rn = Bits32(opcode, 2, 0); 5713 Rm = Bits32(opcode, 5, 3); 5714 setflags = !InITBlock(); 5715 shift_t = SRType_LSL; 5716 shift_n = 0; 5717 break; 5718 case eEncodingT2: 5719 Rd = Bits32(opcode, 11, 8); 5720 Rn = Bits32(opcode, 19, 16); 5721 Rm = Bits32(opcode, 3, 0); 5722 setflags = BitIsSet(opcode, 20); 5723 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5724 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5725 return false; 5726 break; 5727 case eEncodingA1: 5728 Rd = Bits32(opcode, 15, 12); 5729 Rn = Bits32(opcode, 19, 16); 5730 Rm = Bits32(opcode, 3, 0); 5731 setflags = BitIsSet(opcode, 20); 5732 shift_n = DecodeImmShiftARM(opcode, shift_t); 5733 5734 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5735 if (Rd == 15 && setflags) 5736 return EmulateSUBSPcLrEtc (opcode, encoding); 5737 break; 5738 default: 5739 return false; 5740 } 5741 5742 // Read the first operand. 5743 uint32_t val1 = ReadCoreReg(Rn, &success); 5744 if (!success) 5745 return false; 5746 5747 // Read the second operand. 5748 uint32_t val2 = ReadCoreReg(Rm, &success); 5749 if (!success) 5750 return false; 5751 5752 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5753 if (!success) 5754 return false; 5755 uint32_t result = val1 & ~shifted; 5756 5757 EmulateInstruction::Context context; 5758 context.type = EmulateInstruction::eContextImmediate; 5759 context.SetNoArgs (); 5760 5761 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5762 return false; 5763 } 5764 return true; 5765 } 5766 5767 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5768 // from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5769 bool 5770 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5771 { 5772 #if 0 5773 if ConditionPassed() then 5774 EncodingSpecificOperations(); 5775 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5776 address = if index then offset_addr else R[n]; 5777 data = MemU[address,4]; 5778 if wback then R[n] = offset_addr; 5779 if t == 15 then 5780 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5781 elsif UnalignedSupport() || address<1:0> = '00' then 5782 R[t] = data; 5783 else // Can only apply before ARMv7 5784 R[t] = ROR(data, 8*UInt(address<1:0>)); 5785 #endif 5786 5787 bool success = false; 5788 5789 if (ConditionPassed(opcode)) 5790 { 5791 const uint32_t addr_byte_size = GetAddressByteSize(); 5792 5793 uint32_t t; 5794 uint32_t n; 5795 uint32_t imm32; 5796 bool index; 5797 bool add; 5798 bool wback; 5799 5800 switch (encoding) 5801 { 5802 case eEncodingA1: 5803 // if Rn == '1111' then SEE LDR (literal); 5804 // if P == '0' && W == '1' then SEE LDRT; 5805 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5806 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5807 t = Bits32 (opcode, 15, 12); 5808 n = Bits32 (opcode, 19, 16); 5809 imm32 = Bits32 (opcode, 11, 0); 5810 5811 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5812 index = BitIsSet (opcode, 24); 5813 add = BitIsSet (opcode, 23); 5814 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5815 5816 // if wback && n == t then UNPREDICTABLE; 5817 if (wback && (n == t)) 5818 return false; 5819 5820 break; 5821 5822 default: 5823 return false; 5824 } 5825 5826 addr_t address; 5827 addr_t offset_addr; 5828 addr_t base_address = ReadCoreReg (n, &success); 5829 if (!success) 5830 return false; 5831 5832 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5833 if (add) 5834 offset_addr = base_address + imm32; 5835 else 5836 offset_addr = base_address - imm32; 5837 5838 // address = if index then offset_addr else R[n]; 5839 if (index) 5840 address = offset_addr; 5841 else 5842 address = base_address; 5843 5844 // data = MemU[address,4]; 5845 5846 RegisterInfo base_reg; 5847 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5848 5849 EmulateInstruction::Context context; 5850 context.type = eContextRegisterLoad; 5851 context.SetRegisterPlusOffset (base_reg, address - base_address); 5852 5853 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5854 if (!success) 5855 return false; 5856 5857 // if wback then R[n] = offset_addr; 5858 if (wback) 5859 { 5860 context.type = eContextAdjustBaseRegister; 5861 context.SetAddress (offset_addr); 5862 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5863 return false; 5864 } 5865 5866 // if t == 15 then 5867 if (t == 15) 5868 { 5869 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5870 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5871 { 5872 // LoadWritePC (data); 5873 context.type = eContextRegisterLoad; 5874 context.SetRegisterPlusOffset (base_reg, address - base_address); 5875 LoadWritePC (context, data); 5876 } 5877 else 5878 return false; 5879 } 5880 // elsif UnalignedSupport() || address<1:0> = '00' then 5881 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5882 { 5883 // R[t] = data; 5884 context.type = eContextRegisterLoad; 5885 context.SetRegisterPlusOffset (base_reg, address - base_address); 5886 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5887 return false; 5888 } 5889 // else // Can only apply before ARMv7 5890 else 5891 { 5892 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5893 data = ROR (data, Bits32 (address, 1, 0), &success); 5894 if (!success) 5895 return false; 5896 context.type = eContextRegisterLoad; 5897 context.SetImmediate (data); 5898 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5899 return false; 5900 } 5901 5902 } 5903 return true; 5904 } 5905 5906 // LDR (register) calculates an address from a base register value and an offset register value, loads a word 5907 // from memory, and writes it to a resgister. The offset register value can optionally be shifted. 5908 bool 5909 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5910 { 5911 #if 0 5912 if ConditionPassed() then 5913 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5914 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5915 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5916 address = if index then offset_addr else R[n]; 5917 data = MemU[address,4]; 5918 if wback then R[n] = offset_addr; 5919 if t == 15 then 5920 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5921 elsif UnalignedSupport() || address<1:0> = '00' then 5922 R[t] = data; 5923 else // Can only apply before ARMv7 5924 if CurrentInstrSet() == InstrSet_ARM then 5925 R[t] = ROR(data, 8*UInt(address<1:0>)); 5926 else 5927 R[t] = bits(32) UNKNOWN; 5928 #endif 5929 5930 bool success = false; 5931 5932 if (ConditionPassed(opcode)) 5933 { 5934 const uint32_t addr_byte_size = GetAddressByteSize(); 5935 5936 uint32_t t; 5937 uint32_t n; 5938 uint32_t m; 5939 bool index; 5940 bool add; 5941 bool wback; 5942 ARM_ShifterType shift_t; 5943 uint32_t shift_n; 5944 5945 switch (encoding) 5946 { 5947 case eEncodingT1: 5948 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5949 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5950 t = Bits32 (opcode, 2, 0); 5951 n = Bits32 (opcode, 5, 3); 5952 m = Bits32 (opcode, 8, 6); 5953 5954 // index = TRUE; add = TRUE; wback = FALSE; 5955 index = true; 5956 add = true; 5957 wback = false; 5958 5959 // (shift_t, shift_n) = (SRType_LSL, 0); 5960 shift_t = SRType_LSL; 5961 shift_n = 0; 5962 5963 break; 5964 5965 case eEncodingT2: 5966 // if Rn == '1111' then SEE LDR (literal); 5967 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5968 t = Bits32 (opcode, 15, 12); 5969 n = Bits32 (opcode, 19, 16); 5970 m = Bits32 (opcode, 3, 0); 5971 5972 // index = TRUE; add = TRUE; wback = FALSE; 5973 index = true; 5974 add = true; 5975 wback = false; 5976 5977 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5978 shift_t = SRType_LSL; 5979 shift_n = Bits32 (opcode, 5, 4); 5980 5981 // if BadReg(m) then UNPREDICTABLE; 5982 if (BadReg (m)) 5983 return false; 5984 5985 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5986 if ((t == 15) && InITBlock() && !LastInITBlock()) 5987 return false; 5988 5989 break; 5990 5991 case eEncodingA1: 5992 { 5993 // if P == '0' && W == '1' then SEE LDRT; 5994 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5995 t = Bits32 (opcode, 15, 12); 5996 n = Bits32 (opcode, 19, 16); 5997 m = Bits32 (opcode, 3, 0); 5998 5999 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6000 index = BitIsSet (opcode, 24); 6001 add = BitIsSet (opcode, 23); 6002 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6003 6004 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6005 uint32_t type = Bits32 (opcode, 6, 5); 6006 uint32_t imm5 = Bits32 (opcode, 11, 7); 6007 shift_n = DecodeImmShift (type, imm5, shift_t); 6008 6009 // if m == 15 then UNPREDICTABLE; 6010 if (m == 15) 6011 return false; 6012 6013 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6014 if (wback && ((n == 15) || (n == t))) 6015 return false; 6016 } 6017 break; 6018 6019 6020 default: 6021 return false; 6022 } 6023 6024 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6025 if (!success) 6026 return false; 6027 6028 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6029 if (!success) 6030 return false; 6031 6032 addr_t offset_addr; 6033 addr_t address; 6034 6035 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6036 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6037 if (!success) 6038 return false; 6039 6040 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6041 if (add) 6042 offset_addr = Rn + offset; 6043 else 6044 offset_addr = Rn - offset; 6045 6046 // address = if index then offset_addr else R[n]; 6047 if (index) 6048 address = offset_addr; 6049 else 6050 address = Rn; 6051 6052 // data = MemU[address,4]; 6053 RegisterInfo base_reg; 6054 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6055 6056 EmulateInstruction::Context context; 6057 context.type = eContextRegisterLoad; 6058 context.SetRegisterPlusOffset (base_reg, address - Rn); 6059 6060 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6061 if (!success) 6062 return false; 6063 6064 // if wback then R[n] = offset_addr; 6065 if (wback) 6066 { 6067 context.type = eContextAdjustBaseRegister; 6068 context.SetAddress (offset_addr); 6069 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6070 return false; 6071 } 6072 6073 // if t == 15 then 6074 if (t == 15) 6075 { 6076 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6077 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6078 { 6079 context.type = eContextRegisterLoad; 6080 context.SetRegisterPlusOffset (base_reg, address - Rn); 6081 LoadWritePC (context, data); 6082 } 6083 else 6084 return false; 6085 } 6086 // elsif UnalignedSupport() || address<1:0> = '00' then 6087 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6088 { 6089 // R[t] = data; 6090 context.type = eContextRegisterLoad; 6091 context.SetRegisterPlusOffset (base_reg, address - Rn); 6092 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6093 return false; 6094 } 6095 else // Can only apply before ARMv7 6096 { 6097 // if CurrentInstrSet() == InstrSet_ARM then 6098 if (CurrentInstrSet () == eModeARM) 6099 { 6100 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6101 data = ROR (data, Bits32 (address, 1, 0), &success); 6102 if (!success) 6103 return false; 6104 context.type = eContextRegisterLoad; 6105 context.SetImmediate (data); 6106 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6107 return false; 6108 } 6109 else 6110 { 6111 // R[t] = bits(32) UNKNOWN; 6112 WriteBits32Unknown (t); 6113 } 6114 } 6115 } 6116 return true; 6117 } 6118 6119 // LDRB (immediate, Thumb) 6120 bool 6121 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6122 { 6123 #if 0 6124 if ConditionPassed() then 6125 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6126 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6127 address = if index then offset_addr else R[n]; 6128 R[t] = ZeroExtend(MemU[address,1], 32); 6129 if wback then R[n] = offset_addr; 6130 #endif 6131 6132 bool success = false; 6133 6134 if (ConditionPassed(opcode)) 6135 { 6136 uint32_t t; 6137 uint32_t n; 6138 uint32_t imm32; 6139 bool index; 6140 bool add; 6141 bool wback; 6142 6143 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6144 switch (encoding) 6145 { 6146 case eEncodingT1: 6147 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6148 t = Bits32 (opcode, 2, 0); 6149 n = Bits32 (opcode, 5, 3); 6150 imm32 = Bits32 (opcode, 10, 6); 6151 6152 // index = TRUE; add = TRUE; wback = FALSE; 6153 index = true; 6154 add = true; 6155 wback= false; 6156 6157 break; 6158 6159 case eEncodingT2: 6160 // if Rt == '1111' then SEE PLD; 6161 // if Rn == '1111' then SEE LDRB (literal); 6162 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6163 t = Bits32 (opcode, 15, 12); 6164 n = Bits32 (opcode, 19, 16); 6165 imm32 = Bits32 (opcode, 11, 0); 6166 6167 // index = TRUE; add = TRUE; wback = FALSE; 6168 index = true; 6169 add = true; 6170 wback = false; 6171 6172 // if t == 13 then UNPREDICTABLE; 6173 if (t == 13) 6174 return false; 6175 6176 break; 6177 6178 case eEncodingT3: 6179 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6180 // if Rn == '1111' then SEE LDRB (literal); 6181 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6182 // if P == '0' && W == '0' then UNDEFINED; 6183 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6184 return false; 6185 6186 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6187 t = Bits32 (opcode, 15, 12); 6188 n = Bits32 (opcode, 19, 16); 6189 imm32 = Bits32 (opcode, 7, 0); 6190 6191 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6192 index = BitIsSet (opcode, 10); 6193 add = BitIsSet (opcode, 9); 6194 wback = BitIsSet (opcode, 8); 6195 6196 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6197 if (BadReg (t) || (wback && (n == t))) 6198 return false; 6199 6200 break; 6201 6202 default: 6203 return false; 6204 } 6205 6206 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6207 if (!success) 6208 return false; 6209 6210 addr_t address; 6211 addr_t offset_addr; 6212 6213 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6214 if (add) 6215 offset_addr = Rn + imm32; 6216 else 6217 offset_addr = Rn - imm32; 6218 6219 // address = if index then offset_addr else R[n]; 6220 if (index) 6221 address = offset_addr; 6222 else 6223 address = Rn; 6224 6225 // R[t] = ZeroExtend(MemU[address,1], 32); 6226 RegisterInfo base_reg; 6227 RegisterInfo data_reg; 6228 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6229 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6230 6231 EmulateInstruction::Context context; 6232 context.type = eContextRegisterLoad; 6233 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6234 6235 uint64_t data = MemURead (context, address, 1, 0, &success); 6236 if (!success) 6237 return false; 6238 6239 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6240 return false; 6241 6242 // if wback then R[n] = offset_addr; 6243 if (wback) 6244 { 6245 context.type = eContextAdjustBaseRegister; 6246 context.SetAddress (offset_addr); 6247 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6248 return false; 6249 } 6250 } 6251 return true; 6252 } 6253 6254 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6255 // zero-extends it to form a 32-bit word and writes it to a register. 6256 bool 6257 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6258 { 6259 #if 0 6260 if ConditionPassed() then 6261 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6262 base = Align(PC,4); 6263 address = if add then (base + imm32) else (base - imm32); 6264 R[t] = ZeroExtend(MemU[address,1], 32); 6265 #endif 6266 6267 bool success = false; 6268 6269 if (ConditionPassed(opcode)) 6270 { 6271 uint32_t t; 6272 uint32_t imm32; 6273 bool add; 6274 switch (encoding) 6275 { 6276 case eEncodingT1: 6277 // if Rt == '1111' then SEE PLD; 6278 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6279 t = Bits32 (opcode, 15, 12); 6280 imm32 = Bits32 (opcode, 11, 0); 6281 add = BitIsSet (opcode, 23); 6282 6283 // if t == 13 then UNPREDICTABLE; 6284 if (t == 13) 6285 return false; 6286 6287 break; 6288 6289 case eEncodingA1: 6290 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6291 t = Bits32 (opcode, 15, 12); 6292 imm32 = Bits32 (opcode, 11, 0); 6293 add = BitIsSet (opcode, 23); 6294 6295 // if t == 15 then UNPREDICTABLE; 6296 if (t == 15) 6297 return false; 6298 break; 6299 6300 default: 6301 return false; 6302 } 6303 6304 // base = Align(PC,4); 6305 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6306 if (!success) 6307 return false; 6308 6309 uint32_t base = AlignPC (pc_val); 6310 6311 addr_t address; 6312 // address = if add then (base + imm32) else (base - imm32); 6313 if (add) 6314 address = base + imm32; 6315 else 6316 address = base - imm32; 6317 6318 // R[t] = ZeroExtend(MemU[address,1], 32); 6319 EmulateInstruction::Context context; 6320 context.type = eContextRelativeBranchImmediate; 6321 context.SetImmediate (address - base); 6322 6323 uint64_t data = MemURead (context, address, 1, 0, &success); 6324 if (!success) 6325 return false; 6326 6327 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6328 return false; 6329 } 6330 return true; 6331 } 6332 6333 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6334 // memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6335 // optionally be shifted. 6336 bool 6337 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6338 { 6339 #if 0 6340 if ConditionPassed() then 6341 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6342 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6343 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6344 address = if index then offset_addr else R[n]; 6345 R[t] = ZeroExtend(MemU[address,1],32); 6346 if wback then R[n] = offset_addr; 6347 #endif 6348 6349 bool success = false; 6350 6351 if (ConditionPassed(opcode)) 6352 { 6353 uint32_t t; 6354 uint32_t n; 6355 uint32_t m; 6356 bool index; 6357 bool add; 6358 bool wback; 6359 ARM_ShifterType shift_t; 6360 uint32_t shift_n; 6361 6362 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6363 switch (encoding) 6364 { 6365 case eEncodingT1: 6366 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6367 t = Bits32 (opcode, 2, 0); 6368 n = Bits32 (opcode, 5, 3); 6369 m = Bits32 (opcode, 8, 6); 6370 6371 // index = TRUE; add = TRUE; wback = FALSE; 6372 index = true; 6373 add = true; 6374 wback = false; 6375 6376 // (shift_t, shift_n) = (SRType_LSL, 0); 6377 shift_t = SRType_LSL; 6378 shift_n = 0; 6379 break; 6380 6381 case eEncodingT2: 6382 // if Rt == '1111' then SEE PLD; 6383 // if Rn == '1111' then SEE LDRB (literal); 6384 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6385 t = Bits32 (opcode, 15, 12); 6386 n = Bits32 (opcode, 19, 16); 6387 m = Bits32 (opcode, 3, 0); 6388 6389 // index = TRUE; add = TRUE; wback = FALSE; 6390 index = true; 6391 add = true; 6392 wback = false; 6393 6394 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6395 shift_t = SRType_LSL; 6396 shift_n = Bits32 (opcode, 5, 4); 6397 6398 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6399 if ((t == 13) || BadReg (m)) 6400 return false; 6401 break; 6402 6403 case eEncodingA1: 6404 { 6405 // if P == '0' && W == '1' then SEE LDRBT; 6406 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6407 t = Bits32 (opcode, 15, 12); 6408 n = Bits32 (opcode, 19, 16); 6409 m = Bits32 (opcode, 3, 0); 6410 6411 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6412 index = BitIsSet (opcode, 24); 6413 add = BitIsSet (opcode, 23); 6414 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6415 6416 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6417 uint32_t type = Bits32 (opcode, 6, 5); 6418 uint32_t imm5 = Bits32 (opcode, 11, 7); 6419 shift_n = DecodeImmShift (type, imm5, shift_t); 6420 6421 // if t == 15 || m == 15 then UNPREDICTABLE; 6422 if ((t == 15) || (m == 15)) 6423 return false; 6424 6425 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6426 if (wback && ((n == 15) || (n == t))) 6427 return false; 6428 } 6429 break; 6430 6431 default: 6432 return false; 6433 } 6434 6435 addr_t offset_addr; 6436 addr_t address; 6437 6438 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6439 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6440 if (!success) 6441 return false; 6442 6443 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6444 if (!success) 6445 return false; 6446 6447 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6448 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6449 if (!success) 6450 return false; 6451 6452 if (add) 6453 offset_addr = Rn + offset; 6454 else 6455 offset_addr = Rn - offset; 6456 6457 // address = if index then offset_addr else R[n]; 6458 if (index) 6459 address = offset_addr; 6460 else 6461 address = Rn; 6462 6463 // R[t] = ZeroExtend(MemU[address,1],32); 6464 RegisterInfo base_reg; 6465 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6466 6467 EmulateInstruction::Context context; 6468 context.type = eContextRegisterLoad; 6469 context.SetRegisterPlusOffset (base_reg, address - Rn); 6470 6471 uint64_t data = MemURead (context, address, 1, 0, &success); 6472 if (!success) 6473 return false; 6474 6475 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6476 return false; 6477 6478 // if wback then R[n] = offset_addr; 6479 if (wback) 6480 { 6481 context.type = eContextAdjustBaseRegister; 6482 context.SetAddress (offset_addr); 6483 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6484 return false; 6485 } 6486 } 6487 return true; 6488 } 6489 6490 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6491 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6492 // post-indexed, or pre-indexed addressing. 6493 bool 6494 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6495 { 6496 #if 0 6497 if ConditionPassed() then 6498 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6499 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6500 address = if index then offset_addr else R[n]; 6501 data = MemU[address,2]; 6502 if wback then R[n] = offset_addr; 6503 if UnalignedSupport() || address<0> = '0' then 6504 R[t] = ZeroExtend(data, 32); 6505 else // Can only apply before ARMv7 6506 R[t] = bits(32) UNKNOWN; 6507 #endif 6508 6509 6510 bool success = false; 6511 6512 if (ConditionPassed(opcode)) 6513 { 6514 uint32_t t; 6515 uint32_t n; 6516 uint32_t imm32; 6517 bool index; 6518 bool add; 6519 bool wback; 6520 6521 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6522 switch (encoding) 6523 { 6524 case eEncodingT1: 6525 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6526 t = Bits32 (opcode, 2, 0); 6527 n = Bits32 (opcode, 5, 3); 6528 imm32 = Bits32 (opcode, 10, 6) << 1; 6529 6530 // index = TRUE; add = TRUE; wback = FALSE; 6531 index = true; 6532 add = true; 6533 wback = false; 6534 6535 break; 6536 6537 case eEncodingT2: 6538 // if Rt == '1111' then SEE "Unallocated memory hints"; 6539 // if Rn == '1111' then SEE LDRH (literal); 6540 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6541 t = Bits32 (opcode, 15, 12); 6542 n = Bits32 (opcode, 19, 16); 6543 imm32 = Bits32 (opcode, 11, 0); 6544 6545 // index = TRUE; add = TRUE; wback = FALSE; 6546 index = true; 6547 add = true; 6548 wback = false; 6549 6550 // if t == 13 then UNPREDICTABLE; 6551 if (t == 13) 6552 return false; 6553 break; 6554 6555 case eEncodingT3: 6556 // if Rn == '1111' then SEE LDRH (literal); 6557 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6558 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6559 // if P == '0' && W == '0' then UNDEFINED; 6560 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6561 return false; 6562 6563 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6564 t = Bits32 (opcode, 15, 12); 6565 n = Bits32 (opcode, 19, 16); 6566 imm32 = Bits32 (opcode, 7, 0); 6567 6568 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6569 index = BitIsSet (opcode, 10); 6570 add = BitIsSet (opcode, 9); 6571 wback = BitIsSet (opcode, 8); 6572 6573 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6574 if (BadReg (t) || (wback && (n == t))) 6575 return false; 6576 break; 6577 6578 default: 6579 return false; 6580 } 6581 6582 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6583 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6584 if (!success) 6585 return false; 6586 6587 addr_t offset_addr; 6588 addr_t address; 6589 6590 if (add) 6591 offset_addr = Rn + imm32; 6592 else 6593 offset_addr = Rn - imm32; 6594 6595 // address = if index then offset_addr else R[n]; 6596 if (index) 6597 address = offset_addr; 6598 else 6599 address = Rn; 6600 6601 // data = MemU[address,2]; 6602 RegisterInfo base_reg; 6603 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6604 6605 EmulateInstruction::Context context; 6606 context.type = eContextRegisterLoad; 6607 context.SetRegisterPlusOffset (base_reg, address - Rn); 6608 6609 uint64_t data = MemURead (context, address, 2, 0, &success); 6610 if (!success) 6611 return false; 6612 6613 // if wback then R[n] = offset_addr; 6614 if (wback) 6615 { 6616 context.type = eContextAdjustBaseRegister; 6617 context.SetAddress (offset_addr); 6618 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6619 return false; 6620 } 6621 6622 // if UnalignedSupport() || address<0> = '0' then 6623 if (UnalignedSupport () || BitIsClear (address, 0)) 6624 { 6625 // R[t] = ZeroExtend(data, 32); 6626 context.type = eContextRegisterLoad; 6627 context.SetRegisterPlusOffset (base_reg, address - Rn); 6628 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6629 return false; 6630 } 6631 else // Can only apply before ARMv7 6632 { 6633 // R[t] = bits(32) UNKNOWN; 6634 WriteBits32Unknown (t); 6635 } 6636 } 6637 return true; 6638 } 6639 6640 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6641 // zero-extends it to form a 32-bit word, and writes it to a register. 6642 bool 6643 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6644 { 6645 #if 0 6646 if ConditionPassed() then 6647 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6648 base = Align(PC,4); 6649 address = if add then (base + imm32) else (base - imm32); 6650 data = MemU[address,2]; 6651 if UnalignedSupport() || address<0> = '0' then 6652 R[t] = ZeroExtend(data, 32); 6653 else // Can only apply before ARMv7 6654 R[t] = bits(32) UNKNOWN; 6655 #endif 6656 6657 bool success = false; 6658 6659 if (ConditionPassed(opcode)) 6660 { 6661 uint32_t t; 6662 uint32_t imm32; 6663 bool add; 6664 6665 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6666 switch (encoding) 6667 { 6668 case eEncodingT1: 6669 // if Rt == '1111' then SEE "Unallocated memory hints"; 6670 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6671 t = Bits32 (opcode, 15, 12); 6672 imm32 = Bits32 (opcode, 11, 0); 6673 add = BitIsSet (opcode, 23); 6674 6675 // if t == 13 then UNPREDICTABLE; 6676 if (t == 13) 6677 return false; 6678 6679 break; 6680 6681 case eEncodingA1: 6682 { 6683 uint32_t imm4H = Bits32 (opcode, 11, 8); 6684 uint32_t imm4L = Bits32 (opcode, 3, 0); 6685 6686 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6687 t = Bits32 (opcode, 15, 12); 6688 imm32 = (imm4H << 4) | imm4L; 6689 add = BitIsSet (opcode, 23); 6690 6691 // if t == 15 then UNPREDICTABLE; 6692 if (t == 15) 6693 return false; 6694 break; 6695 } 6696 6697 default: 6698 return false; 6699 } 6700 6701 // base = Align(PC,4); 6702 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6703 if (!success) 6704 return false; 6705 6706 addr_t base = AlignPC (pc_value); 6707 addr_t address; 6708 6709 // address = if add then (base + imm32) else (base - imm32); 6710 if (add) 6711 address = base + imm32; 6712 else 6713 address = base - imm32; 6714 6715 // data = MemU[address,2]; 6716 RegisterInfo base_reg; 6717 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6718 6719 EmulateInstruction::Context context; 6720 context.type = eContextRegisterLoad; 6721 context.SetRegisterPlusOffset (base_reg, address - base); 6722 6723 uint64_t data = MemURead (context, address, 2, 0, &success); 6724 if (!success) 6725 return false; 6726 6727 6728 // if UnalignedSupport() || address<0> = '0' then 6729 if (UnalignedSupport () || BitIsClear (address, 0)) 6730 { 6731 // R[t] = ZeroExtend(data, 32); 6732 context.type = eContextRegisterLoad; 6733 context.SetRegisterPlusOffset (base_reg, address - base); 6734 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6735 return false; 6736 6737 } 6738 else // Can only apply before ARMv7 6739 { 6740 // R[t] = bits(32) UNKNOWN; 6741 WriteBits32Unknown (t); 6742 } 6743 } 6744 return true; 6745 } 6746 6747 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6748 // from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6749 // be shifted left by 0, 1, 2, or 3 bits. 6750 bool 6751 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6752 { 6753 #if 0 6754 if ConditionPassed() then 6755 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6756 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6757 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6758 address = if index then offset_addr else R[n]; 6759 data = MemU[address,2]; 6760 if wback then R[n] = offset_addr; 6761 if UnalignedSupport() || address<0> = '0' then 6762 R[t] = ZeroExtend(data, 32); 6763 else // Can only apply before ARMv7 6764 R[t] = bits(32) UNKNOWN; 6765 #endif 6766 6767 bool success = false; 6768 6769 if (ConditionPassed(opcode)) 6770 { 6771 uint32_t t; 6772 uint32_t n; 6773 uint32_t m; 6774 bool index; 6775 bool add; 6776 bool wback; 6777 ARM_ShifterType shift_t; 6778 uint32_t shift_n; 6779 6780 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6781 switch (encoding) 6782 { 6783 case eEncodingT1: 6784 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6785 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6786 t = Bits32 (opcode, 2, 0); 6787 n = Bits32 (opcode, 5, 3); 6788 m = Bits32 (opcode, 8, 6); 6789 6790 // index = TRUE; add = TRUE; wback = FALSE; 6791 index = true; 6792 add = true; 6793 wback = false; 6794 6795 // (shift_t, shift_n) = (SRType_LSL, 0); 6796 shift_t = SRType_LSL; 6797 shift_n = 0; 6798 6799 break; 6800 6801 case eEncodingT2: 6802 // if Rn == '1111' then SEE LDRH (literal); 6803 // if Rt == '1111' then SEE "Unallocated memory hints"; 6804 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6805 t = Bits32 (opcode, 15, 12); 6806 n = Bits32 (opcode, 19, 16); 6807 m = Bits32 (opcode, 3, 0); 6808 6809 // index = TRUE; add = TRUE; wback = FALSE; 6810 index = true; 6811 add = true; 6812 wback = false; 6813 6814 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6815 shift_t = SRType_LSL; 6816 shift_n = Bits32 (opcode, 5, 4); 6817 6818 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6819 if ((t == 13) || BadReg (m)) 6820 return false; 6821 break; 6822 6823 case eEncodingA1: 6824 // if P == '0' && W == '1' then SEE LDRHT; 6825 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6826 t = Bits32 (opcode, 15, 12); 6827 n = Bits32 (opcode, 19, 16); 6828 m = Bits32 (opcode, 3, 0); 6829 6830 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6831 index = BitIsSet (opcode, 24); 6832 add = BitIsSet (opcode, 23); 6833 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6834 6835 // (shift_t, shift_n) = (SRType_LSL, 0); 6836 shift_t = SRType_LSL; 6837 shift_n = 0; 6838 6839 // if t == 15 || m == 15 then UNPREDICTABLE; 6840 if ((t == 15) || (m == 15)) 6841 return false; 6842 6843 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6844 if (wback && ((n == 15) || (n == t))) 6845 return false; 6846 6847 break; 6848 6849 default: 6850 return false; 6851 } 6852 6853 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6854 6855 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6856 if (!success) 6857 return false; 6858 6859 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6860 if (!success) 6861 return false; 6862 6863 addr_t offset_addr; 6864 addr_t address; 6865 6866 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6867 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6868 if (!success) 6869 return false; 6870 6871 if (add) 6872 offset_addr = Rn + offset; 6873 else 6874 offset_addr = Rn - offset; 6875 6876 // address = if index then offset_addr else R[n]; 6877 if (index) 6878 address = offset_addr; 6879 else 6880 address = Rn; 6881 6882 // data = MemU[address,2]; 6883 RegisterInfo base_reg; 6884 RegisterInfo offset_reg; 6885 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6886 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 6887 6888 EmulateInstruction::Context context; 6889 context.type = eContextRegisterLoad; 6890 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6891 uint64_t data = MemURead (context, address, 2, 0, &success); 6892 if (!success) 6893 return false; 6894 6895 // if wback then R[n] = offset_addr; 6896 if (wback) 6897 { 6898 context.type = eContextAdjustBaseRegister; 6899 context.SetAddress (offset_addr); 6900 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6901 return false; 6902 } 6903 6904 // if UnalignedSupport() || address<0> = '0' then 6905 if (UnalignedSupport() || BitIsClear (address, 0)) 6906 { 6907 // R[t] = ZeroExtend(data, 32); 6908 context.type = eContextRegisterLoad; 6909 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6910 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6911 return false; 6912 } 6913 else // Can only apply before ARMv7 6914 { 6915 // R[t] = bits(32) UNKNOWN; 6916 WriteBits32Unknown (t); 6917 } 6918 } 6919 return true; 6920 } 6921 6922 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6923 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6924 // or pre-indexed addressing. 6925 bool 6926 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6927 { 6928 #if 0 6929 if ConditionPassed() then 6930 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6931 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6932 address = if index then offset_addr else R[n]; 6933 R[t] = SignExtend(MemU[address,1], 32); 6934 if wback then R[n] = offset_addr; 6935 #endif 6936 6937 bool success = false; 6938 6939 if (ConditionPassed(opcode)) 6940 { 6941 uint32_t t; 6942 uint32_t n; 6943 uint32_t imm32; 6944 bool index; 6945 bool add; 6946 bool wback; 6947 6948 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6949 switch (encoding) 6950 { 6951 case eEncodingT1: 6952 // if Rt == '1111' then SEE PLI; 6953 // if Rn == '1111' then SEE LDRSB (literal); 6954 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6955 t = Bits32 (opcode, 15, 12); 6956 n = Bits32 (opcode, 19, 16); 6957 imm32 = Bits32 (opcode, 11, 0); 6958 6959 // index = TRUE; add = TRUE; wback = FALSE; 6960 index = true; 6961 add = true; 6962 wback = false; 6963 6964 // if t == 13 then UNPREDICTABLE; 6965 if (t == 13) 6966 return false; 6967 6968 break; 6969 6970 case eEncodingT2: 6971 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 6972 // if Rn == '1111' then SEE LDRSB (literal); 6973 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 6974 // if P == '0' && W == '0' then UNDEFINED; 6975 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6976 return false; 6977 6978 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6979 t = Bits32 (opcode, 15, 12); 6980 n = Bits32 (opcode, 19, 16); 6981 imm32 = Bits32 (opcode, 7, 0); 6982 6983 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6984 index = BitIsSet (opcode, 10); 6985 add = BitIsSet (opcode, 9); 6986 wback = BitIsSet (opcode, 8); 6987 6988 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6989 if (((t == 13) || ((t == 15) 6990 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 6991 || (wback && (n == t))) 6992 return false; 6993 6994 break; 6995 6996 case eEncodingA1: 6997 { 6998 // if Rn == '1111' then SEE LDRSB (literal); 6999 // if P == '0' && W == '1' then SEE LDRSBT; 7000 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7001 t = Bits32 (opcode, 15, 12); 7002 n = Bits32 (opcode, 19, 16); 7003 7004 uint32_t imm4H = Bits32 (opcode, 11, 8); 7005 uint32_t imm4L = Bits32 (opcode, 3, 0); 7006 imm32 = (imm4H << 4) | imm4L; 7007 7008 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7009 index = BitIsSet (opcode, 24); 7010 add = BitIsSet (opcode, 23); 7011 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7012 7013 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7014 if ((t == 15) || (wback && (n == t))) 7015 return false; 7016 7017 break; 7018 } 7019 7020 default: 7021 return false; 7022 } 7023 7024 uint64_t Rn = ReadCoreReg (n, &success); 7025 if (!success) 7026 return false; 7027 7028 addr_t offset_addr; 7029 addr_t address; 7030 7031 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7032 if (add) 7033 offset_addr = Rn + imm32; 7034 else 7035 offset_addr = Rn - imm32; 7036 7037 // address = if index then offset_addr else R[n]; 7038 if (index) 7039 address = offset_addr; 7040 else 7041 address = Rn; 7042 7043 // R[t] = SignExtend(MemU[address,1], 32); 7044 RegisterInfo base_reg; 7045 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7046 7047 EmulateInstruction::Context context; 7048 context.type = eContextRegisterLoad; 7049 context.SetRegisterPlusOffset (base_reg, address - Rn); 7050 7051 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7052 if (!success) 7053 return false; 7054 7055 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7056 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7057 return false; 7058 7059 // if wback then R[n] = offset_addr; 7060 if (wback) 7061 { 7062 context.type = eContextAdjustBaseRegister; 7063 context.SetAddress (offset_addr); 7064 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7065 return false; 7066 } 7067 } 7068 7069 return true; 7070 } 7071 7072 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7073 // sign-extends it to form a 32-bit word, and writes tit to a register. 7074 bool 7075 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7076 { 7077 #if 0 7078 if ConditionPassed() then 7079 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7080 base = Align(PC,4); 7081 address = if add then (base + imm32) else (base - imm32); 7082 R[t] = SignExtend(MemU[address,1], 32); 7083 #endif 7084 7085 bool success = false; 7086 7087 if (ConditionPassed(opcode)) 7088 { 7089 uint32_t t; 7090 uint32_t imm32; 7091 bool add; 7092 7093 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7094 switch (encoding) 7095 { 7096 case eEncodingT1: 7097 // if Rt == '1111' then SEE PLI; 7098 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7099 t = Bits32 (opcode, 15, 12); 7100 imm32 = Bits32 (opcode, 11, 0); 7101 add = BitIsSet (opcode, 23); 7102 7103 // if t == 13 then UNPREDICTABLE; 7104 if (t == 13) 7105 return false; 7106 7107 break; 7108 7109 case eEncodingA1: 7110 { 7111 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7112 t = Bits32 (opcode, 15, 12); 7113 uint32_t imm4H = Bits32 (opcode, 11, 8); 7114 uint32_t imm4L = Bits32 (opcode, 3, 0); 7115 imm32 = (imm4H << 4) | imm4L; 7116 add = BitIsSet (opcode, 23); 7117 7118 // if t == 15 then UNPREDICTABLE; 7119 if (t == 15) 7120 return false; 7121 7122 break; 7123 } 7124 7125 default: 7126 return false; 7127 } 7128 7129 // base = Align(PC,4); 7130 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7131 if (!success) 7132 return false; 7133 uint64_t base = AlignPC (pc_value); 7134 7135 // address = if add then (base + imm32) else (base - imm32); 7136 addr_t address; 7137 if (add) 7138 address = base + imm32; 7139 else 7140 address = base - imm32; 7141 7142 // R[t] = SignExtend(MemU[address,1], 32); 7143 RegisterInfo base_reg; 7144 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7145 7146 EmulateInstruction::Context context; 7147 context.type = eContextRegisterLoad; 7148 context.SetRegisterPlusOffset (base_reg, address - base); 7149 7150 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7151 if (!success) 7152 return false; 7153 7154 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7155 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7156 return false; 7157 } 7158 return true; 7159 } 7160 7161 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7162 // memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7163 // shifted left by 0, 1, 2, or 3 bits. 7164 bool 7165 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7166 { 7167 #if 0 7168 if ConditionPassed() then 7169 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7170 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7171 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7172 address = if index then offset_addr else R[n]; 7173 R[t] = SignExtend(MemU[address,1], 32); 7174 if wback then R[n] = offset_addr; 7175 #endif 7176 7177 bool success = false; 7178 7179 if (ConditionPassed(opcode)) 7180 { 7181 uint32_t t; 7182 uint32_t n; 7183 uint32_t m; 7184 bool index; 7185 bool add; 7186 bool wback; 7187 ARM_ShifterType shift_t; 7188 uint32_t shift_n; 7189 7190 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7191 switch (encoding) 7192 { 7193 case eEncodingT1: 7194 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7195 t = Bits32 (opcode, 2, 0); 7196 n = Bits32 (opcode, 5, 3); 7197 m = Bits32 (opcode, 8, 6); 7198 7199 // index = TRUE; add = TRUE; wback = FALSE; 7200 index = true; 7201 add = true; 7202 wback = false; 7203 7204 // (shift_t, shift_n) = (SRType_LSL, 0); 7205 shift_t = SRType_LSL; 7206 shift_n = 0; 7207 7208 break; 7209 7210 case eEncodingT2: 7211 // if Rt == '1111' then SEE PLI; 7212 // if Rn == '1111' then SEE LDRSB (literal); 7213 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7214 t = Bits32 (opcode, 15, 12); 7215 n = Bits32 (opcode, 19, 16); 7216 m = Bits32 (opcode, 3, 0); 7217 7218 // index = TRUE; add = TRUE; wback = FALSE; 7219 index = true; 7220 add = true; 7221 wback = false; 7222 7223 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7224 shift_t = SRType_LSL; 7225 shift_n = Bits32 (opcode, 5, 4); 7226 7227 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7228 if ((t == 13) || BadReg (m)) 7229 return false; 7230 break; 7231 7232 case eEncodingA1: 7233 // if P == '0' && W == '1' then SEE LDRSBT; 7234 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7235 t = Bits32 (opcode, 15, 12); 7236 n = Bits32 (opcode, 19, 16); 7237 m = Bits32 (opcode, 3, 0); 7238 7239 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7240 index = BitIsSet (opcode, 24); 7241 add = BitIsSet (opcode, 23); 7242 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7243 7244 // (shift_t, shift_n) = (SRType_LSL, 0); 7245 shift_t = SRType_LSL; 7246 shift_n = 0; 7247 7248 // if t == 15 || m == 15 then UNPREDICTABLE; 7249 if ((t == 15) || (m == 15)) 7250 return false; 7251 7252 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7253 if (wback && ((n == 15) || (n == t))) 7254 return false; 7255 break; 7256 7257 default: 7258 return false; 7259 } 7260 7261 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7262 if (!success) 7263 return false; 7264 7265 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7266 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7267 if (!success) 7268 return false; 7269 7270 addr_t offset_addr; 7271 addr_t address; 7272 7273 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7274 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7275 if (!success) 7276 return false; 7277 7278 if (add) 7279 offset_addr = Rn + offset; 7280 else 7281 offset_addr = Rn - offset; 7282 7283 // address = if index then offset_addr else R[n]; 7284 if (index) 7285 address = offset_addr; 7286 else 7287 address = Rn; 7288 7289 // R[t] = SignExtend(MemU[address,1], 32); 7290 RegisterInfo base_reg; 7291 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7292 RegisterInfo offset_reg; 7293 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7294 7295 EmulateInstruction::Context context; 7296 context.type = eContextRegisterLoad; 7297 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7298 7299 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7300 if (!success) 7301 return false; 7302 7303 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7304 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7305 return false; 7306 7307 // if wback then R[n] = offset_addr; 7308 if (wback) 7309 { 7310 context.type = eContextAdjustBaseRegister; 7311 context.SetAddress (offset_addr); 7312 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7313 return false; 7314 } 7315 } 7316 return true; 7317 } 7318 7319 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7320 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7321 // pre-indexed addressing. 7322 bool 7323 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7324 { 7325 #if 0 7326 if ConditionPassed() then 7327 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7328 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7329 address = if index then offset_addr else R[n]; 7330 data = MemU[address,2]; 7331 if wback then R[n] = offset_addr; 7332 if UnalignedSupport() || address<0> = '0' then 7333 R[t] = SignExtend(data, 32); 7334 else // Can only apply before ARMv7 7335 R[t] = bits(32) UNKNOWN; 7336 #endif 7337 7338 bool success = false; 7339 7340 if (ConditionPassed(opcode)) 7341 { 7342 uint32_t t; 7343 uint32_t n; 7344 uint32_t imm32; 7345 bool index; 7346 bool add; 7347 bool wback; 7348 7349 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7350 switch (encoding) 7351 { 7352 case eEncodingT1: 7353 // if Rn == '1111' then SEE LDRSH (literal); 7354 // if Rt == '1111' then SEE "Unallocated memory hints"; 7355 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7356 t = Bits32 (opcode, 15, 12); 7357 n = Bits32 (opcode, 19, 16); 7358 imm32 = Bits32 (opcode, 11, 0); 7359 7360 // index = TRUE; add = TRUE; wback = FALSE; 7361 index = true; 7362 add = true; 7363 wback = false; 7364 7365 // if t == 13 then UNPREDICTABLE; 7366 if (t == 13) 7367 return false; 7368 7369 break; 7370 7371 case eEncodingT2: 7372 // if Rn == '1111' then SEE LDRSH (literal); 7373 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7374 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7375 // if P == '0' && W == '0' then UNDEFINED; 7376 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7377 return false; 7378 7379 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7380 t = Bits32 (opcode, 15, 12); 7381 n = Bits32 (opcode, 19, 16); 7382 imm32 = Bits32 (opcode, 7, 0); 7383 7384 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7385 index = BitIsSet (opcode, 10); 7386 add = BitIsSet (opcode, 9); 7387 wback = BitIsSet (opcode, 8); 7388 7389 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7390 if (BadReg (t) || (wback && (n == t))) 7391 return false; 7392 7393 break; 7394 7395 case eEncodingA1: 7396 { 7397 // if Rn == '1111' then SEE LDRSH (literal); 7398 // if P == '0' && W == '1' then SEE LDRSHT; 7399 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7400 t = Bits32 (opcode, 15, 12); 7401 n = Bits32 (opcode, 19, 16); 7402 uint32_t imm4H = Bits32 (opcode, 11,8); 7403 uint32_t imm4L = Bits32 (opcode, 3, 0); 7404 imm32 = (imm4H << 4) | imm4L; 7405 7406 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7407 index = BitIsSet (opcode, 24); 7408 add = BitIsSet (opcode, 23); 7409 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7410 7411 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7412 if ((t == 15) || (wback && (n == t))) 7413 return false; 7414 7415 break; 7416 } 7417 7418 default: 7419 return false; 7420 } 7421 7422 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7423 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7424 if (!success) 7425 return false; 7426 7427 addr_t offset_addr; 7428 if (add) 7429 offset_addr = Rn + imm32; 7430 else 7431 offset_addr = Rn - imm32; 7432 7433 // address = if index then offset_addr else R[n]; 7434 addr_t address; 7435 if (index) 7436 address = offset_addr; 7437 else 7438 address = Rn; 7439 7440 // data = MemU[address,2]; 7441 RegisterInfo base_reg; 7442 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7443 7444 EmulateInstruction::Context context; 7445 context.type = eContextRegisterLoad; 7446 context.SetRegisterPlusOffset (base_reg, address - Rn); 7447 7448 uint64_t data = MemURead (context, address, 2, 0, &success); 7449 if (!success) 7450 return false; 7451 7452 // if wback then R[n] = offset_addr; 7453 if (wback) 7454 { 7455 context.type = eContextAdjustBaseRegister; 7456 context.SetAddress (offset_addr); 7457 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7458 return false; 7459 } 7460 7461 // if UnalignedSupport() || address<0> = '0' then 7462 if (UnalignedSupport() || BitIsClear (address, 0)) 7463 { 7464 // R[t] = SignExtend(data, 32); 7465 int64_t signed_data = llvm::SignExtend64<16>(data); 7466 context.type = eContextRegisterLoad; 7467 context.SetRegisterPlusOffset (base_reg, address - Rn); 7468 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7469 return false; 7470 } 7471 else // Can only apply before ARMv7 7472 { 7473 // R[t] = bits(32) UNKNOWN; 7474 WriteBits32Unknown (t); 7475 } 7476 } 7477 return true; 7478 } 7479 7480 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7481 // sign-extends it to from a 32-bit word, and writes it to a register. 7482 bool 7483 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7484 { 7485 #if 0 7486 if ConditionPassed() then 7487 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7488 base = Align(PC,4); 7489 address = if add then (base + imm32) else (base - imm32); 7490 data = MemU[address,2]; 7491 if UnalignedSupport() || address<0> = '0' then 7492 R[t] = SignExtend(data, 32); 7493 else // Can only apply before ARMv7 7494 R[t] = bits(32) UNKNOWN; 7495 #endif 7496 7497 bool success = false; 7498 7499 if (ConditionPassed(opcode)) 7500 { 7501 uint32_t t; 7502 uint32_t imm32; 7503 bool add; 7504 7505 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7506 switch (encoding) 7507 { 7508 case eEncodingT1: 7509 // if Rt == '1111' then SEE "Unallocated memory hints"; 7510 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7511 t = Bits32 (opcode, 15, 12); 7512 imm32 = Bits32 (opcode, 11, 0); 7513 add = BitIsSet (opcode, 23); 7514 7515 // if t == 13 then UNPREDICTABLE; 7516 if (t == 13) 7517 return false; 7518 7519 break; 7520 7521 case eEncodingA1: 7522 { 7523 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7524 t = Bits32 (opcode, 15, 12); 7525 uint32_t imm4H = Bits32 (opcode, 11, 8); 7526 uint32_t imm4L = Bits32 (opcode, 3, 0); 7527 imm32 = (imm4H << 4) | imm4L; 7528 add = BitIsSet (opcode, 23); 7529 7530 // if t == 15 then UNPREDICTABLE; 7531 if (t == 15) 7532 return false; 7533 7534 break; 7535 } 7536 default: 7537 return false; 7538 } 7539 7540 // base = Align(PC,4); 7541 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7542 if (!success) 7543 return false; 7544 7545 uint64_t base = AlignPC (pc_value); 7546 7547 addr_t address; 7548 // address = if add then (base + imm32) else (base - imm32); 7549 if (add) 7550 address = base + imm32; 7551 else 7552 address = base - imm32; 7553 7554 // data = MemU[address,2]; 7555 RegisterInfo base_reg; 7556 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7557 7558 EmulateInstruction::Context context; 7559 context.type = eContextRegisterLoad; 7560 context.SetRegisterPlusOffset (base_reg, imm32); 7561 7562 uint64_t data = MemURead (context, address, 2, 0, &success); 7563 if (!success) 7564 return false; 7565 7566 // if UnalignedSupport() || address<0> = '0' then 7567 if (UnalignedSupport() || BitIsClear (address, 0)) 7568 { 7569 // R[t] = SignExtend(data, 32); 7570 int64_t signed_data = llvm::SignExtend64<16>(data); 7571 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7572 return false; 7573 } 7574 else // Can only apply before ARMv7 7575 { 7576 // R[t] = bits(32) UNKNOWN; 7577 WriteBits32Unknown (t); 7578 } 7579 } 7580 return true; 7581 } 7582 7583 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7584 // from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7585 // shifted left by 0, 1, 2, or 3 bits. 7586 bool 7587 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7588 { 7589 #if 0 7590 if ConditionPassed() then 7591 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7592 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7593 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7594 address = if index then offset_addr else R[n]; 7595 data = MemU[address,2]; 7596 if wback then R[n] = offset_addr; 7597 if UnalignedSupport() || address<0> = '0' then 7598 R[t] = SignExtend(data, 32); 7599 else // Can only apply before ARMv7 7600 R[t] = bits(32) UNKNOWN; 7601 #endif 7602 7603 bool success = false; 7604 7605 if (ConditionPassed(opcode)) 7606 { 7607 uint32_t t; 7608 uint32_t n; 7609 uint32_t m; 7610 bool index; 7611 bool add; 7612 bool wback; 7613 ARM_ShifterType shift_t; 7614 uint32_t shift_n; 7615 7616 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7617 switch (encoding) 7618 { 7619 case eEncodingT1: 7620 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7621 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7622 t = Bits32 (opcode, 2, 0); 7623 n = Bits32 (opcode, 5, 3); 7624 m = Bits32 (opcode, 8, 6); 7625 7626 // index = TRUE; add = TRUE; wback = FALSE; 7627 index = true; 7628 add = true; 7629 wback = false; 7630 7631 // (shift_t, shift_n) = (SRType_LSL, 0); 7632 shift_t = SRType_LSL; 7633 shift_n = 0; 7634 7635 break; 7636 7637 case eEncodingT2: 7638 // if Rn == '1111' then SEE LDRSH (literal); 7639 // if Rt == '1111' then SEE "Unallocated memory hints"; 7640 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7641 t = Bits32 (opcode, 15, 12); 7642 n = Bits32 (opcode, 19, 16); 7643 m = Bits32 (opcode, 3, 0); 7644 7645 // index = TRUE; add = TRUE; wback = FALSE; 7646 index = true; 7647 add = true; 7648 wback = false; 7649 7650 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7651 shift_t = SRType_LSL; 7652 shift_n = Bits32 (opcode, 5, 4); 7653 7654 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7655 if ((t == 13) || BadReg (m)) 7656 return false; 7657 7658 break; 7659 7660 case eEncodingA1: 7661 // if P == '0' && W == '1' then SEE LDRSHT; 7662 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7663 t = Bits32 (opcode, 15, 12); 7664 n = Bits32 (opcode, 19, 16); 7665 m = Bits32 (opcode, 3, 0); 7666 7667 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7668 index = BitIsSet (opcode, 24); 7669 add = BitIsSet (opcode, 23); 7670 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7671 7672 // (shift_t, shift_n) = (SRType_LSL, 0); 7673 shift_t = SRType_LSL; 7674 shift_n = 0; 7675 7676 // if t == 15 || m == 15 then UNPREDICTABLE; 7677 if ((t == 15) || (m == 15)) 7678 return false; 7679 7680 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7681 if (wback && ((n == 15) || (n == t))) 7682 return false; 7683 7684 break; 7685 7686 default: 7687 return false; 7688 } 7689 7690 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7691 if (!success) 7692 return false; 7693 7694 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7695 if (!success) 7696 return false; 7697 7698 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7699 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7700 if (!success) 7701 return false; 7702 7703 addr_t offset_addr; 7704 addr_t address; 7705 7706 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7707 if (add) 7708 offset_addr = Rn + offset; 7709 else 7710 offset_addr = Rn - offset; 7711 7712 // address = if index then offset_addr else R[n]; 7713 if (index) 7714 address = offset_addr; 7715 else 7716 address = Rn; 7717 7718 // data = MemU[address,2]; 7719 RegisterInfo base_reg; 7720 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7721 7722 RegisterInfo offset_reg; 7723 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7724 7725 EmulateInstruction::Context context; 7726 context.type = eContextRegisterLoad; 7727 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7728 7729 uint64_t data = MemURead (context, address, 2, 0, &success); 7730 if (!success) 7731 return false; 7732 7733 // if wback then R[n] = offset_addr; 7734 if (wback) 7735 { 7736 context.type = eContextAdjustBaseRegister; 7737 context.SetAddress (offset_addr); 7738 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7739 return false; 7740 } 7741 7742 // if UnalignedSupport() || address<0> = '0' then 7743 if (UnalignedSupport() || BitIsClear (address, 0)) 7744 { 7745 // R[t] = SignExtend(data, 32); 7746 context.type = eContextRegisterLoad; 7747 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7748 7749 int64_t signed_data = llvm::SignExtend64<16>(data); 7750 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7751 return false; 7752 } 7753 else // Can only apply before ARMv7 7754 { 7755 // R[t] = bits(32) UNKNOWN; 7756 WriteBits32Unknown (t); 7757 } 7758 } 7759 return true; 7760 } 7761 7762 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7763 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7764 bool 7765 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7766 { 7767 #if 0 7768 if ConditionPassed() then 7769 EncodingSpecificOperations(); 7770 rotated = ROR(R[m], rotation); 7771 R[d] = SignExtend(rotated<7:0>, 32); 7772 #endif 7773 7774 bool success = false; 7775 7776 if (ConditionPassed(opcode)) 7777 { 7778 uint32_t d; 7779 uint32_t m; 7780 uint32_t rotation; 7781 7782 // EncodingSpecificOperations(); 7783 switch (encoding) 7784 { 7785 case eEncodingT1: 7786 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7787 d = Bits32 (opcode, 2, 0); 7788 m = Bits32 (opcode, 5, 3); 7789 rotation = 0; 7790 7791 break; 7792 7793 case eEncodingT2: 7794 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7795 d = Bits32 (opcode, 11, 8); 7796 m = Bits32 (opcode, 3, 0); 7797 rotation = Bits32 (opcode, 5, 4) << 3; 7798 7799 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7800 if (BadReg (d) || BadReg (m)) 7801 return false; 7802 7803 break; 7804 7805 case eEncodingA1: 7806 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7807 d = Bits32 (opcode, 15, 12); 7808 m = Bits32 (opcode, 3, 0); 7809 rotation = Bits32 (opcode, 11, 10) << 3; 7810 7811 // if d == 15 || m == 15 then UNPREDICTABLE; 7812 if ((d == 15) || (m == 15)) 7813 return false; 7814 7815 break; 7816 7817 default: 7818 return false; 7819 } 7820 7821 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7822 if (!success) 7823 return false; 7824 7825 // rotated = ROR(R[m], rotation); 7826 uint64_t rotated = ROR (Rm, rotation, &success); 7827 if (!success) 7828 return false; 7829 7830 // R[d] = SignExtend(rotated<7:0>, 32); 7831 int64_t data = llvm::SignExtend64<8>(rotated); 7832 7833 RegisterInfo source_reg; 7834 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7835 7836 EmulateInstruction::Context context; 7837 context.type = eContextRegisterLoad; 7838 context.SetRegister (source_reg); 7839 7840 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7841 return false; 7842 } 7843 return true; 7844 } 7845 7846 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7847 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7848 bool 7849 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7850 { 7851 #if 0 7852 if ConditionPassed() then 7853 EncodingSpecificOperations(); 7854 rotated = ROR(R[m], rotation); 7855 R[d] = SignExtend(rotated<15:0>, 32); 7856 #endif 7857 7858 bool success = false; 7859 7860 if (ConditionPassed(opcode)) 7861 { 7862 uint32_t d; 7863 uint32_t m; 7864 uint32_t rotation; 7865 7866 // EncodingSpecificOperations(); 7867 switch (encoding) 7868 { 7869 case eEncodingT1: 7870 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7871 d = Bits32 (opcode, 2, 0); 7872 m = Bits32 (opcode, 5, 3); 7873 rotation = 0; 7874 7875 break; 7876 7877 case eEncodingT2: 7878 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7879 d = Bits32 (opcode, 11, 8); 7880 m = Bits32 (opcode, 3, 0); 7881 rotation = Bits32 (opcode, 5, 4) << 3; 7882 7883 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7884 if (BadReg (d) || BadReg (m)) 7885 return false; 7886 7887 break; 7888 7889 case eEncodingA1: 7890 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7891 d = Bits32 (opcode, 15, 12); 7892 m = Bits32 (opcode, 3, 0); 7893 rotation = Bits32 (opcode, 11, 10) << 3; 7894 7895 // if d == 15 || m == 15 then UNPREDICTABLE; 7896 if ((d == 15) || (m == 15)) 7897 return false; 7898 7899 break; 7900 7901 default: 7902 return false; 7903 } 7904 7905 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7906 if (!success) 7907 return false; 7908 7909 // rotated = ROR(R[m], rotation); 7910 uint64_t rotated = ROR (Rm, rotation, &success); 7911 if (!success) 7912 return false; 7913 7914 // R[d] = SignExtend(rotated<15:0>, 32); 7915 RegisterInfo source_reg; 7916 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7917 7918 EmulateInstruction::Context context; 7919 context.type = eContextRegisterLoad; 7920 context.SetRegister (source_reg); 7921 7922 int64_t data = llvm::SignExtend64<16> (rotated); 7923 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7924 return false; 7925 } 7926 7927 return true; 7928 } 7929 7930 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 7931 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7932 bool 7933 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 7934 { 7935 #if 0 7936 if ConditionPassed() then 7937 EncodingSpecificOperations(); 7938 rotated = ROR(R[m], rotation); 7939 R[d] = ZeroExtend(rotated<7:0>, 32); 7940 #endif 7941 7942 bool success = false; 7943 7944 if (ConditionPassed(opcode)) 7945 { 7946 uint32_t d; 7947 uint32_t m; 7948 uint32_t rotation; 7949 7950 // EncodingSpecificOperations(); 7951 switch (encoding) 7952 { 7953 case eEncodingT1: 7954 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7955 d = Bits32 (opcode, 2, 0); 7956 m = Bits32 (opcode, 5, 3); 7957 rotation = 0; 7958 7959 break; 7960 7961 case eEncodingT2: 7962 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7963 d = Bits32 (opcode, 11, 8); 7964 m = Bits32 (opcode, 3, 0); 7965 rotation = Bits32 (opcode, 5, 4) << 3; 7966 7967 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7968 if (BadReg (d) || BadReg (m)) 7969 return false; 7970 7971 break; 7972 7973 case eEncodingA1: 7974 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7975 d = Bits32 (opcode, 15, 12); 7976 m = Bits32 (opcode, 3, 0); 7977 rotation = Bits32 (opcode, 11, 10) << 3; 7978 7979 // if d == 15 || m == 15 then UNPREDICTABLE; 7980 if ((d == 15) || (m == 15)) 7981 return false; 7982 7983 break; 7984 7985 default: 7986 return false; 7987 } 7988 7989 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7990 if (!success) 7991 return false; 7992 7993 // rotated = ROR(R[m], rotation); 7994 uint64_t rotated = ROR (Rm, rotation, &success); 7995 if (!success) 7996 return false; 7997 7998 // R[d] = ZeroExtend(rotated<7:0>, 32); 7999 RegisterInfo source_reg; 8000 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8001 8002 EmulateInstruction::Context context; 8003 context.type = eContextRegisterLoad; 8004 context.SetRegister (source_reg); 8005 8006 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 8007 return false; 8008 } 8009 return true; 8010 } 8011 8012 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 8013 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 8014 bool 8015 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 8016 { 8017 #if 0 8018 if ConditionPassed() then 8019 EncodingSpecificOperations(); 8020 rotated = ROR(R[m], rotation); 8021 R[d] = ZeroExtend(rotated<15:0>, 32); 8022 #endif 8023 8024 bool success = false; 8025 8026 if (ConditionPassed(opcode)) 8027 { 8028 uint32_t d; 8029 uint32_t m; 8030 uint32_t rotation; 8031 8032 switch (encoding) 8033 { 8034 case eEncodingT1: 8035 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8036 d = Bits32 (opcode, 2, 0); 8037 m = Bits32 (opcode, 5, 3); 8038 rotation = 0; 8039 8040 break; 8041 8042 case eEncodingT2: 8043 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8044 d = Bits32 (opcode, 11, 8); 8045 m = Bits32 (opcode, 3, 0); 8046 rotation = Bits32 (opcode, 5, 4) << 3; 8047 8048 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8049 if (BadReg (d) || BadReg (m)) 8050 return false; 8051 8052 break; 8053 8054 case eEncodingA1: 8055 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8056 d = Bits32 (opcode, 15, 12); 8057 m = Bits32 (opcode, 3, 0); 8058 rotation = Bits32 (opcode, 11, 10) << 3; 8059 8060 // if d == 15 || m == 15 then UNPREDICTABLE; 8061 if ((d == 15) || (m == 15)) 8062 return false; 8063 8064 break; 8065 8066 default: 8067 return false; 8068 } 8069 8070 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8071 if (!success) 8072 return false; 8073 8074 // rotated = ROR(R[m], rotation); 8075 uint64_t rotated = ROR (Rm, rotation, &success); 8076 if (!success) 8077 return false; 8078 8079 // R[d] = ZeroExtend(rotated<15:0>, 32); 8080 RegisterInfo source_reg; 8081 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8082 8083 EmulateInstruction::Context context; 8084 context.type = eContextRegisterLoad; 8085 context.SetRegister (source_reg); 8086 8087 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8088 return false; 8089 } 8090 return true; 8091 } 8092 8093 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8094 // word respectively. 8095 bool 8096 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8097 { 8098 #if 0 8099 if ConditionPassed() then 8100 EncodingSpecificOperations(); 8101 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8102 UNPREDICTABLE; 8103 else 8104 address = if increment then R[n] else R[n]-8; 8105 if wordhigher then address = address+4; 8106 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8107 BranchWritePC(MemA[address,4]); 8108 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8109 #endif 8110 8111 bool success = false; 8112 8113 if (ConditionPassed(opcode)) 8114 { 8115 uint32_t n; 8116 bool wback; 8117 bool increment; 8118 bool wordhigher; 8119 8120 // EncodingSpecificOperations(); 8121 switch (encoding) 8122 { 8123 case eEncodingT1: 8124 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8125 n = Bits32 (opcode, 19, 16); 8126 wback = BitIsSet (opcode, 21); 8127 increment = false; 8128 wordhigher = false; 8129 8130 // if n == 15 then UNPREDICTABLE; 8131 if (n == 15) 8132 return false; 8133 8134 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8135 if (InITBlock() && !LastInITBlock()) 8136 return false; 8137 8138 break; 8139 8140 case eEncodingT2: 8141 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8142 n = Bits32 (opcode, 19, 16); 8143 wback = BitIsSet (opcode, 21); 8144 increment = true; 8145 wordhigher = false; 8146 8147 // if n == 15 then UNPREDICTABLE; 8148 if (n == 15) 8149 return false; 8150 8151 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8152 if (InITBlock() && !LastInITBlock()) 8153 return false; 8154 8155 break; 8156 8157 case eEncodingA1: 8158 // n = UInt(Rn); 8159 n = Bits32 (opcode, 19, 16); 8160 8161 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8162 wback = BitIsSet (opcode, 21); 8163 increment = BitIsSet (opcode, 23); 8164 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8165 8166 // if n == 15 then UNPREDICTABLE; 8167 if (n == 15) 8168 return false; 8169 8170 break; 8171 8172 default: 8173 return false; 8174 } 8175 8176 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8177 if (!CurrentModeIsPrivileged ()) 8178 // UNPREDICTABLE; 8179 return false; 8180 else 8181 { 8182 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8183 if (!success) 8184 return false; 8185 8186 addr_t address; 8187 // address = if increment then R[n] else R[n]-8; 8188 if (increment) 8189 address = Rn; 8190 else 8191 address = Rn - 8; 8192 8193 // if wordhigher then address = address+4; 8194 if (wordhigher) 8195 address = address + 4; 8196 8197 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8198 RegisterInfo base_reg; 8199 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8200 8201 EmulateInstruction::Context context; 8202 context.type = eContextReturnFromException; 8203 context.SetRegisterPlusOffset (base_reg, address - Rn); 8204 8205 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8206 if (!success) 8207 return false; 8208 8209 CPSRWriteByInstr (data, 15, true); 8210 8211 // BranchWritePC(MemA[address,4]); 8212 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8213 if (!success) 8214 return false; 8215 8216 BranchWritePC (context, data2); 8217 8218 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8219 if (wback) 8220 { 8221 context.type = eContextAdjustBaseRegister; 8222 if (increment) 8223 { 8224 context.SetOffset (8); 8225 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8226 return false; 8227 } 8228 else 8229 { 8230 context.SetOffset (-8); 8231 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8232 return false; 8233 } 8234 } // if wback 8235 } 8236 } // if ConditionPassed() 8237 return true; 8238 } 8239 8240 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8241 // and writes the result to the destination register. It can optionally update the condition flags based on 8242 // the result. 8243 bool 8244 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8245 { 8246 #if 0 8247 // ARM pseudo code... 8248 if ConditionPassed() then 8249 EncodingSpecificOperations(); 8250 result = R[n] EOR imm32; 8251 if d == 15 then // Can only occur for ARM encoding 8252 ALUWritePC(result); // setflags is always FALSE here 8253 else 8254 R[d] = result; 8255 if setflags then 8256 APSR.N = result<31>; 8257 APSR.Z = IsZeroBit(result); 8258 APSR.C = carry; 8259 // APSR.V unchanged 8260 #endif 8261 8262 bool success = false; 8263 8264 if (ConditionPassed(opcode)) 8265 { 8266 uint32_t Rd, Rn; 8267 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8268 bool setflags; 8269 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8270 switch (encoding) 8271 { 8272 case eEncodingT1: 8273 Rd = Bits32(opcode, 11, 8); 8274 Rn = Bits32(opcode, 19, 16); 8275 setflags = BitIsSet(opcode, 20); 8276 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8277 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8278 if (Rd == 15 && setflags) 8279 return EmulateTEQImm (opcode, eEncodingT1); 8280 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8281 return false; 8282 break; 8283 case eEncodingA1: 8284 Rd = Bits32(opcode, 15, 12); 8285 Rn = Bits32(opcode, 19, 16); 8286 setflags = BitIsSet(opcode, 20); 8287 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8288 8289 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8290 if (Rd == 15 && setflags) 8291 return EmulateSUBSPcLrEtc (opcode, encoding); 8292 break; 8293 default: 8294 return false; 8295 } 8296 8297 // Read the first operand. 8298 uint32_t val1 = ReadCoreReg(Rn, &success); 8299 if (!success) 8300 return false; 8301 8302 uint32_t result = val1 ^ imm32; 8303 8304 EmulateInstruction::Context context; 8305 context.type = EmulateInstruction::eContextImmediate; 8306 context.SetNoArgs (); 8307 8308 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8309 return false; 8310 } 8311 return true; 8312 } 8313 8314 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8315 // optionally-shifted register value, and writes the result to the destination register. 8316 // It can optionally update the condition flags based on the result. 8317 bool 8318 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8319 { 8320 #if 0 8321 // ARM pseudo code... 8322 if ConditionPassed() then 8323 EncodingSpecificOperations(); 8324 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8325 result = R[n] EOR shifted; 8326 if d == 15 then // Can only occur for ARM encoding 8327 ALUWritePC(result); // setflags is always FALSE here 8328 else 8329 R[d] = result; 8330 if setflags then 8331 APSR.N = result<31>; 8332 APSR.Z = IsZeroBit(result); 8333 APSR.C = carry; 8334 // APSR.V unchanged 8335 #endif 8336 8337 bool success = false; 8338 8339 if (ConditionPassed(opcode)) 8340 { 8341 uint32_t Rd, Rn, Rm; 8342 ARM_ShifterType shift_t; 8343 uint32_t shift_n; // the shift applied to the value read from Rm 8344 bool setflags; 8345 uint32_t carry; 8346 switch (encoding) 8347 { 8348 case eEncodingT1: 8349 Rd = Rn = Bits32(opcode, 2, 0); 8350 Rm = Bits32(opcode, 5, 3); 8351 setflags = !InITBlock(); 8352 shift_t = SRType_LSL; 8353 shift_n = 0; 8354 break; 8355 case eEncodingT2: 8356 Rd = Bits32(opcode, 11, 8); 8357 Rn = Bits32(opcode, 19, 16); 8358 Rm = Bits32(opcode, 3, 0); 8359 setflags = BitIsSet(opcode, 20); 8360 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8361 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8362 if (Rd == 15 && setflags) 8363 return EmulateTEQReg (opcode, eEncodingT1); 8364 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8365 return false; 8366 break; 8367 case eEncodingA1: 8368 Rd = Bits32(opcode, 15, 12); 8369 Rn = Bits32(opcode, 19, 16); 8370 Rm = Bits32(opcode, 3, 0); 8371 setflags = BitIsSet(opcode, 20); 8372 shift_n = DecodeImmShiftARM(opcode, shift_t); 8373 8374 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8375 if (Rd == 15 && setflags) 8376 return EmulateSUBSPcLrEtc (opcode, encoding); 8377 break; 8378 default: 8379 return false; 8380 } 8381 8382 // Read the first operand. 8383 uint32_t val1 = ReadCoreReg(Rn, &success); 8384 if (!success) 8385 return false; 8386 8387 // Read the second operand. 8388 uint32_t val2 = ReadCoreReg(Rm, &success); 8389 if (!success) 8390 return false; 8391 8392 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8393 if (!success) 8394 return false; 8395 uint32_t result = val1 ^ shifted; 8396 8397 EmulateInstruction::Context context; 8398 context.type = EmulateInstruction::eContextImmediate; 8399 context.SetNoArgs (); 8400 8401 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8402 return false; 8403 } 8404 return true; 8405 } 8406 8407 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8408 // writes the result to the destination register. It can optionally update the condition flags based 8409 // on the result. 8410 bool 8411 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8412 { 8413 #if 0 8414 // ARM pseudo code... 8415 if ConditionPassed() then 8416 EncodingSpecificOperations(); 8417 result = R[n] OR imm32; 8418 if d == 15 then // Can only occur for ARM encoding 8419 ALUWritePC(result); // setflags is always FALSE here 8420 else 8421 R[d] = result; 8422 if setflags then 8423 APSR.N = result<31>; 8424 APSR.Z = IsZeroBit(result); 8425 APSR.C = carry; 8426 // APSR.V unchanged 8427 #endif 8428 8429 bool success = false; 8430 8431 if (ConditionPassed(opcode)) 8432 { 8433 uint32_t Rd, Rn; 8434 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8435 bool setflags; 8436 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8437 switch (encoding) 8438 { 8439 case eEncodingT1: 8440 Rd = Bits32(opcode, 11, 8); 8441 Rn = Bits32(opcode, 19, 16); 8442 setflags = BitIsSet(opcode, 20); 8443 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8444 // if Rn == '1111' then SEE MOV (immediate); 8445 if (Rn == 15) 8446 return EmulateMOVRdImm (opcode, eEncodingT2); 8447 if (BadReg(Rd) || Rn == 13) 8448 return false; 8449 break; 8450 case eEncodingA1: 8451 Rd = Bits32(opcode, 15, 12); 8452 Rn = Bits32(opcode, 19, 16); 8453 setflags = BitIsSet(opcode, 20); 8454 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8455 8456 if (Rd == 15 && setflags) 8457 return EmulateSUBSPcLrEtc (opcode, encoding); 8458 break; 8459 default: 8460 return false; 8461 } 8462 8463 // Read the first operand. 8464 uint32_t val1 = ReadCoreReg(Rn, &success); 8465 if (!success) 8466 return false; 8467 8468 uint32_t result = val1 | imm32; 8469 8470 EmulateInstruction::Context context; 8471 context.type = EmulateInstruction::eContextImmediate; 8472 context.SetNoArgs (); 8473 8474 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8475 return false; 8476 } 8477 return true; 8478 } 8479 8480 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8481 // value, and writes the result to the destination register. It can optionally update the condition flags based 8482 // on the result. 8483 bool 8484 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8485 { 8486 #if 0 8487 // ARM pseudo code... 8488 if ConditionPassed() then 8489 EncodingSpecificOperations(); 8490 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8491 result = R[n] OR shifted; 8492 if d == 15 then // Can only occur for ARM encoding 8493 ALUWritePC(result); // setflags is always FALSE here 8494 else 8495 R[d] = result; 8496 if setflags then 8497 APSR.N = result<31>; 8498 APSR.Z = IsZeroBit(result); 8499 APSR.C = carry; 8500 // APSR.V unchanged 8501 #endif 8502 8503 bool success = false; 8504 8505 if (ConditionPassed(opcode)) 8506 { 8507 uint32_t Rd, Rn, Rm; 8508 ARM_ShifterType shift_t; 8509 uint32_t shift_n; // the shift applied to the value read from Rm 8510 bool setflags; 8511 uint32_t carry; 8512 switch (encoding) 8513 { 8514 case eEncodingT1: 8515 Rd = Rn = Bits32(opcode, 2, 0); 8516 Rm = Bits32(opcode, 5, 3); 8517 setflags = !InITBlock(); 8518 shift_t = SRType_LSL; 8519 shift_n = 0; 8520 break; 8521 case eEncodingT2: 8522 Rd = Bits32(opcode, 11, 8); 8523 Rn = Bits32(opcode, 19, 16); 8524 Rm = Bits32(opcode, 3, 0); 8525 setflags = BitIsSet(opcode, 20); 8526 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8527 // if Rn == '1111' then SEE MOV (register); 8528 if (Rn == 15) 8529 return EmulateMOVRdRm (opcode, eEncodingT3); 8530 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8531 return false; 8532 break; 8533 case eEncodingA1: 8534 Rd = Bits32(opcode, 15, 12); 8535 Rn = Bits32(opcode, 19, 16); 8536 Rm = Bits32(opcode, 3, 0); 8537 setflags = BitIsSet(opcode, 20); 8538 shift_n = DecodeImmShiftARM(opcode, shift_t); 8539 8540 if (Rd == 15 && setflags) 8541 return EmulateSUBSPcLrEtc (opcode, encoding); 8542 break; 8543 default: 8544 return false; 8545 } 8546 8547 // Read the first operand. 8548 uint32_t val1 = ReadCoreReg(Rn, &success); 8549 if (!success) 8550 return false; 8551 8552 // Read the second operand. 8553 uint32_t val2 = ReadCoreReg(Rm, &success); 8554 if (!success) 8555 return false; 8556 8557 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8558 if (!success) 8559 return false; 8560 uint32_t result = val1 | shifted; 8561 8562 EmulateInstruction::Context context; 8563 context.type = EmulateInstruction::eContextImmediate; 8564 context.SetNoArgs (); 8565 8566 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8567 return false; 8568 } 8569 return true; 8570 } 8571 8572 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8573 // the destination register. It can optionally update the condition flags based on the result. 8574 bool 8575 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8576 { 8577 #if 0 8578 // ARM pseudo code... 8579 if ConditionPassed() then 8580 EncodingSpecificOperations(); 8581 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8582 if d == 15 then // Can only occur for ARM encoding 8583 ALUWritePC(result); // setflags is always FALSE here 8584 else 8585 R[d] = result; 8586 if setflags then 8587 APSR.N = result<31>; 8588 APSR.Z = IsZeroBit(result); 8589 APSR.C = carry; 8590 APSR.V = overflow; 8591 #endif 8592 8593 bool success = false; 8594 8595 uint32_t Rd; // the destination register 8596 uint32_t Rn; // the first operand 8597 bool setflags; 8598 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8599 switch (encoding) { 8600 case eEncodingT1: 8601 Rd = Bits32(opcode, 2, 0); 8602 Rn = Bits32(opcode, 5, 3); 8603 setflags = !InITBlock(); 8604 imm32 = 0; 8605 break; 8606 case eEncodingT2: 8607 Rd = Bits32(opcode, 11, 8); 8608 Rn = Bits32(opcode, 19, 16); 8609 setflags = BitIsSet(opcode, 20); 8610 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8611 if (BadReg(Rd) || BadReg(Rn)) 8612 return false; 8613 break; 8614 case eEncodingA1: 8615 Rd = Bits32(opcode, 15, 12); 8616 Rn = Bits32(opcode, 19, 16); 8617 setflags = BitIsSet(opcode, 20); 8618 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8619 8620 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8621 if (Rd == 15 && setflags) 8622 return EmulateSUBSPcLrEtc (opcode, encoding); 8623 break; 8624 default: 8625 return false; 8626 } 8627 // Read the register value from the operand register Rn. 8628 uint32_t reg_val = ReadCoreReg(Rn, &success); 8629 if (!success) 8630 return false; 8631 8632 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8633 8634 EmulateInstruction::Context context; 8635 context.type = EmulateInstruction::eContextImmediate; 8636 context.SetNoArgs (); 8637 8638 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8639 return false; 8640 8641 return true; 8642 } 8643 8644 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8645 // result to the destination register. It can optionally update the condition flags based on the result. 8646 bool 8647 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8648 { 8649 #if 0 8650 // ARM pseudo code... 8651 if ConditionPassed() then 8652 EncodingSpecificOperations(); 8653 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8654 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8655 if d == 15 then // Can only occur for ARM encoding 8656 ALUWritePC(result); // setflags is always FALSE here 8657 else 8658 R[d] = result; 8659 if setflags then 8660 APSR.N = result<31>; 8661 APSR.Z = IsZeroBit(result); 8662 APSR.C = carry; 8663 APSR.V = overflow; 8664 #endif 8665 8666 bool success = false; 8667 8668 uint32_t Rd; // the destination register 8669 uint32_t Rn; // the first operand 8670 uint32_t Rm; // the second operand 8671 bool setflags; 8672 ARM_ShifterType shift_t; 8673 uint32_t shift_n; // the shift applied to the value read from Rm 8674 switch (encoding) { 8675 case eEncodingT1: 8676 Rd = Bits32(opcode, 11, 8); 8677 Rn = Bits32(opcode, 19, 16); 8678 Rm = Bits32(opcode, 3, 0); 8679 setflags = BitIsSet(opcode, 20); 8680 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8681 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8682 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8683 return false; 8684 break; 8685 case eEncodingA1: 8686 Rd = Bits32(opcode, 15, 12); 8687 Rn = Bits32(opcode, 19, 16); 8688 Rm = Bits32(opcode, 3, 0); 8689 setflags = BitIsSet(opcode, 20); 8690 shift_n = DecodeImmShiftARM(opcode, shift_t); 8691 8692 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8693 if (Rd == 15 && setflags) 8694 return EmulateSUBSPcLrEtc (opcode, encoding); 8695 break; 8696 default: 8697 return false; 8698 } 8699 // Read the register value from register Rn. 8700 uint32_t val1 = ReadCoreReg(Rn, &success); 8701 if (!success) 8702 return false; 8703 8704 // Read the register value from register Rm. 8705 uint32_t val2 = ReadCoreReg(Rm, &success); 8706 if (!success) 8707 return false; 8708 8709 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8710 if (!success) 8711 return false; 8712 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8713 8714 EmulateInstruction::Context context; 8715 context.type = EmulateInstruction::eContextImmediate; 8716 context.SetNoArgs(); 8717 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8718 return false; 8719 8720 return true; 8721 } 8722 8723 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8724 // an immediate value, and writes the result to the destination register. It can optionally update the condition 8725 // flags based on the result. 8726 bool 8727 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8728 { 8729 #if 0 8730 // ARM pseudo code... 8731 if ConditionPassed() then 8732 EncodingSpecificOperations(); 8733 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8734 if d == 15 then 8735 ALUWritePC(result); // setflags is always FALSE here 8736 else 8737 R[d] = result; 8738 if setflags then 8739 APSR.N = result<31>; 8740 APSR.Z = IsZeroBit(result); 8741 APSR.C = carry; 8742 APSR.V = overflow; 8743 #endif 8744 8745 bool success = false; 8746 8747 uint32_t Rd; // the destination register 8748 uint32_t Rn; // the first operand 8749 bool setflags; 8750 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8751 switch (encoding) { 8752 case eEncodingA1: 8753 Rd = Bits32(opcode, 15, 12); 8754 Rn = Bits32(opcode, 19, 16); 8755 setflags = BitIsSet(opcode, 20); 8756 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8757 8758 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8759 if (Rd == 15 && setflags) 8760 return EmulateSUBSPcLrEtc (opcode, encoding); 8761 break; 8762 default: 8763 return false; 8764 } 8765 // Read the register value from the operand register Rn. 8766 uint32_t reg_val = ReadCoreReg(Rn, &success); 8767 if (!success) 8768 return false; 8769 8770 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8771 8772 EmulateInstruction::Context context; 8773 context.type = EmulateInstruction::eContextImmediate; 8774 context.SetNoArgs (); 8775 8776 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8777 return false; 8778 8779 return true; 8780 } 8781 8782 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8783 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8784 // condition flags based on the result. 8785 bool 8786 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8787 { 8788 #if 0 8789 // ARM pseudo code... 8790 if ConditionPassed() then 8791 EncodingSpecificOperations(); 8792 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8793 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8794 if d == 15 then 8795 ALUWritePC(result); // setflags is always FALSE here 8796 else 8797 R[d] = result; 8798 if setflags then 8799 APSR.N = result<31>; 8800 APSR.Z = IsZeroBit(result); 8801 APSR.C = carry; 8802 APSR.V = overflow; 8803 #endif 8804 8805 bool success = false; 8806 8807 uint32_t Rd; // the destination register 8808 uint32_t Rn; // the first operand 8809 uint32_t Rm; // the second operand 8810 bool setflags; 8811 ARM_ShifterType shift_t; 8812 uint32_t shift_n; // the shift applied to the value read from Rm 8813 switch (encoding) { 8814 case eEncodingA1: 8815 Rd = Bits32(opcode, 15, 12); 8816 Rn = Bits32(opcode, 19, 16); 8817 Rm = Bits32(opcode, 3, 0); 8818 setflags = BitIsSet(opcode, 20); 8819 shift_n = DecodeImmShiftARM(opcode, shift_t); 8820 8821 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8822 if (Rd == 15 && setflags) 8823 return EmulateSUBSPcLrEtc (opcode, encoding); 8824 break; 8825 default: 8826 return false; 8827 } 8828 // Read the register value from register Rn. 8829 uint32_t val1 = ReadCoreReg(Rn, &success); 8830 if (!success) 8831 return false; 8832 8833 // Read the register value from register Rm. 8834 uint32_t val2 = ReadCoreReg(Rm, &success); 8835 if (!success) 8836 return false; 8837 8838 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8839 if (!success) 8840 return false; 8841 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8842 8843 EmulateInstruction::Context context; 8844 context.type = EmulateInstruction::eContextImmediate; 8845 context.SetNoArgs(); 8846 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8847 return false; 8848 8849 return true; 8850 } 8851 8852 // Subtract with Carry (immediate) subtracts an immediate value and the value of 8853 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8854 // It can optionally update the condition flags based on the result. 8855 bool 8856 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8857 { 8858 #if 0 8859 // ARM pseudo code... 8860 if ConditionPassed() then 8861 EncodingSpecificOperations(); 8862 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8863 if d == 15 then // Can only occur for ARM encoding 8864 ALUWritePC(result); // setflags is always FALSE here 8865 else 8866 R[d] = result; 8867 if setflags then 8868 APSR.N = result<31>; 8869 APSR.Z = IsZeroBit(result); 8870 APSR.C = carry; 8871 APSR.V = overflow; 8872 #endif 8873 8874 bool success = false; 8875 8876 uint32_t Rd; // the destination register 8877 uint32_t Rn; // the first operand 8878 bool setflags; 8879 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8880 switch (encoding) { 8881 case eEncodingT1: 8882 Rd = Bits32(opcode, 11, 8); 8883 Rn = Bits32(opcode, 19, 16); 8884 setflags = BitIsSet(opcode, 20); 8885 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8886 if (BadReg(Rd) || BadReg(Rn)) 8887 return false; 8888 break; 8889 case eEncodingA1: 8890 Rd = Bits32(opcode, 15, 12); 8891 Rn = Bits32(opcode, 19, 16); 8892 setflags = BitIsSet(opcode, 20); 8893 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8894 8895 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8896 if (Rd == 15 && setflags) 8897 return EmulateSUBSPcLrEtc (opcode, encoding); 8898 break; 8899 default: 8900 return false; 8901 } 8902 // Read the register value from the operand register Rn. 8903 uint32_t reg_val = ReadCoreReg(Rn, &success); 8904 if (!success) 8905 return false; 8906 8907 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 8908 8909 EmulateInstruction::Context context; 8910 context.type = EmulateInstruction::eContextImmediate; 8911 context.SetNoArgs (); 8912 8913 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8914 return false; 8915 8916 return true; 8917 } 8918 8919 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 8920 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8921 // It can optionally update the condition flags based on the result. 8922 bool 8923 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 8924 { 8925 #if 0 8926 // ARM pseudo code... 8927 if ConditionPassed() then 8928 EncodingSpecificOperations(); 8929 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8930 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 8931 if d == 15 then // Can only occur for ARM encoding 8932 ALUWritePC(result); // setflags is always FALSE here 8933 else 8934 R[d] = result; 8935 if setflags then 8936 APSR.N = result<31>; 8937 APSR.Z = IsZeroBit(result); 8938 APSR.C = carry; 8939 APSR.V = overflow; 8940 #endif 8941 8942 bool success = false; 8943 8944 uint32_t Rd; // the destination register 8945 uint32_t Rn; // the first operand 8946 uint32_t Rm; // the second operand 8947 bool setflags; 8948 ARM_ShifterType shift_t; 8949 uint32_t shift_n; // the shift applied to the value read from Rm 8950 switch (encoding) { 8951 case eEncodingT1: 8952 Rd = Rn = Bits32(opcode, 2, 0); 8953 Rm = Bits32(opcode, 5, 3); 8954 setflags = !InITBlock(); 8955 shift_t = SRType_LSL; 8956 shift_n = 0; 8957 break; 8958 case eEncodingT2: 8959 Rd = Bits32(opcode, 11, 8); 8960 Rn = Bits32(opcode, 19, 16); 8961 Rm = Bits32(opcode, 3, 0); 8962 setflags = BitIsSet(opcode, 20); 8963 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8964 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8965 return false; 8966 break; 8967 case eEncodingA1: 8968 Rd = Bits32(opcode, 15, 12); 8969 Rn = Bits32(opcode, 19, 16); 8970 Rm = Bits32(opcode, 3, 0); 8971 setflags = BitIsSet(opcode, 20); 8972 shift_n = DecodeImmShiftARM(opcode, shift_t); 8973 8974 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8975 if (Rd == 15 && setflags) 8976 return EmulateSUBSPcLrEtc (opcode, encoding); 8977 break; 8978 default: 8979 return false; 8980 } 8981 // Read the register value from register Rn. 8982 uint32_t val1 = ReadCoreReg(Rn, &success); 8983 if (!success) 8984 return false; 8985 8986 // Read the register value from register Rm. 8987 uint32_t val2 = ReadCoreReg(Rm, &success); 8988 if (!success) 8989 return false; 8990 8991 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8992 if (!success) 8993 return false; 8994 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 8995 8996 EmulateInstruction::Context context; 8997 context.type = EmulateInstruction::eContextImmediate; 8998 context.SetNoArgs(); 8999 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9000 return false; 9001 9002 return true; 9003 } 9004 9005 // This instruction subtracts an immediate value from a register value, and writes the result 9006 // to the destination register. It can optionally update the condition flags based on the result. 9007 bool 9008 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9009 { 9010 #if 0 9011 // ARM pseudo code... 9012 if ConditionPassed() then 9013 EncodingSpecificOperations(); 9014 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9015 R[d] = result; 9016 if setflags then 9017 APSR.N = result<31>; 9018 APSR.Z = IsZeroBit(result); 9019 APSR.C = carry; 9020 APSR.V = overflow; 9021 #endif 9022 9023 bool success = false; 9024 9025 uint32_t Rd; // the destination register 9026 uint32_t Rn; // the first operand 9027 bool setflags; 9028 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9029 switch (encoding) { 9030 case eEncodingT1: 9031 Rd = Bits32(opcode, 2, 0); 9032 Rn = Bits32(opcode, 5, 3); 9033 setflags = !InITBlock(); 9034 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9035 break; 9036 case eEncodingT2: 9037 Rd = Rn = Bits32(opcode, 10, 8); 9038 setflags = !InITBlock(); 9039 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9040 break; 9041 case eEncodingT3: 9042 Rd = Bits32(opcode, 11, 8); 9043 Rn = Bits32(opcode, 19, 16); 9044 setflags = BitIsSet(opcode, 20); 9045 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9046 9047 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9048 if (Rd == 15 && setflags) 9049 return EmulateCMPImm (opcode, eEncodingT2); 9050 9051 // if Rn == '1101' then SEE SUB (SP minus immediate); 9052 if (Rn == 13) 9053 return EmulateSUBSPImm (opcode, eEncodingT2); 9054 9055 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9056 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9057 return false; 9058 break; 9059 case eEncodingT4: 9060 Rd = Bits32(opcode, 11, 8); 9061 Rn = Bits32(opcode, 19, 16); 9062 setflags = BitIsSet(opcode, 20); 9063 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9064 9065 // if Rn == '1111' then SEE ADR; 9066 if (Rn == 15) 9067 return EmulateADR (opcode, eEncodingT2); 9068 9069 // if Rn == '1101' then SEE SUB (SP minus immediate); 9070 if (Rn == 13) 9071 return EmulateSUBSPImm (opcode, eEncodingT3); 9072 9073 if (BadReg(Rd)) 9074 return false; 9075 break; 9076 default: 9077 return false; 9078 } 9079 // Read the register value from the operand register Rn. 9080 uint32_t reg_val = ReadCoreReg(Rn, &success); 9081 if (!success) 9082 return false; 9083 9084 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9085 9086 EmulateInstruction::Context context; 9087 context.type = EmulateInstruction::eContextImmediate; 9088 context.SetNoArgs (); 9089 9090 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9091 return false; 9092 9093 return true; 9094 } 9095 9096 // This instruction subtracts an immediate value from a register value, and writes the result 9097 // to the destination register. It can optionally update the condition flags based on the result. 9098 bool 9099 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9100 { 9101 #if 0 9102 // ARM pseudo code... 9103 if ConditionPassed() then 9104 EncodingSpecificOperations(); 9105 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9106 if d == 15 then 9107 ALUWritePC(result); // setflags is always FALSE here 9108 else 9109 R[d] = result; 9110 if setflags then 9111 APSR.N = result<31>; 9112 APSR.Z = IsZeroBit(result); 9113 APSR.C = carry; 9114 APSR.V = overflow; 9115 #endif 9116 9117 bool success = false; 9118 9119 uint32_t Rd; // the destination register 9120 uint32_t Rn; // the first operand 9121 bool setflags; 9122 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9123 switch (encoding) { 9124 case eEncodingA1: 9125 Rd = Bits32(opcode, 15, 12); 9126 Rn = Bits32(opcode, 19, 16); 9127 setflags = BitIsSet(opcode, 20); 9128 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9129 9130 // if Rn == '1111' && S == '0' then SEE ADR; 9131 if (Rn == 15 && !setflags) 9132 return EmulateADR (opcode, eEncodingA2); 9133 9134 // if Rn == '1101' then SEE SUB (SP minus immediate); 9135 if (Rn == 13) 9136 return EmulateSUBSPImm (opcode, eEncodingA1); 9137 9138 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9139 if (Rd == 15 && setflags) 9140 return EmulateSUBSPcLrEtc (opcode, encoding); 9141 break; 9142 default: 9143 return false; 9144 } 9145 // Read the register value from the operand register Rn. 9146 uint32_t reg_val = ReadCoreReg(Rn, &success); 9147 if (!success) 9148 return false; 9149 9150 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9151 9152 EmulateInstruction::Context context; 9153 context.type = EmulateInstruction::eContextImmediate; 9154 context.SetNoArgs (); 9155 9156 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9157 return false; 9158 9159 return true; 9160 } 9161 9162 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9163 // immediate value. It updates the condition flags based on the result, and discards the result. 9164 bool 9165 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9166 { 9167 #if 0 9168 // ARM pseudo code... 9169 if ConditionPassed() then 9170 EncodingSpecificOperations(); 9171 result = R[n] EOR imm32; 9172 APSR.N = result<31>; 9173 APSR.Z = IsZeroBit(result); 9174 APSR.C = carry; 9175 // APSR.V unchanged 9176 #endif 9177 9178 bool success = false; 9179 9180 if (ConditionPassed(opcode)) 9181 { 9182 uint32_t Rn; 9183 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9184 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9185 switch (encoding) 9186 { 9187 case eEncodingT1: 9188 Rn = Bits32(opcode, 19, 16); 9189 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9190 if (BadReg(Rn)) 9191 return false; 9192 break; 9193 case eEncodingA1: 9194 Rn = Bits32(opcode, 19, 16); 9195 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9196 break; 9197 default: 9198 return false; 9199 } 9200 9201 // Read the first operand. 9202 uint32_t val1 = ReadCoreReg(Rn, &success); 9203 if (!success) 9204 return false; 9205 9206 uint32_t result = val1 ^ imm32; 9207 9208 EmulateInstruction::Context context; 9209 context.type = EmulateInstruction::eContextImmediate; 9210 context.SetNoArgs (); 9211 9212 if (!WriteFlags(context, result, carry)) 9213 return false; 9214 } 9215 return true; 9216 } 9217 9218 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9219 // optionally-shifted register value. It updates the condition flags based on the result, and discards 9220 // the result. 9221 bool 9222 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9223 { 9224 #if 0 9225 // ARM pseudo code... 9226 if ConditionPassed() then 9227 EncodingSpecificOperations(); 9228 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9229 result = R[n] EOR shifted; 9230 APSR.N = result<31>; 9231 APSR.Z = IsZeroBit(result); 9232 APSR.C = carry; 9233 // APSR.V unchanged 9234 #endif 9235 9236 bool success = false; 9237 9238 if (ConditionPassed(opcode)) 9239 { 9240 uint32_t Rn, Rm; 9241 ARM_ShifterType shift_t; 9242 uint32_t shift_n; // the shift applied to the value read from Rm 9243 uint32_t carry; 9244 switch (encoding) 9245 { 9246 case eEncodingT1: 9247 Rn = Bits32(opcode, 19, 16); 9248 Rm = Bits32(opcode, 3, 0); 9249 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9250 if (BadReg(Rn) || BadReg(Rm)) 9251 return false; 9252 break; 9253 case eEncodingA1: 9254 Rn = Bits32(opcode, 19, 16); 9255 Rm = Bits32(opcode, 3, 0); 9256 shift_n = DecodeImmShiftARM(opcode, shift_t); 9257 break; 9258 default: 9259 return false; 9260 } 9261 9262 // Read the first operand. 9263 uint32_t val1 = ReadCoreReg(Rn, &success); 9264 if (!success) 9265 return false; 9266 9267 // Read the second operand. 9268 uint32_t val2 = ReadCoreReg(Rm, &success); 9269 if (!success) 9270 return false; 9271 9272 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9273 if (!success) 9274 return false; 9275 uint32_t result = val1 ^ shifted; 9276 9277 EmulateInstruction::Context context; 9278 context.type = EmulateInstruction::eContextImmediate; 9279 context.SetNoArgs (); 9280 9281 if (!WriteFlags(context, result, carry)) 9282 return false; 9283 } 9284 return true; 9285 } 9286 9287 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9288 // It updates the condition flags based on the result, and discards the result. 9289 bool 9290 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9291 { 9292 #if 0 9293 // ARM pseudo code... 9294 if ConditionPassed() then 9295 EncodingSpecificOperations(); 9296 result = R[n] AND imm32; 9297 APSR.N = result<31>; 9298 APSR.Z = IsZeroBit(result); 9299 APSR.C = carry; 9300 // APSR.V unchanged 9301 #endif 9302 9303 bool success = false; 9304 9305 if (ConditionPassed(opcode)) 9306 { 9307 uint32_t Rn; 9308 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9309 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9310 switch (encoding) 9311 { 9312 case eEncodingT1: 9313 Rn = Bits32(opcode, 19, 16); 9314 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9315 if (BadReg(Rn)) 9316 return false; 9317 break; 9318 case eEncodingA1: 9319 Rn = Bits32(opcode, 19, 16); 9320 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9321 break; 9322 default: 9323 return false; 9324 } 9325 9326 // Read the first operand. 9327 uint32_t val1 = ReadCoreReg(Rn, &success); 9328 if (!success) 9329 return false; 9330 9331 uint32_t result = val1 & imm32; 9332 9333 EmulateInstruction::Context context; 9334 context.type = EmulateInstruction::eContextImmediate; 9335 context.SetNoArgs (); 9336 9337 if (!WriteFlags(context, result, carry)) 9338 return false; 9339 } 9340 return true; 9341 } 9342 9343 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9344 // It updates the condition flags based on the result, and discards the result. 9345 bool 9346 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9347 { 9348 #if 0 9349 // ARM pseudo code... 9350 if ConditionPassed() then 9351 EncodingSpecificOperations(); 9352 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9353 result = R[n] AND shifted; 9354 APSR.N = result<31>; 9355 APSR.Z = IsZeroBit(result); 9356 APSR.C = carry; 9357 // APSR.V unchanged 9358 #endif 9359 9360 bool success = false; 9361 9362 if (ConditionPassed(opcode)) 9363 { 9364 uint32_t Rn, Rm; 9365 ARM_ShifterType shift_t; 9366 uint32_t shift_n; // the shift applied to the value read from Rm 9367 uint32_t carry; 9368 switch (encoding) 9369 { 9370 case eEncodingT1: 9371 Rn = Bits32(opcode, 2, 0); 9372 Rm = Bits32(opcode, 5, 3); 9373 shift_t = SRType_LSL; 9374 shift_n = 0; 9375 break; 9376 case eEncodingT2: 9377 Rn = Bits32(opcode, 19, 16); 9378 Rm = Bits32(opcode, 3, 0); 9379 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9380 if (BadReg(Rn) || BadReg(Rm)) 9381 return false; 9382 break; 9383 case eEncodingA1: 9384 Rn = Bits32(opcode, 19, 16); 9385 Rm = Bits32(opcode, 3, 0); 9386 shift_n = DecodeImmShiftARM(opcode, shift_t); 9387 break; 9388 default: 9389 return false; 9390 } 9391 9392 // Read the first operand. 9393 uint32_t val1 = ReadCoreReg(Rn, &success); 9394 if (!success) 9395 return false; 9396 9397 // Read the second operand. 9398 uint32_t val2 = ReadCoreReg(Rm, &success); 9399 if (!success) 9400 return false; 9401 9402 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9403 if (!success) 9404 return false; 9405 uint32_t result = val1 & shifted; 9406 9407 EmulateInstruction::Context context; 9408 context.type = EmulateInstruction::eContextImmediate; 9409 context.SetNoArgs (); 9410 9411 if (!WriteFlags(context, result, carry)) 9412 return false; 9413 } 9414 return true; 9415 } 9416 9417 // A8.6.216 SUB (SP minus register) 9418 bool 9419 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9420 { 9421 #if 0 9422 if ConditionPassed() then 9423 EncodingSpecificOperations(); 9424 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9425 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9426 if d == 15 then // Can only occur for ARM encoding 9427 ALUWritePC(result); // setflags is always FALSE here 9428 else 9429 R[d] = result; 9430 if setflags then 9431 APSR.N = result<31>; 9432 APSR.Z = IsZeroBit(result); 9433 APSR.C = carry; 9434 APSR.V = overflow; 9435 #endif 9436 9437 bool success = false; 9438 9439 if (ConditionPassed(opcode)) 9440 { 9441 uint32_t d; 9442 uint32_t m; 9443 bool setflags; 9444 ARM_ShifterType shift_t; 9445 uint32_t shift_n; 9446 9447 switch (encoding) 9448 { 9449 case eEncodingT1: 9450 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9451 d = Bits32 (opcode, 11, 8); 9452 m = Bits32 (opcode, 3, 0); 9453 setflags = BitIsSet (opcode, 20); 9454 9455 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9456 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9457 9458 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9459 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9460 return false; 9461 9462 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9463 if ((d == 15) || BadReg (m)) 9464 return false; 9465 break; 9466 9467 case eEncodingA1: 9468 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9469 d = Bits32 (opcode, 15, 12); 9470 m = Bits32 (opcode, 3, 0); 9471 setflags = BitIsSet (opcode, 20); 9472 9473 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9474 if (d == 15 && setflags) 9475 EmulateSUBSPcLrEtc (opcode, encoding); 9476 9477 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9478 shift_n = DecodeImmShiftARM (opcode, shift_t); 9479 break; 9480 9481 default: 9482 return false; 9483 } 9484 9485 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9486 uint32_t Rm = ReadCoreReg (m, &success); 9487 if (!success) 9488 return false; 9489 9490 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9491 if (!success) 9492 return false; 9493 9494 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9495 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9496 if (!success) 9497 return false; 9498 9499 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9500 9501 EmulateInstruction::Context context; 9502 context.type = eContextArithmetic; 9503 RegisterInfo sp_reg; 9504 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9505 RegisterInfo dwarf_reg; 9506 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9507 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9508 9509 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9510 return false; 9511 } 9512 return true; 9513 } 9514 9515 9516 // A8.6.7 ADD (register-shifted register) 9517 bool 9518 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9519 { 9520 #if 0 9521 if ConditionPassed() then 9522 EncodingSpecificOperations(); 9523 shift_n = UInt(R[s]<7:0>); 9524 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9525 (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9526 R[d] = result; 9527 if setflags then 9528 APSR.N = result<31>; 9529 APSR.Z = IsZeroBit(result); 9530 APSR.C = carry; 9531 APSR.V = overflow; 9532 #endif 9533 9534 bool success = false; 9535 9536 if (ConditionPassed(opcode)) 9537 { 9538 uint32_t d; 9539 uint32_t n; 9540 uint32_t m; 9541 uint32_t s; 9542 bool setflags; 9543 ARM_ShifterType shift_t; 9544 9545 switch (encoding) 9546 { 9547 case eEncodingA1: 9548 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9549 d = Bits32 (opcode, 15, 12); 9550 n = Bits32 (opcode, 19, 16); 9551 m = Bits32 (opcode, 3, 0); 9552 s = Bits32 (opcode, 11, 8); 9553 9554 // setflags = (S == �1�); shift_t = DecodeRegShift(type); 9555 setflags = BitIsSet (opcode, 20); 9556 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9557 9558 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9559 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9560 return false; 9561 break; 9562 9563 default: 9564 return false; 9565 } 9566 9567 // shift_n = UInt(R[s]<7:0>); 9568 uint32_t Rs = ReadCoreReg (s, &success); 9569 if (!success) 9570 return false; 9571 9572 uint32_t shift_n = Bits32 (Rs, 7, 0); 9573 9574 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9575 uint32_t Rm = ReadCoreReg (m, &success); 9576 if (!success) 9577 return false; 9578 9579 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9580 if (!success) 9581 return false; 9582 9583 // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9584 uint32_t Rn = ReadCoreReg (n, &success); 9585 if (!success) 9586 return false; 9587 9588 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9589 9590 // R[d] = result; 9591 EmulateInstruction::Context context; 9592 context.type = eContextArithmetic; 9593 RegisterInfo reg_n; 9594 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9595 RegisterInfo reg_m; 9596 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9597 9598 context.SetRegisterRegisterOperands (reg_n, reg_m); 9599 9600 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9601 return false; 9602 9603 // if setflags then 9604 // APSR.N = result<31>; 9605 // APSR.Z = IsZeroBit(result); 9606 // APSR.C = carry; 9607 // APSR.V = overflow; 9608 if (setflags) 9609 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9610 } 9611 return true; 9612 } 9613 9614 // A8.6.213 SUB (register) 9615 bool 9616 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9617 { 9618 #if 0 9619 if ConditionPassed() then 9620 EncodingSpecificOperations(); 9621 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9622 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9623 if d == 15 then // Can only occur for ARM encoding 9624 ALUWritePC(result); // setflags is always FALSE here 9625 else 9626 R[d] = result; 9627 if setflags then 9628 APSR.N = result<31>; 9629 APSR.Z = IsZeroBit(result); 9630 APSR.C = carry; 9631 APSR.V = overflow; 9632 #endif 9633 9634 bool success = false; 9635 9636 if (ConditionPassed(opcode)) 9637 { 9638 uint32_t d; 9639 uint32_t n; 9640 uint32_t m; 9641 bool setflags; 9642 ARM_ShifterType shift_t; 9643 uint32_t shift_n; 9644 9645 switch (encoding) 9646 { 9647 case eEncodingT1: 9648 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9649 d = Bits32 (opcode, 2, 0); 9650 n = Bits32 (opcode, 5, 3); 9651 m = Bits32 (opcode, 8, 6); 9652 setflags = !InITBlock(); 9653 9654 // (shift_t, shift_n) = (SRType_LSL, 0); 9655 shift_t = SRType_LSL; 9656 shift_n = 0; 9657 9658 break; 9659 9660 case eEncodingT2: 9661 // if Rd == �1111� && S == �1� then SEE CMP (register); 9662 // if Rn == �1101� then SEE SUB (SP minus register); 9663 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9664 d = Bits32 (opcode, 11, 8); 9665 n = Bits32 (opcode, 19, 16); 9666 m = Bits32 (opcode, 3, 0); 9667 setflags = BitIsSet (opcode, 20); 9668 9669 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9670 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9671 9672 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9673 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9674 return false; 9675 9676 break; 9677 9678 case eEncodingA1: 9679 // if Rn == �1101� then SEE SUB (SP minus register); 9680 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9681 d = Bits32 (opcode, 15, 12); 9682 n = Bits32 (opcode, 19, 16); 9683 m = Bits32 (opcode, 3, 0); 9684 setflags = BitIsSet (opcode, 20); 9685 9686 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9687 if ((d == 15) && setflags) 9688 EmulateSUBSPcLrEtc (opcode, encoding); 9689 9690 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9691 shift_n = DecodeImmShiftARM (opcode, shift_t); 9692 9693 break; 9694 9695 default: 9696 return false; 9697 } 9698 9699 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9700 uint32_t Rm = ReadCoreReg (m, &success); 9701 if (!success) 9702 return false; 9703 9704 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9705 if (!success) 9706 return false; 9707 9708 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9709 uint32_t Rn = ReadCoreReg (n, &success); 9710 if (!success) 9711 return false; 9712 9713 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9714 9715 // if d == 15 then // Can only occur for ARM encoding 9716 // ALUWritePC(result); // setflags is always FALSE here 9717 // else 9718 // R[d] = result; 9719 // if setflags then 9720 // APSR.N = result<31>; 9721 // APSR.Z = IsZeroBit(result); 9722 // APSR.C = carry; 9723 // APSR.V = overflow; 9724 9725 EmulateInstruction::Context context; 9726 context.type = eContextArithmetic; 9727 RegisterInfo reg_n; 9728 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9729 RegisterInfo reg_m; 9730 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9731 context.SetRegisterRegisterOperands (reg_n, reg_m); 9732 9733 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9734 return false; 9735 } 9736 return true; 9737 } 9738 9739 // A8.6.202 STREX 9740 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9741 // word from a register to memory if the executing processor has exclusive access to the memory addressed. 9742 bool 9743 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9744 { 9745 #if 0 9746 if ConditionPassed() then 9747 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9748 address = R[n] + imm32; 9749 if ExclusiveMonitorsPass(address,4) then 9750 MemA[address,4] = R[t]; 9751 R[d] = 0; 9752 else 9753 R[d] = 1; 9754 #endif 9755 9756 bool success = false; 9757 9758 if (ConditionPassed(opcode)) 9759 { 9760 uint32_t d; 9761 uint32_t t; 9762 uint32_t n; 9763 uint32_t imm32; 9764 const uint32_t addr_byte_size = GetAddressByteSize(); 9765 9766 switch (encoding) 9767 { 9768 case eEncodingT1: 9769 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 9770 d = Bits32 (opcode, 11, 8); 9771 t = Bits32 (opcode, 15, 12); 9772 n = Bits32 (opcode, 19, 16); 9773 imm32 = Bits32 (opcode, 7, 0) << 2; 9774 9775 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9776 if (BadReg (d) || BadReg (t) || (n == 15)) 9777 return false; 9778 9779 // if d == n || d == t then UNPREDICTABLE; 9780 if ((d == n) || (d == t)) 9781 return false; 9782 9783 break; 9784 9785 case eEncodingA1: 9786 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9787 d = Bits32 (opcode, 15, 12); 9788 t = Bits32 (opcode, 3, 0); 9789 n = Bits32 (opcode, 19, 16); 9790 imm32 = 0; 9791 9792 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9793 if ((d == 15) || (t == 15) || (n == 15)) 9794 return false; 9795 9796 // if d == n || d == t then UNPREDICTABLE; 9797 if ((d == n) || (d == t)) 9798 return false; 9799 9800 break; 9801 9802 default: 9803 return false; 9804 } 9805 9806 // address = R[n] + imm32; 9807 uint32_t Rn = ReadCoreReg (n, &success); 9808 if (!success) 9809 return false; 9810 9811 addr_t address = Rn + imm32; 9812 9813 RegisterInfo base_reg; 9814 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9815 RegisterInfo data_reg; 9816 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9817 EmulateInstruction::Context context; 9818 context.type = eContextRegisterStore; 9819 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9820 9821 // if ExclusiveMonitorsPass(address,4) then 9822 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9823 // always return true. 9824 if (true) 9825 { 9826 // MemA[address,4] = R[t]; 9827 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9828 if (!success) 9829 return false; 9830 9831 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9832 return false; 9833 9834 // R[d] = 0; 9835 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9836 return false; 9837 } 9838 else 9839 { 9840 // R[d] = 1; 9841 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9842 return false; 9843 } 9844 } 9845 return true; 9846 } 9847 9848 // A8.6.197 STRB (immediate, ARM) 9849 bool 9850 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9851 { 9852 #if 0 9853 if ConditionPassed() then 9854 EncodingSpecificOperations(); 9855 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9856 address = if index then offset_addr else R[n]; 9857 MemU[address,1] = R[t]<7:0>; 9858 if wback then R[n] = offset_addr; 9859 #endif 9860 9861 bool success = false; 9862 9863 if (ConditionPassed(opcode)) 9864 { 9865 uint32_t t; 9866 uint32_t n; 9867 uint32_t imm32; 9868 bool index; 9869 bool add; 9870 bool wback; 9871 9872 switch (encoding) 9873 { 9874 case eEncodingA1: 9875 // if P == �0� && W == �1� then SEE STRBT; 9876 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9877 t = Bits32 (opcode, 15, 12); 9878 n = Bits32 (opcode, 19, 16); 9879 imm32 = Bits32 (opcode, 11, 0); 9880 9881 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9882 index = BitIsSet (opcode, 24); 9883 add = BitIsSet (opcode, 23); 9884 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9885 9886 // if t == 15 then UNPREDICTABLE; 9887 if (t == 15) 9888 return false; 9889 9890 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9891 if (wback && ((n == 15) || (n == t))) 9892 return false; 9893 9894 break; 9895 9896 default: 9897 return false; 9898 } 9899 9900 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9901 uint32_t Rn = ReadCoreReg (n, &success); 9902 if (!success) 9903 return false; 9904 9905 addr_t offset_addr; 9906 if (add) 9907 offset_addr = Rn + imm32; 9908 else 9909 offset_addr = Rn - imm32; 9910 9911 // address = if index then offset_addr else R[n]; 9912 addr_t address; 9913 if (index) 9914 address = offset_addr; 9915 else 9916 address = Rn; 9917 9918 // MemU[address,1] = R[t]<7:0>; 9919 uint32_t Rt = ReadCoreReg (t, &success); 9920 if (!success) 9921 return false; 9922 9923 RegisterInfo base_reg; 9924 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9925 RegisterInfo data_reg; 9926 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9927 EmulateInstruction::Context context; 9928 context.type = eContextRegisterStore; 9929 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9930 9931 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 9932 return false; 9933 9934 // if wback then R[n] = offset_addr; 9935 if (wback) 9936 { 9937 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9938 return false; 9939 } 9940 } 9941 return true; 9942 } 9943 9944 // A8.6.194 STR (immediate, ARM) 9945 bool 9946 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9947 { 9948 #if 0 9949 if ConditionPassed() then 9950 EncodingSpecificOperations(); 9951 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9952 address = if index then offset_addr else R[n]; 9953 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9954 if wback then R[n] = offset_addr; 9955 #endif 9956 9957 bool success = false; 9958 9959 if (ConditionPassed(opcode)) 9960 { 9961 uint32_t t; 9962 uint32_t n; 9963 uint32_t imm32; 9964 bool index; 9965 bool add; 9966 bool wback; 9967 9968 const uint32_t addr_byte_size = GetAddressByteSize(); 9969 9970 switch (encoding) 9971 { 9972 case eEncodingA1: 9973 // if P == �0� && W == �1� then SEE STRT; 9974 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH; 9975 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9976 t = Bits32 (opcode, 15, 12); 9977 n = Bits32 (opcode, 19, 16); 9978 imm32 = Bits32 (opcode, 11, 0); 9979 9980 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9981 index = BitIsSet (opcode, 24); 9982 add = BitIsSet (opcode, 23); 9983 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9984 9985 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9986 if (wback && ((n == 15) || (n == t))) 9987 return false; 9988 9989 break; 9990 9991 default: 9992 return false; 9993 } 9994 9995 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9996 uint32_t Rn = ReadCoreReg (n, &success); 9997 if (!success) 9998 return false; 9999 10000 addr_t offset_addr; 10001 if (add) 10002 offset_addr = Rn + imm32; 10003 else 10004 offset_addr = Rn - imm32; 10005 10006 // address = if index then offset_addr else R[n]; 10007 addr_t address; 10008 if (index) 10009 address = offset_addr; 10010 else 10011 address = Rn; 10012 10013 RegisterInfo base_reg; 10014 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10015 RegisterInfo data_reg; 10016 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10017 EmulateInstruction::Context context; 10018 context.type = eContextRegisterStore; 10019 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10020 10021 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10022 uint32_t Rt = ReadCoreReg (t, &success); 10023 if (!success) 10024 return false; 10025 10026 if (t == 15) 10027 { 10028 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10029 if (!success) 10030 return false; 10031 10032 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10033 return false; 10034 } 10035 else 10036 { 10037 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10038 return false; 10039 } 10040 10041 // if wback then R[n] = offset_addr; 10042 if (wback) 10043 { 10044 context.type = eContextAdjustBaseRegister; 10045 context.SetImmediate (offset_addr); 10046 10047 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10048 return false; 10049 } 10050 } 10051 return true; 10052 } 10053 10054 // A8.6.66 LDRD (immediate) 10055 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10056 // words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10057 bool 10058 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10059 { 10060 #if 0 10061 if ConditionPassed() then 10062 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10063 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10064 address = if index then offset_addr else R[n]; 10065 R[t] = MemA[address,4]; 10066 R[t2] = MemA[address+4,4]; 10067 if wback then R[n] = offset_addr; 10068 #endif 10069 10070 bool success = false; 10071 10072 if (ConditionPassed(opcode)) 10073 { 10074 uint32_t t; 10075 uint32_t t2; 10076 uint32_t n; 10077 uint32_t imm32; 10078 bool index; 10079 bool add; 10080 bool wback; 10081 10082 switch (encoding) 10083 { 10084 case eEncodingT1: 10085 //if P == �0� && W == �0� then SEE �Related encodings�; 10086 //if Rn == �1111� then SEE LDRD (literal); 10087 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10088 t = Bits32 (opcode, 15, 12); 10089 t2 = Bits32 (opcode, 11, 8); 10090 n = Bits32 (opcode, 19, 16); 10091 imm32 = Bits32 (opcode, 7, 0) << 2; 10092 10093 //index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10094 index = BitIsSet (opcode, 24); 10095 add = BitIsSet (opcode, 23); 10096 wback = BitIsSet (opcode, 21); 10097 10098 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10099 if (wback && ((n == t) || (n == t2))) 10100 return false; 10101 10102 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10103 if (BadReg (t) || BadReg (t2) || (t == t2)) 10104 return false; 10105 10106 break; 10107 10108 case eEncodingA1: 10109 //if Rn == �1111� then SEE LDRD (literal); 10110 //if Rt<0> == �1� then UNPREDICTABLE; 10111 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10112 t = Bits32 (opcode, 15, 12); 10113 if (BitIsSet (t, 0)) 10114 return false; 10115 t2 = t + 1; 10116 n = Bits32 (opcode, 19, 16); 10117 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10118 10119 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10120 index = BitIsSet (opcode, 24); 10121 add = BitIsSet (opcode, 23); 10122 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10123 10124 //if P == �0� && W == �1� then UNPREDICTABLE; 10125 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10126 return false; 10127 10128 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10129 if (wback && ((n == t) || (n == t2))) 10130 return false; 10131 10132 //if t2 == 15 then UNPREDICTABLE; 10133 if (t2 == 15) 10134 return false; 10135 10136 break; 10137 10138 default: 10139 return false; 10140 } 10141 10142 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10143 uint32_t Rn = ReadCoreReg (n, &success); 10144 if (!success) 10145 return false; 10146 10147 addr_t offset_addr; 10148 if (add) 10149 offset_addr = Rn + imm32; 10150 else 10151 offset_addr = Rn - imm32; 10152 10153 //address = if index then offset_addr else R[n]; 10154 addr_t address; 10155 if (index) 10156 address = offset_addr; 10157 else 10158 address = Rn; 10159 10160 //R[t] = MemA[address,4]; 10161 RegisterInfo base_reg; 10162 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10163 10164 EmulateInstruction::Context context; 10165 context.type = eContextRegisterLoad; 10166 context.SetRegisterPlusOffset (base_reg, address - Rn); 10167 10168 const uint32_t addr_byte_size = GetAddressByteSize(); 10169 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10170 if (!success) 10171 return false; 10172 10173 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10174 return false; 10175 10176 //R[t2] = MemA[address+4,4]; 10177 10178 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10179 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10180 if (!success) 10181 return false; 10182 10183 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10184 return false; 10185 10186 //if wback then R[n] = offset_addr; 10187 if (wback) 10188 { 10189 context.type = eContextAdjustBaseRegister; 10190 context.SetAddress (offset_addr); 10191 10192 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10193 return false; 10194 } 10195 } 10196 return true; 10197 } 10198 10199 // A8.6.68 LDRD (register) 10200 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10201 // words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10202 bool 10203 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10204 { 10205 #if 0 10206 if ConditionPassed() then 10207 EncodingSpecificOperations(); 10208 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10209 address = if index then offset_addr else R[n]; 10210 R[t] = MemA[address,4]; 10211 R[t2] = MemA[address+4,4]; 10212 if wback then R[n] = offset_addr; 10213 #endif 10214 10215 bool success = false; 10216 10217 if (ConditionPassed(opcode)) 10218 { 10219 uint32_t t; 10220 uint32_t t2; 10221 uint32_t n; 10222 uint32_t m; 10223 bool index; 10224 bool add; 10225 bool wback; 10226 10227 switch (encoding) 10228 { 10229 case eEncodingA1: 10230 // if Rt<0> == �1� then UNPREDICTABLE; 10231 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10232 t = Bits32 (opcode, 15, 12); 10233 if (BitIsSet (t, 0)) 10234 return false; 10235 t2 = t + 1; 10236 n = Bits32 (opcode, 19, 16); 10237 m = Bits32 (opcode, 3, 0); 10238 10239 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10240 index = BitIsSet (opcode, 24); 10241 add = BitIsSet (opcode, 23); 10242 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10243 10244 // if P == �0� && W == �1� then UNPREDICTABLE; 10245 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10246 return false; 10247 10248 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10249 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10250 return false; 10251 10252 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10253 if (wback && ((n == 15) || (n == t) || (n == t2))) 10254 return false; 10255 10256 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10257 if ((ArchVersion() < 6) && wback && (m == n)) 10258 return false; 10259 break; 10260 10261 default: 10262 return false; 10263 } 10264 10265 uint32_t Rn = ReadCoreReg (n, &success); 10266 if (!success) 10267 return false; 10268 RegisterInfo base_reg; 10269 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10270 10271 uint32_t Rm = ReadCoreReg (m, &success); 10272 if (!success) 10273 return false; 10274 RegisterInfo offset_reg; 10275 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10276 10277 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10278 addr_t offset_addr; 10279 if (add) 10280 offset_addr = Rn + Rm; 10281 else 10282 offset_addr = Rn - Rm; 10283 10284 // address = if index then offset_addr else R[n]; 10285 addr_t address; 10286 if (index) 10287 address = offset_addr; 10288 else 10289 address = Rn; 10290 10291 EmulateInstruction::Context context; 10292 context.type = eContextRegisterLoad; 10293 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10294 10295 // R[t] = MemA[address,4]; 10296 const uint32_t addr_byte_size = GetAddressByteSize(); 10297 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10298 if (!success) 10299 return false; 10300 10301 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10302 return false; 10303 10304 // R[t2] = MemA[address+4,4]; 10305 10306 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10307 if (!success) 10308 return false; 10309 10310 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10311 return false; 10312 10313 // if wback then R[n] = offset_addr; 10314 if (wback) 10315 { 10316 context.type = eContextAdjustBaseRegister; 10317 context.SetAddress (offset_addr); 10318 10319 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10320 return false; 10321 } 10322 } 10323 return true; 10324 } 10325 10326 // A8.6.200 STRD (immediate) 10327 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10328 // stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10329 bool 10330 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10331 { 10332 #if 0 10333 if ConditionPassed() then 10334 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10335 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10336 address = if index then offset_addr else R[n]; 10337 MemA[address,4] = R[t]; 10338 MemA[address+4,4] = R[t2]; 10339 if wback then R[n] = offset_addr; 10340 #endif 10341 10342 bool success = false; 10343 10344 if (ConditionPassed(opcode)) 10345 { 10346 uint32_t t; 10347 uint32_t t2; 10348 uint32_t n; 10349 uint32_t imm32; 10350 bool index; 10351 bool add; 10352 bool wback; 10353 10354 switch (encoding) 10355 { 10356 case eEncodingT1: 10357 // if P == �0� && W == �0� then SEE �Related encodings�; 10358 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10359 t = Bits32 (opcode, 15, 12); 10360 t2 = Bits32 (opcode, 11, 8); 10361 n = Bits32 (opcode, 19, 16); 10362 imm32 = Bits32 (opcode, 7, 0) << 2; 10363 10364 // index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10365 index = BitIsSet (opcode, 24); 10366 add = BitIsSet (opcode, 23); 10367 wback = BitIsSet (opcode, 21); 10368 10369 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10370 if (wback && ((n == t) || (n == t2))) 10371 return false; 10372 10373 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10374 if ((n == 15) || BadReg (t) || BadReg (t2)) 10375 return false; 10376 10377 break; 10378 10379 case eEncodingA1: 10380 // if Rt<0> == �1� then UNPREDICTABLE; 10381 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10382 t = Bits32 (opcode, 15, 12); 10383 if (BitIsSet (t, 0)) 10384 return false; 10385 10386 t2 = t + 1; 10387 n = Bits32 (opcode, 19, 16); 10388 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10389 10390 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10391 index = BitIsSet (opcode, 24); 10392 add = BitIsSet (opcode, 23); 10393 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10394 10395 // if P == �0� && W == �1� then UNPREDICTABLE; 10396 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10397 return false; 10398 10399 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10400 if (wback && ((n == 15) || (n == t) || (n == t2))) 10401 return false; 10402 10403 // if t2 == 15 then UNPREDICTABLE; 10404 if (t2 == 15) 10405 return false; 10406 10407 break; 10408 10409 default: 10410 return false; 10411 } 10412 10413 RegisterInfo base_reg; 10414 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10415 10416 uint32_t Rn = ReadCoreReg (n, &success); 10417 if (!success) 10418 return false; 10419 10420 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10421 addr_t offset_addr; 10422 if (add) 10423 offset_addr = Rn + imm32; 10424 else 10425 offset_addr = Rn - imm32; 10426 10427 //address = if index then offset_addr else R[n]; 10428 addr_t address; 10429 if (index) 10430 address = offset_addr; 10431 else 10432 address = Rn; 10433 10434 //MemA[address,4] = R[t]; 10435 RegisterInfo data_reg; 10436 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10437 10438 uint32_t data = ReadCoreReg (t, &success); 10439 if (!success) 10440 return false; 10441 10442 EmulateInstruction::Context context; 10443 context.type = eContextRegisterStore; 10444 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10445 10446 const uint32_t addr_byte_size = GetAddressByteSize(); 10447 10448 if (!MemAWrite (context, address, data, addr_byte_size)) 10449 return false; 10450 10451 //MemA[address+4,4] = R[t2]; 10452 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10453 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10454 10455 data = ReadCoreReg (t2, &success); 10456 if (!success) 10457 return false; 10458 10459 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10460 return false; 10461 10462 //if wback then R[n] = offset_addr; 10463 if (wback) 10464 { 10465 context.type = eContextAdjustBaseRegister; 10466 context.SetAddress (offset_addr); 10467 10468 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10469 return false; 10470 } 10471 } 10472 return true; 10473 } 10474 10475 10476 // A8.6.201 STRD (register) 10477 bool 10478 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10479 { 10480 #if 0 10481 if ConditionPassed() then 10482 EncodingSpecificOperations(); 10483 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10484 address = if index then offset_addr else R[n]; 10485 MemA[address,4] = R[t]; 10486 MemA[address+4,4] = R[t2]; 10487 if wback then R[n] = offset_addr; 10488 #endif 10489 10490 bool success = false; 10491 10492 if (ConditionPassed(opcode)) 10493 { 10494 uint32_t t; 10495 uint32_t t2; 10496 uint32_t n; 10497 uint32_t m; 10498 bool index; 10499 bool add; 10500 bool wback; 10501 10502 switch (encoding) 10503 { 10504 case eEncodingA1: 10505 // if Rt<0> == �1� then UNPREDICTABLE; 10506 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10507 t = Bits32 (opcode, 15, 12); 10508 if (BitIsSet (t, 0)) 10509 return false; 10510 10511 t2 = t+1; 10512 n = Bits32 (opcode, 19, 16); 10513 m = Bits32 (opcode, 3, 0); 10514 10515 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10516 index = BitIsSet (opcode, 24); 10517 add = BitIsSet (opcode, 23); 10518 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10519 10520 // if P == �0� && W == �1� then UNPREDICTABLE; 10521 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10522 return false; 10523 10524 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10525 if ((t2 == 15) || (m == 15)) 10526 return false; 10527 10528 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10529 if (wback && ((n == 15) || (n == t) || (n == t2))) 10530 return false; 10531 10532 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10533 if ((ArchVersion() < 6) && wback && (m == n)) 10534 return false; 10535 10536 break; 10537 10538 default: 10539 return false; 10540 } 10541 10542 RegisterInfo base_reg; 10543 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10544 RegisterInfo offset_reg; 10545 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10546 RegisterInfo data_reg; 10547 10548 uint32_t Rn = ReadCoreReg (n, &success); 10549 if (!success) 10550 return false; 10551 10552 uint32_t Rm = ReadCoreReg (m, &success); 10553 if (!success) 10554 return false; 10555 10556 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10557 addr_t offset_addr; 10558 if (add) 10559 offset_addr = Rn + Rm; 10560 else 10561 offset_addr = Rn - Rm; 10562 10563 // address = if index then offset_addr else R[n]; 10564 addr_t address; 10565 if (index) 10566 address = offset_addr; 10567 else 10568 address = Rn; 10569 // MemA[address,4] = R[t]; 10570 uint32_t Rt = ReadCoreReg (t, &success); 10571 if (!success) 10572 return false; 10573 10574 EmulateInstruction::Context context; 10575 context.type = eContextRegisterStore; 10576 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10577 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10578 10579 const uint32_t addr_byte_size = GetAddressByteSize(); 10580 10581 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10582 return false; 10583 10584 // MemA[address+4,4] = R[t2]; 10585 uint32_t Rt2 = ReadCoreReg (t2, &success); 10586 if (!success) 10587 return false; 10588 10589 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10590 10591 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10592 10593 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10594 return false; 10595 10596 // if wback then R[n] = offset_addr; 10597 if (wback) 10598 { 10599 context.type = eContextAdjustBaseRegister; 10600 context.SetAddress (offset_addr); 10601 10602 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10603 return false; 10604 10605 } 10606 } 10607 return true; 10608 } 10609 10610 // A8.6.319 VLDM 10611 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10612 // an ARM core register. 10613 bool 10614 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10615 { 10616 #if 0 10617 if ConditionPassed() then 10618 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10619 address = if add then R[n] else R[n]-imm32; 10620 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10621 for r = 0 to regs-1 10622 if single_regs then 10623 S[d+r] = MemA[address,4]; address = address+4; 10624 else 10625 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10626 // Combine the word-aligned words in the correct order for current endianness. 10627 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10628 #endif 10629 10630 bool success = false; 10631 10632 if (ConditionPassed(opcode)) 10633 { 10634 bool single_regs; 10635 bool add; 10636 bool wback; 10637 uint32_t d; 10638 uint32_t n; 10639 uint32_t imm32; 10640 uint32_t regs; 10641 10642 switch (encoding) 10643 { 10644 case eEncodingT1: 10645 case eEncodingA1: 10646 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10647 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10648 // if P == �1� && W == �0� then SEE VLDR; 10649 // if P == U && W == �1� then UNDEFINED; 10650 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10651 return false; 10652 10653 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10654 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10655 single_regs = false; 10656 add = BitIsSet (opcode, 23); 10657 wback = BitIsSet (opcode, 21); 10658 10659 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10660 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10661 n = Bits32 (opcode, 19, 16); 10662 imm32 = Bits32 (opcode, 7, 0) << 2; 10663 10664 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�. 10665 regs = Bits32 (opcode, 7, 0) / 2; 10666 10667 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10668 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10669 return false; 10670 10671 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10672 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10673 return false; 10674 10675 break; 10676 10677 case eEncodingT2: 10678 case eEncodingA2: 10679 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10680 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10681 // if P == �1� && W == �0� then SEE VLDR; 10682 // if P == U && W == �1� then UNDEFINED; 10683 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10684 return false; 10685 10686 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10687 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10688 single_regs = true; 10689 add = BitIsSet (opcode, 23); 10690 wback = BitIsSet (opcode, 21); 10691 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10692 n = Bits32 (opcode, 19, 16); 10693 10694 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10695 imm32 = Bits32 (opcode, 7, 0) << 2; 10696 regs = Bits32 (opcode, 7, 0); 10697 10698 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10699 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10700 return false; 10701 10702 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10703 if ((regs == 0) || ((d + regs) > 32)) 10704 return false; 10705 break; 10706 10707 default: 10708 return false; 10709 } 10710 10711 RegisterInfo base_reg; 10712 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10713 10714 uint32_t Rn = ReadCoreReg (n, &success); 10715 if (!success) 10716 return false; 10717 10718 // address = if add then R[n] else R[n]-imm32; 10719 addr_t address; 10720 if (add) 10721 address = Rn; 10722 else 10723 address = Rn - imm32; 10724 10725 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10726 EmulateInstruction::Context context; 10727 10728 if (wback) 10729 { 10730 uint32_t value; 10731 if (add) 10732 value = Rn + imm32; 10733 else 10734 value = Rn - imm32; 10735 10736 context.type = eContextAdjustBaseRegister; 10737 context.SetImmediateSigned (value - Rn); 10738 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10739 return false; 10740 10741 } 10742 10743 const uint32_t addr_byte_size = GetAddressByteSize(); 10744 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10745 10746 context.type = eContextRegisterLoad; 10747 10748 // for r = 0 to regs-1 10749 for (uint32_t r = 0; r < regs; ++r) 10750 { 10751 if (single_regs) 10752 { 10753 // S[d+r] = MemA[address,4]; address = address+4; 10754 context.SetRegisterPlusOffset (base_reg, address - Rn); 10755 10756 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10757 if (!success) 10758 return false; 10759 10760 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10761 return false; 10762 10763 address = address + 4; 10764 } 10765 else 10766 { 10767 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10768 context.SetRegisterPlusOffset (base_reg, address - Rn); 10769 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10770 if (!success) 10771 return false; 10772 10773 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10774 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10775 if (!success) 10776 return false; 10777 10778 address = address + 8; 10779 // // Combine the word-aligned words in the correct order for current endianness. 10780 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10781 uint64_t data; 10782 if (GetByteOrder() == eByteOrderBig) 10783 { 10784 data = word1; 10785 data = (data << 32) | word2; 10786 } 10787 else 10788 { 10789 data = word2; 10790 data = (data << 32) | word1; 10791 } 10792 10793 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10794 return false; 10795 } 10796 } 10797 } 10798 return true; 10799 } 10800 10801 // A8.6.399 VSTM 10802 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10803 // ARM core register. 10804 bool 10805 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10806 { 10807 #if 0 10808 if ConditionPassed() then 10809 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10810 address = if add then R[n] else R[n]-imm32; 10811 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10812 for r = 0 to regs-1 10813 if single_regs then 10814 MemA[address,4] = S[d+r]; address = address+4; 10815 else 10816 // Store as two word-aligned words in the correct order for current endianness. 10817 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10818 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10819 address = address+8; 10820 #endif 10821 10822 bool success = false; 10823 10824 if (ConditionPassed (opcode)) 10825 { 10826 bool single_regs; 10827 bool add; 10828 bool wback; 10829 uint32_t d; 10830 uint32_t n; 10831 uint32_t imm32; 10832 uint32_t regs; 10833 10834 switch (encoding) 10835 { 10836 case eEncodingT1: 10837 case eEncodingA1: 10838 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10839 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10840 // if P == �1� && W == �0� then SEE VSTR; 10841 // if P == U && W == �1� then UNDEFINED; 10842 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10843 return false; 10844 10845 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10846 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10847 single_regs = false; 10848 add = BitIsSet (opcode, 23); 10849 wback = BitIsSet (opcode, 21); 10850 10851 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10852 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10853 n = Bits32 (opcode, 19, 16); 10854 imm32 = Bits32 (opcode, 7, 0) << 2; 10855 10856 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�. 10857 regs = Bits32 (opcode, 7, 0) / 2; 10858 10859 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10860 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10861 return false; 10862 10863 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10864 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10865 return false; 10866 10867 break; 10868 10869 case eEncodingT2: 10870 case eEncodingA2: 10871 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10872 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10873 // if P == �1� && W == �0� then SEE VSTR; 10874 // if P == U && W == �1� then UNDEFINED; 10875 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10876 return false; 10877 10878 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10879 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10880 single_regs = true; 10881 add = BitIsSet (opcode, 23); 10882 wback = BitIsSet (opcode, 21); 10883 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10884 n = Bits32 (opcode, 19, 16); 10885 10886 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10887 imm32 = Bits32 (opcode, 7, 0) << 2; 10888 regs = Bits32 (opcode, 7, 0); 10889 10890 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10891 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 10892 return false; 10893 10894 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10895 if ((regs == 0) || ((d + regs) > 32)) 10896 return false; 10897 10898 break; 10899 10900 default: 10901 return false; 10902 } 10903 10904 RegisterInfo base_reg; 10905 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10906 10907 uint32_t Rn = ReadCoreReg (n, &success); 10908 if (!success) 10909 return false; 10910 10911 // address = if add then R[n] else R[n]-imm32; 10912 addr_t address; 10913 if (add) 10914 address = Rn; 10915 else 10916 address = Rn - imm32; 10917 10918 EmulateInstruction::Context context; 10919 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10920 if (wback) 10921 { 10922 uint32_t value; 10923 if (add) 10924 value = Rn + imm32; 10925 else 10926 value = Rn - imm32; 10927 10928 context.type = eContextAdjustBaseRegister; 10929 context.SetRegisterPlusOffset (base_reg, value - Rn); 10930 10931 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10932 return false; 10933 } 10934 10935 const uint32_t addr_byte_size = GetAddressByteSize(); 10936 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10937 10938 context.type = eContextRegisterStore; 10939 // for r = 0 to regs-1 10940 for (int r = 0; r < regs; ++r) 10941 { 10942 10943 if (single_regs) 10944 { 10945 // MemA[address,4] = S[d+r]; address = address+4; 10946 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10947 if (!success) 10948 return false; 10949 10950 RegisterInfo data_reg; 10951 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10952 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10953 if (!MemAWrite (context, address, data, addr_byte_size)) 10954 return false; 10955 10956 address = address + 4; 10957 } 10958 else 10959 { 10960 // // Store as two word-aligned words in the correct order for current endianness. 10961 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10962 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10963 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10964 if (!success) 10965 return false; 10966 10967 RegisterInfo data_reg; 10968 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10969 10970 if (GetByteOrder() == eByteOrderBig) 10971 { 10972 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10973 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 10974 return false; 10975 10976 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10977 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 10978 return false; 10979 } 10980 else 10981 { 10982 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10983 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 10984 return false; 10985 10986 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10987 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 10988 return false; 10989 } 10990 // address = address+8; 10991 address = address + 8; 10992 } 10993 } 10994 } 10995 return true; 10996 } 10997 10998 // A8.6.320 10999 // This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with 11000 // an optional offset. 11001 bool 11002 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 11003 { 11004 #if 0 11005 if ConditionPassed() then 11006 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11007 base = if n == 15 then Align(PC,4) else R[n]; 11008 address = if add then (base + imm32) else (base - imm32); 11009 if single_reg then 11010 S[d] = MemA[address,4]; 11011 else 11012 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11013 // Combine the word-aligned words in the correct order for current endianness. 11014 D[d] = if BigEndian() then word1:word2 else word2:word1; 11015 #endif 11016 11017 bool success = false; 11018 11019 if (ConditionPassed (opcode)) 11020 { 11021 bool single_reg; 11022 bool add; 11023 uint32_t imm32; 11024 uint32_t d; 11025 uint32_t n; 11026 11027 switch (encoding) 11028 { 11029 case eEncodingT1: 11030 case eEncodingA1: 11031 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11032 single_reg = false; 11033 add = BitIsSet (opcode, 23); 11034 imm32 = Bits32 (opcode, 7, 0) << 2; 11035 11036 // d = UInt(D:Vd); n = UInt(Rn); 11037 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11038 n = Bits32 (opcode, 19, 16); 11039 11040 break; 11041 11042 case eEncodingT2: 11043 case eEncodingA2: 11044 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11045 single_reg = true; 11046 add = BitIsSet (opcode, 23); 11047 imm32 = Bits32 (opcode, 7, 0) << 2; 11048 11049 // d = UInt(Vd:D); n = UInt(Rn); 11050 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11051 n = Bits32 (opcode, 19, 16); 11052 11053 break; 11054 11055 default: 11056 return false; 11057 } 11058 RegisterInfo base_reg; 11059 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11060 11061 uint32_t Rn = ReadCoreReg (n, &success); 11062 if (!success) 11063 return false; 11064 11065 // base = if n == 15 then Align(PC,4) else R[n]; 11066 uint32_t base; 11067 if (n == 15) 11068 base = AlignPC (Rn); 11069 else 11070 base = Rn; 11071 11072 // address = if add then (base + imm32) else (base - imm32); 11073 addr_t address; 11074 if (add) 11075 address = base + imm32; 11076 else 11077 address = base - imm32; 11078 11079 const uint32_t addr_byte_size = GetAddressByteSize(); 11080 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11081 11082 EmulateInstruction::Context context; 11083 context.type = eContextRegisterLoad; 11084 context.SetRegisterPlusOffset (base_reg, address - base); 11085 11086 if (single_reg) 11087 { 11088 // S[d] = MemA[address,4]; 11089 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11090 if (!success) 11091 return false; 11092 11093 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11094 return false; 11095 } 11096 else 11097 { 11098 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11099 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11100 if (!success) 11101 return false; 11102 11103 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11104 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11105 if (!success) 11106 return false; 11107 // // Combine the word-aligned words in the correct order for current endianness. 11108 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11109 uint64_t data64; 11110 if (GetByteOrder() == eByteOrderBig) 11111 { 11112 data64 = word1; 11113 data64 = (data64 << 32) | word2; 11114 } 11115 else 11116 { 11117 data64 = word2; 11118 data64 = (data64 << 32) | word1; 11119 } 11120 11121 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11122 return false; 11123 } 11124 } 11125 return true; 11126 } 11127 11128 // A8.6.400 VSTR 11129 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11130 // optional offset. 11131 bool 11132 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11133 { 11134 #if 0 11135 if ConditionPassed() then 11136 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11137 address = if add then (R[n] + imm32) else (R[n] - imm32); 11138 if single_reg then 11139 MemA[address,4] = S[d]; 11140 else 11141 // Store as two word-aligned words in the correct order for current endianness. 11142 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11143 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11144 #endif 11145 11146 bool success = false; 11147 11148 if (ConditionPassed (opcode)) 11149 { 11150 bool single_reg; 11151 bool add; 11152 uint32_t imm32; 11153 uint32_t d; 11154 uint32_t n; 11155 11156 switch (encoding) 11157 { 11158 case eEncodingT1: 11159 case eEncodingA1: 11160 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11161 single_reg = false; 11162 add = BitIsSet (opcode, 23); 11163 imm32 = Bits32 (opcode, 7, 0) << 2; 11164 11165 // d = UInt(D:Vd); n = UInt(Rn); 11166 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11167 n = Bits32 (opcode, 19, 16); 11168 11169 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11170 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11171 return false; 11172 11173 break; 11174 11175 case eEncodingT2: 11176 case eEncodingA2: 11177 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11178 single_reg = true; 11179 add = BitIsSet (opcode, 23); 11180 imm32 = Bits32 (opcode, 7, 0) << 2; 11181 11182 // d = UInt(Vd:D); n = UInt(Rn); 11183 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11184 n = Bits32 (opcode, 19, 16); 11185 11186 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11187 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11188 return false; 11189 11190 break; 11191 11192 default: 11193 return false; 11194 } 11195 11196 RegisterInfo base_reg; 11197 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11198 11199 uint32_t Rn = ReadCoreReg (n, &success); 11200 if (!success) 11201 return false; 11202 11203 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11204 addr_t address; 11205 if (add) 11206 address = Rn + imm32; 11207 else 11208 address = Rn - imm32; 11209 11210 const uint32_t addr_byte_size = GetAddressByteSize(); 11211 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11212 11213 RegisterInfo data_reg; 11214 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11215 EmulateInstruction::Context context; 11216 context.type = eContextRegisterStore; 11217 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11218 11219 if (single_reg) 11220 { 11221 // MemA[address,4] = S[d]; 11222 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11223 if (!success) 11224 return false; 11225 11226 if (!MemAWrite (context, address, data, addr_byte_size)) 11227 return false; 11228 } 11229 else 11230 { 11231 // // Store as two word-aligned words in the correct order for current endianness. 11232 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11233 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11234 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11235 if (!success) 11236 return false; 11237 11238 if (GetByteOrder() == eByteOrderBig) 11239 { 11240 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11241 return false; 11242 11243 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11244 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11245 return false; 11246 } 11247 else 11248 { 11249 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11250 return false; 11251 11252 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11253 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11254 return false; 11255 } 11256 } 11257 } 11258 return true; 11259 } 11260 11261 // A8.6.307 VLDI1 (multiple single elements) 11262 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11263 // element of each register is loaded. 11264 bool 11265 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11266 { 11267 #if 0 11268 if ConditionPassed() then 11269 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11270 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11271 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11272 for r = 0 to regs-1 11273 for e = 0 to elements-1 11274 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11275 address = address + ebytes; 11276 #endif 11277 11278 bool success = false; 11279 11280 if (ConditionPassed (opcode)) 11281 { 11282 uint32_t regs; 11283 uint32_t alignment; 11284 uint32_t ebytes; 11285 uint32_t esize; 11286 uint32_t elements; 11287 uint32_t d; 11288 uint32_t n; 11289 uint32_t m; 11290 bool wback; 11291 bool register_index; 11292 11293 switch (encoding) 11294 { 11295 case eEncodingT1: 11296 case eEncodingA1: 11297 { 11298 // case type of 11299 // when �0111� 11300 // regs = 1; if align<1> == �1� then UNDEFINED; 11301 // when �1010� 11302 // regs = 2; if align == �11� then UNDEFINED; 11303 // when �0110� 11304 // regs = 3; if align<1> == �1� then UNDEFINED; 11305 // when �0010� 11306 // regs = 4; 11307 // otherwise 11308 // SEE �Related encodings�; 11309 uint32_t type = Bits32 (opcode, 11, 8); 11310 uint32_t align = Bits32 (opcode, 5, 4); 11311 if (type == 7) // '0111' 11312 { 11313 regs = 1; 11314 if (BitIsSet (align, 1)) 11315 return false; 11316 } 11317 else if (type == 10) // '1010' 11318 { 11319 regs = 2; 11320 if (align == 3) 11321 return false; 11322 11323 } 11324 else if (type == 6) // '0110' 11325 { 11326 regs = 3; 11327 if (BitIsSet (align, 1)) 11328 return false; 11329 } 11330 else if (type == 2) // '0010' 11331 { 11332 regs = 4; 11333 } 11334 else 11335 return false; 11336 11337 // alignment = if align == �00� then 1 else 4 << UInt(align); 11338 if (align == 0) 11339 alignment = 1; 11340 else 11341 alignment = 4 << align; 11342 11343 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11344 ebytes = 1 << Bits32 (opcode, 7, 6); 11345 esize = 8 * ebytes; 11346 elements = 8 / ebytes; 11347 11348 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11349 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11350 n = Bits32 (opcode, 19, 15); 11351 m = Bits32 (opcode, 3, 0); 11352 11353 // wback = (m != 15); register_index = (m != 15 && m != 13); 11354 wback = (m != 15); 11355 register_index = ((m != 15) && (m != 13)); 11356 11357 // if d+regs > 32 then UNPREDICTABLE; 11358 if ((d + regs) > 32) 11359 return false; 11360 } 11361 break; 11362 11363 default: 11364 return false; 11365 } 11366 11367 RegisterInfo base_reg; 11368 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11369 11370 uint32_t Rn = ReadCoreReg (n, &success); 11371 if (!success) 11372 return false; 11373 11374 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11375 addr_t address = Rn; 11376 if ((address % alignment) != 0) 11377 return false; 11378 11379 EmulateInstruction::Context context; 11380 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11381 if (wback) 11382 { 11383 uint32_t Rm = ReadCoreReg (m, &success); 11384 if (!success) 11385 return false; 11386 11387 uint32_t offset; 11388 if (register_index) 11389 offset = Rm; 11390 else 11391 offset = 8 * regs; 11392 11393 uint32_t value = Rn + offset; 11394 context.type = eContextAdjustBaseRegister; 11395 context.SetRegisterPlusOffset (base_reg, offset); 11396 11397 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11398 return false; 11399 11400 } 11401 11402 // for r = 0 to regs-1 11403 for (int r = 0; r < regs; ++r) 11404 { 11405 // for e = 0 to elements-1 11406 uint64_t assembled_data = 0; 11407 for (int e = 0; e < elements; ++e) 11408 { 11409 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11410 context.type = eContextRegisterLoad; 11411 context.SetRegisterPlusOffset (base_reg, address - Rn); 11412 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11413 if (!success) 11414 return false; 11415 11416 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11417 11418 // address = address + ebytes; 11419 address = address + ebytes; 11420 } 11421 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11422 return false; 11423 } 11424 } 11425 return true; 11426 } 11427 11428 // A8.6.308 VLD1 (single element to one lane) 11429 // 11430 bool 11431 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11432 { 11433 #if 0 11434 if ConditionPassed() then 11435 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11436 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11437 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11438 Elem[D[d],index,esize] = MemU[address,ebytes]; 11439 #endif 11440 11441 bool success = false; 11442 11443 if (ConditionPassed (opcode)) 11444 { 11445 uint32_t ebytes; 11446 uint32_t esize; 11447 uint32_t index; 11448 uint32_t alignment; 11449 uint32_t d; 11450 uint32_t n; 11451 uint32_t m; 11452 bool wback; 11453 bool register_index; 11454 11455 switch (encoding) 11456 { 11457 case eEncodingT1: 11458 case eEncodingA1: 11459 { 11460 uint32_t size = Bits32 (opcode, 11, 10); 11461 uint32_t index_align = Bits32 (opcode, 7, 4); 11462 // if size == �11� then SEE VLD1 (single element to all lanes); 11463 if (size == 3) 11464 return EmulateVLD1SingleAll (opcode, encoding); 11465 // case size of 11466 if (size == 0) // when '00' 11467 { 11468 // if index_align<0> != �0� then UNDEFINED; 11469 if (BitIsClear (index_align, 0)) 11470 return false; 11471 11472 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11473 ebytes = 1; 11474 esize = 8; 11475 index = Bits32 (index_align, 3, 1); 11476 alignment = 1; 11477 } 11478 else if (size == 1) // when �01� 11479 { 11480 // if index_align<1> != �0� then UNDEFINED; 11481 if (BitIsClear (index_align, 1)) 11482 return false; 11483 11484 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11485 ebytes = 2; 11486 esize = 16; 11487 index = Bits32 (index_align, 3, 2); 11488 11489 // alignment = if index_align<0> == �0� then 1 else 2; 11490 if (BitIsClear (index_align, 0)) 11491 alignment = 1; 11492 else 11493 alignment = 2; 11494 } 11495 else if (size == 2) // when �10� 11496 { 11497 // if index_align<2> != �0� then UNDEFINED; 11498 if (BitIsClear (index_align, 2)) 11499 return false; 11500 11501 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11502 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11503 return false; 11504 11505 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11506 ebytes = 4; 11507 esize = 32; 11508 index = Bit32 (index_align, 3); 11509 11510 // alignment = if index_align<1:0> == �00� then 1 else 4; 11511 if (Bits32 (index_align, 1, 0) == 0) 11512 alignment = 1; 11513 else 11514 alignment = 4; 11515 } 11516 else 11517 { 11518 return false; 11519 } 11520 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11521 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11522 n = Bits32 (opcode, 19, 16); 11523 m = Bits32 (opcode, 3, 0); 11524 11525 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11526 wback = (m != 15); 11527 register_index = ((m != 15) && (m != 13)); 11528 11529 if (n == 15) 11530 return false; 11531 11532 } 11533 break; 11534 11535 default: 11536 return false; 11537 } 11538 11539 RegisterInfo base_reg; 11540 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11541 11542 uint32_t Rn = ReadCoreReg (n, &success); 11543 if (!success) 11544 return false; 11545 11546 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11547 addr_t address = Rn; 11548 if ((address % alignment) != 0) 11549 return false; 11550 11551 EmulateInstruction::Context context; 11552 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11553 if (wback) 11554 { 11555 uint32_t Rm = ReadCoreReg (m, &success); 11556 if (!success) 11557 return false; 11558 11559 uint32_t offset; 11560 if (register_index) 11561 offset = Rm; 11562 else 11563 offset = ebytes; 11564 11565 uint32_t value = Rn + offset; 11566 11567 context.type = eContextAdjustBaseRegister; 11568 context.SetRegisterPlusOffset (base_reg, offset); 11569 11570 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11571 return false; 11572 } 11573 11574 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11575 uint32_t element = MemURead (context, address, esize, 0, &success); 11576 if (!success) 11577 return false; 11578 11579 element = element << (index * esize); 11580 11581 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11582 if (!success) 11583 return false; 11584 11585 uint64_t all_ones = -1; 11586 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11587 // at element & to the right of element. 11588 if (index > 0) 11589 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11590 // now mask should be 0's where element goes & 1's 11591 // everywhere else. 11592 11593 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11594 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11595 11596 context.type = eContextRegisterLoad; 11597 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11598 return false; 11599 } 11600 return true; 11601 } 11602 11603 // A8.6.391 VST1 (multiple single elements) 11604 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without 11605 // interleaving. Every element of each register is stored. 11606 bool 11607 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11608 { 11609 #if 0 11610 if ConditionPassed() then 11611 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11612 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11613 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11614 for r = 0 to regs-1 11615 for e = 0 to elements-1 11616 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11617 address = address + ebytes; 11618 #endif 11619 11620 bool success = false; 11621 11622 if (ConditionPassed (opcode)) 11623 { 11624 uint32_t regs; 11625 uint32_t alignment; 11626 uint32_t ebytes; 11627 uint32_t esize; 11628 uint32_t elements; 11629 uint32_t d; 11630 uint32_t n; 11631 uint32_t m; 11632 bool wback; 11633 bool register_index; 11634 11635 switch (encoding) 11636 { 11637 case eEncodingT1: 11638 case eEncodingA1: 11639 { 11640 uint32_t type = Bits32 (opcode, 11, 8); 11641 uint32_t align = Bits32 (opcode, 5, 4); 11642 11643 // case type of 11644 if (type == 7) // when �0111� 11645 { 11646 // regs = 1; if align<1> == �1� then UNDEFINED; 11647 regs = 1; 11648 if (BitIsSet (align, 1)) 11649 return false; 11650 } 11651 else if (type == 10) // when �1010� 11652 { 11653 // regs = 2; if align == �11� then UNDEFINED; 11654 regs = 2; 11655 if (align == 3) 11656 return false; 11657 } 11658 else if (type == 6) // when �0110� 11659 { 11660 // regs = 3; if align<1> == �1� then UNDEFINED; 11661 regs = 3; 11662 if (BitIsSet (align, 1)) 11663 return false; 11664 } 11665 else if (type == 2) // when �0010� 11666 // regs = 4; 11667 regs = 4; 11668 else // otherwise 11669 // SEE �Related encodings�; 11670 return false; 11671 11672 // alignment = if align == �00� then 1 else 4 << UInt(align); 11673 if (align == 0) 11674 alignment = 1; 11675 else 11676 alignment = 4 << align; 11677 11678 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11679 ebytes = 1 << Bits32 (opcode,7, 6); 11680 esize = 8 * ebytes; 11681 elements = 8 / ebytes; 11682 11683 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11684 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11685 n = Bits32 (opcode, 19, 16); 11686 m = Bits32 (opcode, 3, 0); 11687 11688 // wback = (m != 15); register_index = (m != 15 && m != 13); 11689 wback = (m != 15); 11690 register_index = ((m != 15) && (m != 13)); 11691 11692 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11693 if ((d + regs) > 32) 11694 return false; 11695 11696 if (n == 15) 11697 return false; 11698 11699 } 11700 break; 11701 11702 default: 11703 return false; 11704 } 11705 11706 RegisterInfo base_reg; 11707 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11708 11709 uint32_t Rn = ReadCoreReg (n, &success); 11710 if (!success) 11711 return false; 11712 11713 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11714 addr_t address = Rn; 11715 if ((address % alignment) != 0) 11716 return false; 11717 11718 EmulateInstruction::Context context; 11719 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11720 if (wback) 11721 { 11722 uint32_t Rm = ReadCoreReg (m, &success); 11723 if (!success) 11724 return false; 11725 11726 uint32_t offset; 11727 if (register_index) 11728 offset = Rm; 11729 else 11730 offset = 8 * regs; 11731 11732 context.type = eContextAdjustBaseRegister; 11733 context.SetRegisterPlusOffset (base_reg, offset); 11734 11735 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11736 return false; 11737 } 11738 11739 RegisterInfo data_reg; 11740 context.type = eContextRegisterStore; 11741 // for r = 0 to regs-1 11742 for (int r = 0; r < regs; ++r) 11743 { 11744 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11745 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11746 if (!success) 11747 return false; 11748 11749 // for e = 0 to elements-1 11750 for (int e = 0; e < elements; ++e) 11751 { 11752 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11753 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11754 11755 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11756 if (!MemUWrite (context, address, word, ebytes)) 11757 return false; 11758 11759 // address = address + ebytes; 11760 address = address + ebytes; 11761 } 11762 } 11763 } 11764 return true; 11765 } 11766 11767 // A8.6.392 VST1 (single element from one lane) 11768 // This instruction stores one element to memory from one element of a register. 11769 bool 11770 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11771 { 11772 #if 0 11773 if ConditionPassed() then 11774 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11775 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11776 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11777 MemU[address,ebytes] = Elem[D[d],index,esize]; 11778 #endif 11779 11780 bool success = false; 11781 11782 if (ConditionPassed (opcode)) 11783 { 11784 uint32_t ebytes; 11785 uint32_t esize; 11786 uint32_t index; 11787 uint32_t alignment; 11788 uint32_t d; 11789 uint32_t n; 11790 uint32_t m; 11791 bool wback; 11792 bool register_index; 11793 11794 switch (encoding) 11795 { 11796 case eEncodingT1: 11797 case eEncodingA1: 11798 { 11799 uint32_t size = Bits32 (opcode, 11, 10); 11800 uint32_t index_align = Bits32 (opcode, 7, 4); 11801 11802 // if size == �11� then UNDEFINED; 11803 if (size == 3) 11804 return false; 11805 11806 // case size of 11807 if (size == 0) // when �00� 11808 { 11809 // if index_align<0> != �0� then UNDEFINED; 11810 if (BitIsClear (index_align, 0)) 11811 return false; 11812 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11813 ebytes = 1; 11814 esize = 8; 11815 index = Bits32 (index_align, 3, 1); 11816 alignment = 1; 11817 } 11818 else if (size == 1) // when �01� 11819 { 11820 // if index_align<1> != �0� then UNDEFINED; 11821 if (BitIsClear (index_align, 1)) 11822 return false; 11823 11824 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11825 ebytes = 2; 11826 esize = 16; 11827 index = Bits32 (index_align, 3, 2); 11828 11829 // alignment = if index_align<0> == �0� then 1 else 2; 11830 if (BitIsClear (index_align, 0)) 11831 alignment = 1; 11832 else 11833 alignment = 2; 11834 } 11835 else if (size == 2) // when �10� 11836 { 11837 // if index_align<2> != �0� then UNDEFINED; 11838 if (BitIsClear (index_align, 2)) 11839 return false; 11840 11841 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11842 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11843 return false; 11844 11845 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11846 ebytes = 4; 11847 esize = 32; 11848 index = Bit32 (index_align, 3); 11849 11850 // alignment = if index_align<1:0> == �00� then 1 else 4; 11851 if (Bits32 (index_align, 1, 0) == 0) 11852 alignment = 1; 11853 else 11854 alignment = 4; 11855 } 11856 else 11857 { 11858 return false; 11859 } 11860 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11861 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11862 n = Bits32 (opcode, 19, 16); 11863 m = Bits32 (opcode, 3, 0); 11864 11865 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11866 wback = (m != 15); 11867 register_index = ((m != 15) && (m != 13)); 11868 11869 if (n == 15) 11870 return false; 11871 } 11872 break; 11873 11874 default: 11875 return false; 11876 } 11877 11878 RegisterInfo base_reg; 11879 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11880 11881 uint32_t Rn = ReadCoreReg (n, &success); 11882 if (!success) 11883 return false; 11884 11885 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11886 addr_t address = Rn; 11887 if ((address % alignment) != 0) 11888 return false; 11889 11890 EmulateInstruction::Context context; 11891 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11892 if (wback) 11893 { 11894 uint32_t Rm = ReadCoreReg (m, &success); 11895 if (!success) 11896 return false; 11897 11898 uint32_t offset; 11899 if (register_index) 11900 offset = Rm; 11901 else 11902 offset = ebytes; 11903 11904 context.type = eContextAdjustBaseRegister; 11905 context.SetRegisterPlusOffset (base_reg, offset); 11906 11907 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11908 return false; 11909 } 11910 11911 // MemU[address,ebytes] = Elem[D[d],index,esize]; 11912 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11913 if (!success) 11914 return false; 11915 11916 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 11917 11918 RegisterInfo data_reg; 11919 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 11920 context.type = eContextRegisterStore; 11921 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11922 11923 if (!MemUWrite (context, address, word, ebytes)) 11924 return false; 11925 } 11926 return true; 11927 } 11928 11929 // A8.6.309 VLD1 (single element to all lanes) 11930 // This instruction loads one element from memory into every element of one or two vectors. 11931 bool 11932 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 11933 { 11934 #if 0 11935 if ConditionPassed() then 11936 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11937 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11938 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11939 replicated_element = Replicate(MemU[address,ebytes], elements); 11940 for r = 0 to regs-1 11941 D[d+r] = replicated_element; 11942 #endif 11943 11944 bool success = false; 11945 11946 if (ConditionPassed (opcode)) 11947 { 11948 uint32_t ebytes; 11949 uint32_t elements; 11950 uint32_t regs; 11951 uint32_t alignment; 11952 uint32_t d; 11953 uint32_t n; 11954 uint32_t m; 11955 bool wback; 11956 bool register_index; 11957 11958 switch (encoding) 11959 { 11960 case eEncodingT1: 11961 case eEncodingA1: 11962 { 11963 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED; 11964 uint32_t size = Bits32 (opcode, 7, 6); 11965 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 11966 return false; 11967 11968 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2; 11969 ebytes = 1 << size; 11970 elements = 8 / ebytes; 11971 if (BitIsClear (opcode, 5)) 11972 regs = 1; 11973 else 11974 regs = 2; 11975 11976 //alignment = if a == �0� then 1 else ebytes; 11977 if (BitIsClear (opcode, 4)) 11978 alignment = 1; 11979 else 11980 alignment = ebytes; 11981 11982 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11983 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11984 n = Bits32 (opcode, 19, 16); 11985 m = Bits32 (opcode, 3, 0); 11986 11987 //wback = (m != 15); register_index = (m != 15 && m != 13); 11988 wback = (m != 15); 11989 register_index = ((m != 15) && (m != 13)); 11990 11991 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11992 if ((d + regs) > 32) 11993 return false; 11994 11995 if (n == 15) 11996 return false; 11997 } 11998 break; 11999 12000 default: 12001 return false; 12002 } 12003 12004 RegisterInfo base_reg; 12005 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12006 12007 uint32_t Rn = ReadCoreReg (n, &success); 12008 if (!success) 12009 return false; 12010 12011 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12012 addr_t address = Rn; 12013 if ((address % alignment) != 0) 12014 return false; 12015 12016 EmulateInstruction::Context context; 12017 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12018 if (wback) 12019 { 12020 uint32_t Rm = ReadCoreReg (m, &success); 12021 if (!success) 12022 return false; 12023 12024 uint32_t offset; 12025 if (register_index) 12026 offset = Rm; 12027 else 12028 offset = ebytes; 12029 12030 context.type = eContextAdjustBaseRegister; 12031 context.SetRegisterPlusOffset (base_reg, offset); 12032 12033 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12034 return false; 12035 } 12036 12037 // replicated_element = Replicate(MemU[address,ebytes], elements); 12038 12039 context.type = eContextRegisterLoad; 12040 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12041 if (!success) 12042 return false; 12043 12044 uint64_t replicated_element = 0; 12045 uint32_t esize = ebytes * 8; 12046 for (int e = 0; e < elements; ++e) 12047 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12048 12049 // for r = 0 to regs-1 12050 for (int r = 0; r < regs; ++r) 12051 { 12052 // D[d+r] = replicated_element; 12053 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12054 return false; 12055 } 12056 } 12057 return true; 12058 } 12059 12060 // B6.2.13 SUBS PC, LR and related instructions 12061 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12062 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12063 bool 12064 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12065 { 12066 #if 0 12067 if ConditionPassed() then 12068 EncodingSpecificOperations(); 12069 if CurrentInstrSet() == InstrSet_ThumbEE then 12070 UNPREDICTABLE; 12071 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12072 case opcode of 12073 when �0000� result = R[n] AND operand2; // AND 12074 when �0001� result = R[n] EOR operand2; // EOR 12075 when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12076 when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12077 when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12078 when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12079 when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12080 when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12081 when �1100� result = R[n] OR operand2; // ORR 12082 when �1101� result = operand2; // MOV 12083 when �1110� result = R[n] AND NOT(operand2); // BIC 12084 when �1111� result = NOT(operand2); // MVN 12085 CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12086 BranchWritePC(result); 12087 #endif 12088 12089 bool success = false; 12090 12091 if (ConditionPassed (opcode)) 12092 { 12093 uint32_t n; 12094 uint32_t m; 12095 uint32_t imm32; 12096 bool register_form; 12097 ARM_ShifterType shift_t; 12098 uint32_t shift_n; 12099 uint32_t code; 12100 12101 switch (encoding) 12102 { 12103 case eEncodingT1: 12104 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12105 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB 12106 n = 14; 12107 imm32 = Bits32 (opcode, 7, 0); 12108 register_form = false; 12109 code = 2; 12110 12111 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12112 if (InITBlock() && !LastInITBlock()) 12113 return false; 12114 12115 break; 12116 12117 case eEncodingA1: 12118 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12119 n = Bits32 (opcode, 19, 16); 12120 imm32 = ARMExpandImm (opcode); 12121 register_form = false; 12122 code = Bits32 (opcode, 24, 21); 12123 12124 break; 12125 12126 case eEncodingA2: 12127 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12128 n = Bits32 (opcode, 19, 16); 12129 m = Bits32 (opcode, 3, 0); 12130 register_form = true; 12131 12132 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12133 shift_n = DecodeImmShiftARM (opcode, shift_t); 12134 12135 break; 12136 12137 default: 12138 return false; 12139 } 12140 12141 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12142 uint32_t operand2; 12143 if (register_form) 12144 { 12145 uint32_t Rm = ReadCoreReg (m, &success); 12146 if (!success) 12147 return false; 12148 12149 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12150 if (!success) 12151 return false; 12152 } 12153 else 12154 { 12155 operand2 = imm32; 12156 } 12157 12158 uint32_t Rn = ReadCoreReg (n, &success); 12159 if (!success) 12160 return false; 12161 12162 AddWithCarryResult result; 12163 12164 // case opcode of 12165 switch (code) 12166 { 12167 case 0: // when �0000� 12168 // result = R[n] AND operand2; // AND 12169 result.result = Rn & operand2; 12170 break; 12171 12172 case 1: // when �0001� 12173 // result = R[n] EOR operand2; // EOR 12174 result.result = Rn ^ operand2; 12175 break; 12176 12177 case 2: // when �0010� 12178 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12179 result = AddWithCarry (Rn, ~(operand2), 1); 12180 break; 12181 12182 case 3: // when �0011� 12183 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12184 result = AddWithCarry (~(Rn), operand2, 1); 12185 break; 12186 12187 case 4: // when �0100� 12188 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12189 result = AddWithCarry (Rn, operand2, 0); 12190 break; 12191 12192 case 5: // when �0101� 12193 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12194 result = AddWithCarry (Rn, operand2, APSR_C); 12195 break; 12196 12197 case 6: // when �0110� 12198 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12199 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12200 break; 12201 12202 case 7: // when �0111� 12203 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12204 result = AddWithCarry (~(Rn), operand2, APSR_C); 12205 break; 12206 12207 case 10: // when �1100� 12208 // result = R[n] OR operand2; // ORR 12209 result.result = Rn | operand2; 12210 break; 12211 12212 case 11: // when �1101� 12213 // result = operand2; // MOV 12214 result.result = operand2; 12215 break; 12216 12217 case 12: // when �1110� 12218 // result = R[n] AND NOT(operand2); // BIC 12219 result.result = Rn & ~(operand2); 12220 break; 12221 12222 case 15: // when �1111� 12223 // result = NOT(operand2); // MVN 12224 result.result = ~(operand2); 12225 break; 12226 12227 default: 12228 return false; 12229 } 12230 // CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12231 12232 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12233 // the best. 12234 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12235 if (!success) 12236 return false; 12237 12238 CPSRWriteByInstr (spsr, 15, true); 12239 12240 // BranchWritePC(result); 12241 EmulateInstruction::Context context; 12242 context.type = eContextAdjustPC; 12243 context.SetImmediate (result.result); 12244 12245 BranchWritePC (context, result.result); 12246 } 12247 return true; 12248 } 12249 12250 EmulateInstructionARM::ARMOpcode* 12251 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12252 { 12253 static ARMOpcode 12254 g_arm_opcodes[] = 12255 { 12256 //---------------------------------------------------------------------- 12257 // Prologue instructions 12258 //---------------------------------------------------------------------- 12259 12260 // push register(s) 12261 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12262 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12263 12264 // set r7 to point to a stack offset 12265 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12266 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12267 // copy the stack pointer to ip 12268 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12269 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12270 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12271 12272 // adjust the stack pointer 12273 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12274 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12275 12276 // push one register 12277 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12278 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12279 12280 // vector push consecutive extension register(s) 12281 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12282 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12283 12284 //---------------------------------------------------------------------- 12285 // Epilogue instructions 12286 //---------------------------------------------------------------------- 12287 12288 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12289 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12290 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12291 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12292 12293 //---------------------------------------------------------------------- 12294 // Supervisor Call (previously Software Interrupt) 12295 //---------------------------------------------------------------------- 12296 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12297 12298 //---------------------------------------------------------------------- 12299 // Branch instructions 12300 //---------------------------------------------------------------------- 12301 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12302 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 12303 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12304 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12305 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12306 // for example, "bx lr" 12307 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12308 // bxj 12309 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12310 12311 //---------------------------------------------------------------------- 12312 // Data-processing instructions 12313 //---------------------------------------------------------------------- 12314 // adc (immediate) 12315 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12316 // adc (register) 12317 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12318 // add (immediate) 12319 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12320 // add (register) 12321 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12322 // add (register-shifted register) 12323 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12324 // adr 12325 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12326 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12327 // and (immediate) 12328 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12329 // and (register) 12330 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12331 // bic (immediate) 12332 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12333 // bic (register) 12334 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12335 // eor (immediate) 12336 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12337 // eor (register) 12338 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12339 // orr (immediate) 12340 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12341 // orr (register) 12342 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12343 // rsb (immediate) 12344 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12345 // rsb (register) 12346 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12347 // rsc (immediate) 12348 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12349 // rsc (register) 12350 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12351 // sbc (immediate) 12352 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12353 // sbc (register) 12354 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12355 // sub (immediate, ARM) 12356 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12357 // sub (sp minus immediate) 12358 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12359 // sub (register) 12360 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12361 // teq (immediate) 12362 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12363 // teq (register) 12364 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12365 // tst (immediate) 12366 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12367 // tst (register) 12368 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12369 12370 // mov (immediate) 12371 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12372 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12373 // mov (register) 12374 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12375 // mvn (immediate) 12376 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12377 // mvn (register) 12378 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12379 // cmn (immediate) 12380 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12381 // cmn (register) 12382 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12383 // cmp (immediate) 12384 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12385 // cmp (register) 12386 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12387 // asr (immediate) 12388 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12389 // asr (register) 12390 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12391 // lsl (immediate) 12392 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12393 // lsl (register) 12394 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12395 // lsr (immediate) 12396 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12397 // lsr (register) 12398 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12399 // rrx is a special case encoding of ror (immediate) 12400 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12401 // ror (immediate) 12402 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12403 // ror (register) 12404 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12405 // mul 12406 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12407 12408 // subs pc, lr and related instructions 12409 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12410 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12411 12412 //---------------------------------------------------------------------- 12413 // Load instructions 12414 //---------------------------------------------------------------------- 12415 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12416 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12417 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12418 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12419 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12420 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12421 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12422 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12423 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12424 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12425 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12426 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12427 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12428 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12429 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12430 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12431 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12432 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12433 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12434 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12435 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12436 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12437 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12438 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12439 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12440 12441 //---------------------------------------------------------------------- 12442 // Store instructions 12443 //---------------------------------------------------------------------- 12444 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12445 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12446 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12447 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12448 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12449 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12450 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12451 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12452 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12453 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12454 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12455 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12456 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12457 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12458 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12459 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12460 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12461 12462 //---------------------------------------------------------------------- 12463 // Other instructions 12464 //---------------------------------------------------------------------- 12465 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12466 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12467 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12468 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12469 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12470 12471 }; 12472 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 12473 12474 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12475 { 12476 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12477 (g_arm_opcodes[i].variants & arm_isa) != 0) 12478 return &g_arm_opcodes[i]; 12479 } 12480 return NULL; 12481 } 12482 12483 12484 EmulateInstructionARM::ARMOpcode* 12485 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12486 { 12487 12488 static ARMOpcode 12489 g_thumb_opcodes[] = 12490 { 12491 //---------------------------------------------------------------------- 12492 // Prologue instructions 12493 //---------------------------------------------------------------------- 12494 12495 // push register(s) 12496 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12497 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12498 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12499 12500 // set r7 to point to a stack offset 12501 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12502 // copy the stack pointer to r7 12503 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12504 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12505 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12506 12507 // PC-relative load into register (see also EmulateADDSPRm) 12508 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12509 12510 // adjust the stack pointer 12511 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12512 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12513 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12514 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12515 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12516 12517 // vector push consecutive extension register(s) 12518 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12519 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12520 12521 //---------------------------------------------------------------------- 12522 // Epilogue instructions 12523 //---------------------------------------------------------------------- 12524 12525 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12526 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12527 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12528 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12529 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12530 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12531 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12532 12533 //---------------------------------------------------------------------- 12534 // Supervisor Call (previously Software Interrupt) 12535 //---------------------------------------------------------------------- 12536 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12537 12538 //---------------------------------------------------------------------- 12539 // If Then makes up to four following instructions conditional. 12540 //---------------------------------------------------------------------- 12541 // The next 5 opcode _must_ come before the if then instruction 12542 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12543 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12544 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12545 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12546 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12547 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12548 12549 //---------------------------------------------------------------------- 12550 // Branch instructions 12551 //---------------------------------------------------------------------- 12552 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12553 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12554 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12555 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12556 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12557 // J1 == J2 == 1 12558 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12559 // J1 == J2 == 1 12560 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12561 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12562 // for example, "bx lr" 12563 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12564 // bxj 12565 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12566 // compare and branch 12567 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12568 // table branch byte 12569 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12570 // table branch halfword 12571 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12572 12573 //---------------------------------------------------------------------- 12574 // Data-processing instructions 12575 //---------------------------------------------------------------------- 12576 // adc (immediate) 12577 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12578 // adc (register) 12579 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12580 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12581 // add (register) 12582 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12583 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12584 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12585 // adr 12586 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12587 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12588 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12589 // and (immediate) 12590 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12591 // and (register) 12592 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12593 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12594 // bic (immediate) 12595 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12596 // bic (register) 12597 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12598 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12599 // eor (immediate) 12600 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12601 // eor (register) 12602 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12603 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12604 // orr (immediate) 12605 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12606 // orr (register) 12607 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12608 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12609 // rsb (immediate) 12610 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12611 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12612 // rsb (register) 12613 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12614 // sbc (immediate) 12615 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12616 // sbc (register) 12617 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12618 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12619 // add (immediate, Thumb) 12620 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12621 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12622 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12623 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12624 // sub (immediate, Thumb) 12625 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12626 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12627 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12628 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12629 // sub (sp minus immediate) 12630 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12631 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12632 // sub (register) 12633 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12634 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12635 // teq (immediate) 12636 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12637 // teq (register) 12638 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12639 // tst (immediate) 12640 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12641 // tst (register) 12642 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12643 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12644 12645 12646 // move from high register to high register 12647 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12648 // move from low register to low register 12649 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12650 // mov{s}<c>.w <Rd>, <Rm> 12651 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12652 // move immediate 12653 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12654 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12655 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12656 // mvn (immediate) 12657 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12658 // mvn (register) 12659 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12660 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12661 // cmn (immediate) 12662 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12663 // cmn (register) 12664 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12665 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12666 // cmp (immediate) 12667 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12668 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12669 // cmp (register) (Rn and Rm both from r0-r7) 12670 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12671 // cmp (register) (Rn and Rm not both from r0-r7) 12672 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12673 // asr (immediate) 12674 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12675 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12676 // asr (register) 12677 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12678 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12679 // lsl (immediate) 12680 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12681 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12682 // lsl (register) 12683 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12684 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12685 // lsr (immediate) 12686 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12687 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12688 // lsr (register) 12689 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12690 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12691 // rrx is a special case encoding of ror (immediate) 12692 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12693 // ror (immediate) 12694 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12695 // ror (register) 12696 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12697 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12698 // mul 12699 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12700 // mul 12701 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12702 12703 // subs pc, lr and related instructions 12704 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12705 12706 //---------------------------------------------------------------------- 12707 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12708 // otherwise the wrong instructions will be selected. 12709 //---------------------------------------------------------------------- 12710 12711 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12712 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12713 12714 //---------------------------------------------------------------------- 12715 // Load instructions 12716 //---------------------------------------------------------------------- 12717 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12718 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12719 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12720 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12721 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12722 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12723 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12724 // Thumb2 PC-relative load into register 12725 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12726 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12727 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12728 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12729 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12730 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12731 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12732 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12733 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12734 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12735 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12736 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12737 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12738 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12739 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12740 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12741 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12742 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12743 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12744 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12745 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12746 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12747 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12748 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12749 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12750 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12751 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12752 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12753 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12754 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12755 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12756 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12757 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12758 12759 //---------------------------------------------------------------------- 12760 // Store instructions 12761 //---------------------------------------------------------------------- 12762 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12763 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12764 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12765 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12766 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12767 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12768 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12769 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12770 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12771 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12772 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12773 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12774 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12775 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12776 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12777 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12778 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12779 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12780 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12781 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12782 { 0xffb00000, 0xfa000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12783 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12784 12785 //---------------------------------------------------------------------- 12786 // Other instructions 12787 //---------------------------------------------------------------------- 12788 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12789 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12790 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12791 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12792 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12793 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12794 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12795 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12796 }; 12797 12798 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 12799 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12800 { 12801 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12802 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12803 return &g_thumb_opcodes[i]; 12804 } 12805 return NULL; 12806 } 12807 12808 bool 12809 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12810 { 12811 m_arch = arch; 12812 m_arm_isa = 0; 12813 const char *arch_cstr = arch.GetArchitectureName (); 12814 if (arch_cstr) 12815 { 12816 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12817 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12818 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12819 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12820 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12821 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12822 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12823 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12824 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12825 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12826 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12827 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12828 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12829 } 12830 return m_arm_isa != 0; 12831 } 12832 12833 bool 12834 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12835 { 12836 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12837 { 12838 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12839 m_opcode_mode = eModeThumb; 12840 else 12841 { 12842 AddressClass addr_class = inst_addr.GetAddressClass(); 12843 12844 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 12845 m_opcode_mode = eModeARM; 12846 else if (addr_class == eAddressClassCodeAlternateISA) 12847 m_opcode_mode = eModeThumb; 12848 else 12849 return false; 12850 } 12851 if (m_opcode_mode == eModeThumb) 12852 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 12853 else 12854 m_opcode_cpsr = CPSR_MODE_USR; 12855 return true; 12856 } 12857 return false; 12858 } 12859 12860 bool 12861 EmulateInstructionARM::ReadInstruction () 12862 { 12863 bool success = false; 12864 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 12865 if (success) 12866 { 12867 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 12868 if (success) 12869 { 12870 Context read_inst_context; 12871 read_inst_context.type = eContextReadOpcode; 12872 read_inst_context.SetNoArgs (); 12873 12874 if (m_opcode_cpsr & MASK_CPSR_T) 12875 { 12876 m_opcode_mode = eModeThumb; 12877 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 12878 12879 if (success) 12880 { 12881 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 12882 { 12883 m_opcode.SetOpcode16 (thumb_opcode); 12884 } 12885 else 12886 { 12887 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success)); 12888 } 12889 } 12890 } 12891 else 12892 { 12893 m_opcode_mode = eModeARM; 12894 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success)); 12895 } 12896 } 12897 } 12898 if (!success) 12899 { 12900 m_opcode_mode = eModeInvalid; 12901 m_addr = LLDB_INVALID_ADDRESS; 12902 } 12903 return success; 12904 } 12905 12906 uint32_t 12907 EmulateInstructionARM::ArchVersion () 12908 { 12909 return m_arm_isa; 12910 } 12911 12912 bool 12913 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) 12914 { 12915 // If we are ignoring conditions, then always return true. 12916 // this allows us to iterate over disassembly code and still 12917 // emulate an instruction even if we don't have all the right 12918 // bits set in the CPSR register... 12919 if (m_ignore_conditions) 12920 return true; 12921 12922 if (is_conditional) 12923 *is_conditional = true; 12924 12925 const uint32_t cond = CurrentCond (opcode); 12926 12927 if (cond == UINT32_MAX) 12928 return false; 12929 12930 bool result = false; 12931 switch (UnsignedBits(cond, 3, 1)) 12932 { 12933 case 0: 12934 if (m_opcode_cpsr == 0) 12935 result = true; 12936 else 12937 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 12938 break; 12939 case 1: 12940 if (m_opcode_cpsr == 0) 12941 result = true; 12942 else 12943 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 12944 break; 12945 case 2: 12946 if (m_opcode_cpsr == 0) 12947 result = true; 12948 else 12949 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 12950 break; 12951 case 3: 12952 if (m_opcode_cpsr == 0) 12953 result = true; 12954 else 12955 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 12956 break; 12957 case 4: 12958 if (m_opcode_cpsr == 0) 12959 result = true; 12960 else 12961 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12962 break; 12963 case 5: 12964 if (m_opcode_cpsr == 0) 12965 result = true; 12966 else 12967 { 12968 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12969 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12970 result = n == v; 12971 } 12972 break; 12973 case 6: 12974 if (m_opcode_cpsr == 0) 12975 result = true; 12976 else 12977 { 12978 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12979 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12980 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12981 } 12982 break; 12983 case 7: 12984 // Always execute (cond == 0b1110, or the special 0b1111 which gives 12985 // opcodes different meanings, but always means execution happpens. 12986 if (is_conditional) 12987 *is_conditional = false; 12988 result = true; 12989 break; 12990 } 12991 12992 if (cond & 1) 12993 result = !result; 12994 return result; 12995 } 12996 12997 uint32_t 12998 EmulateInstructionARM::CurrentCond (const uint32_t opcode) 12999 { 13000 switch (m_opcode_mode) 13001 { 13002 default: 13003 case eModeInvalid: 13004 break; 13005 13006 case eModeARM: 13007 return UnsignedBits(opcode, 31, 28); 13008 13009 case eModeThumb: 13010 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13011 // 'cond' field of the encoding. 13012 { 13013 const uint32_t byte_size = m_opcode.GetByteSize(); 13014 if (byte_size == 2) 13015 { 13016 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 13017 return Bits32(opcode, 11, 7); 13018 } 13019 else if (byte_size == 4) 13020 { 13021 if (Bits32(opcode, 31, 27) == 0x1e && 13022 Bits32(opcode, 15, 14) == 0x02 && 13023 Bits32(opcode, 12, 12) == 0x00 && 13024 Bits32(opcode, 25, 22) <= 0x0d) 13025 { 13026 return Bits32(opcode, 25, 22); 13027 } 13028 } 13029 else 13030 // We have an invalid thumb instruction, let's bail out. 13031 break; 13032 13033 return m_it_session.GetCond(); 13034 } 13035 } 13036 return UINT32_MAX; // Return invalid value 13037 } 13038 13039 bool 13040 EmulateInstructionARM::InITBlock() 13041 { 13042 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13043 } 13044 13045 bool 13046 EmulateInstructionARM::LastInITBlock() 13047 { 13048 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13049 } 13050 13051 bool 13052 EmulateInstructionARM::BadMode (uint32_t mode) 13053 { 13054 13055 switch (mode) 13056 { 13057 case 16: return false; // '10000' 13058 case 17: return false; // '10001' 13059 case 18: return false; // '10010' 13060 case 19: return false; // '10011' 13061 case 22: return false; // '10110' 13062 case 23: return false; // '10111' 13063 case 27: return false; // '11011' 13064 case 31: return false; // '11111' 13065 default: return true; 13066 } 13067 return true; 13068 } 13069 13070 bool 13071 EmulateInstructionARM::CurrentModeIsPrivileged () 13072 { 13073 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13074 13075 if (BadMode (mode)) 13076 return false; 13077 13078 if (mode == 16) 13079 return false; 13080 13081 return true; 13082 } 13083 13084 void 13085 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13086 { 13087 bool privileged = CurrentModeIsPrivileged(); 13088 13089 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13090 13091 if (BitIsSet (bytemask, 3)) 13092 { 13093 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13094 if (affect_execstate) 13095 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13096 } 13097 13098 if (BitIsSet (bytemask, 2)) 13099 { 13100 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13101 } 13102 13103 if (BitIsSet (bytemask, 1)) 13104 { 13105 if (affect_execstate) 13106 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13107 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13108 if (privileged) 13109 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13110 } 13111 13112 if (BitIsSet (bytemask, 0)) 13113 { 13114 if (privileged) 13115 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13116 if (affect_execstate) 13117 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13118 if (privileged) 13119 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13120 } 13121 13122 m_opcode_cpsr = tmp_cpsr; 13123 } 13124 13125 13126 bool 13127 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13128 { 13129 addr_t target; 13130 13131 // Check the current instruction set. 13132 if (CurrentInstrSet() == eModeARM) 13133 target = addr & 0xfffffffc; 13134 else 13135 target = addr & 0xfffffffe; 13136 13137 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13138 return false; 13139 13140 return true; 13141 } 13142 13143 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13144 bool 13145 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13146 { 13147 addr_t target; 13148 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13149 // we want to record it and issue a WriteRegister callback so the clients 13150 // can track the mode changes accordingly. 13151 bool cpsr_changed = false; 13152 13153 if (BitIsSet(addr, 0)) 13154 { 13155 if (CurrentInstrSet() != eModeThumb) 13156 { 13157 SelectInstrSet(eModeThumb); 13158 cpsr_changed = true; 13159 } 13160 target = addr & 0xfffffffe; 13161 context.SetISA (eModeThumb); 13162 } 13163 else if (BitIsClear(addr, 1)) 13164 { 13165 if (CurrentInstrSet() != eModeARM) 13166 { 13167 SelectInstrSet(eModeARM); 13168 cpsr_changed = true; 13169 } 13170 target = addr & 0xfffffffc; 13171 context.SetISA (eModeARM); 13172 } 13173 else 13174 return false; // address<1:0> == '10' => UNPREDICTABLE 13175 13176 if (cpsr_changed) 13177 { 13178 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13179 return false; 13180 } 13181 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13182 return false; 13183 13184 return true; 13185 } 13186 13187 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13188 bool 13189 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13190 { 13191 if (ArchVersion() >= ARMv5T) 13192 return BXWritePC(context, addr); 13193 else 13194 return BranchWritePC((const Context)context, addr); 13195 } 13196 13197 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13198 bool 13199 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13200 { 13201 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13202 return BXWritePC(context, addr); 13203 else 13204 return BranchWritePC((const Context)context, addr); 13205 } 13206 13207 EmulateInstructionARM::Mode 13208 EmulateInstructionARM::CurrentInstrSet () 13209 { 13210 return m_opcode_mode; 13211 } 13212 13213 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13214 // ReadInstruction() is performed. This function has a side effect of updating 13215 // the m_new_inst_cpsr member variable if necessary. 13216 bool 13217 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13218 { 13219 m_new_inst_cpsr = m_opcode_cpsr; 13220 switch (arm_or_thumb) 13221 { 13222 default: 13223 return false; 13224 case eModeARM: 13225 // Clear the T bit. 13226 m_new_inst_cpsr &= ~MASK_CPSR_T; 13227 break; 13228 case eModeThumb: 13229 // Set the T bit. 13230 m_new_inst_cpsr |= MASK_CPSR_T; 13231 break; 13232 } 13233 return true; 13234 } 13235 13236 // This function returns TRUE if the processor currently provides support for 13237 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13238 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13239 bool 13240 EmulateInstructionARM::UnalignedSupport() 13241 { 13242 return (ArchVersion() >= ARMv7); 13243 } 13244 13245 // The main addition and subtraction instructions can produce status information 13246 // about both unsigned carry and signed overflow conditions. This status 13247 // information can be used to synthesize multi-word additions and subtractions. 13248 EmulateInstructionARM::AddWithCarryResult 13249 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13250 { 13251 uint32_t result; 13252 uint8_t carry_out; 13253 uint8_t overflow; 13254 13255 uint64_t unsigned_sum = x + y + carry_in; 13256 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13257 13258 result = UnsignedBits(unsigned_sum, 31, 0); 13259 // carry_out = (result == unsigned_sum ? 0 : 1); 13260 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13261 13262 if (carry_in) 13263 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13264 else 13265 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13266 13267 AddWithCarryResult res = { result, carry_out, overflow }; 13268 return res; 13269 } 13270 13271 uint32_t 13272 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13273 { 13274 uint32_t reg_kind, reg_num; 13275 switch (num) 13276 { 13277 case SP_REG: 13278 reg_kind = eRegisterKindGeneric; 13279 reg_num = LLDB_REGNUM_GENERIC_SP; 13280 break; 13281 case LR_REG: 13282 reg_kind = eRegisterKindGeneric; 13283 reg_num = LLDB_REGNUM_GENERIC_RA; 13284 break; 13285 case PC_REG: 13286 reg_kind = eRegisterKindGeneric; 13287 reg_num = LLDB_REGNUM_GENERIC_PC; 13288 break; 13289 default: 13290 if (num < SP_REG) 13291 { 13292 reg_kind = eRegisterKindDWARF; 13293 reg_num = dwarf_r0 + num; 13294 } 13295 else 13296 { 13297 //assert(0 && "Invalid register number"); 13298 *success = false; 13299 return UINT32_MAX; 13300 } 13301 break; 13302 } 13303 13304 // Read our register. 13305 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13306 13307 // When executing an ARM instruction , PC reads as the address of the current 13308 // instruction plus 8. 13309 // When executing a Thumb instruction , PC reads as the address of the current 13310 // instruction plus 4. 13311 if (num == 15) 13312 { 13313 if (CurrentInstrSet() == eModeARM) 13314 val += 8; 13315 else 13316 val += 4; 13317 } 13318 13319 return val; 13320 } 13321 13322 // Write the result to the ARM core register Rd, and optionally update the 13323 // condition flags based on the result. 13324 // 13325 // This helper method tries to encapsulate the following pseudocode from the 13326 // ARM Architecture Reference Manual: 13327 // 13328 // if d == 15 then // Can only occur for encoding A1 13329 // ALUWritePC(result); // setflags is always FALSE here 13330 // else 13331 // R[d] = result; 13332 // if setflags then 13333 // APSR.N = result<31>; 13334 // APSR.Z = IsZeroBit(result); 13335 // APSR.C = carry; 13336 // // APSR.V unchanged 13337 // 13338 // In the above case, the API client does not pass in the overflow arg, which 13339 // defaults to ~0u. 13340 bool 13341 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13342 const uint32_t result, 13343 const uint32_t Rd, 13344 bool setflags, 13345 const uint32_t carry, 13346 const uint32_t overflow) 13347 { 13348 if (Rd == 15) 13349 { 13350 if (!ALUWritePC (context, result)) 13351 return false; 13352 } 13353 else 13354 { 13355 uint32_t reg_kind, reg_num; 13356 switch (Rd) 13357 { 13358 case SP_REG: 13359 reg_kind = eRegisterKindGeneric; 13360 reg_num = LLDB_REGNUM_GENERIC_SP; 13361 break; 13362 case LR_REG: 13363 reg_kind = eRegisterKindGeneric; 13364 reg_num = LLDB_REGNUM_GENERIC_RA; 13365 break; 13366 default: 13367 reg_kind = eRegisterKindDWARF; 13368 reg_num = dwarf_r0 + Rd; 13369 } 13370 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13371 return false; 13372 if (setflags) 13373 return WriteFlags (context, result, carry, overflow); 13374 } 13375 return true; 13376 } 13377 13378 // This helper method tries to encapsulate the following pseudocode from the 13379 // ARM Architecture Reference Manual: 13380 // 13381 // APSR.N = result<31>; 13382 // APSR.Z = IsZeroBit(result); 13383 // APSR.C = carry; 13384 // APSR.V = overflow 13385 // 13386 // Default arguments can be specified for carry and overflow parameters, which means 13387 // not to update the respective flags. 13388 bool 13389 EmulateInstructionARM::WriteFlags (Context &context, 13390 const uint32_t result, 13391 const uint32_t carry, 13392 const uint32_t overflow) 13393 { 13394 m_new_inst_cpsr = m_opcode_cpsr; 13395 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13396 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13397 if (carry != ~0u) 13398 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13399 if (overflow != ~0u) 13400 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13401 if (m_new_inst_cpsr != m_opcode_cpsr) 13402 { 13403 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13404 return false; 13405 } 13406 return true; 13407 } 13408 13409 bool 13410 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13411 { 13412 // Advance the ITSTATE bits to their values for the next instruction. 13413 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13414 m_it_session.ITAdvance(); 13415 13416 ARMOpcode *opcode_data = NULL; 13417 13418 if (m_opcode_mode == eModeThumb) 13419 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13420 else if (m_opcode_mode == eModeARM) 13421 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13422 13423 if (opcode_data == NULL) 13424 return false; 13425 13426 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13427 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13428 13429 bool success = false; 13430 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13431 { 13432 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13433 dwarf_cpsr, 13434 0, 13435 &success); 13436 } 13437 13438 // Only return false if we are unable to read the CPSR if we care about conditions 13439 if (success == false && m_ignore_conditions == false) 13440 return false; 13441 13442 uint32_t orig_pc_value = 0; 13443 if (auto_advance_pc) 13444 { 13445 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13446 if (!success) 13447 return false; 13448 } 13449 13450 // Call the Emulate... function. 13451 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13452 if (!success) 13453 return false; 13454 13455 if (auto_advance_pc) 13456 { 13457 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13458 if (!success) 13459 return false; 13460 13461 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13462 { 13463 if (opcode_data->size == eSize32) 13464 after_pc_value += 4; 13465 else if (opcode_data->size == eSize16) 13466 after_pc_value += 2; 13467 13468 EmulateInstruction::Context context; 13469 context.type = eContextAdvancePC; 13470 context.SetNoArgs(); 13471 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13472 return false; 13473 13474 } 13475 } 13476 return true; 13477 } 13478 13479 bool 13480 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13481 { 13482 if (!test_data) 13483 { 13484 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13485 return false; 13486 } 13487 13488 static ConstString opcode_key ("opcode"); 13489 static ConstString before_key ("before_state"); 13490 static ConstString after_key ("after_state"); 13491 13492 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13493 13494 uint32_t test_opcode; 13495 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13496 { 13497 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13498 return false; 13499 } 13500 test_opcode = value_sp->GetUInt64Value (); 13501 13502 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13503 { 13504 m_opcode_mode = eModeARM; 13505 m_opcode.SetOpcode32 (test_opcode); 13506 } 13507 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13508 { 13509 m_opcode_mode = eModeThumb; 13510 if (test_opcode < 0x10000) 13511 m_opcode.SetOpcode16 (test_opcode); 13512 else 13513 m_opcode.SetOpcode32 (test_opcode); 13514 13515 } 13516 else 13517 { 13518 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13519 return false; 13520 } 13521 13522 EmulationStateARM before_state; 13523 EmulationStateARM after_state; 13524 13525 value_sp = test_data->GetValueForKey (before_key); 13526 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13527 { 13528 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13529 return false; 13530 } 13531 13532 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13533 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13534 { 13535 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13536 return false; 13537 } 13538 13539 value_sp = test_data->GetValueForKey (after_key); 13540 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13541 { 13542 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13543 return false; 13544 } 13545 13546 state_dictionary = value_sp->GetAsDictionary (); 13547 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13548 { 13549 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13550 return false; 13551 } 13552 13553 SetBaton ((void *) &before_state); 13554 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13555 &EmulationStateARM::WritePseudoMemory, 13556 &EmulationStateARM::ReadPseudoRegister, 13557 &EmulationStateARM::WritePseudoRegister); 13558 13559 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13560 if (!success) 13561 { 13562 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13563 return false; 13564 } 13565 13566 success = before_state.CompareState (after_state); 13567 if (!success) 13568 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13569 13570 return success; 13571 } 13572 // 13573 // 13574 //const char * 13575 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13576 //{ 13577 // if (reg_kind == eRegisterKindGeneric) 13578 // { 13579 // switch (reg_num) 13580 // { 13581 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 13582 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 13583 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 13584 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 13585 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13586 // default: return NULL; 13587 // } 13588 // } 13589 // else if (reg_kind == eRegisterKindDWARF) 13590 // { 13591 // return GetARMDWARFRegisterName (reg_num); 13592 // } 13593 // return NULL; 13594 //} 13595 // 13596 bool 13597 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13598 { 13599 unwind_plan.Clear(); 13600 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13601 13602 UnwindPlan::RowSP row(new UnwindPlan::Row); 13603 13604 // Our previous Call Frame Address is the stack pointer 13605 row->SetCFARegister (dwarf_sp); 13606 13607 // Our previous PC is in the LR 13608 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true); 13609 unwind_plan.AppendRow (row); 13610 13611 // All other registers are the same. 13612 13613 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13614 return true; 13615 } 13616 13617 13618 13619 13620