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 ARMv8 (1u << 9) 134 #define ARMvAll (0xffffffffu) 135 136 #define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 137 #define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 138 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 139 #define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 140 #define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 141 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8) 142 #define ARMV7_ABOVE (ARMv7|ARMv8) 143 144 #define No_VFP 0 145 #define VFPv1 (1u << 1) 146 #define VFPv2 (1u << 2) 147 #define VFPv3 (1u << 3) 148 #define AdvancedSIMD (1u << 4) 149 150 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 151 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 152 #define VFPv2v3 (VFPv2 | VFPv3) 153 154 //---------------------------------------------------------------------- 155 // 156 // EmulateInstructionARM implementation 157 // 158 //---------------------------------------------------------------------- 159 160 void 161 EmulateInstructionARM::Initialize () 162 { 163 PluginManager::RegisterPlugin (GetPluginNameStatic (), 164 GetPluginDescriptionStatic (), 165 CreateInstance); 166 } 167 168 void 169 EmulateInstructionARM::Terminate () 170 { 171 PluginManager::UnregisterPlugin (CreateInstance); 172 } 173 174 const char * 175 EmulateInstructionARM::GetPluginNameStatic () 176 { 177 return "lldb.emulate-instruction.arm"; 178 } 179 180 const char * 181 EmulateInstructionARM::GetPluginDescriptionStatic () 182 { 183 return "Emulate instructions for the ARM architecture."; 184 } 185 186 EmulateInstruction * 187 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) 188 { 189 if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type)) 190 { 191 if (arch.GetTriple().getArch() == llvm::Triple::arm) 192 { 193 std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 194 195 if (emulate_insn_ap.get()) 196 return emulate_insn_ap.release(); 197 } 198 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 199 { 200 std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 201 202 if (emulate_insn_ap.get()) 203 return emulate_insn_ap.release(); 204 } 205 } 206 207 return NULL; 208 } 209 210 bool 211 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch) 212 { 213 if (arch.GetTriple().getArch () == llvm::Triple::arm) 214 return true; 215 else if (arch.GetTriple().getArch () == llvm::Triple::thumb) 216 return true; 217 218 return false; 219 } 220 221 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 222 bool 223 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 224 { 225 EmulateInstruction::Context context; 226 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 227 context.SetNoArgs (); 228 229 uint32_t random_data = rand (); 230 const uint32_t addr_byte_size = GetAddressByteSize(); 231 232 if (!MemAWrite (context, address, random_data, addr_byte_size)) 233 return false; 234 235 return true; 236 } 237 238 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 239 bool 240 EmulateInstructionARM::WriteBits32Unknown (int n) 241 { 242 EmulateInstruction::Context context; 243 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 244 context.SetNoArgs (); 245 246 bool success; 247 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 248 249 if (!success) 250 return false; 251 252 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 253 return false; 254 255 return true; 256 } 257 258 bool 259 EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo ®_info) 260 { 261 if (reg_kind == eRegisterKindGeneric) 262 { 263 switch (reg_num) 264 { 265 case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break; 266 case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break; 267 case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break; 268 case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break; 269 case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break; 270 default: return false; 271 } 272 } 273 274 if (reg_kind == eRegisterKindDWARF) 275 return GetARMDWARFRegisterInfo(reg_num, reg_info); 276 return false; 277 } 278 279 uint32_t 280 EmulateInstructionARM::GetFramePointerRegisterNumber () const 281 { 282 if (m_opcode_mode == eModeThumb || m_arch.GetTriple().getOS() == llvm::Triple::Darwin) 283 return 7; 284 else 285 return 11; 286 } 287 288 uint32_t 289 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 290 { 291 if (m_opcode_mode == eModeThumb || m_arch.GetTriple().getOS() == llvm::Triple::Darwin) 292 return dwarf_r7; 293 else 294 return dwarf_r11; 295 } 296 297 // Push Multiple Registers stores multiple registers to the stack, storing to 298 // consecutive memory locations ending just below the address in SP, and updates 299 // SP to point to the start of the stored data. 300 bool 301 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 302 { 303 #if 0 304 // ARM pseudo code... 305 if (ConditionPassed()) 306 { 307 EncodingSpecificOperations(); 308 NullCheckIfThumbEE(13); 309 address = SP - 4*BitCount(registers); 310 311 for (i = 0 to 14) 312 { 313 if (registers<i> == '1') 314 { 315 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 316 MemA[address,4] = bits(32) UNKNOWN; 317 else 318 MemA[address,4] = R[i]; 319 address = address + 4; 320 } 321 } 322 323 if (registers<15> == '1') // Only possible for encoding A1 or A2 324 MemA[address,4] = PCStoreValue(); 325 326 SP = SP - 4*BitCount(registers); 327 } 328 #endif 329 330 bool conditional = false; 331 bool success = false; 332 if (ConditionPassed(opcode, &conditional)) 333 { 334 const uint32_t addr_byte_size = GetAddressByteSize(); 335 const addr_t sp = ReadCoreReg (SP_REG, &success); 336 if (!success) 337 return false; 338 uint32_t registers = 0; 339 uint32_t Rt; // the source register 340 switch (encoding) { 341 case eEncodingT1: 342 registers = Bits32(opcode, 7, 0); 343 // The M bit represents LR. 344 if (Bit32(opcode, 8)) 345 registers |= (1u << 14); 346 // if BitCount(registers) < 1 then UNPREDICTABLE; 347 if (BitCount(registers) < 1) 348 return false; 349 break; 350 case eEncodingT2: 351 // Ignore bits 15 & 13. 352 registers = Bits32(opcode, 15, 0) & ~0xa000; 353 // if BitCount(registers) < 2 then UNPREDICTABLE; 354 if (BitCount(registers) < 2) 355 return false; 356 break; 357 case eEncodingT3: 358 Rt = Bits32(opcode, 15, 12); 359 // if BadReg(t) then UNPREDICTABLE; 360 if (BadReg(Rt)) 361 return false; 362 registers = (1u << Rt); 363 break; 364 case eEncodingA1: 365 registers = Bits32(opcode, 15, 0); 366 // Instead of return false, let's handle the following case as well, 367 // which amounts to pushing one reg onto the full descending stacks. 368 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 369 break; 370 case eEncodingA2: 371 Rt = Bits32(opcode, 15, 12); 372 // if t == 13 then UNPREDICTABLE; 373 if (Rt == dwarf_sp) 374 return false; 375 registers = (1u << Rt); 376 break; 377 default: 378 return false; 379 } 380 addr_t sp_offset = addr_byte_size * BitCount (registers); 381 addr_t addr = sp - sp_offset; 382 uint32_t i; 383 384 EmulateInstruction::Context context; 385 if (conditional) 386 context.type = EmulateInstruction::eContextRegisterStore; 387 else 388 context.type = EmulateInstruction::eContextPushRegisterOnStack; 389 RegisterInfo reg_info; 390 RegisterInfo sp_reg; 391 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 392 for (i=0; i<15; ++i) 393 { 394 if (BitIsSet (registers, i)) 395 { 396 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 397 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 398 uint32_t reg_value = ReadCoreReg(i, &success); 399 if (!success) 400 return false; 401 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 402 return false; 403 addr += addr_byte_size; 404 } 405 } 406 407 if (BitIsSet (registers, 15)) 408 { 409 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 410 context.SetRegisterPlusOffset (reg_info, addr - sp); 411 const uint32_t pc = ReadCoreReg(PC_REG, &success); 412 if (!success) 413 return false; 414 if (!MemAWrite (context, addr, pc, addr_byte_size)) 415 return false; 416 } 417 418 context.type = EmulateInstruction::eContextAdjustStackPointer; 419 context.SetImmediateSigned (-sp_offset); 420 421 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 422 return false; 423 } 424 return true; 425 } 426 427 // Pop Multiple Registers loads multiple registers from the stack, loading from 428 // consecutive memory locations staring at the address in SP, and updates 429 // SP to point just above the loaded data. 430 bool 431 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 432 { 433 #if 0 434 // ARM pseudo code... 435 if (ConditionPassed()) 436 { 437 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 438 address = SP; 439 for i = 0 to 14 440 if registers<i> == '1' then 441 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 442 if registers<15> == '1' then 443 if UnalignedAllowed then 444 LoadWritePC(MemU[address,4]); 445 else 446 LoadWritePC(MemA[address,4]); 447 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 448 if registers<13> == '1' then SP = bits(32) UNKNOWN; 449 } 450 #endif 451 452 bool success = false; 453 454 bool conditional = false; 455 if (ConditionPassed(opcode, &conditional)) 456 { 457 const uint32_t addr_byte_size = GetAddressByteSize(); 458 const addr_t sp = ReadCoreReg (SP_REG, &success); 459 if (!success) 460 return false; 461 uint32_t registers = 0; 462 uint32_t Rt; // the destination register 463 switch (encoding) { 464 case eEncodingT1: 465 registers = Bits32(opcode, 7, 0); 466 // The P bit represents PC. 467 if (Bit32(opcode, 8)) 468 registers |= (1u << 15); 469 // if BitCount(registers) < 1 then UNPREDICTABLE; 470 if (BitCount(registers) < 1) 471 return false; 472 break; 473 case eEncodingT2: 474 // Ignore bit 13. 475 registers = Bits32(opcode, 15, 0) & ~0x2000; 476 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 477 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 478 return false; 479 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 480 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 481 return false; 482 break; 483 case eEncodingT3: 484 Rt = Bits32(opcode, 15, 12); 485 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 486 if (Rt == 13) 487 return false; 488 if (Rt == 15 && InITBlock() && !LastInITBlock()) 489 return false; 490 registers = (1u << Rt); 491 break; 492 case eEncodingA1: 493 registers = Bits32(opcode, 15, 0); 494 // Instead of return false, let's handle the following case as well, 495 // which amounts to popping one reg from the full descending stacks. 496 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 497 498 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 499 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 500 return false; 501 break; 502 case eEncodingA2: 503 Rt = Bits32(opcode, 15, 12); 504 // if t == 13 then UNPREDICTABLE; 505 if (Rt == dwarf_sp) 506 return false; 507 registers = (1u << Rt); 508 break; 509 default: 510 return false; 511 } 512 addr_t sp_offset = addr_byte_size * BitCount (registers); 513 addr_t addr = sp; 514 uint32_t i, data; 515 516 EmulateInstruction::Context context; 517 if (conditional) 518 context.type = EmulateInstruction::eContextRegisterLoad; 519 else 520 context.type = EmulateInstruction::eContextPopRegisterOffStack; 521 522 RegisterInfo sp_reg; 523 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 524 525 for (i=0; i<15; ++i) 526 { 527 if (BitIsSet (registers, i)) 528 { 529 context.SetRegisterPlusOffset (sp_reg, addr - sp); 530 data = MemARead(context, addr, 4, 0, &success); 531 if (!success) 532 return false; 533 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 534 return false; 535 addr += addr_byte_size; 536 } 537 } 538 539 if (BitIsSet (registers, 15)) 540 { 541 context.SetRegisterPlusOffset (sp_reg, addr - sp); 542 data = MemARead(context, addr, 4, 0, &success); 543 if (!success) 544 return false; 545 // In ARMv5T and above, this is an interworking branch. 546 if (!LoadWritePC(context, data)) 547 return false; 548 addr += addr_byte_size; 549 } 550 551 context.type = EmulateInstruction::eContextAdjustStackPointer; 552 context.SetImmediateSigned (sp_offset); 553 554 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 555 return false; 556 } 557 return true; 558 } 559 560 // Set r7 or ip to point to saved value residing within the stack. 561 // ADD (SP plus immediate) 562 bool 563 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 564 { 565 #if 0 566 // ARM pseudo code... 567 if (ConditionPassed()) 568 { 569 EncodingSpecificOperations(); 570 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 571 if d == 15 then 572 ALUWritePC(result); // setflags is always FALSE here 573 else 574 R[d] = result; 575 if setflags then 576 APSR.N = result<31>; 577 APSR.Z = IsZeroBit(result); 578 APSR.C = carry; 579 APSR.V = overflow; 580 } 581 #endif 582 583 bool success = false; 584 585 if (ConditionPassed(opcode)) 586 { 587 const addr_t sp = ReadCoreReg (SP_REG, &success); 588 if (!success) 589 return false; 590 uint32_t Rd; // the destination register 591 uint32_t imm32; 592 switch (encoding) { 593 case eEncodingT1: 594 Rd = 7; 595 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 596 break; 597 case eEncodingA1: 598 Rd = Bits32(opcode, 15, 12); 599 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 600 break; 601 default: 602 return false; 603 } 604 addr_t sp_offset = imm32; 605 addr_t addr = sp + sp_offset; // a pointer to the stack area 606 607 EmulateInstruction::Context context; 608 context.type = eContextSetFramePointer; 609 RegisterInfo sp_reg; 610 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 611 context.SetRegisterPlusOffset (sp_reg, sp_offset); 612 613 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 614 return false; 615 } 616 return true; 617 } 618 619 // Set r7 or ip to the current stack pointer. 620 // MOV (register) 621 bool 622 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 623 { 624 #if 0 625 // ARM pseudo code... 626 if (ConditionPassed()) 627 { 628 EncodingSpecificOperations(); 629 result = R[m]; 630 if d == 15 then 631 ALUWritePC(result); // setflags is always FALSE here 632 else 633 R[d] = result; 634 if setflags then 635 APSR.N = result<31>; 636 APSR.Z = IsZeroBit(result); 637 // APSR.C unchanged 638 // APSR.V unchanged 639 } 640 #endif 641 642 bool success = false; 643 644 if (ConditionPassed(opcode)) 645 { 646 const addr_t sp = ReadCoreReg (SP_REG, &success); 647 if (!success) 648 return false; 649 uint32_t Rd; // the destination register 650 switch (encoding) { 651 case eEncodingT1: 652 Rd = 7; 653 break; 654 case eEncodingA1: 655 Rd = 12; 656 break; 657 default: 658 return false; 659 } 660 661 EmulateInstruction::Context context; 662 if (Rd == GetFramePointerRegisterNumber()) 663 context.type = EmulateInstruction::eContextSetFramePointer; 664 else 665 context.type = EmulateInstruction::eContextRegisterPlusOffset; 666 RegisterInfo sp_reg; 667 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 668 context.SetRegisterPlusOffset (sp_reg, 0); 669 670 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 671 return false; 672 } 673 return true; 674 } 675 676 // Move from high register (r8-r15) to low register (r0-r7). 677 // MOV (register) 678 bool 679 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 680 { 681 return EmulateMOVRdRm (opcode, encoding); 682 } 683 684 // Move from register to register. 685 // MOV (register) 686 bool 687 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 688 { 689 #if 0 690 // ARM pseudo code... 691 if (ConditionPassed()) 692 { 693 EncodingSpecificOperations(); 694 result = R[m]; 695 if d == 15 then 696 ALUWritePC(result); // setflags is always FALSE here 697 else 698 R[d] = result; 699 if setflags then 700 APSR.N = result<31>; 701 APSR.Z = IsZeroBit(result); 702 // APSR.C unchanged 703 // APSR.V unchanged 704 } 705 #endif 706 707 bool success = false; 708 709 if (ConditionPassed(opcode)) 710 { 711 uint32_t Rm; // the source register 712 uint32_t Rd; // the destination register 713 bool setflags; 714 switch (encoding) { 715 case eEncodingT1: 716 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 717 Rm = Bits32(opcode, 6, 3); 718 setflags = false; 719 if (Rd == 15 && InITBlock() && !LastInITBlock()) 720 return false; 721 break; 722 case eEncodingT2: 723 Rd = Bits32(opcode, 2, 0); 724 Rm = Bits32(opcode, 5, 3); 725 setflags = true; 726 if (InITBlock()) 727 return false; 728 break; 729 case eEncodingT3: 730 Rd = Bits32(opcode, 11, 8); 731 Rm = Bits32(opcode, 3, 0); 732 setflags = BitIsSet(opcode, 20); 733 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 734 if (setflags && (BadReg(Rd) || BadReg(Rm))) 735 return false; 736 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 737 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 738 return false; 739 break; 740 case eEncodingA1: 741 Rd = Bits32(opcode, 15, 12); 742 Rm = Bits32(opcode, 3, 0); 743 setflags = BitIsSet(opcode, 20); 744 745 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 746 if (Rd == 15 && setflags) 747 return EmulateSUBSPcLrEtc (opcode, encoding); 748 break; 749 default: 750 return false; 751 } 752 uint32_t result = ReadCoreReg(Rm, &success); 753 if (!success) 754 return false; 755 756 // The context specifies that Rm is to be moved into Rd. 757 EmulateInstruction::Context context; 758 context.type = EmulateInstruction::eContextRegisterLoad; 759 RegisterInfo dwarf_reg; 760 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 761 context.SetRegister (dwarf_reg); 762 763 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 764 return false; 765 } 766 return true; 767 } 768 769 // Move (immediate) writes an immediate value to the destination register. It 770 // can optionally update the condition flags based on the value. 771 // MOV (immediate) 772 bool 773 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 774 { 775 #if 0 776 // ARM pseudo code... 777 if (ConditionPassed()) 778 { 779 EncodingSpecificOperations(); 780 result = imm32; 781 if d == 15 then // Can only occur for ARM encoding 782 ALUWritePC(result); // setflags is always FALSE here 783 else 784 R[d] = result; 785 if setflags then 786 APSR.N = result<31>; 787 APSR.Z = IsZeroBit(result); 788 APSR.C = carry; 789 // APSR.V unchanged 790 } 791 #endif 792 793 if (ConditionPassed(opcode)) 794 { 795 uint32_t Rd; // the destination register 796 uint32_t imm32; // the immediate value to be written to Rd 797 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 798 // for setflags == false, this value is a don't care 799 // initialized to 0 to silence the static analyzer 800 bool setflags; 801 switch (encoding) { 802 case eEncodingT1: 803 Rd = Bits32(opcode, 10, 8); 804 setflags = !InITBlock(); 805 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 806 carry = APSR_C; 807 808 break; 809 810 case eEncodingT2: 811 Rd = Bits32(opcode, 11, 8); 812 setflags = BitIsSet(opcode, 20); 813 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 814 if (BadReg(Rd)) 815 return false; 816 817 break; 818 819 case eEncodingT3: 820 { 821 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 822 Rd = Bits32 (opcode, 11, 8); 823 setflags = false; 824 uint32_t imm4 = Bits32 (opcode, 19, 16); 825 uint32_t imm3 = Bits32 (opcode, 14, 12); 826 uint32_t i = Bit32 (opcode, 26); 827 uint32_t imm8 = Bits32 (opcode, 7, 0); 828 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 829 830 // if BadReg(d) then UNPREDICTABLE; 831 if (BadReg (Rd)) 832 return false; 833 } 834 break; 835 836 case eEncodingA1: 837 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 838 Rd = Bits32 (opcode, 15, 12); 839 setflags = BitIsSet (opcode, 20); 840 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 841 842 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 843 if ((Rd == 15) && setflags) 844 return EmulateSUBSPcLrEtc (opcode, encoding); 845 846 break; 847 848 case eEncodingA2: 849 { 850 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 851 Rd = Bits32 (opcode, 15, 12); 852 setflags = false; 853 uint32_t imm4 = Bits32 (opcode, 19, 16); 854 uint32_t imm12 = Bits32 (opcode, 11, 0); 855 imm32 = (imm4 << 12) | imm12; 856 857 // if d == 15 then UNPREDICTABLE; 858 if (Rd == 15) 859 return false; 860 } 861 break; 862 863 default: 864 return false; 865 } 866 uint32_t result = imm32; 867 868 // The context specifies that an immediate is to be moved into Rd. 869 EmulateInstruction::Context context; 870 context.type = EmulateInstruction::eContextImmediate; 871 context.SetNoArgs (); 872 873 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 874 return false; 875 } 876 return true; 877 } 878 879 // MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 880 // register. These 32 bits do not depend on whether the source register values are considered to be signed values or 881 // unsigned values. 882 // 883 // Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 884 // limited to only a few forms of the instruction. 885 bool 886 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 887 { 888 #if 0 889 if ConditionPassed() then 890 EncodingSpecificOperations(); 891 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 892 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 893 result = operand1 * operand2; 894 R[d] = result<31:0>; 895 if setflags then 896 APSR.N = result<31>; 897 APSR.Z = IsZeroBit(result); 898 if ArchVersion() == 4 then 899 APSR.C = bit UNKNOWN; 900 // else APSR.C unchanged 901 // APSR.V always unchanged 902 #endif 903 904 if (ConditionPassed(opcode)) 905 { 906 uint32_t d; 907 uint32_t n; 908 uint32_t m; 909 bool setflags; 910 911 // EncodingSpecificOperations(); 912 switch (encoding) 913 { 914 case eEncodingT1: 915 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 916 d = Bits32 (opcode, 2, 0); 917 n = Bits32 (opcode, 5, 3); 918 m = Bits32 (opcode, 2, 0); 919 setflags = !InITBlock(); 920 921 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 922 if ((ArchVersion() < ARMv6) && (d == n)) 923 return false; 924 925 break; 926 927 case eEncodingT2: 928 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 929 d = Bits32 (opcode, 11, 8); 930 n = Bits32 (opcode, 19, 16); 931 m = Bits32 (opcode, 3, 0); 932 setflags = false; 933 934 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 935 if (BadReg (d) || BadReg (n) || BadReg (m)) 936 return false; 937 938 break; 939 940 case eEncodingA1: 941 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 942 d = Bits32 (opcode, 19, 16); 943 n = Bits32 (opcode, 3, 0); 944 m = Bits32 (opcode, 11, 8); 945 setflags = BitIsSet (opcode, 20); 946 947 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 948 if ((d == 15) || (n == 15) || (m == 15)) 949 return false; 950 951 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 952 if ((ArchVersion() < ARMv6) && (d == n)) 953 return false; 954 955 break; 956 957 default: 958 return false; 959 } 960 961 bool success = false; 962 963 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 964 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 965 if (!success) 966 return false; 967 968 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 969 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 970 if (!success) 971 return false; 972 973 // result = operand1 * operand2; 974 uint64_t result = operand1 * operand2; 975 976 // R[d] = result<31:0>; 977 RegisterInfo op1_reg; 978 RegisterInfo op2_reg; 979 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 980 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 981 982 EmulateInstruction::Context context; 983 context.type = eContextArithmetic; 984 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 985 986 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 987 return false; 988 989 // if setflags then 990 if (setflags) 991 { 992 // APSR.N = result<31>; 993 // APSR.Z = IsZeroBit(result); 994 m_new_inst_cpsr = m_opcode_cpsr; 995 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 996 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 997 if (m_new_inst_cpsr != m_opcode_cpsr) 998 { 999 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1000 return false; 1001 } 1002 1003 // if ArchVersion() == 4 then 1004 // APSR.C = bit UNKNOWN; 1005 } 1006 } 1007 return true; 1008 } 1009 1010 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1011 // It can optionally update the condition flags based on the value. 1012 bool 1013 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1014 { 1015 #if 0 1016 // ARM pseudo code... 1017 if (ConditionPassed()) 1018 { 1019 EncodingSpecificOperations(); 1020 result = NOT(imm32); 1021 if d == 15 then // Can only occur for ARM encoding 1022 ALUWritePC(result); // setflags is always FALSE here 1023 else 1024 R[d] = result; 1025 if setflags then 1026 APSR.N = result<31>; 1027 APSR.Z = IsZeroBit(result); 1028 APSR.C = carry; 1029 // APSR.V unchanged 1030 } 1031 #endif 1032 1033 if (ConditionPassed(opcode)) 1034 { 1035 uint32_t Rd; // the destination register 1036 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1037 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1038 bool setflags; 1039 switch (encoding) { 1040 case eEncodingT1: 1041 Rd = Bits32(opcode, 11, 8); 1042 setflags = BitIsSet(opcode, 20); 1043 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1044 break; 1045 case eEncodingA1: 1046 Rd = Bits32(opcode, 15, 12); 1047 setflags = BitIsSet(opcode, 20); 1048 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1049 1050 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1051 if (Rd == 15 && setflags) 1052 return EmulateSUBSPcLrEtc (opcode, encoding); 1053 break; 1054 default: 1055 return false; 1056 } 1057 uint32_t result = ~imm32; 1058 1059 // The context specifies that an immediate is to be moved into Rd. 1060 EmulateInstruction::Context context; 1061 context.type = EmulateInstruction::eContextImmediate; 1062 context.SetNoArgs (); 1063 1064 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1065 return false; 1066 } 1067 return true; 1068 } 1069 1070 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1071 // It can optionally update the condition flags based on the result. 1072 bool 1073 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1074 { 1075 #if 0 1076 // ARM pseudo code... 1077 if (ConditionPassed()) 1078 { 1079 EncodingSpecificOperations(); 1080 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1081 result = NOT(shifted); 1082 if d == 15 then // Can only occur for ARM encoding 1083 ALUWritePC(result); // setflags is always FALSE here 1084 else 1085 R[d] = result; 1086 if setflags then 1087 APSR.N = result<31>; 1088 APSR.Z = IsZeroBit(result); 1089 APSR.C = carry; 1090 // APSR.V unchanged 1091 } 1092 #endif 1093 1094 if (ConditionPassed(opcode)) 1095 { 1096 uint32_t Rm; // the source register 1097 uint32_t Rd; // the destination register 1098 ARM_ShifterType shift_t; 1099 uint32_t shift_n; // the shift applied to the value read from Rm 1100 bool setflags; 1101 uint32_t carry; // the carry bit after the shift operation 1102 switch (encoding) { 1103 case eEncodingT1: 1104 Rd = Bits32(opcode, 2, 0); 1105 Rm = Bits32(opcode, 5, 3); 1106 setflags = !InITBlock(); 1107 shift_t = SRType_LSL; 1108 shift_n = 0; 1109 if (InITBlock()) 1110 return false; 1111 break; 1112 case eEncodingT2: 1113 Rd = Bits32(opcode, 11, 8); 1114 Rm = Bits32(opcode, 3, 0); 1115 setflags = BitIsSet(opcode, 20); 1116 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1117 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1118 if (BadReg(Rd) || BadReg(Rm)) 1119 return false; 1120 break; 1121 case eEncodingA1: 1122 Rd = Bits32(opcode, 15, 12); 1123 Rm = Bits32(opcode, 3, 0); 1124 setflags = BitIsSet(opcode, 20); 1125 shift_n = DecodeImmShiftARM(opcode, shift_t); 1126 break; 1127 default: 1128 return false; 1129 } 1130 bool success = false; 1131 uint32_t value = ReadCoreReg(Rm, &success); 1132 if (!success) 1133 return false; 1134 1135 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1136 if (!success) 1137 return false; 1138 uint32_t result = ~shifted; 1139 1140 // The context specifies that an immediate is to be moved into Rd. 1141 EmulateInstruction::Context context; 1142 context.type = EmulateInstruction::eContextImmediate; 1143 context.SetNoArgs (); 1144 1145 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1146 return false; 1147 } 1148 return true; 1149 } 1150 1151 // PC relative immediate load into register, possibly followed by ADD (SP plus register). 1152 // LDR (literal) 1153 bool 1154 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1155 { 1156 #if 0 1157 // ARM pseudo code... 1158 if (ConditionPassed()) 1159 { 1160 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1161 base = Align(PC,4); 1162 address = if add then (base + imm32) else (base - imm32); 1163 data = MemU[address,4]; 1164 if t == 15 then 1165 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1166 elsif UnalignedSupport() || address<1:0> = '00' then 1167 R[t] = data; 1168 else // Can only apply before ARMv7 1169 if CurrentInstrSet() == InstrSet_ARM then 1170 R[t] = ROR(data, 8*UInt(address<1:0>)); 1171 else 1172 R[t] = bits(32) UNKNOWN; 1173 } 1174 #endif 1175 1176 if (ConditionPassed(opcode)) 1177 { 1178 bool success = false; 1179 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1180 if (!success) 1181 return false; 1182 1183 // PC relative immediate load context 1184 EmulateInstruction::Context context; 1185 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1186 RegisterInfo pc_reg; 1187 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1188 context.SetRegisterPlusOffset (pc_reg, 0); 1189 1190 uint32_t Rt; // the destination register 1191 uint32_t imm32; // immediate offset from the PC 1192 bool add; // +imm32 or -imm32? 1193 addr_t base; // the base address 1194 addr_t address; // the PC relative address 1195 uint32_t data; // the literal data value from the PC relative load 1196 switch (encoding) { 1197 case eEncodingT1: 1198 Rt = Bits32(opcode, 10, 8); 1199 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1200 add = true; 1201 break; 1202 case eEncodingT2: 1203 Rt = Bits32(opcode, 15, 12); 1204 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1205 add = BitIsSet(opcode, 23); 1206 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1207 return false; 1208 break; 1209 default: 1210 return false; 1211 } 1212 1213 base = Align(pc, 4); 1214 if (add) 1215 address = base + imm32; 1216 else 1217 address = base - imm32; 1218 1219 context.SetRegisterPlusOffset(pc_reg, address - base); 1220 data = MemURead(context, address, 4, 0, &success); 1221 if (!success) 1222 return false; 1223 1224 if (Rt == 15) 1225 { 1226 if (Bits32(address, 1, 0) == 0) 1227 { 1228 // In ARMv5T and above, this is an interworking branch. 1229 if (!LoadWritePC(context, data)) 1230 return false; 1231 } 1232 else 1233 return false; 1234 } 1235 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1236 { 1237 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1238 return false; 1239 } 1240 else // We don't handle ARM for now. 1241 return false; 1242 1243 } 1244 return true; 1245 } 1246 1247 // An add operation to adjust the SP. 1248 // ADD (SP plus immediate) 1249 bool 1250 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1251 { 1252 #if 0 1253 // ARM pseudo code... 1254 if (ConditionPassed()) 1255 { 1256 EncodingSpecificOperations(); 1257 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1258 if d == 15 then // Can only occur for ARM encoding 1259 ALUWritePC(result); // setflags is always FALSE here 1260 else 1261 R[d] = result; 1262 if setflags then 1263 APSR.N = result<31>; 1264 APSR.Z = IsZeroBit(result); 1265 APSR.C = carry; 1266 APSR.V = overflow; 1267 } 1268 #endif 1269 1270 bool success = false; 1271 1272 if (ConditionPassed(opcode)) 1273 { 1274 const addr_t sp = ReadCoreReg (SP_REG, &success); 1275 if (!success) 1276 return false; 1277 uint32_t imm32; // the immediate operand 1278 uint32_t d; 1279 bool setflags; 1280 switch (encoding) 1281 { 1282 case eEncodingT1: 1283 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1284 d = Bits32 (opcode, 10, 8); 1285 setflags = false; 1286 imm32 = (Bits32 (opcode, 7, 0) << 2); 1287 1288 break; 1289 1290 case eEncodingT2: 1291 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1292 d = 13; 1293 setflags = false; 1294 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1295 1296 break; 1297 1298 default: 1299 return false; 1300 } 1301 addr_t sp_offset = imm32; 1302 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1303 1304 EmulateInstruction::Context context; 1305 context.type = EmulateInstruction::eContextAdjustStackPointer; 1306 RegisterInfo sp_reg; 1307 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1308 context.SetRegisterPlusOffset (sp_reg, sp_offset); 1309 1310 if (d == 15) 1311 { 1312 if (!ALUWritePC (context, addr)) 1313 return false; 1314 } 1315 else 1316 { 1317 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr)) 1318 return false; 1319 } 1320 } 1321 return true; 1322 } 1323 1324 // An add operation to adjust the SP. 1325 // ADD (SP plus register) 1326 bool 1327 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1328 { 1329 #if 0 1330 // ARM pseudo code... 1331 if (ConditionPassed()) 1332 { 1333 EncodingSpecificOperations(); 1334 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1335 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1336 if d == 15 then 1337 ALUWritePC(result); // setflags is always FALSE here 1338 else 1339 R[d] = result; 1340 if setflags then 1341 APSR.N = result<31>; 1342 APSR.Z = IsZeroBit(result); 1343 APSR.C = carry; 1344 APSR.V = overflow; 1345 } 1346 #endif 1347 1348 bool success = false; 1349 1350 if (ConditionPassed(opcode)) 1351 { 1352 const addr_t sp = ReadCoreReg (SP_REG, &success); 1353 if (!success) 1354 return false; 1355 uint32_t Rm; // the second operand 1356 switch (encoding) { 1357 case eEncodingT2: 1358 Rm = Bits32(opcode, 6, 3); 1359 break; 1360 default: 1361 return false; 1362 } 1363 int32_t reg_value = ReadCoreReg(Rm, &success); 1364 if (!success) 1365 return false; 1366 1367 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1368 1369 EmulateInstruction::Context context; 1370 context.type = eContextArithmetic; 1371 RegisterInfo sp_reg; 1372 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1373 1374 RegisterInfo other_reg; 1375 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1376 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1377 1378 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1379 return false; 1380 } 1381 return true; 1382 } 1383 1384 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1385 // at a PC-relative address, and changes instruction set from ARM to Thumb, or 1386 // from Thumb to ARM. 1387 // BLX (immediate) 1388 bool 1389 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1390 { 1391 #if 0 1392 // ARM pseudo code... 1393 if (ConditionPassed()) 1394 { 1395 EncodingSpecificOperations(); 1396 if CurrentInstrSet() == InstrSet_ARM then 1397 LR = PC - 4; 1398 else 1399 LR = PC<31:1> : '1'; 1400 if targetInstrSet == InstrSet_ARM then 1401 targetAddress = Align(PC,4) + imm32; 1402 else 1403 targetAddress = PC + imm32; 1404 SelectInstrSet(targetInstrSet); 1405 BranchWritePC(targetAddress); 1406 } 1407 #endif 1408 1409 bool success = true; 1410 1411 if (ConditionPassed(opcode)) 1412 { 1413 EmulateInstruction::Context context; 1414 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1415 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1416 if (!success) 1417 return false; 1418 addr_t lr; // next instruction address 1419 addr_t target; // target address 1420 int32_t imm32; // PC-relative offset 1421 switch (encoding) { 1422 case eEncodingT1: 1423 { 1424 lr = pc | 1u; // return address 1425 uint32_t S = Bit32(opcode, 26); 1426 uint32_t imm10 = Bits32(opcode, 25, 16); 1427 uint32_t J1 = Bit32(opcode, 13); 1428 uint32_t J2 = Bit32(opcode, 11); 1429 uint32_t imm11 = Bits32(opcode, 10, 0); 1430 uint32_t I1 = !(J1 ^ S); 1431 uint32_t I2 = !(J2 ^ S); 1432 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1433 imm32 = llvm::SignExtend32<25>(imm25); 1434 target = pc + imm32; 1435 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1436 if (InITBlock() && !LastInITBlock()) 1437 return false; 1438 break; 1439 } 1440 case eEncodingT2: 1441 { 1442 lr = pc | 1u; // return address 1443 uint32_t S = Bit32(opcode, 26); 1444 uint32_t imm10H = Bits32(opcode, 25, 16); 1445 uint32_t J1 = Bit32(opcode, 13); 1446 uint32_t J2 = Bit32(opcode, 11); 1447 uint32_t imm10L = Bits32(opcode, 10, 1); 1448 uint32_t I1 = !(J1 ^ S); 1449 uint32_t I2 = !(J2 ^ S); 1450 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1451 imm32 = llvm::SignExtend32<25>(imm25); 1452 target = Align(pc, 4) + imm32; 1453 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1454 if (InITBlock() && !LastInITBlock()) 1455 return false; 1456 break; 1457 } 1458 case eEncodingA1: 1459 lr = pc - 4; // return address 1460 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1461 target = Align(pc, 4) + imm32; 1462 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1463 break; 1464 case eEncodingA2: 1465 lr = pc - 4; // return address 1466 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1467 target = pc + imm32; 1468 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1469 break; 1470 default: 1471 return false; 1472 } 1473 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1474 return false; 1475 if (!BranchWritePC(context, target)) 1476 return false; 1477 } 1478 return true; 1479 } 1480 1481 // Branch with Link and Exchange (register) calls a subroutine at an address and 1482 // instruction set specified by a register. 1483 // BLX (register) 1484 bool 1485 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1486 { 1487 #if 0 1488 // ARM pseudo code... 1489 if (ConditionPassed()) 1490 { 1491 EncodingSpecificOperations(); 1492 target = R[m]; 1493 if CurrentInstrSet() == InstrSet_ARM then 1494 next_instr_addr = PC - 4; 1495 LR = next_instr_addr; 1496 else 1497 next_instr_addr = PC - 2; 1498 LR = next_instr_addr<31:1> : '1'; 1499 BXWritePC(target); 1500 } 1501 #endif 1502 1503 bool success = false; 1504 1505 if (ConditionPassed(opcode)) 1506 { 1507 EmulateInstruction::Context context; 1508 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1509 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1510 addr_t lr; // next instruction address 1511 if (!success) 1512 return false; 1513 uint32_t Rm; // the register with the target address 1514 switch (encoding) { 1515 case eEncodingT1: 1516 lr = (pc - 2) | 1u; // return address 1517 Rm = Bits32(opcode, 6, 3); 1518 // if m == 15 then UNPREDICTABLE; 1519 if (Rm == 15) 1520 return false; 1521 if (InITBlock() && !LastInITBlock()) 1522 return false; 1523 break; 1524 case eEncodingA1: 1525 lr = pc - 4; // return address 1526 Rm = Bits32(opcode, 3, 0); 1527 // if m == 15 then UNPREDICTABLE; 1528 if (Rm == 15) 1529 return false; 1530 break; 1531 default: 1532 return false; 1533 } 1534 addr_t target = ReadCoreReg (Rm, &success); 1535 if (!success) 1536 return false; 1537 RegisterInfo dwarf_reg; 1538 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1539 context.SetRegister (dwarf_reg); 1540 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1541 return false; 1542 if (!BXWritePC(context, target)) 1543 return false; 1544 } 1545 return true; 1546 } 1547 1548 // Branch and Exchange causes a branch to an address and instruction set specified by a register. 1549 bool 1550 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1551 { 1552 #if 0 1553 // ARM pseudo code... 1554 if (ConditionPassed()) 1555 { 1556 EncodingSpecificOperations(); 1557 BXWritePC(R[m]); 1558 } 1559 #endif 1560 1561 if (ConditionPassed(opcode)) 1562 { 1563 EmulateInstruction::Context context; 1564 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1565 uint32_t Rm; // the register with the target address 1566 switch (encoding) { 1567 case eEncodingT1: 1568 Rm = Bits32(opcode, 6, 3); 1569 if (InITBlock() && !LastInITBlock()) 1570 return false; 1571 break; 1572 case eEncodingA1: 1573 Rm = Bits32(opcode, 3, 0); 1574 break; 1575 default: 1576 return false; 1577 } 1578 bool success = false; 1579 addr_t target = ReadCoreReg (Rm, &success); 1580 if (!success) 1581 return false; 1582 1583 RegisterInfo dwarf_reg; 1584 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1585 context.SetRegister (dwarf_reg); 1586 if (!BXWritePC(context, target)) 1587 return false; 1588 } 1589 return true; 1590 } 1591 1592 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1593 // address and instruction set specified by a register as though it were a BX instruction. 1594 // 1595 // TODO: Emulate Jazelle architecture? 1596 // We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1597 bool 1598 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1599 { 1600 #if 0 1601 // ARM pseudo code... 1602 if (ConditionPassed()) 1603 { 1604 EncodingSpecificOperations(); 1605 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1606 BXWritePC(R[m]); 1607 else 1608 if JazelleAcceptsExecution() then 1609 SwitchToJazelleExecution(); 1610 else 1611 SUBARCHITECTURE_DEFINED handler call; 1612 } 1613 #endif 1614 1615 if (ConditionPassed(opcode)) 1616 { 1617 EmulateInstruction::Context context; 1618 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1619 uint32_t Rm; // the register with the target address 1620 switch (encoding) { 1621 case eEncodingT1: 1622 Rm = Bits32(opcode, 19, 16); 1623 if (BadReg(Rm)) 1624 return false; 1625 if (InITBlock() && !LastInITBlock()) 1626 return false; 1627 break; 1628 case eEncodingA1: 1629 Rm = Bits32(opcode, 3, 0); 1630 if (Rm == 15) 1631 return false; 1632 break; 1633 default: 1634 return false; 1635 } 1636 bool success = false; 1637 addr_t target = ReadCoreReg (Rm, &success); 1638 if (!success) 1639 return false; 1640 1641 RegisterInfo dwarf_reg; 1642 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1643 context.SetRegister (dwarf_reg); 1644 if (!BXWritePC(context, target)) 1645 return false; 1646 } 1647 return true; 1648 } 1649 1650 // Set r7 to point to some ip offset. 1651 // SUB (immediate) 1652 bool 1653 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1654 { 1655 #if 0 1656 // ARM pseudo code... 1657 if (ConditionPassed()) 1658 { 1659 EncodingSpecificOperations(); 1660 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1661 if d == 15 then // Can only occur for ARM encoding 1662 ALUWritePC(result); // setflags is always FALSE here 1663 else 1664 R[d] = result; 1665 if setflags then 1666 APSR.N = result<31>; 1667 APSR.Z = IsZeroBit(result); 1668 APSR.C = carry; 1669 APSR.V = overflow; 1670 } 1671 #endif 1672 1673 if (ConditionPassed(opcode)) 1674 { 1675 bool success = false; 1676 const addr_t ip = ReadCoreReg (12, &success); 1677 if (!success) 1678 return false; 1679 uint32_t imm32; 1680 switch (encoding) { 1681 case eEncodingA1: 1682 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1683 break; 1684 default: 1685 return false; 1686 } 1687 addr_t ip_offset = imm32; 1688 addr_t addr = ip - ip_offset; // the adjusted ip value 1689 1690 EmulateInstruction::Context context; 1691 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1692 RegisterInfo dwarf_reg; 1693 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1694 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1695 1696 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1697 return false; 1698 } 1699 return true; 1700 } 1701 1702 // Set ip to point to some stack offset. 1703 // SUB (SP minus immediate) 1704 bool 1705 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1706 { 1707 #if 0 1708 // ARM pseudo code... 1709 if (ConditionPassed()) 1710 { 1711 EncodingSpecificOperations(); 1712 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1713 if d == 15 then // Can only occur for ARM encoding 1714 ALUWritePC(result); // setflags is always FALSE here 1715 else 1716 R[d] = result; 1717 if setflags then 1718 APSR.N = result<31>; 1719 APSR.Z = IsZeroBit(result); 1720 APSR.C = carry; 1721 APSR.V = overflow; 1722 } 1723 #endif 1724 1725 if (ConditionPassed(opcode)) 1726 { 1727 bool success = false; 1728 const addr_t sp = ReadCoreReg (SP_REG, &success); 1729 if (!success) 1730 return false; 1731 uint32_t imm32; 1732 switch (encoding) { 1733 case eEncodingA1: 1734 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1735 break; 1736 default: 1737 return false; 1738 } 1739 addr_t sp_offset = imm32; 1740 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1741 1742 EmulateInstruction::Context context; 1743 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1744 RegisterInfo dwarf_reg; 1745 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1746 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1747 1748 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1749 return false; 1750 } 1751 return true; 1752 } 1753 1754 // This instruction subtracts an immediate value from the SP value, and writes 1755 // the result to the destination register. 1756 // 1757 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1758 bool 1759 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1760 { 1761 #if 0 1762 // ARM pseudo code... 1763 if (ConditionPassed()) 1764 { 1765 EncodingSpecificOperations(); 1766 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1767 if d == 15 then // Can only occur for ARM encoding 1768 ALUWritePC(result); // setflags is always FALSE here 1769 else 1770 R[d] = result; 1771 if setflags then 1772 APSR.N = result<31>; 1773 APSR.Z = IsZeroBit(result); 1774 APSR.C = carry; 1775 APSR.V = overflow; 1776 } 1777 #endif 1778 1779 bool success = false; 1780 if (ConditionPassed(opcode)) 1781 { 1782 const addr_t sp = ReadCoreReg (SP_REG, &success); 1783 if (!success) 1784 return false; 1785 1786 uint32_t Rd; 1787 bool setflags; 1788 uint32_t imm32; 1789 switch (encoding) { 1790 case eEncodingT1: 1791 Rd = 13; 1792 setflags = false; 1793 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1794 break; 1795 case eEncodingT2: 1796 Rd = Bits32(opcode, 11, 8); 1797 setflags = BitIsSet(opcode, 20); 1798 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1799 if (Rd == 15 && setflags) 1800 return EmulateCMPImm(opcode, eEncodingT2); 1801 if (Rd == 15 && !setflags) 1802 return false; 1803 break; 1804 case eEncodingT3: 1805 Rd = Bits32(opcode, 11, 8); 1806 setflags = false; 1807 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1808 if (Rd == 15) 1809 return false; 1810 break; 1811 case eEncodingA1: 1812 Rd = Bits32(opcode, 15, 12); 1813 setflags = BitIsSet(opcode, 20); 1814 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1815 1816 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1817 if (Rd == 15 && setflags) 1818 return EmulateSUBSPcLrEtc (opcode, encoding); 1819 break; 1820 default: 1821 return false; 1822 } 1823 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1824 1825 EmulateInstruction::Context context; 1826 if (Rd == 13) 1827 { 1828 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1829 // value gets passed down to context.SetImmediateSigned. 1830 context.type = EmulateInstruction::eContextAdjustStackPointer; 1831 context.SetImmediateSigned (-imm64); // the stack pointer offset 1832 } 1833 else 1834 { 1835 context.type = EmulateInstruction::eContextImmediate; 1836 context.SetNoArgs (); 1837 } 1838 1839 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1840 return false; 1841 } 1842 return true; 1843 } 1844 1845 // A store operation to the stack that also updates the SP. 1846 bool 1847 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1848 { 1849 #if 0 1850 // ARM pseudo code... 1851 if (ConditionPassed()) 1852 { 1853 EncodingSpecificOperations(); 1854 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1855 address = if index then offset_addr else R[n]; 1856 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1857 if wback then R[n] = offset_addr; 1858 } 1859 #endif 1860 1861 bool conditional = false; 1862 bool success = false; 1863 if (ConditionPassed(opcode, &conditional)) 1864 { 1865 const uint32_t addr_byte_size = GetAddressByteSize(); 1866 const addr_t sp = ReadCoreReg (SP_REG, &success); 1867 if (!success) 1868 return false; 1869 uint32_t Rt; // the source register 1870 uint32_t imm12; 1871 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1872 1873 bool index; 1874 bool add; 1875 bool wback; 1876 switch (encoding) { 1877 case eEncodingA1: 1878 Rt = Bits32(opcode, 15, 12); 1879 imm12 = Bits32(opcode, 11, 0); 1880 Rn = Bits32 (opcode, 19, 16); 1881 1882 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1883 return false; 1884 1885 index = BitIsSet (opcode, 24); 1886 add = BitIsSet (opcode, 23); 1887 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1888 1889 if (wback && ((Rn == 15) || (Rn == Rt))) 1890 return false; 1891 break; 1892 default: 1893 return false; 1894 } 1895 addr_t offset_addr; 1896 if (add) 1897 offset_addr = sp + imm12; 1898 else 1899 offset_addr = sp - imm12; 1900 1901 addr_t addr; 1902 if (index) 1903 addr = offset_addr; 1904 else 1905 addr = sp; 1906 1907 EmulateInstruction::Context context; 1908 if (conditional) 1909 context.type = EmulateInstruction::eContextRegisterStore; 1910 else 1911 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1912 RegisterInfo sp_reg; 1913 RegisterInfo dwarf_reg; 1914 1915 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1916 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 1917 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 1918 if (Rt != 15) 1919 { 1920 uint32_t reg_value = ReadCoreReg(Rt, &success); 1921 if (!success) 1922 return false; 1923 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1924 return false; 1925 } 1926 else 1927 { 1928 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1929 if (!success) 1930 return false; 1931 if (!MemUWrite (context, addr, pc, addr_byte_size)) 1932 return false; 1933 } 1934 1935 1936 if (wback) 1937 { 1938 context.type = EmulateInstruction::eContextAdjustStackPointer; 1939 context.SetImmediateSigned (addr - sp); 1940 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 1941 return false; 1942 } 1943 } 1944 return true; 1945 } 1946 1947 // Vector Push stores multiple extension registers to the stack. 1948 // It also updates SP to point to the start of the stored data. 1949 bool 1950 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 1951 { 1952 #if 0 1953 // ARM pseudo code... 1954 if (ConditionPassed()) 1955 { 1956 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1957 address = SP - imm32; 1958 SP = SP - imm32; 1959 if single_regs then 1960 for r = 0 to regs-1 1961 MemA[address,4] = S[d+r]; address = address+4; 1962 else 1963 for r = 0 to regs-1 1964 // Store as two word-aligned words in the correct order for current endianness. 1965 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1966 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1967 address = address+8; 1968 } 1969 #endif 1970 1971 bool success = false; 1972 bool conditional = false; 1973 if (ConditionPassed(opcode, &conditional)) 1974 { 1975 const uint32_t addr_byte_size = GetAddressByteSize(); 1976 const addr_t sp = ReadCoreReg (SP_REG, &success); 1977 if (!success) 1978 return false; 1979 bool single_regs; 1980 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1981 uint32_t imm32; // stack offset 1982 uint32_t regs; // number of registers 1983 switch (encoding) { 1984 case eEncodingT1: 1985 case eEncodingA1: 1986 single_regs = false; 1987 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1988 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1989 // If UInt(imm8) is odd, see "FSTMX". 1990 regs = Bits32(opcode, 7, 0) / 2; 1991 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1992 if (regs == 0 || regs > 16 || (d + regs) > 32) 1993 return false; 1994 break; 1995 case eEncodingT2: 1996 case eEncodingA2: 1997 single_regs = true; 1998 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1999 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2000 regs = Bits32(opcode, 7, 0); 2001 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2002 if (regs == 0 || regs > 16 || (d + regs) > 32) 2003 return false; 2004 break; 2005 default: 2006 return false; 2007 } 2008 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2009 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2010 addr_t sp_offset = imm32; 2011 addr_t addr = sp - sp_offset; 2012 uint32_t i; 2013 2014 EmulateInstruction::Context context; 2015 if (conditional) 2016 context.type = EmulateInstruction::eContextRegisterStore; 2017 else 2018 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2019 RegisterInfo dwarf_reg; 2020 RegisterInfo sp_reg; 2021 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2022 for (i=0; i<regs; ++i) 2023 { 2024 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2025 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2026 // uint64_t to accommodate 64-bit registers. 2027 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2028 if (!success) 2029 return false; 2030 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2031 return false; 2032 addr += reg_byte_size; 2033 } 2034 2035 context.type = EmulateInstruction::eContextAdjustStackPointer; 2036 context.SetImmediateSigned (-sp_offset); 2037 2038 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2039 return false; 2040 } 2041 return true; 2042 } 2043 2044 // Vector Pop loads multiple extension registers from the stack. 2045 // It also updates SP to point just above the loaded data. 2046 bool 2047 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2048 { 2049 #if 0 2050 // ARM pseudo code... 2051 if (ConditionPassed()) 2052 { 2053 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2054 address = SP; 2055 SP = SP + imm32; 2056 if single_regs then 2057 for r = 0 to regs-1 2058 S[d+r] = MemA[address,4]; address = address+4; 2059 else 2060 for r = 0 to regs-1 2061 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2062 // Combine the word-aligned words in the correct order for current endianness. 2063 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2064 } 2065 #endif 2066 2067 bool success = false; 2068 bool conditional = false; 2069 if (ConditionPassed(opcode, &conditional)) 2070 { 2071 const uint32_t addr_byte_size = GetAddressByteSize(); 2072 const addr_t sp = ReadCoreReg (SP_REG, &success); 2073 if (!success) 2074 return false; 2075 bool single_regs; 2076 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2077 uint32_t imm32; // stack offset 2078 uint32_t regs; // number of registers 2079 switch (encoding) { 2080 case eEncodingT1: 2081 case eEncodingA1: 2082 single_regs = false; 2083 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2084 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2085 // If UInt(imm8) is odd, see "FLDMX". 2086 regs = Bits32(opcode, 7, 0) / 2; 2087 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2088 if (regs == 0 || regs > 16 || (d + regs) > 32) 2089 return false; 2090 break; 2091 case eEncodingT2: 2092 case eEncodingA2: 2093 single_regs = true; 2094 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2095 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2096 regs = Bits32(opcode, 7, 0); 2097 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2098 if (regs == 0 || regs > 16 || (d + regs) > 32) 2099 return false; 2100 break; 2101 default: 2102 return false; 2103 } 2104 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2105 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2106 addr_t sp_offset = imm32; 2107 addr_t addr = sp; 2108 uint32_t i; 2109 uint64_t data; // uint64_t to accomodate 64-bit registers. 2110 2111 EmulateInstruction::Context context; 2112 if (conditional) 2113 context.type = EmulateInstruction::eContextRegisterLoad; 2114 else 2115 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2116 RegisterInfo dwarf_reg; 2117 RegisterInfo sp_reg; 2118 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2119 for (i=0; i<regs; ++i) 2120 { 2121 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2122 context.SetRegisterPlusOffset (sp_reg, addr - sp); 2123 data = MemARead(context, addr, reg_byte_size, 0, &success); 2124 if (!success) 2125 return false; 2126 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2127 return false; 2128 addr += reg_byte_size; 2129 } 2130 2131 context.type = EmulateInstruction::eContextAdjustStackPointer; 2132 context.SetImmediateSigned (sp_offset); 2133 2134 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2135 return false; 2136 } 2137 return true; 2138 } 2139 2140 // SVC (previously SWI) 2141 bool 2142 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2143 { 2144 #if 0 2145 // ARM pseudo code... 2146 if (ConditionPassed()) 2147 { 2148 EncodingSpecificOperations(); 2149 CallSupervisor(); 2150 } 2151 #endif 2152 2153 bool success = false; 2154 2155 if (ConditionPassed(opcode)) 2156 { 2157 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2158 addr_t lr; // next instruction address 2159 if (!success) 2160 return false; 2161 uint32_t imm32; // the immediate constant 2162 uint32_t mode; // ARM or Thumb mode 2163 switch (encoding) { 2164 case eEncodingT1: 2165 lr = (pc + 2) | 1u; // return address 2166 imm32 = Bits32(opcode, 7, 0); 2167 mode = eModeThumb; 2168 break; 2169 case eEncodingA1: 2170 lr = pc + 4; // return address 2171 imm32 = Bits32(opcode, 23, 0); 2172 mode = eModeARM; 2173 break; 2174 default: 2175 return false; 2176 } 2177 2178 EmulateInstruction::Context context; 2179 context.type = EmulateInstruction::eContextSupervisorCall; 2180 context.SetISAAndImmediate (mode, imm32); 2181 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2182 return false; 2183 } 2184 return true; 2185 } 2186 2187 // If Then makes up to four following instructions (the IT block) conditional. 2188 bool 2189 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2190 { 2191 #if 0 2192 // ARM pseudo code... 2193 EncodingSpecificOperations(); 2194 ITSTATE.IT<7:0> = firstcond:mask; 2195 #endif 2196 2197 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2198 return true; 2199 } 2200 2201 bool 2202 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2203 { 2204 // NOP, nothing to do... 2205 return true; 2206 } 2207 2208 // Branch causes a branch to a target address. 2209 bool 2210 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2211 { 2212 #if 0 2213 // ARM pseudo code... 2214 if (ConditionPassed()) 2215 { 2216 EncodingSpecificOperations(); 2217 BranchWritePC(PC + imm32); 2218 } 2219 #endif 2220 2221 bool success = false; 2222 2223 if (ConditionPassed(opcode)) 2224 { 2225 EmulateInstruction::Context context; 2226 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2227 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2228 if (!success) 2229 return false; 2230 addr_t target; // target address 2231 int32_t imm32; // PC-relative offset 2232 switch (encoding) { 2233 case eEncodingT1: 2234 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2235 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2236 target = pc + imm32; 2237 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2238 break; 2239 case eEncodingT2: 2240 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2241 target = pc + imm32; 2242 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2243 break; 2244 case eEncodingT3: 2245 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2246 { 2247 uint32_t S = Bit32(opcode, 26); 2248 uint32_t imm6 = Bits32(opcode, 21, 16); 2249 uint32_t J1 = Bit32(opcode, 13); 2250 uint32_t J2 = Bit32(opcode, 11); 2251 uint32_t imm11 = Bits32(opcode, 10, 0); 2252 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2253 imm32 = llvm::SignExtend32<21>(imm21); 2254 target = pc + imm32; 2255 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2256 break; 2257 } 2258 case eEncodingT4: 2259 { 2260 uint32_t S = Bit32(opcode, 26); 2261 uint32_t imm10 = Bits32(opcode, 25, 16); 2262 uint32_t J1 = Bit32(opcode, 13); 2263 uint32_t J2 = Bit32(opcode, 11); 2264 uint32_t imm11 = Bits32(opcode, 10, 0); 2265 uint32_t I1 = !(J1 ^ S); 2266 uint32_t I2 = !(J2 ^ S); 2267 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2268 imm32 = llvm::SignExtend32<25>(imm25); 2269 target = pc + imm32; 2270 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2271 break; 2272 } 2273 case eEncodingA1: 2274 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2275 target = pc + imm32; 2276 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2277 break; 2278 default: 2279 return false; 2280 } 2281 if (!BranchWritePC(context, target)) 2282 return false; 2283 } 2284 return true; 2285 } 2286 2287 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2288 // zero and conditionally branch forward a constant value. They do not affect the condition flags. 2289 // CBNZ, CBZ 2290 bool 2291 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2292 { 2293 #if 0 2294 // ARM pseudo code... 2295 EncodingSpecificOperations(); 2296 if nonzero ^ IsZero(R[n]) then 2297 BranchWritePC(PC + imm32); 2298 #endif 2299 2300 bool success = false; 2301 2302 // Read the register value from the operand register Rn. 2303 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2304 if (!success) 2305 return false; 2306 2307 EmulateInstruction::Context context; 2308 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2309 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2310 if (!success) 2311 return false; 2312 2313 addr_t target; // target address 2314 uint32_t imm32; // PC-relative offset to branch forward 2315 bool nonzero; 2316 switch (encoding) { 2317 case eEncodingT1: 2318 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2319 nonzero = BitIsSet(opcode, 11); 2320 target = pc + imm32; 2321 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2322 break; 2323 default: 2324 return false; 2325 } 2326 if (nonzero ^ (reg_val == 0)) 2327 if (!BranchWritePC(context, target)) 2328 return false; 2329 2330 return true; 2331 } 2332 2333 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2334 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2335 // The branch length is twice the value of the byte returned from the table. 2336 // 2337 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2338 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2339 // The branch length is twice the value of the halfword returned from the table. 2340 // TBB, TBH 2341 bool 2342 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2343 { 2344 #if 0 2345 // ARM pseudo code... 2346 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2347 if is_tbh then 2348 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2349 else 2350 halfwords = UInt(MemU[R[n]+R[m], 1]); 2351 BranchWritePC(PC + 2*halfwords); 2352 #endif 2353 2354 bool success = false; 2355 2356 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2357 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2358 bool is_tbh; // true if table branch halfword 2359 switch (encoding) { 2360 case eEncodingT1: 2361 Rn = Bits32(opcode, 19, 16); 2362 Rm = Bits32(opcode, 3, 0); 2363 is_tbh = BitIsSet(opcode, 4); 2364 if (Rn == 13 || BadReg(Rm)) 2365 return false; 2366 if (InITBlock() && !LastInITBlock()) 2367 return false; 2368 break; 2369 default: 2370 return false; 2371 } 2372 2373 // Read the address of the table from the operand register Rn. 2374 // The PC can be used, in which case the table immediately follows this instruction. 2375 uint32_t base = ReadCoreReg(Rm, &success); 2376 if (!success) 2377 return false; 2378 2379 // the table index 2380 uint32_t index = ReadCoreReg(Rm, &success); 2381 if (!success) 2382 return false; 2383 2384 // the offsetted table address 2385 addr_t addr = base + (is_tbh ? index*2 : index); 2386 2387 // PC-relative offset to branch forward 2388 EmulateInstruction::Context context; 2389 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2390 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2391 if (!success) 2392 return false; 2393 2394 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2395 if (!success) 2396 return false; 2397 2398 // target address 2399 addr_t target = pc + offset; 2400 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2401 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2402 2403 if (!BranchWritePC(context, target)) 2404 return false; 2405 2406 return true; 2407 } 2408 2409 // This instruction adds an immediate value to a register value, and writes the result to the destination register. 2410 // It can optionally update the condition flags based on the result. 2411 bool 2412 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2413 { 2414 #if 0 2415 if ConditionPassed() then 2416 EncodingSpecificOperations(); 2417 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2418 R[d] = result; 2419 if setflags then 2420 APSR.N = result<31>; 2421 APSR.Z = IsZeroBit(result); 2422 APSR.C = carry; 2423 APSR.V = overflow; 2424 #endif 2425 2426 bool success = false; 2427 2428 if (ConditionPassed(opcode)) 2429 { 2430 uint32_t d; 2431 uint32_t n; 2432 bool setflags; 2433 uint32_t imm32; 2434 uint32_t carry_out; 2435 2436 //EncodingSpecificOperations(); 2437 switch (encoding) 2438 { 2439 case eEncodingT1: 2440 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2441 d = Bits32 (opcode, 2, 0); 2442 n = Bits32 (opcode, 5, 3); 2443 setflags = !InITBlock(); 2444 imm32 = Bits32 (opcode, 8,6); 2445 2446 break; 2447 2448 case eEncodingT2: 2449 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2450 d = Bits32 (opcode, 10, 8); 2451 n = Bits32 (opcode, 10, 8); 2452 setflags = !InITBlock(); 2453 imm32 = Bits32 (opcode, 7, 0); 2454 2455 break; 2456 2457 case eEncodingT3: 2458 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2459 // if Rn == '1101' then SEE ADD (SP plus immediate); 2460 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2461 d = Bits32 (opcode, 11, 8); 2462 n = Bits32 (opcode, 19, 16); 2463 setflags = BitIsSet (opcode, 20); 2464 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2465 2466 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2467 if (BadReg (d) || (n == 15)) 2468 return false; 2469 2470 break; 2471 2472 case eEncodingT4: 2473 { 2474 // if Rn == '1111' then SEE ADR; 2475 // if Rn == '1101' then SEE ADD (SP plus immediate); 2476 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2477 d = Bits32 (opcode, 11, 8); 2478 n = Bits32 (opcode, 19, 16); 2479 setflags = false; 2480 uint32_t i = Bit32 (opcode, 26); 2481 uint32_t imm3 = Bits32 (opcode, 14, 12); 2482 uint32_t imm8 = Bits32 (opcode, 7, 0); 2483 imm32 = (i << 11) | (imm3 << 8) | imm8; 2484 2485 // if BadReg(d) then UNPREDICTABLE; 2486 if (BadReg (d)) 2487 return false; 2488 2489 break; 2490 } 2491 default: 2492 return false; 2493 } 2494 2495 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2496 if (!success) 2497 return false; 2498 2499 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2500 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2501 2502 RegisterInfo reg_n; 2503 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2504 2505 EmulateInstruction::Context context; 2506 context.type = eContextArithmetic; 2507 context.SetRegisterPlusOffset (reg_n, imm32); 2508 2509 //R[d] = result; 2510 //if setflags then 2511 //APSR.N = result<31>; 2512 //APSR.Z = IsZeroBit(result); 2513 //APSR.C = carry; 2514 //APSR.V = overflow; 2515 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2516 return false; 2517 2518 } 2519 return true; 2520 } 2521 2522 // This instruction adds an immediate value to a register value, and writes the result to the destination 2523 // register. It can optionally update the condition flags based on the result. 2524 bool 2525 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2526 { 2527 #if 0 2528 // ARM pseudo code... 2529 if ConditionPassed() then 2530 EncodingSpecificOperations(); 2531 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2532 if d == 15 then 2533 ALUWritePC(result); // setflags is always FALSE here 2534 else 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 #endif 2542 2543 bool success = false; 2544 2545 if (ConditionPassed(opcode)) 2546 { 2547 uint32_t Rd, Rn; 2548 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2549 bool setflags; 2550 switch (encoding) 2551 { 2552 case eEncodingA1: 2553 Rd = Bits32(opcode, 15, 12); 2554 Rn = Bits32(opcode, 19, 16); 2555 setflags = BitIsSet(opcode, 20); 2556 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2557 break; 2558 default: 2559 return false; 2560 } 2561 2562 // Read the first operand. 2563 uint32_t val1 = ReadCoreReg(Rn, &success); 2564 if (!success) 2565 return false; 2566 2567 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2568 2569 EmulateInstruction::Context context; 2570 context.type = eContextArithmetic; 2571 RegisterInfo dwarf_reg; 2572 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2573 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2574 2575 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2576 return false; 2577 } 2578 return true; 2579 } 2580 2581 // This instruction adds a register value and an optionally-shifted register value, and writes the result 2582 // to the destination register. It can optionally update the condition flags based on the result. 2583 bool 2584 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2585 { 2586 #if 0 2587 // ARM pseudo code... 2588 if ConditionPassed() then 2589 EncodingSpecificOperations(); 2590 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2591 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2592 if d == 15 then 2593 ALUWritePC(result); // setflags is always FALSE here 2594 else 2595 R[d] = result; 2596 if setflags then 2597 APSR.N = result<31>; 2598 APSR.Z = IsZeroBit(result); 2599 APSR.C = carry; 2600 APSR.V = overflow; 2601 #endif 2602 2603 bool success = false; 2604 2605 if (ConditionPassed(opcode)) 2606 { 2607 uint32_t Rd, Rn, Rm; 2608 ARM_ShifterType shift_t; 2609 uint32_t shift_n; // the shift applied to the value read from Rm 2610 bool setflags; 2611 switch (encoding) 2612 { 2613 case eEncodingT1: 2614 Rd = Bits32(opcode, 2, 0); 2615 Rn = Bits32(opcode, 5, 3); 2616 Rm = Bits32(opcode, 8, 6); 2617 setflags = !InITBlock(); 2618 shift_t = SRType_LSL; 2619 shift_n = 0; 2620 break; 2621 case eEncodingT2: 2622 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2623 Rm = Bits32(opcode, 6, 3); 2624 setflags = false; 2625 shift_t = SRType_LSL; 2626 shift_n = 0; 2627 if (Rn == 15 && Rm == 15) 2628 return false; 2629 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2630 return false; 2631 break; 2632 case eEncodingA1: 2633 Rd = Bits32(opcode, 15, 12); 2634 Rn = Bits32(opcode, 19, 16); 2635 Rm = Bits32(opcode, 3, 0); 2636 setflags = BitIsSet(opcode, 20); 2637 shift_n = DecodeImmShiftARM(opcode, shift_t); 2638 break; 2639 default: 2640 return false; 2641 } 2642 2643 // Read the first operand. 2644 uint32_t val1 = ReadCoreReg(Rn, &success); 2645 if (!success) 2646 return false; 2647 2648 // Read the second operand. 2649 uint32_t val2 = ReadCoreReg(Rm, &success); 2650 if (!success) 2651 return false; 2652 2653 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2654 if (!success) 2655 return false; 2656 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2657 2658 EmulateInstruction::Context context; 2659 context.type = eContextArithmetic; 2660 RegisterInfo op1_reg; 2661 RegisterInfo op2_reg; 2662 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2663 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2664 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2665 2666 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2667 return false; 2668 } 2669 return true; 2670 } 2671 2672 // Compare Negative (immediate) adds a register value and an immediate value. 2673 // It updates the condition flags based on the result, and discards the result. 2674 bool 2675 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2676 { 2677 #if 0 2678 // ARM pseudo code... 2679 if ConditionPassed() then 2680 EncodingSpecificOperations(); 2681 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2682 APSR.N = result<31>; 2683 APSR.Z = IsZeroBit(result); 2684 APSR.C = carry; 2685 APSR.V = overflow; 2686 #endif 2687 2688 bool success = false; 2689 2690 uint32_t Rn; // the first operand 2691 uint32_t imm32; // the immediate value to be compared with 2692 switch (encoding) { 2693 case eEncodingT1: 2694 Rn = Bits32(opcode, 19, 16); 2695 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2696 if (Rn == 15) 2697 return false; 2698 break; 2699 case eEncodingA1: 2700 Rn = Bits32(opcode, 19, 16); 2701 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2702 break; 2703 default: 2704 return false; 2705 } 2706 // Read the register value from the operand register Rn. 2707 uint32_t reg_val = ReadCoreReg(Rn, &success); 2708 if (!success) 2709 return false; 2710 2711 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2712 2713 EmulateInstruction::Context context; 2714 context.type = EmulateInstruction::eContextImmediate; 2715 context.SetNoArgs (); 2716 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2717 return false; 2718 2719 return true; 2720 } 2721 2722 // Compare Negative (register) adds a register value and an optionally-shifted register value. 2723 // It updates the condition flags based on the result, and discards the result. 2724 bool 2725 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2726 { 2727 #if 0 2728 // ARM pseudo code... 2729 if ConditionPassed() then 2730 EncodingSpecificOperations(); 2731 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2732 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2733 APSR.N = result<31>; 2734 APSR.Z = IsZeroBit(result); 2735 APSR.C = carry; 2736 APSR.V = overflow; 2737 #endif 2738 2739 bool success = false; 2740 2741 uint32_t Rn; // the first operand 2742 uint32_t Rm; // the second operand 2743 ARM_ShifterType shift_t; 2744 uint32_t shift_n; // the shift applied to the value read from Rm 2745 switch (encoding) { 2746 case eEncodingT1: 2747 Rn = Bits32(opcode, 2, 0); 2748 Rm = Bits32(opcode, 5, 3); 2749 shift_t = SRType_LSL; 2750 shift_n = 0; 2751 break; 2752 case eEncodingT2: 2753 Rn = Bits32(opcode, 19, 16); 2754 Rm = Bits32(opcode, 3, 0); 2755 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2756 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2757 if (Rn == 15 || BadReg(Rm)) 2758 return false; 2759 break; 2760 case eEncodingA1: 2761 Rn = Bits32(opcode, 19, 16); 2762 Rm = Bits32(opcode, 3, 0); 2763 shift_n = DecodeImmShiftARM(opcode, shift_t); 2764 break; 2765 default: 2766 return false; 2767 } 2768 // Read the register value from register Rn. 2769 uint32_t val1 = ReadCoreReg(Rn, &success); 2770 if (!success) 2771 return false; 2772 2773 // Read the register value from register Rm. 2774 uint32_t val2 = ReadCoreReg(Rm, &success); 2775 if (!success) 2776 return false; 2777 2778 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2779 if (!success) 2780 return false; 2781 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2782 2783 EmulateInstruction::Context context; 2784 context.type = EmulateInstruction::eContextImmediate; 2785 context.SetNoArgs(); 2786 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2787 return false; 2788 2789 return true; 2790 } 2791 2792 // Compare (immediate) subtracts an immediate value from a register value. 2793 // It updates the condition flags based on the result, and discards the result. 2794 bool 2795 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2796 { 2797 #if 0 2798 // ARM pseudo code... 2799 if ConditionPassed() then 2800 EncodingSpecificOperations(); 2801 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2802 APSR.N = result<31>; 2803 APSR.Z = IsZeroBit(result); 2804 APSR.C = carry; 2805 APSR.V = overflow; 2806 #endif 2807 2808 bool success = false; 2809 2810 uint32_t Rn; // the first operand 2811 uint32_t imm32; // the immediate value to be compared with 2812 switch (encoding) { 2813 case eEncodingT1: 2814 Rn = Bits32(opcode, 10, 8); 2815 imm32 = Bits32(opcode, 7, 0); 2816 break; 2817 case eEncodingT2: 2818 Rn = Bits32(opcode, 19, 16); 2819 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2820 if (Rn == 15) 2821 return false; 2822 break; 2823 case eEncodingA1: 2824 Rn = Bits32(opcode, 19, 16); 2825 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2826 break; 2827 default: 2828 return false; 2829 } 2830 // Read the register value from the operand register Rn. 2831 uint32_t reg_val = ReadCoreReg(Rn, &success); 2832 if (!success) 2833 return false; 2834 2835 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2836 2837 EmulateInstruction::Context context; 2838 context.type = EmulateInstruction::eContextImmediate; 2839 context.SetNoArgs (); 2840 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2841 return false; 2842 2843 return true; 2844 } 2845 2846 // Compare (register) subtracts an optionally-shifted register value from a register value. 2847 // It updates the condition flags based on the result, and discards the result. 2848 bool 2849 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2850 { 2851 #if 0 2852 // ARM pseudo code... 2853 if ConditionPassed() then 2854 EncodingSpecificOperations(); 2855 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2856 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2857 APSR.N = result<31>; 2858 APSR.Z = IsZeroBit(result); 2859 APSR.C = carry; 2860 APSR.V = overflow; 2861 #endif 2862 2863 bool success = false; 2864 2865 uint32_t Rn; // the first operand 2866 uint32_t Rm; // the second operand 2867 ARM_ShifterType shift_t; 2868 uint32_t shift_n; // the shift applied to the value read from Rm 2869 switch (encoding) { 2870 case eEncodingT1: 2871 Rn = Bits32(opcode, 2, 0); 2872 Rm = Bits32(opcode, 5, 3); 2873 shift_t = SRType_LSL; 2874 shift_n = 0; 2875 break; 2876 case eEncodingT2: 2877 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2878 Rm = Bits32(opcode, 6, 3); 2879 shift_t = SRType_LSL; 2880 shift_n = 0; 2881 if (Rn < 8 && Rm < 8) 2882 return false; 2883 if (Rn == 15 || Rm == 15) 2884 return false; 2885 break; 2886 case eEncodingA1: 2887 Rn = Bits32(opcode, 19, 16); 2888 Rm = Bits32(opcode, 3, 0); 2889 shift_n = DecodeImmShiftARM(opcode, shift_t); 2890 break; 2891 default: 2892 return false; 2893 } 2894 // Read the register value from register Rn. 2895 uint32_t val1 = ReadCoreReg(Rn, &success); 2896 if (!success) 2897 return false; 2898 2899 // Read the register value from register Rm. 2900 uint32_t val2 = ReadCoreReg(Rm, &success); 2901 if (!success) 2902 return false; 2903 2904 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2905 if (!success) 2906 return false; 2907 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 2908 2909 EmulateInstruction::Context context; 2910 context.type = EmulateInstruction::eContextImmediate; 2911 context.SetNoArgs(); 2912 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2913 return false; 2914 2915 return true; 2916 } 2917 2918 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2919 // shifting in copies of its sign bit, and writes the result to the destination register. It can 2920 // optionally update the condition flags based on the result. 2921 bool 2922 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 2923 { 2924 #if 0 2925 // ARM pseudo code... 2926 if ConditionPassed() then 2927 EncodingSpecificOperations(); 2928 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2929 if d == 15 then // Can only occur for ARM encoding 2930 ALUWritePC(result); // setflags is always FALSE here 2931 else 2932 R[d] = result; 2933 if setflags then 2934 APSR.N = result<31>; 2935 APSR.Z = IsZeroBit(result); 2936 APSR.C = carry; 2937 // APSR.V unchanged 2938 #endif 2939 2940 return EmulateShiftImm (opcode, encoding, SRType_ASR); 2941 } 2942 2943 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 2944 // shifting in copies of its sign bit, and writes the result to the destination register. 2945 // The variable number of bits is read from the bottom byte of a register. It can optionally update 2946 // the condition flags based on the result. 2947 bool 2948 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 2949 { 2950 #if 0 2951 // ARM pseudo code... 2952 if ConditionPassed() then 2953 EncodingSpecificOperations(); 2954 shift_n = UInt(R[m]<7:0>); 2955 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2956 R[d] = result; 2957 if setflags then 2958 APSR.N = result<31>; 2959 APSR.Z = IsZeroBit(result); 2960 APSR.C = carry; 2961 // APSR.V unchanged 2962 #endif 2963 2964 return EmulateShiftReg (opcode, encoding, SRType_ASR); 2965 } 2966 2967 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 2968 // shifting in zeros, and writes the result to the destination register. It can optionally 2969 // update the condition flags based on the result. 2970 bool 2971 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 2972 { 2973 #if 0 2974 // ARM pseudo code... 2975 if ConditionPassed() then 2976 EncodingSpecificOperations(); 2977 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 2978 if d == 15 then // Can only occur for ARM encoding 2979 ALUWritePC(result); // setflags is always FALSE here 2980 else 2981 R[d] = result; 2982 if setflags then 2983 APSR.N = result<31>; 2984 APSR.Z = IsZeroBit(result); 2985 APSR.C = carry; 2986 // APSR.V unchanged 2987 #endif 2988 2989 return EmulateShiftImm (opcode, encoding, SRType_LSL); 2990 } 2991 2992 // Logical Shift Left (register) shifts a register value left by a variable number of bits, 2993 // shifting in zeros, and writes the result to the destination register. The variable number 2994 // of bits is read from the bottom byte of a register. It can optionally update the condition 2995 // flags based on the result. 2996 bool 2997 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 2998 { 2999 #if 0 3000 // ARM pseudo code... 3001 if ConditionPassed() then 3002 EncodingSpecificOperations(); 3003 shift_n = UInt(R[m]<7:0>); 3004 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3005 R[d] = result; 3006 if setflags then 3007 APSR.N = result<31>; 3008 APSR.Z = IsZeroBit(result); 3009 APSR.C = carry; 3010 // APSR.V unchanged 3011 #endif 3012 3013 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3014 } 3015 3016 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3017 // shifting in zeros, and writes the result to the destination register. It can optionally 3018 // update the condition flags based on the result. 3019 bool 3020 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3021 { 3022 #if 0 3023 // ARM pseudo code... 3024 if ConditionPassed() then 3025 EncodingSpecificOperations(); 3026 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3027 if d == 15 then // Can only occur for ARM encoding 3028 ALUWritePC(result); // setflags is always FALSE here 3029 else 3030 R[d] = result; 3031 if setflags then 3032 APSR.N = result<31>; 3033 APSR.Z = IsZeroBit(result); 3034 APSR.C = carry; 3035 // APSR.V unchanged 3036 #endif 3037 3038 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3039 } 3040 3041 // Logical Shift Right (register) shifts a register value right by a variable number of bits, 3042 // shifting in zeros, and writes the result to the destination register. The variable number 3043 // of bits is read from the bottom byte of a register. It can optionally update the condition 3044 // flags based on the result. 3045 bool 3046 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3047 { 3048 #if 0 3049 // ARM pseudo code... 3050 if ConditionPassed() then 3051 EncodingSpecificOperations(); 3052 shift_n = UInt(R[m]<7:0>); 3053 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3054 R[d] = result; 3055 if setflags then 3056 APSR.N = result<31>; 3057 APSR.Z = IsZeroBit(result); 3058 APSR.C = carry; 3059 // APSR.V unchanged 3060 #endif 3061 3062 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3063 } 3064 3065 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3066 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3067 // It can optionally update the condition flags based on the result. 3068 bool 3069 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3070 { 3071 #if 0 3072 // ARM pseudo code... 3073 if ConditionPassed() then 3074 EncodingSpecificOperations(); 3075 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3076 if d == 15 then // Can only occur for ARM encoding 3077 ALUWritePC(result); // setflags is always FALSE here 3078 else 3079 R[d] = result; 3080 if setflags then 3081 APSR.N = result<31>; 3082 APSR.Z = IsZeroBit(result); 3083 APSR.C = carry; 3084 // APSR.V unchanged 3085 #endif 3086 3087 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3088 } 3089 3090 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3091 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3092 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3093 // flags based on the result. 3094 bool 3095 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3096 { 3097 #if 0 3098 // ARM pseudo code... 3099 if ConditionPassed() then 3100 EncodingSpecificOperations(); 3101 shift_n = UInt(R[m]<7:0>); 3102 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3103 R[d] = result; 3104 if setflags then 3105 APSR.N = result<31>; 3106 APSR.Z = IsZeroBit(result); 3107 APSR.C = carry; 3108 // APSR.V unchanged 3109 #endif 3110 3111 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3112 } 3113 3114 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3115 // with the carry flag shifted into bit [31]. 3116 // 3117 // RRX can optionally update the condition flags based on the result. 3118 // In that case, bit [0] is shifted into the carry flag. 3119 bool 3120 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3121 { 3122 #if 0 3123 // ARM pseudo code... 3124 if ConditionPassed() then 3125 EncodingSpecificOperations(); 3126 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3127 if d == 15 then // Can only occur for ARM encoding 3128 ALUWritePC(result); // setflags is always FALSE here 3129 else 3130 R[d] = result; 3131 if setflags then 3132 APSR.N = result<31>; 3133 APSR.Z = IsZeroBit(result); 3134 APSR.C = carry; 3135 // APSR.V unchanged 3136 #endif 3137 3138 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3139 } 3140 3141 bool 3142 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3143 { 3144 // assert(shift_type == SRType_ASR 3145 // || shift_type == SRType_LSL 3146 // || shift_type == SRType_LSR 3147 // || shift_type == SRType_ROR 3148 // || shift_type == SRType_RRX); 3149 3150 bool success = false; 3151 3152 if (ConditionPassed(opcode)) 3153 { 3154 uint32_t Rd; // the destination register 3155 uint32_t Rm; // the first operand register 3156 uint32_t imm5; // encoding for the shift amount 3157 uint32_t carry; // the carry bit after the shift operation 3158 bool setflags; 3159 3160 // Special case handling! 3161 // A8.6.139 ROR (immediate) -- Encoding T1 3162 ARMEncoding use_encoding = encoding; 3163 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3164 { 3165 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3166 // have the same decoding of bit fields as the other Thumb2 shift operations. 3167 use_encoding = eEncodingT2; 3168 } 3169 3170 switch (use_encoding) { 3171 case eEncodingT1: 3172 // Due to the above special case handling! 3173 if (shift_type == SRType_ROR) 3174 return false; 3175 3176 Rd = Bits32(opcode, 2, 0); 3177 Rm = Bits32(opcode, 5, 3); 3178 setflags = !InITBlock(); 3179 imm5 = Bits32(opcode, 10, 6); 3180 break; 3181 case eEncodingT2: 3182 // A8.6.141 RRX 3183 // There's no imm form of RRX instructions. 3184 if (shift_type == SRType_RRX) 3185 return false; 3186 3187 Rd = Bits32(opcode, 11, 8); 3188 Rm = Bits32(opcode, 3, 0); 3189 setflags = BitIsSet(opcode, 20); 3190 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3191 if (BadReg(Rd) || BadReg(Rm)) 3192 return false; 3193 break; 3194 case eEncodingA1: 3195 Rd = Bits32(opcode, 15, 12); 3196 Rm = Bits32(opcode, 3, 0); 3197 setflags = BitIsSet(opcode, 20); 3198 imm5 = Bits32(opcode, 11, 7); 3199 break; 3200 default: 3201 return false; 3202 } 3203 3204 // A8.6.139 ROR (immediate) 3205 if (shift_type == SRType_ROR && imm5 == 0) 3206 shift_type = SRType_RRX; 3207 3208 // Get the first operand. 3209 uint32_t value = ReadCoreReg (Rm, &success); 3210 if (!success) 3211 return false; 3212 3213 // Decode the shift amount if not RRX. 3214 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3215 3216 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3217 if (!success) 3218 return false; 3219 3220 // The context specifies that an immediate is to be moved into Rd. 3221 EmulateInstruction::Context context; 3222 context.type = EmulateInstruction::eContextImmediate; 3223 context.SetNoArgs (); 3224 3225 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3226 return false; 3227 } 3228 return true; 3229 } 3230 3231 bool 3232 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3233 { 3234 // assert(shift_type == SRType_ASR 3235 // || shift_type == SRType_LSL 3236 // || shift_type == SRType_LSR 3237 // || shift_type == SRType_ROR); 3238 3239 bool success = false; 3240 3241 if (ConditionPassed(opcode)) 3242 { 3243 uint32_t Rd; // the destination register 3244 uint32_t Rn; // the first operand register 3245 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3246 uint32_t carry; // the carry bit after the shift operation 3247 bool setflags; 3248 switch (encoding) { 3249 case eEncodingT1: 3250 Rd = Bits32(opcode, 2, 0); 3251 Rn = Rd; 3252 Rm = Bits32(opcode, 5, 3); 3253 setflags = !InITBlock(); 3254 break; 3255 case eEncodingT2: 3256 Rd = Bits32(opcode, 11, 8); 3257 Rn = Bits32(opcode, 19, 16); 3258 Rm = Bits32(opcode, 3, 0); 3259 setflags = BitIsSet(opcode, 20); 3260 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3261 return false; 3262 break; 3263 case eEncodingA1: 3264 Rd = Bits32(opcode, 15, 12); 3265 Rn = Bits32(opcode, 3, 0); 3266 Rm = Bits32(opcode, 11, 8); 3267 setflags = BitIsSet(opcode, 20); 3268 if (Rd == 15 || Rn == 15 || Rm == 15) 3269 return false; 3270 break; 3271 default: 3272 return false; 3273 } 3274 3275 // Get the first operand. 3276 uint32_t value = ReadCoreReg (Rn, &success); 3277 if (!success) 3278 return false; 3279 // Get the Rm register content. 3280 uint32_t val = ReadCoreReg (Rm, &success); 3281 if (!success) 3282 return false; 3283 3284 // Get the shift amount. 3285 uint32_t amt = Bits32(val, 7, 0); 3286 3287 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3288 if (!success) 3289 return false; 3290 3291 // The context specifies that an immediate is to be moved into Rd. 3292 EmulateInstruction::Context context; 3293 context.type = EmulateInstruction::eContextImmediate; 3294 context.SetNoArgs (); 3295 3296 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3297 return false; 3298 } 3299 return true; 3300 } 3301 3302 // LDM loads multiple registers from consecutive memory locations, using an 3303 // address from a base register. Optionally the address just above the highest of those locations 3304 // can be written back to the base register. 3305 bool 3306 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3307 { 3308 #if 0 3309 // ARM pseudo code... 3310 if ConditionPassed() 3311 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3312 address = R[n]; 3313 3314 for i = 0 to 14 3315 if registers<i> == '1' then 3316 R[i] = MemA[address, 4]; address = address + 4; 3317 if registers<15> == '1' then 3318 LoadWritePC (MemA[address, 4]); 3319 3320 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3321 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3322 3323 #endif 3324 3325 bool success = false; 3326 bool conditional = false; 3327 if (ConditionPassed(opcode, &conditional)) 3328 { 3329 uint32_t n; 3330 uint32_t registers = 0; 3331 bool wback; 3332 const uint32_t addr_byte_size = GetAddressByteSize(); 3333 switch (encoding) 3334 { 3335 case eEncodingT1: 3336 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3337 n = Bits32 (opcode, 10, 8); 3338 registers = Bits32 (opcode, 7, 0); 3339 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3340 wback = BitIsClear (registers, n); 3341 // if BitCount(registers) < 1 then UNPREDICTABLE; 3342 if (BitCount(registers) < 1) 3343 return false; 3344 break; 3345 case eEncodingT2: 3346 // if W == '1' && Rn == '1101' then SEE POP; 3347 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3348 n = Bits32 (opcode, 19, 16); 3349 registers = Bits32 (opcode, 15, 0); 3350 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3351 wback = BitIsSet (opcode, 21); 3352 3353 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3354 if ((n == 15) 3355 || (BitCount (registers) < 2) 3356 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3357 return false; 3358 3359 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3360 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3361 return false; 3362 3363 // if wback && registers<n> == '1' then UNPREDICTABLE; 3364 if (wback 3365 && BitIsSet (registers, n)) 3366 return false; 3367 break; 3368 3369 case eEncodingA1: 3370 n = Bits32 (opcode, 19, 16); 3371 registers = Bits32 (opcode, 15, 0); 3372 wback = BitIsSet (opcode, 21); 3373 if ((n == 15) 3374 || (BitCount (registers) < 1)) 3375 return false; 3376 break; 3377 default: 3378 return false; 3379 } 3380 3381 int32_t offset = 0; 3382 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3383 if (!success) 3384 return false; 3385 3386 EmulateInstruction::Context context; 3387 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3388 RegisterInfo dwarf_reg; 3389 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3390 context.SetRegisterPlusOffset (dwarf_reg, offset); 3391 3392 for (int i = 0; i < 14; ++i) 3393 { 3394 if (BitIsSet (registers, i)) 3395 { 3396 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3397 context.SetRegisterPlusOffset (dwarf_reg, offset); 3398 if (wback && (n == 13)) // Pop Instruction 3399 { 3400 if (conditional) 3401 context.type = EmulateInstruction::eContextRegisterLoad; 3402 else 3403 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3404 } 3405 3406 // R[i] = MemA [address, 4]; address = address + 4; 3407 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3408 if (!success) 3409 return false; 3410 3411 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3412 return false; 3413 3414 offset += addr_byte_size; 3415 } 3416 } 3417 3418 if (BitIsSet (registers, 15)) 3419 { 3420 //LoadWritePC (MemA [address, 4]); 3421 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3422 context.SetRegisterPlusOffset (dwarf_reg, offset); 3423 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3424 if (!success) 3425 return false; 3426 // In ARMv5T and above, this is an interworking branch. 3427 if (!LoadWritePC(context, data)) 3428 return false; 3429 } 3430 3431 if (wback && BitIsClear (registers, n)) 3432 { 3433 // R[n] = R[n] + 4 * BitCount (registers) 3434 int32_t offset = addr_byte_size * BitCount (registers); 3435 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3436 context.SetRegisterPlusOffset (dwarf_reg, offset); 3437 3438 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3439 return false; 3440 } 3441 if (wback && BitIsSet (registers, n)) 3442 // R[n] bits(32) UNKNOWN; 3443 return WriteBits32Unknown (n); 3444 } 3445 return true; 3446 } 3447 3448 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3449 // The consecutive memory locations end at this address and the address just below the lowest of those locations 3450 // can optionally be written back to the base register. 3451 bool 3452 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3453 { 3454 #if 0 3455 // ARM pseudo code... 3456 if ConditionPassed() then 3457 EncodingSpecificOperations(); 3458 address = R[n] - 4*BitCount(registers) + 4; 3459 3460 for i = 0 to 14 3461 if registers<i> == '1' then 3462 R[i] = MemA[address,4]; address = address + 4; 3463 3464 if registers<15> == '1' then 3465 LoadWritePC(MemA[address,4]); 3466 3467 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3468 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3469 #endif 3470 3471 bool success = false; 3472 3473 if (ConditionPassed(opcode)) 3474 { 3475 uint32_t n; 3476 uint32_t registers = 0; 3477 bool wback; 3478 const uint32_t addr_byte_size = GetAddressByteSize(); 3479 3480 // EncodingSpecificOperations(); 3481 switch (encoding) 3482 { 3483 case eEncodingA1: 3484 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3485 n = Bits32 (opcode, 19, 16); 3486 registers = Bits32 (opcode, 15, 0); 3487 wback = BitIsSet (opcode, 21); 3488 3489 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3490 if ((n == 15) || (BitCount (registers) < 1)) 3491 return false; 3492 3493 break; 3494 3495 default: 3496 return false; 3497 } 3498 // address = R[n] - 4*BitCount(registers) + 4; 3499 3500 int32_t offset = 0; 3501 addr_t Rn = ReadCoreReg (n, &success); 3502 3503 if (!success) 3504 return false; 3505 3506 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3507 3508 EmulateInstruction::Context context; 3509 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3510 RegisterInfo dwarf_reg; 3511 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3512 context.SetRegisterPlusOffset (dwarf_reg, offset); 3513 3514 // for i = 0 to 14 3515 for (int i = 0; i < 14; ++i) 3516 { 3517 // if registers<i> == '1' then 3518 if (BitIsSet (registers, i)) 3519 { 3520 // R[i] = MemA[address,4]; address = address + 4; 3521 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3522 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3523 if (!success) 3524 return false; 3525 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3526 return false; 3527 offset += addr_byte_size; 3528 } 3529 } 3530 3531 // if registers<15> == '1' then 3532 // LoadWritePC(MemA[address,4]); 3533 if (BitIsSet (registers, 15)) 3534 { 3535 context.SetRegisterPlusOffset (dwarf_reg, offset); 3536 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3537 if (!success) 3538 return false; 3539 // In ARMv5T and above, this is an interworking branch. 3540 if (!LoadWritePC(context, data)) 3541 return false; 3542 } 3543 3544 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3545 if (wback && BitIsClear (registers, n)) 3546 { 3547 if (!success) 3548 return false; 3549 3550 offset = (addr_byte_size * BitCount (registers)) * -1; 3551 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3552 context.SetImmediateSigned (offset); 3553 addr_t addr = Rn + offset; 3554 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3555 return false; 3556 } 3557 3558 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3559 if (wback && BitIsSet (registers, n)) 3560 return WriteBits32Unknown (n); 3561 } 3562 return true; 3563 } 3564 3565 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3566 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3567 // be optionally written back to the base register. 3568 bool 3569 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3570 { 3571 #if 0 3572 // ARM pseudo code... 3573 if ConditionPassed() then 3574 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3575 address = R[n] - 4*BitCount(registers); 3576 3577 for i = 0 to 14 3578 if registers<i> == '1' then 3579 R[i] = MemA[address,4]; address = address + 4; 3580 if registers<15> == '1' then 3581 LoadWritePC(MemA[address,4]); 3582 3583 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3584 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3585 #endif 3586 3587 bool success = false; 3588 3589 if (ConditionPassed(opcode)) 3590 { 3591 uint32_t n; 3592 uint32_t registers = 0; 3593 bool wback; 3594 const uint32_t addr_byte_size = GetAddressByteSize(); 3595 switch (encoding) 3596 { 3597 case eEncodingT1: 3598 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3599 n = Bits32 (opcode, 19, 16); 3600 registers = Bits32 (opcode, 15, 0); 3601 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3602 wback = BitIsSet (opcode, 21); 3603 3604 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3605 if ((n == 15) 3606 || (BitCount (registers) < 2) 3607 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3608 return false; 3609 3610 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3611 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3612 return false; 3613 3614 // if wback && registers<n> == '1' then UNPREDICTABLE; 3615 if (wback && BitIsSet (registers, n)) 3616 return false; 3617 3618 break; 3619 3620 case eEncodingA1: 3621 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3622 n = Bits32 (opcode, 19, 16); 3623 registers = Bits32 (opcode, 15, 0); 3624 wback = BitIsSet (opcode, 21); 3625 3626 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3627 if ((n == 15) || (BitCount (registers) < 1)) 3628 return false; 3629 3630 break; 3631 3632 default: 3633 return false; 3634 } 3635 3636 // address = R[n] - 4*BitCount(registers); 3637 3638 int32_t offset = 0; 3639 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3640 3641 if (!success) 3642 return false; 3643 3644 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3645 EmulateInstruction::Context context; 3646 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3647 RegisterInfo dwarf_reg; 3648 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3649 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3650 3651 for (int i = 0; i < 14; ++i) 3652 { 3653 if (BitIsSet (registers, i)) 3654 { 3655 // R[i] = MemA[address,4]; address = address + 4; 3656 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3657 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3658 if (!success) 3659 return false; 3660 3661 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3662 return false; 3663 3664 offset += addr_byte_size; 3665 } 3666 } 3667 3668 // if registers<15> == '1' then 3669 // LoadWritePC(MemA[address,4]); 3670 if (BitIsSet (registers, 15)) 3671 { 3672 context.SetRegisterPlusOffset (dwarf_reg, offset); 3673 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3674 if (!success) 3675 return false; 3676 // In ARMv5T and above, this is an interworking branch. 3677 if (!LoadWritePC(context, data)) 3678 return false; 3679 } 3680 3681 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3682 if (wback && BitIsClear (registers, n)) 3683 { 3684 if (!success) 3685 return false; 3686 3687 offset = (addr_byte_size * BitCount (registers)) * -1; 3688 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3689 context.SetImmediateSigned (offset); 3690 addr_t addr = Rn + offset; 3691 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3692 return false; 3693 } 3694 3695 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3696 if (wback && BitIsSet (registers, n)) 3697 return WriteBits32Unknown (n); 3698 } 3699 return true; 3700 } 3701 3702 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3703 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3704 // optinoally be written back to the base register. 3705 bool 3706 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3707 { 3708 #if 0 3709 if ConditionPassed() then 3710 EncodingSpecificOperations(); 3711 address = R[n] + 4; 3712 3713 for i = 0 to 14 3714 if registers<i> == '1' then 3715 R[i] = MemA[address,4]; address = address + 4; 3716 if registers<15> == '1' then 3717 LoadWritePC(MemA[address,4]); 3718 3719 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3720 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3721 #endif 3722 3723 bool success = false; 3724 3725 if (ConditionPassed(opcode)) 3726 { 3727 uint32_t n; 3728 uint32_t registers = 0; 3729 bool wback; 3730 const uint32_t addr_byte_size = GetAddressByteSize(); 3731 switch (encoding) 3732 { 3733 case eEncodingA1: 3734 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3735 n = Bits32 (opcode, 19, 16); 3736 registers = Bits32 (opcode, 15, 0); 3737 wback = BitIsSet (opcode, 21); 3738 3739 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3740 if ((n == 15) || (BitCount (registers) < 1)) 3741 return false; 3742 3743 break; 3744 default: 3745 return false; 3746 } 3747 // address = R[n] + 4; 3748 3749 int32_t offset = 0; 3750 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3751 3752 if (!success) 3753 return false; 3754 3755 addr_t address = Rn + addr_byte_size; 3756 3757 EmulateInstruction::Context context; 3758 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3759 RegisterInfo dwarf_reg; 3760 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3761 context.SetRegisterPlusOffset (dwarf_reg, offset); 3762 3763 for (int i = 0; i < 14; ++i) 3764 { 3765 if (BitIsSet (registers, i)) 3766 { 3767 // R[i] = MemA[address,4]; address = address + 4; 3768 3769 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3770 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3771 if (!success) 3772 return false; 3773 3774 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3775 return false; 3776 3777 offset += addr_byte_size; 3778 } 3779 } 3780 3781 // if registers<15> == '1' then 3782 // LoadWritePC(MemA[address,4]); 3783 if (BitIsSet (registers, 15)) 3784 { 3785 context.SetRegisterPlusOffset (dwarf_reg, offset); 3786 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3787 if (!success) 3788 return false; 3789 // In ARMv5T and above, this is an interworking branch. 3790 if (!LoadWritePC(context, data)) 3791 return false; 3792 } 3793 3794 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3795 if (wback && BitIsClear (registers, n)) 3796 { 3797 if (!success) 3798 return false; 3799 3800 offset = addr_byte_size * BitCount (registers); 3801 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3802 context.SetImmediateSigned (offset); 3803 addr_t addr = Rn + offset; 3804 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3805 return false; 3806 } 3807 3808 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3809 if (wback && BitIsSet (registers, n)) 3810 return WriteBits32Unknown (n); 3811 } 3812 return true; 3813 } 3814 3815 // Load Register (immediate) calculates an address from a base register value and 3816 // an immediate offset, loads a word from memory, and writes to a register. 3817 // LDR (immediate, Thumb) 3818 bool 3819 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3820 { 3821 #if 0 3822 // ARM pseudo code... 3823 if (ConditionPassed()) 3824 { 3825 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3826 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3827 address = if index then offset_addr else R[n]; 3828 data = MemU[address,4]; 3829 if wback then R[n] = offset_addr; 3830 if t == 15 then 3831 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3832 elsif UnalignedSupport() || address<1:0> = '00' then 3833 R[t] = data; 3834 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3835 } 3836 #endif 3837 3838 bool success = false; 3839 3840 if (ConditionPassed(opcode)) 3841 { 3842 uint32_t Rt; // the destination register 3843 uint32_t Rn; // the base register 3844 uint32_t imm32; // the immediate offset used to form the address 3845 addr_t offset_addr; // the offset address 3846 addr_t address; // the calculated address 3847 uint32_t data; // the literal data value from memory load 3848 bool add, index, wback; 3849 switch (encoding) { 3850 case eEncodingT1: 3851 Rt = Bits32(opcode, 2, 0); 3852 Rn = Bits32(opcode, 5, 3); 3853 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3854 // index = TRUE; add = TRUE; wback = FALSE 3855 add = true; 3856 index = true; 3857 wback = false; 3858 3859 break; 3860 3861 case eEncodingT2: 3862 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3863 Rt = Bits32 (opcode, 10, 8); 3864 Rn = 13; 3865 imm32 = Bits32 (opcode, 7, 0) << 2; 3866 3867 // index = TRUE; add = TRUE; wback = FALSE; 3868 index = true; 3869 add = true; 3870 wback = false; 3871 3872 break; 3873 3874 case eEncodingT3: 3875 // if Rn == '1111' then SEE LDR (literal); 3876 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3877 Rt = Bits32 (opcode, 15, 12); 3878 Rn = Bits32 (opcode, 19, 16); 3879 imm32 = Bits32 (opcode, 11, 0); 3880 3881 // index = TRUE; add = TRUE; wback = FALSE; 3882 index = true; 3883 add = true; 3884 wback = false; 3885 3886 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3887 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3888 return false; 3889 3890 break; 3891 3892 case eEncodingT4: 3893 // if Rn == '1111' then SEE LDR (literal); 3894 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3895 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3896 // if P == '0' && W == '0' then UNDEFINED; 3897 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3898 return false; 3899 3900 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3901 Rt = Bits32 (opcode, 15, 12); 3902 Rn = Bits32 (opcode, 19, 16); 3903 imm32 = Bits32 (opcode, 7, 0); 3904 3905 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3906 index = BitIsSet (opcode, 10); 3907 add = BitIsSet (opcode, 9); 3908 wback = BitIsSet (opcode, 8); 3909 3910 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3911 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3912 return false; 3913 3914 break; 3915 3916 default: 3917 return false; 3918 } 3919 uint32_t base = ReadCoreReg (Rn, &success); 3920 if (!success) 3921 return false; 3922 if (add) 3923 offset_addr = base + imm32; 3924 else 3925 offset_addr = base - imm32; 3926 3927 address = (index ? offset_addr : base); 3928 3929 RegisterInfo base_reg; 3930 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 3931 if (wback) 3932 { 3933 EmulateInstruction::Context ctx; 3934 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 3935 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3936 3937 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3938 return false; 3939 } 3940 3941 // Prepare to write to the Rt register. 3942 EmulateInstruction::Context context; 3943 context.type = EmulateInstruction::eContextRegisterLoad; 3944 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3945 3946 // Read memory from the address. 3947 data = MemURead(context, address, 4, 0, &success); 3948 if (!success) 3949 return false; 3950 3951 if (Rt == 15) 3952 { 3953 if (Bits32(address, 1, 0) == 0) 3954 { 3955 if (!LoadWritePC(context, data)) 3956 return false; 3957 } 3958 else 3959 return false; 3960 } 3961 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3962 { 3963 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3964 return false; 3965 } 3966 else 3967 WriteBits32Unknown (Rt); 3968 } 3969 return true; 3970 } 3971 3972 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 3973 // from a base register. The consecutive memory locations start at this address, and teh address just above the last 3974 // of those locations can optionally be written back to the base register. 3975 bool 3976 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 3977 { 3978 #if 0 3979 if ConditionPassed() then 3980 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3981 address = R[n]; 3982 3983 for i = 0 to 14 3984 if registers<i> == '1' then 3985 if i == n && wback && i != LowestSetBit(registers) then 3986 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3987 else 3988 MemA[address,4] = R[i]; 3989 address = address + 4; 3990 3991 if registers<15> == '1' then // Only possible for encoding A1 3992 MemA[address,4] = PCStoreValue(); 3993 if wback then R[n] = R[n] + 4*BitCount(registers); 3994 #endif 3995 3996 bool success = false; 3997 3998 if (ConditionPassed(opcode)) 3999 { 4000 uint32_t n; 4001 uint32_t registers = 0; 4002 bool wback; 4003 const uint32_t addr_byte_size = GetAddressByteSize(); 4004 4005 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4006 switch (encoding) 4007 { 4008 case eEncodingT1: 4009 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4010 n = Bits32 (opcode, 10, 8); 4011 registers = Bits32 (opcode, 7, 0); 4012 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4013 wback = true; 4014 4015 // if BitCount(registers) < 1 then UNPREDICTABLE; 4016 if (BitCount (registers) < 1) 4017 return false; 4018 4019 break; 4020 4021 case eEncodingT2: 4022 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4023 n = Bits32 (opcode, 19, 16); 4024 registers = Bits32 (opcode, 15, 0); 4025 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4026 wback = BitIsSet (opcode, 21); 4027 4028 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4029 if ((n == 15) || (BitCount (registers) < 2)) 4030 return false; 4031 4032 // if wback && registers<n> == '1' then UNPREDICTABLE; 4033 if (wback && BitIsSet (registers, n)) 4034 return false; 4035 4036 break; 4037 4038 case eEncodingA1: 4039 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4040 n = Bits32 (opcode, 19, 16); 4041 registers = Bits32 (opcode, 15, 0); 4042 wback = BitIsSet (opcode, 21); 4043 4044 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4045 if ((n == 15) || (BitCount (registers) < 1)) 4046 return false; 4047 4048 break; 4049 4050 default: 4051 return false; 4052 } 4053 4054 // address = R[n]; 4055 int32_t offset = 0; 4056 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4057 if (!success) 4058 return false; 4059 4060 EmulateInstruction::Context context; 4061 context.type = EmulateInstruction::eContextRegisterStore; 4062 RegisterInfo base_reg; 4063 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4064 4065 // for i = 0 to 14 4066 int lowest_set_bit = 14; 4067 for (int i = 0; i < 14; ++i) 4068 { 4069 // if registers<i> == '1' then 4070 if (BitIsSet (registers, i)) 4071 { 4072 if (i < lowest_set_bit) 4073 lowest_set_bit = i; 4074 // if i == n && wback && i != LowestSetBit(registers) then 4075 if ((i == n) && wback && (i != lowest_set_bit)) 4076 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4077 WriteBits32UnknownToMemory (address + offset); 4078 else 4079 { 4080 // MemA[address,4] = R[i]; 4081 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4082 if (!success) 4083 return false; 4084 4085 RegisterInfo data_reg; 4086 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4087 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4088 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4089 return false; 4090 } 4091 4092 // address = address + 4; 4093 offset += addr_byte_size; 4094 } 4095 } 4096 4097 // if registers<15> == '1' then // Only possible for encoding A1 4098 // MemA[address,4] = PCStoreValue(); 4099 if (BitIsSet (registers, 15)) 4100 { 4101 RegisterInfo pc_reg; 4102 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4103 context.SetRegisterPlusOffset (pc_reg, 8); 4104 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4105 if (!success) 4106 return false; 4107 4108 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4109 return false; 4110 } 4111 4112 // if wback then R[n] = R[n] + 4*BitCount(registers); 4113 if (wback) 4114 { 4115 offset = addr_byte_size * BitCount (registers); 4116 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4117 context.SetImmediateSigned (offset); 4118 addr_t data = address + offset; 4119 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4120 return false; 4121 } 4122 } 4123 return true; 4124 } 4125 4126 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4127 // from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4128 // of those locations can optionally be written back to the base register. 4129 bool 4130 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4131 { 4132 #if 0 4133 if ConditionPassed() then 4134 EncodingSpecificOperations(); 4135 address = R[n] - 4*BitCount(registers) + 4; 4136 4137 for i = 0 to 14 4138 if registers<i> == '1' then 4139 if i == n && wback && i != LowestSetBit(registers) then 4140 MemA[address,4] = bits(32) UNKNOWN; 4141 else 4142 MemA[address,4] = R[i]; 4143 address = address + 4; 4144 4145 if registers<15> == '1' then 4146 MemA[address,4] = PCStoreValue(); 4147 4148 if wback then R[n] = R[n] - 4*BitCount(registers); 4149 #endif 4150 4151 bool success = false; 4152 4153 if (ConditionPassed(opcode)) 4154 { 4155 uint32_t n; 4156 uint32_t registers = 0; 4157 bool wback; 4158 const uint32_t addr_byte_size = GetAddressByteSize(); 4159 4160 // EncodingSpecificOperations(); 4161 switch (encoding) 4162 { 4163 case eEncodingA1: 4164 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4165 n = Bits32 (opcode, 19, 16); 4166 registers = Bits32 (opcode, 15, 0); 4167 wback = BitIsSet (opcode, 21); 4168 4169 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4170 if ((n == 15) || (BitCount (registers) < 1)) 4171 return false; 4172 break; 4173 default: 4174 return false; 4175 } 4176 4177 // address = R[n] - 4*BitCount(registers) + 4; 4178 int32_t offset = 0; 4179 addr_t Rn = ReadCoreReg (n, &success); 4180 if (!success) 4181 return false; 4182 4183 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4184 4185 EmulateInstruction::Context context; 4186 context.type = EmulateInstruction::eContextRegisterStore; 4187 RegisterInfo base_reg; 4188 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4189 4190 // for i = 0 to 14 4191 int lowest_bit_set = 14; 4192 for (int i = 0; i < 14; ++i) 4193 { 4194 // if registers<i> == '1' then 4195 if (BitIsSet (registers, i)) 4196 { 4197 if (i < lowest_bit_set) 4198 lowest_bit_set = i; 4199 //if i == n && wback && i != LowestSetBit(registers) then 4200 if ((i == n) && wback && (i != lowest_bit_set)) 4201 // MemA[address,4] = bits(32) UNKNOWN; 4202 WriteBits32UnknownToMemory (address + offset); 4203 else 4204 { 4205 // MemA[address,4] = R[i]; 4206 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4207 if (!success) 4208 return false; 4209 4210 RegisterInfo data_reg; 4211 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4212 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4213 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4214 return false; 4215 } 4216 4217 // address = address + 4; 4218 offset += addr_byte_size; 4219 } 4220 } 4221 4222 // if registers<15> == '1' then 4223 // MemA[address,4] = PCStoreValue(); 4224 if (BitIsSet (registers, 15)) 4225 { 4226 RegisterInfo pc_reg; 4227 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4228 context.SetRegisterPlusOffset (pc_reg, 8); 4229 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4230 if (!success) 4231 return false; 4232 4233 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4234 return false; 4235 } 4236 4237 // if wback then R[n] = R[n] - 4*BitCount(registers); 4238 if (wback) 4239 { 4240 offset = (addr_byte_size * BitCount (registers)) * -1; 4241 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4242 context.SetImmediateSigned (offset); 4243 addr_t data = Rn + offset; 4244 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4245 return false; 4246 } 4247 } 4248 return true; 4249 } 4250 4251 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4252 // from a base register. The consecutive memory locations end just below this address, and the address of the first of 4253 // those locations can optionally be written back to the base register. 4254 bool 4255 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4256 { 4257 #if 0 4258 if ConditionPassed() then 4259 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4260 address = R[n] - 4*BitCount(registers); 4261 4262 for i = 0 to 14 4263 if registers<i> == '1' then 4264 if i == n && wback && i != LowestSetBit(registers) then 4265 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4266 else 4267 MemA[address,4] = R[i]; 4268 address = address + 4; 4269 4270 if registers<15> == '1' then // Only possible for encoding A1 4271 MemA[address,4] = PCStoreValue(); 4272 4273 if wback then R[n] = R[n] - 4*BitCount(registers); 4274 #endif 4275 4276 4277 bool success = false; 4278 4279 if (ConditionPassed(opcode)) 4280 { 4281 uint32_t n; 4282 uint32_t registers = 0; 4283 bool wback; 4284 const uint32_t addr_byte_size = GetAddressByteSize(); 4285 4286 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4287 switch (encoding) 4288 { 4289 case eEncodingT1: 4290 // if W == '1' && Rn == '1101' then SEE PUSH; 4291 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4292 { 4293 // See PUSH 4294 } 4295 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4296 n = Bits32 (opcode, 19, 16); 4297 registers = Bits32 (opcode, 15, 0); 4298 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4299 wback = BitIsSet (opcode, 21); 4300 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4301 if ((n == 15) || BitCount (registers) < 2) 4302 return false; 4303 // if wback && registers<n> == '1' then UNPREDICTABLE; 4304 if (wback && BitIsSet (registers, n)) 4305 return false; 4306 break; 4307 4308 case eEncodingA1: 4309 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH; 4310 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4311 { 4312 // See Push 4313 } 4314 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4315 n = Bits32 (opcode, 19, 16); 4316 registers = Bits32 (opcode, 15, 0); 4317 wback = BitIsSet (opcode, 21); 4318 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4319 if ((n == 15) || BitCount (registers) < 1) 4320 return false; 4321 break; 4322 4323 default: 4324 return false; 4325 } 4326 4327 // address = R[n] - 4*BitCount(registers); 4328 4329 int32_t offset = 0; 4330 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4331 if (!success) 4332 return false; 4333 4334 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4335 4336 EmulateInstruction::Context context; 4337 context.type = EmulateInstruction::eContextRegisterStore; 4338 RegisterInfo base_reg; 4339 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4340 4341 // for i = 0 to 14 4342 uint32_t lowest_set_bit = 14; 4343 for (int i = 0; i < 14; ++i) 4344 { 4345 // if registers<i> == '1' then 4346 if (BitIsSet (registers, i)) 4347 { 4348 if (i < lowest_set_bit) 4349 lowest_set_bit = i; 4350 // if i == n && wback && i != LowestSetBit(registers) then 4351 if ((i == n) && wback && (i != lowest_set_bit)) 4352 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4353 WriteBits32UnknownToMemory (address + offset); 4354 else 4355 { 4356 // MemA[address,4] = R[i]; 4357 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4358 if (!success) 4359 return false; 4360 4361 RegisterInfo data_reg; 4362 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4363 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4364 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4365 return false; 4366 } 4367 4368 // address = address + 4; 4369 offset += addr_byte_size; 4370 } 4371 } 4372 4373 // if registers<15> == '1' then // Only possible for encoding A1 4374 // MemA[address,4] = PCStoreValue(); 4375 if (BitIsSet (registers, 15)) 4376 { 4377 RegisterInfo pc_reg; 4378 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4379 context.SetRegisterPlusOffset (pc_reg, 8); 4380 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4381 if (!success) 4382 return false; 4383 4384 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4385 return false; 4386 } 4387 4388 // if wback then R[n] = R[n] - 4*BitCount(registers); 4389 if (wback) 4390 { 4391 offset = (addr_byte_size * BitCount (registers)) * -1; 4392 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4393 context.SetImmediateSigned (offset); 4394 addr_t data = Rn + offset; 4395 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4396 return false; 4397 } 4398 } 4399 return true; 4400 } 4401 4402 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4403 // from a base register. The consecutive memory locations start just above this address, and the address of the last 4404 // of those locations can optionally be written back to the base register. 4405 bool 4406 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4407 { 4408 #if 0 4409 if ConditionPassed() then 4410 EncodingSpecificOperations(); 4411 address = R[n] + 4; 4412 4413 for i = 0 to 14 4414 if registers<i> == '1' then 4415 if i == n && wback && i != LowestSetBit(registers) then 4416 MemA[address,4] = bits(32) UNKNOWN; 4417 else 4418 MemA[address,4] = R[i]; 4419 address = address + 4; 4420 4421 if registers<15> == '1' then 4422 MemA[address,4] = PCStoreValue(); 4423 4424 if wback then R[n] = R[n] + 4*BitCount(registers); 4425 #endif 4426 4427 bool success = false; 4428 4429 if (ConditionPassed(opcode)) 4430 { 4431 uint32_t n; 4432 uint32_t registers = 0; 4433 bool wback; 4434 const uint32_t addr_byte_size = GetAddressByteSize(); 4435 4436 // EncodingSpecificOperations(); 4437 switch (encoding) 4438 { 4439 case eEncodingA1: 4440 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4441 n = Bits32 (opcode, 19, 16); 4442 registers = Bits32 (opcode, 15, 0); 4443 wback = BitIsSet (opcode, 21); 4444 4445 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4446 if ((n == 15) && (BitCount (registers) < 1)) 4447 return false; 4448 break; 4449 default: 4450 return false; 4451 } 4452 // address = R[n] + 4; 4453 4454 int32_t offset = 0; 4455 addr_t Rn = ReadCoreReg (n, &success); 4456 if (!success) 4457 return false; 4458 4459 addr_t address = Rn + addr_byte_size; 4460 4461 EmulateInstruction::Context context; 4462 context.type = EmulateInstruction::eContextRegisterStore; 4463 RegisterInfo base_reg; 4464 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4465 4466 uint32_t lowest_set_bit = 14; 4467 // for i = 0 to 14 4468 for (int i = 0; i < 14; ++i) 4469 { 4470 // if registers<i> == '1' then 4471 if (BitIsSet (registers, i)) 4472 { 4473 if (i < lowest_set_bit) 4474 lowest_set_bit = i; 4475 // if i == n && wback && i != LowestSetBit(registers) then 4476 if ((i == n) && wback && (i != lowest_set_bit)) 4477 // MemA[address,4] = bits(32) UNKNOWN; 4478 WriteBits32UnknownToMemory (address + offset); 4479 // else 4480 else 4481 { 4482 // MemA[address,4] = R[i]; 4483 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4484 if (!success) 4485 return false; 4486 4487 RegisterInfo data_reg; 4488 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4489 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4490 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4491 return false; 4492 } 4493 4494 // address = address + 4; 4495 offset += addr_byte_size; 4496 } 4497 } 4498 4499 // if registers<15> == '1' then 4500 // MemA[address,4] = PCStoreValue(); 4501 if (BitIsSet (registers, 15)) 4502 { 4503 RegisterInfo pc_reg; 4504 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4505 context.SetRegisterPlusOffset (pc_reg, 8); 4506 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4507 if (!success) 4508 return false; 4509 4510 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4511 return false; 4512 } 4513 4514 // if wback then R[n] = R[n] + 4*BitCount(registers); 4515 if (wback) 4516 { 4517 offset = addr_byte_size * BitCount (registers); 4518 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4519 context.SetImmediateSigned (offset); 4520 addr_t data = Rn + offset; 4521 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4522 return false; 4523 } 4524 } 4525 return true; 4526 } 4527 4528 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 4529 // from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4530 bool 4531 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4532 { 4533 #if 0 4534 if ConditionPassed() then 4535 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4536 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4537 address = if index then offset_addr else R[n]; 4538 if UnalignedSupport() || address<1:0> == '00' then 4539 MemU[address,4] = R[t]; 4540 else // Can only occur before ARMv7 4541 MemU[address,4] = bits(32) UNKNOWN; 4542 if wback then R[n] = offset_addr; 4543 #endif 4544 4545 bool success = false; 4546 4547 if (ConditionPassed(opcode)) 4548 { 4549 const uint32_t addr_byte_size = GetAddressByteSize(); 4550 4551 uint32_t t; 4552 uint32_t n; 4553 uint32_t imm32; 4554 bool index; 4555 bool add; 4556 bool wback; 4557 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4558 switch (encoding) 4559 { 4560 case eEncodingT1: 4561 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4562 t = Bits32 (opcode, 2, 0); 4563 n = Bits32 (opcode, 5, 3); 4564 imm32 = Bits32 (opcode, 10, 6) << 2; 4565 4566 // index = TRUE; add = TRUE; wback = FALSE; 4567 index = true; 4568 add = false; 4569 wback = false; 4570 break; 4571 4572 case eEncodingT2: 4573 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4574 t = Bits32 (opcode, 10, 8); 4575 n = 13; 4576 imm32 = Bits32 (opcode, 7, 0) << 2; 4577 4578 // index = TRUE; add = TRUE; wback = FALSE; 4579 index = true; 4580 add = true; 4581 wback = false; 4582 break; 4583 4584 case eEncodingT3: 4585 // if Rn == '1111' then UNDEFINED; 4586 if (Bits32 (opcode, 19, 16) == 15) 4587 return false; 4588 4589 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4590 t = Bits32 (opcode, 15, 12); 4591 n = Bits32 (opcode, 19, 16); 4592 imm32 = Bits32 (opcode, 11, 0); 4593 4594 // index = TRUE; add = TRUE; wback = FALSE; 4595 index = true; 4596 add = true; 4597 wback = false; 4598 4599 // if t == 15 then UNPREDICTABLE; 4600 if (t == 15) 4601 return false; 4602 break; 4603 4604 case eEncodingT4: 4605 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4606 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4607 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4608 if ((Bits32 (opcode, 19, 16) == 15) 4609 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4610 return false; 4611 4612 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4613 t = Bits32 (opcode, 15, 12); 4614 n = Bits32 (opcode, 19, 16); 4615 imm32 = Bits32 (opcode, 7, 0); 4616 4617 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4618 index = BitIsSet (opcode, 10); 4619 add = BitIsSet (opcode, 9); 4620 wback = BitIsSet (opcode, 8); 4621 4622 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4623 if ((t == 15) || (wback && (n == t))) 4624 return false; 4625 break; 4626 4627 default: 4628 return false; 4629 } 4630 4631 addr_t offset_addr; 4632 addr_t address; 4633 4634 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4635 uint32_t base_address = ReadCoreReg (n, &success); 4636 if (!success) 4637 return false; 4638 4639 if (add) 4640 offset_addr = base_address + imm32; 4641 else 4642 offset_addr = base_address - imm32; 4643 4644 // address = if index then offset_addr else R[n]; 4645 if (index) 4646 address = offset_addr; 4647 else 4648 address = base_address; 4649 4650 EmulateInstruction::Context context; 4651 context.type = eContextRegisterStore; 4652 RegisterInfo base_reg; 4653 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4654 4655 // if UnalignedSupport() || address<1:0> == '00' then 4656 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4657 { 4658 // MemU[address,4] = R[t]; 4659 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4660 if (!success) 4661 return false; 4662 4663 RegisterInfo data_reg; 4664 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4665 int32_t offset = address - base_address; 4666 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4667 if (!MemUWrite (context, address, data, addr_byte_size)) 4668 return false; 4669 } 4670 else 4671 { 4672 // MemU[address,4] = bits(32) UNKNOWN; 4673 WriteBits32UnknownToMemory (address); 4674 } 4675 4676 // if wback then R[n] = offset_addr; 4677 if (wback) 4678 { 4679 context.type = eContextRegisterLoad; 4680 context.SetAddress (offset_addr); 4681 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4682 return false; 4683 } 4684 } 4685 return true; 4686 } 4687 4688 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4689 // word from a register to memory. The offset register value can optionally be shifted. 4690 bool 4691 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4692 { 4693 #if 0 4694 if ConditionPassed() then 4695 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4696 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4697 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4698 address = if index then offset_addr else R[n]; 4699 if t == 15 then // Only possible for encoding A1 4700 data = PCStoreValue(); 4701 else 4702 data = R[t]; 4703 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4704 MemU[address,4] = data; 4705 else // Can only occur before ARMv7 4706 MemU[address,4] = bits(32) UNKNOWN; 4707 if wback then R[n] = offset_addr; 4708 #endif 4709 4710 bool success = false; 4711 4712 if (ConditionPassed(opcode)) 4713 { 4714 const uint32_t addr_byte_size = GetAddressByteSize(); 4715 4716 uint32_t t; 4717 uint32_t n; 4718 uint32_t m; 4719 ARM_ShifterType shift_t; 4720 uint32_t shift_n; 4721 bool index; 4722 bool add; 4723 bool wback; 4724 4725 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4726 switch (encoding) 4727 { 4728 case eEncodingT1: 4729 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4730 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4731 t = Bits32 (opcode, 2, 0); 4732 n = Bits32 (opcode, 5, 3); 4733 m = Bits32 (opcode, 8, 6); 4734 4735 // index = TRUE; add = TRUE; wback = FALSE; 4736 index = true; 4737 add = true; 4738 wback = false; 4739 4740 // (shift_t, shift_n) = (SRType_LSL, 0); 4741 shift_t = SRType_LSL; 4742 shift_n = 0; 4743 break; 4744 4745 case eEncodingT2: 4746 // if Rn == '1111' then UNDEFINED; 4747 if (Bits32 (opcode, 19, 16) == 15) 4748 return false; 4749 4750 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4751 t = Bits32 (opcode, 15, 12); 4752 n = Bits32 (opcode, 19, 16); 4753 m = Bits32 (opcode, 3, 0); 4754 4755 // index = TRUE; add = TRUE; wback = FALSE; 4756 index = true; 4757 add = true; 4758 wback = false; 4759 4760 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4761 shift_t = SRType_LSL; 4762 shift_n = Bits32 (opcode, 5, 4); 4763 4764 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4765 if ((t == 15) || (BadReg (m))) 4766 return false; 4767 break; 4768 4769 case eEncodingA1: 4770 { 4771 // if P == '0' && W == '1' then SEE STRT; 4772 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4773 t = Bits32 (opcode, 15, 12); 4774 n = Bits32 (opcode, 19, 16); 4775 m = Bits32 (opcode, 3, 0); 4776 4777 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4778 index = BitIsSet (opcode, 24); 4779 add = BitIsSet (opcode, 23); 4780 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4781 4782 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4783 uint32_t typ = Bits32 (opcode, 6, 5); 4784 uint32_t imm5 = Bits32 (opcode, 11, 7); 4785 shift_n = DecodeImmShift(typ, imm5, shift_t); 4786 4787 // if m == 15 then UNPREDICTABLE; 4788 if (m == 15) 4789 return false; 4790 4791 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4792 if (wback && ((n == 15) || (n == t))) 4793 return false; 4794 4795 break; 4796 } 4797 default: 4798 return false; 4799 } 4800 4801 addr_t offset_addr; 4802 addr_t address; 4803 int32_t offset = 0; 4804 4805 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4806 if (!success) 4807 return false; 4808 4809 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4810 if (!success) 4811 return false; 4812 4813 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4814 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4815 if (!success) 4816 return false; 4817 4818 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4819 if (add) 4820 offset_addr = base_address + offset; 4821 else 4822 offset_addr = base_address - offset; 4823 4824 // address = if index then offset_addr else R[n]; 4825 if (index) 4826 address = offset_addr; 4827 else 4828 address = base_address; 4829 4830 uint32_t data; 4831 // if t == 15 then // Only possible for encoding A1 4832 if (t == 15) 4833 // data = PCStoreValue(); 4834 data = ReadCoreReg (PC_REG, &success); 4835 else 4836 // data = R[t]; 4837 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4838 4839 if (!success) 4840 return false; 4841 4842 EmulateInstruction::Context context; 4843 context.type = eContextRegisterStore; 4844 4845 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4846 if (UnalignedSupport () 4847 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4848 || CurrentInstrSet() == eModeARM) 4849 { 4850 // MemU[address,4] = data; 4851 4852 RegisterInfo base_reg; 4853 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4854 4855 RegisterInfo data_reg; 4856 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4857 4858 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4859 if (!MemUWrite (context, address, data, addr_byte_size)) 4860 return false; 4861 4862 } 4863 else 4864 // MemU[address,4] = bits(32) UNKNOWN; 4865 WriteBits32UnknownToMemory (address); 4866 4867 // if wback then R[n] = offset_addr; 4868 if (wback) 4869 { 4870 context.type = eContextRegisterLoad; 4871 context.SetAddress (offset_addr); 4872 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4873 return false; 4874 } 4875 4876 } 4877 return true; 4878 } 4879 4880 bool 4881 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 4882 { 4883 #if 0 4884 if ConditionPassed() then 4885 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4886 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4887 address = if index then offset_addr else R[n]; 4888 MemU[address,1] = R[t]<7:0>; 4889 if wback then R[n] = offset_addr; 4890 #endif 4891 4892 4893 bool success = false; 4894 4895 if (ConditionPassed(opcode)) 4896 { 4897 uint32_t t; 4898 uint32_t n; 4899 uint32_t imm32; 4900 bool index; 4901 bool add; 4902 bool wback; 4903 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4904 switch (encoding) 4905 { 4906 case eEncodingT1: 4907 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4908 t = Bits32 (opcode, 2, 0); 4909 n = Bits32 (opcode, 5, 3); 4910 imm32 = Bits32 (opcode, 10, 6); 4911 4912 // index = TRUE; add = TRUE; wback = FALSE; 4913 index = true; 4914 add = true; 4915 wback = false; 4916 break; 4917 4918 case eEncodingT2: 4919 // if Rn == '1111' then UNDEFINED; 4920 if (Bits32 (opcode, 19, 16) == 15) 4921 return false; 4922 4923 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4924 t = Bits32 (opcode, 15, 12); 4925 n = Bits32 (opcode, 19, 16); 4926 imm32 = Bits32 (opcode, 11, 0); 4927 4928 // index = TRUE; add = TRUE; wback = FALSE; 4929 index = true; 4930 add = true; 4931 wback = false; 4932 4933 // if BadReg(t) then UNPREDICTABLE; 4934 if (BadReg (t)) 4935 return false; 4936 break; 4937 4938 case eEncodingT3: 4939 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 4940 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4941 if (Bits32 (opcode, 19, 16) == 15) 4942 return false; 4943 4944 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4945 t = Bits32 (opcode, 15, 12); 4946 n = Bits32 (opcode, 19, 16); 4947 imm32 = Bits32 (opcode, 7, 0); 4948 4949 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4950 index = BitIsSet (opcode, 10); 4951 add = BitIsSet (opcode, 9); 4952 wback = BitIsSet (opcode, 8); 4953 4954 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 4955 if ((BadReg (t)) || (wback && (n == t))) 4956 return false; 4957 break; 4958 4959 default: 4960 return false; 4961 } 4962 4963 addr_t offset_addr; 4964 addr_t address; 4965 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4966 if (!success) 4967 return false; 4968 4969 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4970 if (add) 4971 offset_addr = base_address + imm32; 4972 else 4973 offset_addr = base_address - imm32; 4974 4975 // address = if index then offset_addr else R[n]; 4976 if (index) 4977 address = offset_addr; 4978 else 4979 address = base_address; 4980 4981 // MemU[address,1] = R[t]<7:0> 4982 RegisterInfo base_reg; 4983 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4984 4985 RegisterInfo data_reg; 4986 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4987 4988 EmulateInstruction::Context context; 4989 context.type = eContextRegisterStore; 4990 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4991 4992 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4993 if (!success) 4994 return false; 4995 4996 data = Bits32 (data, 7, 0); 4997 4998 if (!MemUWrite (context, address, data, 1)) 4999 return false; 5000 5001 // if wback then R[n] = offset_addr; 5002 if (wback) 5003 { 5004 context.type = eContextRegisterLoad; 5005 context.SetAddress (offset_addr); 5006 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5007 return false; 5008 } 5009 5010 } 5011 5012 return true; 5013 } 5014 5015 // STRH (register) calculates an address from a base register value and an offset register value, and stores a 5016 // halfword from a register to memory. The offset register alue can be shifted left by 0, 1, 2, or 3 bits. 5017 bool 5018 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5019 { 5020 #if 0 5021 if ConditionPassed() then 5022 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5023 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5024 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5025 address = if index then offset_addr else R[n]; 5026 if UnalignedSupport() || address<0> == '0' then 5027 MemU[address,2] = R[t]<15:0>; 5028 else // Can only occur before ARMv7 5029 MemU[address,2] = bits(16) UNKNOWN; 5030 if wback then R[n] = offset_addr; 5031 #endif 5032 5033 bool success = false; 5034 5035 if (ConditionPassed(opcode)) 5036 { 5037 uint32_t t; 5038 uint32_t n; 5039 uint32_t m; 5040 bool index; 5041 bool add; 5042 bool wback; 5043 ARM_ShifterType shift_t; 5044 uint32_t shift_n; 5045 5046 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5047 switch (encoding) 5048 { 5049 case eEncodingT1: 5050 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5051 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5052 t = Bits32 (opcode, 2, 0); 5053 n = Bits32 (opcode, 5, 3); 5054 m = Bits32 (opcode, 8, 6); 5055 5056 // index = TRUE; add = TRUE; wback = FALSE; 5057 index = true; 5058 add = true; 5059 wback = false; 5060 5061 // (shift_t, shift_n) = (SRType_LSL, 0); 5062 shift_t = SRType_LSL; 5063 shift_n = 0; 5064 5065 break; 5066 5067 case eEncodingT2: 5068 // if Rn == '1111' then UNDEFINED; 5069 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5070 t = Bits32 (opcode, 15, 12); 5071 n = Bits32 (opcode, 19, 16); 5072 m = Bits32 (opcode, 3, 0); 5073 if (n == 15) 5074 return false; 5075 5076 // index = TRUE; add = TRUE; wback = FALSE; 5077 index = true; 5078 add = true; 5079 wback = false; 5080 5081 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5082 shift_t = SRType_LSL; 5083 shift_n = Bits32 (opcode, 5, 4); 5084 5085 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5086 if (BadReg (t) || BadReg (m)) 5087 return false; 5088 5089 break; 5090 5091 case eEncodingA1: 5092 // if P == '0' && W == '1' then SEE STRHT; 5093 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5094 t = Bits32 (opcode, 15, 12); 5095 n = Bits32 (opcode, 19, 16); 5096 m = Bits32 (opcode, 3, 0); 5097 5098 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5099 index = BitIsSet (opcode, 24); 5100 add = BitIsSet (opcode, 23); 5101 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5102 5103 // (shift_t, shift_n) = (SRType_LSL, 0); 5104 shift_t = SRType_LSL; 5105 shift_n = 0; 5106 5107 // if t == 15 || m == 15 then UNPREDICTABLE; 5108 if ((t == 15) || (m == 15)) 5109 return false; 5110 5111 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5112 if (wback && ((n == 15) || (n == t))) 5113 return false; 5114 5115 break; 5116 5117 default: 5118 return false; 5119 } 5120 5121 uint32_t Rm = ReadCoreReg (m, &success); 5122 if (!success) 5123 return false; 5124 5125 uint32_t Rn = ReadCoreReg (n, &success); 5126 if (!success) 5127 return false; 5128 5129 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5130 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5131 if (!success) 5132 return false; 5133 5134 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5135 addr_t offset_addr; 5136 if (add) 5137 offset_addr = Rn + offset; 5138 else 5139 offset_addr = Rn - offset; 5140 5141 // address = if index then offset_addr else R[n]; 5142 addr_t address; 5143 if (index) 5144 address = offset_addr; 5145 else 5146 address = Rn; 5147 5148 EmulateInstruction::Context context; 5149 context.type = eContextRegisterStore; 5150 RegisterInfo base_reg; 5151 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5152 RegisterInfo offset_reg; 5153 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5154 5155 // if UnalignedSupport() || address<0> == '0' then 5156 if (UnalignedSupport() || BitIsClear (address, 0)) 5157 { 5158 // MemU[address,2] = R[t]<15:0>; 5159 uint32_t Rt = ReadCoreReg (t, &success); 5160 if (!success) 5161 return false; 5162 5163 EmulateInstruction::Context context; 5164 context.type = eContextRegisterStore; 5165 RegisterInfo base_reg; 5166 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5167 RegisterInfo offset_reg; 5168 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5169 RegisterInfo data_reg; 5170 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5171 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5172 5173 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5174 return false; 5175 } 5176 else // Can only occur before ARMv7 5177 { 5178 // MemU[address,2] = bits(16) UNKNOWN; 5179 } 5180 5181 // if wback then R[n] = offset_addr; 5182 if (wback) 5183 { 5184 context.type = eContextAdjustBaseRegister; 5185 context.SetAddress (offset_addr); 5186 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5187 return false; 5188 } 5189 } 5190 5191 return true; 5192 } 5193 5194 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5195 // and writes the result to the destination register. It can optionally update the condition flags 5196 // based on the result. 5197 bool 5198 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5199 { 5200 #if 0 5201 // ARM pseudo code... 5202 if ConditionPassed() then 5203 EncodingSpecificOperations(); 5204 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5205 if d == 15 then // Can only occur for ARM encoding 5206 ALUWritePC(result); // setflags is always FALSE here 5207 else 5208 R[d] = result; 5209 if setflags then 5210 APSR.N = result<31>; 5211 APSR.Z = IsZeroBit(result); 5212 APSR.C = carry; 5213 APSR.V = overflow; 5214 #endif 5215 5216 bool success = false; 5217 5218 if (ConditionPassed(opcode)) 5219 { 5220 uint32_t Rd, Rn; 5221 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5222 bool setflags; 5223 switch (encoding) 5224 { 5225 case eEncodingT1: 5226 Rd = Bits32(opcode, 11, 8); 5227 Rn = Bits32(opcode, 19, 16); 5228 setflags = BitIsSet(opcode, 20); 5229 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5230 if (BadReg(Rd) || BadReg(Rn)) 5231 return false; 5232 break; 5233 case eEncodingA1: 5234 Rd = Bits32(opcode, 15, 12); 5235 Rn = Bits32(opcode, 19, 16); 5236 setflags = BitIsSet(opcode, 20); 5237 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5238 5239 if (Rd == 15 && setflags) 5240 return EmulateSUBSPcLrEtc (opcode, encoding); 5241 break; 5242 default: 5243 return false; 5244 } 5245 5246 // Read the first operand. 5247 int32_t val1 = ReadCoreReg(Rn, &success); 5248 if (!success) 5249 return false; 5250 5251 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5252 5253 EmulateInstruction::Context context; 5254 context.type = EmulateInstruction::eContextImmediate; 5255 context.SetNoArgs (); 5256 5257 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5258 return false; 5259 } 5260 return true; 5261 } 5262 5263 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5264 // register value, and writes the result to the destination register. It can optionally update the 5265 // condition flags based on the result. 5266 bool 5267 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5268 { 5269 #if 0 5270 // ARM pseudo code... 5271 if ConditionPassed() then 5272 EncodingSpecificOperations(); 5273 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5274 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5275 if d == 15 then // Can only occur for ARM encoding 5276 ALUWritePC(result); // setflags is always FALSE here 5277 else 5278 R[d] = result; 5279 if setflags then 5280 APSR.N = result<31>; 5281 APSR.Z = IsZeroBit(result); 5282 APSR.C = carry; 5283 APSR.V = overflow; 5284 #endif 5285 5286 bool success = false; 5287 5288 if (ConditionPassed(opcode)) 5289 { 5290 uint32_t Rd, Rn, Rm; 5291 ARM_ShifterType shift_t; 5292 uint32_t shift_n; // the shift applied to the value read from Rm 5293 bool setflags; 5294 switch (encoding) 5295 { 5296 case eEncodingT1: 5297 Rd = Rn = Bits32(opcode, 2, 0); 5298 Rm = Bits32(opcode, 5, 3); 5299 setflags = !InITBlock(); 5300 shift_t = SRType_LSL; 5301 shift_n = 0; 5302 break; 5303 case eEncodingT2: 5304 Rd = Bits32(opcode, 11, 8); 5305 Rn = Bits32(opcode, 19, 16); 5306 Rm = Bits32(opcode, 3, 0); 5307 setflags = BitIsSet(opcode, 20); 5308 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5309 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5310 return false; 5311 break; 5312 case eEncodingA1: 5313 Rd = Bits32(opcode, 15, 12); 5314 Rn = Bits32(opcode, 19, 16); 5315 Rm = Bits32(opcode, 3, 0); 5316 setflags = BitIsSet(opcode, 20); 5317 shift_n = DecodeImmShiftARM(opcode, shift_t); 5318 5319 if (Rd == 15 && setflags) 5320 return EmulateSUBSPcLrEtc (opcode, encoding); 5321 break; 5322 default: 5323 return false; 5324 } 5325 5326 // Read the first operand. 5327 int32_t val1 = ReadCoreReg(Rn, &success); 5328 if (!success) 5329 return false; 5330 5331 // Read the second operand. 5332 int32_t val2 = ReadCoreReg(Rm, &success); 5333 if (!success) 5334 return false; 5335 5336 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5337 if (!success) 5338 return false; 5339 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5340 5341 EmulateInstruction::Context context; 5342 context.type = EmulateInstruction::eContextImmediate; 5343 context.SetNoArgs (); 5344 5345 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5346 return false; 5347 } 5348 return true; 5349 } 5350 5351 // This instruction adds an immediate value to the PC value to form a PC-relative address, 5352 // and writes the result to the destination register. 5353 bool 5354 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5355 { 5356 #if 0 5357 // ARM pseudo code... 5358 if ConditionPassed() then 5359 EncodingSpecificOperations(); 5360 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5361 if d == 15 then // Can only occur for ARM encodings 5362 ALUWritePC(result); 5363 else 5364 R[d] = result; 5365 #endif 5366 5367 bool success = false; 5368 5369 if (ConditionPassed(opcode)) 5370 { 5371 uint32_t Rd; 5372 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5373 bool add; 5374 switch (encoding) 5375 { 5376 case eEncodingT1: 5377 Rd = Bits32(opcode, 10, 8); 5378 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5379 break; 5380 case eEncodingT2: 5381 case eEncodingT3: 5382 Rd = Bits32(opcode, 11, 8); 5383 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5384 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5385 if (BadReg(Rd)) 5386 return false; 5387 break; 5388 case eEncodingA1: 5389 case eEncodingA2: 5390 Rd = Bits32(opcode, 15, 12); 5391 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5392 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5393 break; 5394 default: 5395 return false; 5396 } 5397 5398 // Read the PC value. 5399 uint32_t pc = ReadCoreReg(PC_REG, &success); 5400 if (!success) 5401 return false; 5402 5403 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5404 5405 EmulateInstruction::Context context; 5406 context.type = EmulateInstruction::eContextImmediate; 5407 context.SetNoArgs (); 5408 5409 if (!WriteCoreReg(context, result, Rd)) 5410 return false; 5411 } 5412 return true; 5413 } 5414 5415 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5416 // to the destination register. It can optionally update the condition flags based on the result. 5417 bool 5418 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5419 { 5420 #if 0 5421 // ARM pseudo code... 5422 if ConditionPassed() then 5423 EncodingSpecificOperations(); 5424 result = R[n] AND imm32; 5425 if d == 15 then // Can only occur for ARM encoding 5426 ALUWritePC(result); // setflags is always FALSE here 5427 else 5428 R[d] = result; 5429 if setflags then 5430 APSR.N = result<31>; 5431 APSR.Z = IsZeroBit(result); 5432 APSR.C = carry; 5433 // APSR.V unchanged 5434 #endif 5435 5436 bool success = false; 5437 5438 if (ConditionPassed(opcode)) 5439 { 5440 uint32_t Rd, Rn; 5441 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5442 bool setflags; 5443 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5444 switch (encoding) 5445 { 5446 case eEncodingT1: 5447 Rd = Bits32(opcode, 11, 8); 5448 Rn = Bits32(opcode, 19, 16); 5449 setflags = BitIsSet(opcode, 20); 5450 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5451 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5452 if (Rd == 15 && setflags) 5453 return EmulateTSTImm(opcode, eEncodingT1); 5454 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5455 return false; 5456 break; 5457 case eEncodingA1: 5458 Rd = Bits32(opcode, 15, 12); 5459 Rn = Bits32(opcode, 19, 16); 5460 setflags = BitIsSet(opcode, 20); 5461 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5462 5463 if (Rd == 15 && setflags) 5464 return EmulateSUBSPcLrEtc (opcode, encoding); 5465 break; 5466 default: 5467 return false; 5468 } 5469 5470 // Read the first operand. 5471 uint32_t val1 = ReadCoreReg(Rn, &success); 5472 if (!success) 5473 return false; 5474 5475 uint32_t result = val1 & imm32; 5476 5477 EmulateInstruction::Context context; 5478 context.type = EmulateInstruction::eContextImmediate; 5479 context.SetNoArgs (); 5480 5481 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5482 return false; 5483 } 5484 return true; 5485 } 5486 5487 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5488 // and writes the result to the destination register. It can optionally update the condition flags 5489 // based on the result. 5490 bool 5491 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5492 { 5493 #if 0 5494 // ARM pseudo code... 5495 if ConditionPassed() then 5496 EncodingSpecificOperations(); 5497 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5498 result = R[n] AND shifted; 5499 if d == 15 then // Can only occur for ARM encoding 5500 ALUWritePC(result); // setflags is always FALSE here 5501 else 5502 R[d] = result; 5503 if setflags then 5504 APSR.N = result<31>; 5505 APSR.Z = IsZeroBit(result); 5506 APSR.C = carry; 5507 // APSR.V unchanged 5508 #endif 5509 5510 bool success = false; 5511 5512 if (ConditionPassed(opcode)) 5513 { 5514 uint32_t Rd, Rn, Rm; 5515 ARM_ShifterType shift_t; 5516 uint32_t shift_n; // the shift applied to the value read from Rm 5517 bool setflags; 5518 uint32_t carry; 5519 switch (encoding) 5520 { 5521 case eEncodingT1: 5522 Rd = Rn = Bits32(opcode, 2, 0); 5523 Rm = Bits32(opcode, 5, 3); 5524 setflags = !InITBlock(); 5525 shift_t = SRType_LSL; 5526 shift_n = 0; 5527 break; 5528 case eEncodingT2: 5529 Rd = Bits32(opcode, 11, 8); 5530 Rn = Bits32(opcode, 19, 16); 5531 Rm = Bits32(opcode, 3, 0); 5532 setflags = BitIsSet(opcode, 20); 5533 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5534 // if Rd == '1111' && S == '1' then SEE TST (register); 5535 if (Rd == 15 && setflags) 5536 return EmulateTSTReg(opcode, eEncodingT2); 5537 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5538 return false; 5539 break; 5540 case eEncodingA1: 5541 Rd = Bits32(opcode, 15, 12); 5542 Rn = Bits32(opcode, 19, 16); 5543 Rm = Bits32(opcode, 3, 0); 5544 setflags = BitIsSet(opcode, 20); 5545 shift_n = DecodeImmShiftARM(opcode, shift_t); 5546 5547 if (Rd == 15 && setflags) 5548 return EmulateSUBSPcLrEtc (opcode, encoding); 5549 break; 5550 default: 5551 return false; 5552 } 5553 5554 // Read the first operand. 5555 uint32_t val1 = ReadCoreReg(Rn, &success); 5556 if (!success) 5557 return false; 5558 5559 // Read the second operand. 5560 uint32_t val2 = ReadCoreReg(Rm, &success); 5561 if (!success) 5562 return false; 5563 5564 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5565 if (!success) 5566 return false; 5567 uint32_t result = val1 & shifted; 5568 5569 EmulateInstruction::Context context; 5570 context.type = EmulateInstruction::eContextImmediate; 5571 context.SetNoArgs (); 5572 5573 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5574 return false; 5575 } 5576 return true; 5577 } 5578 5579 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5580 // immediate value, and writes the result to the destination register. It can optionally update the 5581 // condition flags based on the result. 5582 bool 5583 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5584 { 5585 #if 0 5586 // ARM pseudo code... 5587 if ConditionPassed() then 5588 EncodingSpecificOperations(); 5589 result = R[n] AND NOT(imm32); 5590 if d == 15 then // Can only occur for ARM encoding 5591 ALUWritePC(result); // setflags is always FALSE here 5592 else 5593 R[d] = result; 5594 if setflags then 5595 APSR.N = result<31>; 5596 APSR.Z = IsZeroBit(result); 5597 APSR.C = carry; 5598 // APSR.V unchanged 5599 #endif 5600 5601 bool success = false; 5602 5603 if (ConditionPassed(opcode)) 5604 { 5605 uint32_t Rd, Rn; 5606 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5607 bool setflags; 5608 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5609 switch (encoding) 5610 { 5611 case eEncodingT1: 5612 Rd = Bits32(opcode, 11, 8); 5613 Rn = Bits32(opcode, 19, 16); 5614 setflags = BitIsSet(opcode, 20); 5615 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5616 if (BadReg(Rd) || BadReg(Rn)) 5617 return false; 5618 break; 5619 case eEncodingA1: 5620 Rd = Bits32(opcode, 15, 12); 5621 Rn = Bits32(opcode, 19, 16); 5622 setflags = BitIsSet(opcode, 20); 5623 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5624 5625 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5626 if (Rd == 15 && setflags) 5627 return EmulateSUBSPcLrEtc (opcode, encoding); 5628 break; 5629 default: 5630 return false; 5631 } 5632 5633 // Read the first operand. 5634 uint32_t val1 = ReadCoreReg(Rn, &success); 5635 if (!success) 5636 return false; 5637 5638 uint32_t result = val1 & ~imm32; 5639 5640 EmulateInstruction::Context context; 5641 context.type = EmulateInstruction::eContextImmediate; 5642 context.SetNoArgs (); 5643 5644 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5645 return false; 5646 } 5647 return true; 5648 } 5649 5650 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5651 // optionally-shifted register value, and writes the result to the destination register. 5652 // It can optionally update the condition flags based on the result. 5653 bool 5654 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5655 { 5656 #if 0 5657 // ARM pseudo code... 5658 if ConditionPassed() then 5659 EncodingSpecificOperations(); 5660 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5661 result = R[n] AND NOT(shifted); 5662 if d == 15 then // Can only occur for ARM encoding 5663 ALUWritePC(result); // setflags is always FALSE here 5664 else 5665 R[d] = result; 5666 if setflags then 5667 APSR.N = result<31>; 5668 APSR.Z = IsZeroBit(result); 5669 APSR.C = carry; 5670 // APSR.V unchanged 5671 #endif 5672 5673 bool success = false; 5674 5675 if (ConditionPassed(opcode)) 5676 { 5677 uint32_t Rd, Rn, Rm; 5678 ARM_ShifterType shift_t; 5679 uint32_t shift_n; // the shift applied to the value read from Rm 5680 bool setflags; 5681 uint32_t carry; 5682 switch (encoding) 5683 { 5684 case eEncodingT1: 5685 Rd = Rn = Bits32(opcode, 2, 0); 5686 Rm = Bits32(opcode, 5, 3); 5687 setflags = !InITBlock(); 5688 shift_t = SRType_LSL; 5689 shift_n = 0; 5690 break; 5691 case eEncodingT2: 5692 Rd = Bits32(opcode, 11, 8); 5693 Rn = Bits32(opcode, 19, 16); 5694 Rm = Bits32(opcode, 3, 0); 5695 setflags = BitIsSet(opcode, 20); 5696 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5697 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5698 return false; 5699 break; 5700 case eEncodingA1: 5701 Rd = Bits32(opcode, 15, 12); 5702 Rn = Bits32(opcode, 19, 16); 5703 Rm = Bits32(opcode, 3, 0); 5704 setflags = BitIsSet(opcode, 20); 5705 shift_n = DecodeImmShiftARM(opcode, shift_t); 5706 5707 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5708 if (Rd == 15 && setflags) 5709 return EmulateSUBSPcLrEtc (opcode, encoding); 5710 break; 5711 default: 5712 return false; 5713 } 5714 5715 // Read the first operand. 5716 uint32_t val1 = ReadCoreReg(Rn, &success); 5717 if (!success) 5718 return false; 5719 5720 // Read the second operand. 5721 uint32_t val2 = ReadCoreReg(Rm, &success); 5722 if (!success) 5723 return false; 5724 5725 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5726 if (!success) 5727 return false; 5728 uint32_t result = val1 & ~shifted; 5729 5730 EmulateInstruction::Context context; 5731 context.type = EmulateInstruction::eContextImmediate; 5732 context.SetNoArgs (); 5733 5734 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5735 return false; 5736 } 5737 return true; 5738 } 5739 5740 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5741 // from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5742 bool 5743 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5744 { 5745 #if 0 5746 if ConditionPassed() then 5747 EncodingSpecificOperations(); 5748 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5749 address = if index then offset_addr else R[n]; 5750 data = MemU[address,4]; 5751 if wback then R[n] = offset_addr; 5752 if t == 15 then 5753 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5754 elsif UnalignedSupport() || address<1:0> = '00' then 5755 R[t] = data; 5756 else // Can only apply before ARMv7 5757 R[t] = ROR(data, 8*UInt(address<1:0>)); 5758 #endif 5759 5760 bool success = false; 5761 5762 if (ConditionPassed(opcode)) 5763 { 5764 const uint32_t addr_byte_size = GetAddressByteSize(); 5765 5766 uint32_t t; 5767 uint32_t n; 5768 uint32_t imm32; 5769 bool index; 5770 bool add; 5771 bool wback; 5772 5773 switch (encoding) 5774 { 5775 case eEncodingA1: 5776 // if Rn == '1111' then SEE LDR (literal); 5777 // if P == '0' && W == '1' then SEE LDRT; 5778 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5779 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5780 t = Bits32 (opcode, 15, 12); 5781 n = Bits32 (opcode, 19, 16); 5782 imm32 = Bits32 (opcode, 11, 0); 5783 5784 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5785 index = BitIsSet (opcode, 24); 5786 add = BitIsSet (opcode, 23); 5787 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5788 5789 // if wback && n == t then UNPREDICTABLE; 5790 if (wback && (n == t)) 5791 return false; 5792 5793 break; 5794 5795 default: 5796 return false; 5797 } 5798 5799 addr_t address; 5800 addr_t offset_addr; 5801 addr_t base_address = ReadCoreReg (n, &success); 5802 if (!success) 5803 return false; 5804 5805 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5806 if (add) 5807 offset_addr = base_address + imm32; 5808 else 5809 offset_addr = base_address - imm32; 5810 5811 // address = if index then offset_addr else R[n]; 5812 if (index) 5813 address = offset_addr; 5814 else 5815 address = base_address; 5816 5817 // data = MemU[address,4]; 5818 5819 RegisterInfo base_reg; 5820 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5821 5822 EmulateInstruction::Context context; 5823 context.type = eContextRegisterLoad; 5824 context.SetRegisterPlusOffset (base_reg, address - base_address); 5825 5826 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5827 if (!success) 5828 return false; 5829 5830 // if wback then R[n] = offset_addr; 5831 if (wback) 5832 { 5833 context.type = eContextAdjustBaseRegister; 5834 context.SetAddress (offset_addr); 5835 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5836 return false; 5837 } 5838 5839 // if t == 15 then 5840 if (t == 15) 5841 { 5842 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5843 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5844 { 5845 // LoadWritePC (data); 5846 context.type = eContextRegisterLoad; 5847 context.SetRegisterPlusOffset (base_reg, address - base_address); 5848 LoadWritePC (context, data); 5849 } 5850 else 5851 return false; 5852 } 5853 // elsif UnalignedSupport() || address<1:0> = '00' then 5854 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5855 { 5856 // R[t] = data; 5857 context.type = eContextRegisterLoad; 5858 context.SetRegisterPlusOffset (base_reg, address - base_address); 5859 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5860 return false; 5861 } 5862 // else // Can only apply before ARMv7 5863 else 5864 { 5865 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5866 data = ROR (data, Bits32 (address, 1, 0), &success); 5867 if (!success) 5868 return false; 5869 context.type = eContextRegisterLoad; 5870 context.SetImmediate (data); 5871 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5872 return false; 5873 } 5874 5875 } 5876 return true; 5877 } 5878 5879 // LDR (register) calculates an address from a base register value and an offset register value, loads a word 5880 // from memory, and writes it to a resgister. The offset register value can optionally be shifted. 5881 bool 5882 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5883 { 5884 #if 0 5885 if ConditionPassed() then 5886 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5887 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5888 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5889 address = if index then offset_addr else R[n]; 5890 data = MemU[address,4]; 5891 if wback then R[n] = offset_addr; 5892 if t == 15 then 5893 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5894 elsif UnalignedSupport() || address<1:0> = '00' then 5895 R[t] = data; 5896 else // Can only apply before ARMv7 5897 if CurrentInstrSet() == InstrSet_ARM then 5898 R[t] = ROR(data, 8*UInt(address<1:0>)); 5899 else 5900 R[t] = bits(32) UNKNOWN; 5901 #endif 5902 5903 bool success = false; 5904 5905 if (ConditionPassed(opcode)) 5906 { 5907 const uint32_t addr_byte_size = GetAddressByteSize(); 5908 5909 uint32_t t; 5910 uint32_t n; 5911 uint32_t m; 5912 bool index; 5913 bool add; 5914 bool wback; 5915 ARM_ShifterType shift_t; 5916 uint32_t shift_n; 5917 5918 switch (encoding) 5919 { 5920 case eEncodingT1: 5921 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5922 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5923 t = Bits32 (opcode, 2, 0); 5924 n = Bits32 (opcode, 5, 3); 5925 m = Bits32 (opcode, 8, 6); 5926 5927 // index = TRUE; add = TRUE; wback = FALSE; 5928 index = true; 5929 add = true; 5930 wback = false; 5931 5932 // (shift_t, shift_n) = (SRType_LSL, 0); 5933 shift_t = SRType_LSL; 5934 shift_n = 0; 5935 5936 break; 5937 5938 case eEncodingT2: 5939 // if Rn == '1111' then SEE LDR (literal); 5940 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5941 t = Bits32 (opcode, 15, 12); 5942 n = Bits32 (opcode, 19, 16); 5943 m = Bits32 (opcode, 3, 0); 5944 5945 // index = TRUE; add = TRUE; wback = FALSE; 5946 index = true; 5947 add = true; 5948 wback = false; 5949 5950 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5951 shift_t = SRType_LSL; 5952 shift_n = Bits32 (opcode, 5, 4); 5953 5954 // if BadReg(m) then UNPREDICTABLE; 5955 if (BadReg (m)) 5956 return false; 5957 5958 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5959 if ((t == 15) && InITBlock() && !LastInITBlock()) 5960 return false; 5961 5962 break; 5963 5964 case eEncodingA1: 5965 { 5966 // if P == '0' && W == '1' then SEE LDRT; 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 = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5973 index = BitIsSet (opcode, 24); 5974 add = BitIsSet (opcode, 23); 5975 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5976 5977 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5978 uint32_t type = Bits32 (opcode, 6, 5); 5979 uint32_t imm5 = Bits32 (opcode, 11, 7); 5980 shift_n = DecodeImmShift (type, imm5, shift_t); 5981 5982 // if m == 15 then UNPREDICTABLE; 5983 if (m == 15) 5984 return false; 5985 5986 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5987 if (wback && ((n == 15) || (n == t))) 5988 return false; 5989 } 5990 break; 5991 5992 5993 default: 5994 return false; 5995 } 5996 5997 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5998 if (!success) 5999 return false; 6000 6001 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6002 if (!success) 6003 return false; 6004 6005 addr_t offset_addr; 6006 addr_t address; 6007 6008 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6009 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6010 if (!success) 6011 return false; 6012 6013 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6014 if (add) 6015 offset_addr = Rn + offset; 6016 else 6017 offset_addr = Rn - offset; 6018 6019 // address = if index then offset_addr else R[n]; 6020 if (index) 6021 address = offset_addr; 6022 else 6023 address = Rn; 6024 6025 // data = MemU[address,4]; 6026 RegisterInfo base_reg; 6027 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6028 6029 EmulateInstruction::Context context; 6030 context.type = eContextRegisterLoad; 6031 context.SetRegisterPlusOffset (base_reg, address - Rn); 6032 6033 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6034 if (!success) 6035 return false; 6036 6037 // if wback then R[n] = offset_addr; 6038 if (wback) 6039 { 6040 context.type = eContextAdjustBaseRegister; 6041 context.SetAddress (offset_addr); 6042 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6043 return false; 6044 } 6045 6046 // if t == 15 then 6047 if (t == 15) 6048 { 6049 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6050 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6051 { 6052 context.type = eContextRegisterLoad; 6053 context.SetRegisterPlusOffset (base_reg, address - Rn); 6054 LoadWritePC (context, data); 6055 } 6056 else 6057 return false; 6058 } 6059 // elsif UnalignedSupport() || address<1:0> = '00' then 6060 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6061 { 6062 // R[t] = data; 6063 context.type = eContextRegisterLoad; 6064 context.SetRegisterPlusOffset (base_reg, address - Rn); 6065 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6066 return false; 6067 } 6068 else // Can only apply before ARMv7 6069 { 6070 // if CurrentInstrSet() == InstrSet_ARM then 6071 if (CurrentInstrSet () == eModeARM) 6072 { 6073 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6074 data = ROR (data, Bits32 (address, 1, 0), &success); 6075 if (!success) 6076 return false; 6077 context.type = eContextRegisterLoad; 6078 context.SetImmediate (data); 6079 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6080 return false; 6081 } 6082 else 6083 { 6084 // R[t] = bits(32) UNKNOWN; 6085 WriteBits32Unknown (t); 6086 } 6087 } 6088 } 6089 return true; 6090 } 6091 6092 // LDRB (immediate, Thumb) 6093 bool 6094 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6095 { 6096 #if 0 6097 if ConditionPassed() then 6098 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6099 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6100 address = if index then offset_addr else R[n]; 6101 R[t] = ZeroExtend(MemU[address,1], 32); 6102 if wback then R[n] = offset_addr; 6103 #endif 6104 6105 bool success = false; 6106 6107 if (ConditionPassed(opcode)) 6108 { 6109 uint32_t t; 6110 uint32_t n; 6111 uint32_t imm32; 6112 bool index; 6113 bool add; 6114 bool wback; 6115 6116 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6117 switch (encoding) 6118 { 6119 case eEncodingT1: 6120 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6121 t = Bits32 (opcode, 2, 0); 6122 n = Bits32 (opcode, 5, 3); 6123 imm32 = Bits32 (opcode, 10, 6); 6124 6125 // index = TRUE; add = TRUE; wback = FALSE; 6126 index = true; 6127 add = true; 6128 wback= false; 6129 6130 break; 6131 6132 case eEncodingT2: 6133 // if Rt == '1111' then SEE PLD; 6134 // if Rn == '1111' then SEE LDRB (literal); 6135 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6136 t = Bits32 (opcode, 15, 12); 6137 n = Bits32 (opcode, 19, 16); 6138 imm32 = Bits32 (opcode, 11, 0); 6139 6140 // index = TRUE; add = TRUE; wback = FALSE; 6141 index = true; 6142 add = true; 6143 wback = false; 6144 6145 // if t == 13 then UNPREDICTABLE; 6146 if (t == 13) 6147 return false; 6148 6149 break; 6150 6151 case eEncodingT3: 6152 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6153 // if Rn == '1111' then SEE LDRB (literal); 6154 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6155 // if P == '0' && W == '0' then UNDEFINED; 6156 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6157 return false; 6158 6159 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6160 t = Bits32 (opcode, 15, 12); 6161 n = Bits32 (opcode, 19, 16); 6162 imm32 = Bits32 (opcode, 7, 0); 6163 6164 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6165 index = BitIsSet (opcode, 10); 6166 add = BitIsSet (opcode, 9); 6167 wback = BitIsSet (opcode, 8); 6168 6169 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6170 if (BadReg (t) || (wback && (n == t))) 6171 return false; 6172 6173 break; 6174 6175 default: 6176 return false; 6177 } 6178 6179 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6180 if (!success) 6181 return false; 6182 6183 addr_t address; 6184 addr_t offset_addr; 6185 6186 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6187 if (add) 6188 offset_addr = Rn + imm32; 6189 else 6190 offset_addr = Rn - imm32; 6191 6192 // address = if index then offset_addr else R[n]; 6193 if (index) 6194 address = offset_addr; 6195 else 6196 address = Rn; 6197 6198 // R[t] = ZeroExtend(MemU[address,1], 32); 6199 RegisterInfo base_reg; 6200 RegisterInfo data_reg; 6201 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6202 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6203 6204 EmulateInstruction::Context context; 6205 context.type = eContextRegisterLoad; 6206 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6207 6208 uint64_t data = MemURead (context, address, 1, 0, &success); 6209 if (!success) 6210 return false; 6211 6212 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6213 return false; 6214 6215 // if wback then R[n] = offset_addr; 6216 if (wback) 6217 { 6218 context.type = eContextAdjustBaseRegister; 6219 context.SetAddress (offset_addr); 6220 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6221 return false; 6222 } 6223 } 6224 return true; 6225 } 6226 6227 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6228 // zero-extends it to form a 32-bit word and writes it to a register. 6229 bool 6230 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6231 { 6232 #if 0 6233 if ConditionPassed() then 6234 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6235 base = Align(PC,4); 6236 address = if add then (base + imm32) else (base - imm32); 6237 R[t] = ZeroExtend(MemU[address,1], 32); 6238 #endif 6239 6240 bool success = false; 6241 6242 if (ConditionPassed(opcode)) 6243 { 6244 uint32_t t; 6245 uint32_t imm32; 6246 bool add; 6247 switch (encoding) 6248 { 6249 case eEncodingT1: 6250 // if Rt == '1111' then SEE PLD; 6251 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6252 t = Bits32 (opcode, 15, 12); 6253 imm32 = Bits32 (opcode, 11, 0); 6254 add = BitIsSet (opcode, 23); 6255 6256 // if t == 13 then UNPREDICTABLE; 6257 if (t == 13) 6258 return false; 6259 6260 break; 6261 6262 case eEncodingA1: 6263 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6264 t = Bits32 (opcode, 15, 12); 6265 imm32 = Bits32 (opcode, 11, 0); 6266 add = BitIsSet (opcode, 23); 6267 6268 // if t == 15 then UNPREDICTABLE; 6269 if (t == 15) 6270 return false; 6271 break; 6272 6273 default: 6274 return false; 6275 } 6276 6277 // base = Align(PC,4); 6278 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6279 if (!success) 6280 return false; 6281 6282 uint32_t base = AlignPC (pc_val); 6283 6284 addr_t address; 6285 // address = if add then (base + imm32) else (base - imm32); 6286 if (add) 6287 address = base + imm32; 6288 else 6289 address = base - imm32; 6290 6291 // R[t] = ZeroExtend(MemU[address,1], 32); 6292 EmulateInstruction::Context context; 6293 context.type = eContextRelativeBranchImmediate; 6294 context.SetImmediate (address - base); 6295 6296 uint64_t data = MemURead (context, address, 1, 0, &success); 6297 if (!success) 6298 return false; 6299 6300 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6301 return false; 6302 } 6303 return true; 6304 } 6305 6306 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6307 // memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6308 // optionally be shifted. 6309 bool 6310 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6311 { 6312 #if 0 6313 if ConditionPassed() then 6314 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6315 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6316 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6317 address = if index then offset_addr else R[n]; 6318 R[t] = ZeroExtend(MemU[address,1],32); 6319 if wback then R[n] = offset_addr; 6320 #endif 6321 6322 bool success = false; 6323 6324 if (ConditionPassed(opcode)) 6325 { 6326 uint32_t t; 6327 uint32_t n; 6328 uint32_t m; 6329 bool index; 6330 bool add; 6331 bool wback; 6332 ARM_ShifterType shift_t; 6333 uint32_t shift_n; 6334 6335 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6336 switch (encoding) 6337 { 6338 case eEncodingT1: 6339 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6340 t = Bits32 (opcode, 2, 0); 6341 n = Bits32 (opcode, 5, 3); 6342 m = Bits32 (opcode, 8, 6); 6343 6344 // index = TRUE; add = TRUE; wback = FALSE; 6345 index = true; 6346 add = true; 6347 wback = false; 6348 6349 // (shift_t, shift_n) = (SRType_LSL, 0); 6350 shift_t = SRType_LSL; 6351 shift_n = 0; 6352 break; 6353 6354 case eEncodingT2: 6355 // if Rt == '1111' then SEE PLD; 6356 // if Rn == '1111' then SEE LDRB (literal); 6357 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6358 t = Bits32 (opcode, 15, 12); 6359 n = Bits32 (opcode, 19, 16); 6360 m = Bits32 (opcode, 3, 0); 6361 6362 // index = TRUE; add = TRUE; wback = FALSE; 6363 index = true; 6364 add = true; 6365 wback = false; 6366 6367 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6368 shift_t = SRType_LSL; 6369 shift_n = Bits32 (opcode, 5, 4); 6370 6371 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6372 if ((t == 13) || BadReg (m)) 6373 return false; 6374 break; 6375 6376 case eEncodingA1: 6377 { 6378 // if P == '0' && W == '1' then SEE LDRBT; 6379 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6380 t = Bits32 (opcode, 15, 12); 6381 n = Bits32 (opcode, 19, 16); 6382 m = Bits32 (opcode, 3, 0); 6383 6384 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6385 index = BitIsSet (opcode, 24); 6386 add = BitIsSet (opcode, 23); 6387 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6388 6389 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6390 uint32_t type = Bits32 (opcode, 6, 5); 6391 uint32_t imm5 = Bits32 (opcode, 11, 7); 6392 shift_n = DecodeImmShift (type, imm5, shift_t); 6393 6394 // if t == 15 || m == 15 then UNPREDICTABLE; 6395 if ((t == 15) || (m == 15)) 6396 return false; 6397 6398 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6399 if (wback && ((n == 15) || (n == t))) 6400 return false; 6401 } 6402 break; 6403 6404 default: 6405 return false; 6406 } 6407 6408 addr_t offset_addr; 6409 addr_t address; 6410 6411 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6412 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6413 if (!success) 6414 return false; 6415 6416 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6417 if (!success) 6418 return false; 6419 6420 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6421 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6422 if (!success) 6423 return false; 6424 6425 if (add) 6426 offset_addr = Rn + offset; 6427 else 6428 offset_addr = Rn - offset; 6429 6430 // address = if index then offset_addr else R[n]; 6431 if (index) 6432 address = offset_addr; 6433 else 6434 address = Rn; 6435 6436 // R[t] = ZeroExtend(MemU[address,1],32); 6437 RegisterInfo base_reg; 6438 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6439 6440 EmulateInstruction::Context context; 6441 context.type = eContextRegisterLoad; 6442 context.SetRegisterPlusOffset (base_reg, address - Rn); 6443 6444 uint64_t data = MemURead (context, address, 1, 0, &success); 6445 if (!success) 6446 return false; 6447 6448 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6449 return false; 6450 6451 // if wback then R[n] = offset_addr; 6452 if (wback) 6453 { 6454 context.type = eContextAdjustBaseRegister; 6455 context.SetAddress (offset_addr); 6456 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6457 return false; 6458 } 6459 } 6460 return true; 6461 } 6462 6463 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6464 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6465 // post-indexed, or pre-indexed addressing. 6466 bool 6467 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6468 { 6469 #if 0 6470 if ConditionPassed() then 6471 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6472 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6473 address = if index then offset_addr else R[n]; 6474 data = MemU[address,2]; 6475 if wback then R[n] = offset_addr; 6476 if UnalignedSupport() || address<0> = '0' then 6477 R[t] = ZeroExtend(data, 32); 6478 else // Can only apply before ARMv7 6479 R[t] = bits(32) UNKNOWN; 6480 #endif 6481 6482 6483 bool success = false; 6484 6485 if (ConditionPassed(opcode)) 6486 { 6487 uint32_t t; 6488 uint32_t n; 6489 uint32_t imm32; 6490 bool index; 6491 bool add; 6492 bool wback; 6493 6494 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6495 switch (encoding) 6496 { 6497 case eEncodingT1: 6498 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6499 t = Bits32 (opcode, 2, 0); 6500 n = Bits32 (opcode, 5, 3); 6501 imm32 = Bits32 (opcode, 10, 6) << 1; 6502 6503 // index = TRUE; add = TRUE; wback = FALSE; 6504 index = true; 6505 add = true; 6506 wback = false; 6507 6508 break; 6509 6510 case eEncodingT2: 6511 // if Rt == '1111' then SEE "Unallocated memory hints"; 6512 // if Rn == '1111' then SEE LDRH (literal); 6513 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6514 t = Bits32 (opcode, 15, 12); 6515 n = Bits32 (opcode, 19, 16); 6516 imm32 = Bits32 (opcode, 11, 0); 6517 6518 // index = TRUE; add = TRUE; wback = FALSE; 6519 index = true; 6520 add = true; 6521 wback = false; 6522 6523 // if t == 13 then UNPREDICTABLE; 6524 if (t == 13) 6525 return false; 6526 break; 6527 6528 case eEncodingT3: 6529 // if Rn == '1111' then SEE LDRH (literal); 6530 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6531 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6532 // if P == '0' && W == '0' then UNDEFINED; 6533 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6534 return false; 6535 6536 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6537 t = Bits32 (opcode, 15, 12); 6538 n = Bits32 (opcode, 19, 16); 6539 imm32 = Bits32 (opcode, 7, 0); 6540 6541 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6542 index = BitIsSet (opcode, 10); 6543 add = BitIsSet (opcode, 9); 6544 wback = BitIsSet (opcode, 8); 6545 6546 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6547 if (BadReg (t) || (wback && (n == t))) 6548 return false; 6549 break; 6550 6551 default: 6552 return false; 6553 } 6554 6555 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6556 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6557 if (!success) 6558 return false; 6559 6560 addr_t offset_addr; 6561 addr_t address; 6562 6563 if (add) 6564 offset_addr = Rn + imm32; 6565 else 6566 offset_addr = Rn - imm32; 6567 6568 // address = if index then offset_addr else R[n]; 6569 if (index) 6570 address = offset_addr; 6571 else 6572 address = Rn; 6573 6574 // data = MemU[address,2]; 6575 RegisterInfo base_reg; 6576 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6577 6578 EmulateInstruction::Context context; 6579 context.type = eContextRegisterLoad; 6580 context.SetRegisterPlusOffset (base_reg, address - Rn); 6581 6582 uint64_t data = MemURead (context, address, 2, 0, &success); 6583 if (!success) 6584 return false; 6585 6586 // if wback then R[n] = offset_addr; 6587 if (wback) 6588 { 6589 context.type = eContextAdjustBaseRegister; 6590 context.SetAddress (offset_addr); 6591 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6592 return false; 6593 } 6594 6595 // if UnalignedSupport() || address<0> = '0' then 6596 if (UnalignedSupport () || BitIsClear (address, 0)) 6597 { 6598 // R[t] = ZeroExtend(data, 32); 6599 context.type = eContextRegisterLoad; 6600 context.SetRegisterPlusOffset (base_reg, address - Rn); 6601 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6602 return false; 6603 } 6604 else // Can only apply before ARMv7 6605 { 6606 // R[t] = bits(32) UNKNOWN; 6607 WriteBits32Unknown (t); 6608 } 6609 } 6610 return true; 6611 } 6612 6613 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6614 // zero-extends it to form a 32-bit word, and writes it to a register. 6615 bool 6616 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6617 { 6618 #if 0 6619 if ConditionPassed() then 6620 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6621 base = Align(PC,4); 6622 address = if add then (base + imm32) else (base - imm32); 6623 data = MemU[address,2]; 6624 if UnalignedSupport() || address<0> = '0' then 6625 R[t] = ZeroExtend(data, 32); 6626 else // Can only apply before ARMv7 6627 R[t] = bits(32) UNKNOWN; 6628 #endif 6629 6630 bool success = false; 6631 6632 if (ConditionPassed(opcode)) 6633 { 6634 uint32_t t; 6635 uint32_t imm32; 6636 bool add; 6637 6638 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6639 switch (encoding) 6640 { 6641 case eEncodingT1: 6642 // if Rt == '1111' then SEE "Unallocated memory hints"; 6643 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6644 t = Bits32 (opcode, 15, 12); 6645 imm32 = Bits32 (opcode, 11, 0); 6646 add = BitIsSet (opcode, 23); 6647 6648 // if t == 13 then UNPREDICTABLE; 6649 if (t == 13) 6650 return false; 6651 6652 break; 6653 6654 case eEncodingA1: 6655 { 6656 uint32_t imm4H = Bits32 (opcode, 11, 8); 6657 uint32_t imm4L = Bits32 (opcode, 3, 0); 6658 6659 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6660 t = Bits32 (opcode, 15, 12); 6661 imm32 = (imm4H << 4) | imm4L; 6662 add = BitIsSet (opcode, 23); 6663 6664 // if t == 15 then UNPREDICTABLE; 6665 if (t == 15) 6666 return false; 6667 break; 6668 } 6669 6670 default: 6671 return false; 6672 } 6673 6674 // base = Align(PC,4); 6675 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6676 if (!success) 6677 return false; 6678 6679 addr_t base = AlignPC (pc_value); 6680 addr_t address; 6681 6682 // address = if add then (base + imm32) else (base - imm32); 6683 if (add) 6684 address = base + imm32; 6685 else 6686 address = base - imm32; 6687 6688 // data = MemU[address,2]; 6689 RegisterInfo base_reg; 6690 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6691 6692 EmulateInstruction::Context context; 6693 context.type = eContextRegisterLoad; 6694 context.SetRegisterPlusOffset (base_reg, address - base); 6695 6696 uint64_t data = MemURead (context, address, 2, 0, &success); 6697 if (!success) 6698 return false; 6699 6700 6701 // if UnalignedSupport() || address<0> = '0' then 6702 if (UnalignedSupport () || BitIsClear (address, 0)) 6703 { 6704 // R[t] = ZeroExtend(data, 32); 6705 context.type = eContextRegisterLoad; 6706 context.SetRegisterPlusOffset (base_reg, address - base); 6707 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6708 return false; 6709 6710 } 6711 else // Can only apply before ARMv7 6712 { 6713 // R[t] = bits(32) UNKNOWN; 6714 WriteBits32Unknown (t); 6715 } 6716 } 6717 return true; 6718 } 6719 6720 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6721 // from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6722 // be shifted left by 0, 1, 2, or 3 bits. 6723 bool 6724 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6725 { 6726 #if 0 6727 if ConditionPassed() then 6728 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6729 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6730 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6731 address = if index then offset_addr else R[n]; 6732 data = MemU[address,2]; 6733 if wback then R[n] = offset_addr; 6734 if UnalignedSupport() || address<0> = '0' then 6735 R[t] = ZeroExtend(data, 32); 6736 else // Can only apply before ARMv7 6737 R[t] = bits(32) UNKNOWN; 6738 #endif 6739 6740 bool success = false; 6741 6742 if (ConditionPassed(opcode)) 6743 { 6744 uint32_t t; 6745 uint32_t n; 6746 uint32_t m; 6747 bool index; 6748 bool add; 6749 bool wback; 6750 ARM_ShifterType shift_t; 6751 uint32_t shift_n; 6752 6753 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6754 switch (encoding) 6755 { 6756 case eEncodingT1: 6757 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6758 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6759 t = Bits32 (opcode, 2, 0); 6760 n = Bits32 (opcode, 5, 3); 6761 m = Bits32 (opcode, 8, 6); 6762 6763 // index = TRUE; add = TRUE; wback = FALSE; 6764 index = true; 6765 add = true; 6766 wback = false; 6767 6768 // (shift_t, shift_n) = (SRType_LSL, 0); 6769 shift_t = SRType_LSL; 6770 shift_n = 0; 6771 6772 break; 6773 6774 case eEncodingT2: 6775 // if Rn == '1111' then SEE LDRH (literal); 6776 // if Rt == '1111' then SEE "Unallocated memory hints"; 6777 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6778 t = Bits32 (opcode, 15, 12); 6779 n = Bits32 (opcode, 19, 16); 6780 m = Bits32 (opcode, 3, 0); 6781 6782 // index = TRUE; add = TRUE; wback = FALSE; 6783 index = true; 6784 add = true; 6785 wback = false; 6786 6787 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6788 shift_t = SRType_LSL; 6789 shift_n = Bits32 (opcode, 5, 4); 6790 6791 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6792 if ((t == 13) || BadReg (m)) 6793 return false; 6794 break; 6795 6796 case eEncodingA1: 6797 // if P == '0' && W == '1' then SEE LDRHT; 6798 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6799 t = Bits32 (opcode, 15, 12); 6800 n = Bits32 (opcode, 19, 16); 6801 m = Bits32 (opcode, 3, 0); 6802 6803 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6804 index = BitIsSet (opcode, 24); 6805 add = BitIsSet (opcode, 23); 6806 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6807 6808 // (shift_t, shift_n) = (SRType_LSL, 0); 6809 shift_t = SRType_LSL; 6810 shift_n = 0; 6811 6812 // if t == 15 || m == 15 then UNPREDICTABLE; 6813 if ((t == 15) || (m == 15)) 6814 return false; 6815 6816 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6817 if (wback && ((n == 15) || (n == t))) 6818 return false; 6819 6820 break; 6821 6822 default: 6823 return false; 6824 } 6825 6826 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6827 6828 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6829 if (!success) 6830 return false; 6831 6832 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6833 if (!success) 6834 return false; 6835 6836 addr_t offset_addr; 6837 addr_t address; 6838 6839 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6840 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6841 if (!success) 6842 return false; 6843 6844 if (add) 6845 offset_addr = Rn + offset; 6846 else 6847 offset_addr = Rn - offset; 6848 6849 // address = if index then offset_addr else R[n]; 6850 if (index) 6851 address = offset_addr; 6852 else 6853 address = Rn; 6854 6855 // data = MemU[address,2]; 6856 RegisterInfo base_reg; 6857 RegisterInfo offset_reg; 6858 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6859 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 6860 6861 EmulateInstruction::Context context; 6862 context.type = eContextRegisterLoad; 6863 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6864 uint64_t data = MemURead (context, address, 2, 0, &success); 6865 if (!success) 6866 return false; 6867 6868 // if wback then R[n] = offset_addr; 6869 if (wback) 6870 { 6871 context.type = eContextAdjustBaseRegister; 6872 context.SetAddress (offset_addr); 6873 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6874 return false; 6875 } 6876 6877 // if UnalignedSupport() || address<0> = '0' then 6878 if (UnalignedSupport() || BitIsClear (address, 0)) 6879 { 6880 // R[t] = ZeroExtend(data, 32); 6881 context.type = eContextRegisterLoad; 6882 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6883 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6884 return false; 6885 } 6886 else // Can only apply before ARMv7 6887 { 6888 // R[t] = bits(32) UNKNOWN; 6889 WriteBits32Unknown (t); 6890 } 6891 } 6892 return true; 6893 } 6894 6895 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6896 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6897 // or pre-indexed addressing. 6898 bool 6899 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6900 { 6901 #if 0 6902 if ConditionPassed() then 6903 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6904 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6905 address = if index then offset_addr else R[n]; 6906 R[t] = SignExtend(MemU[address,1], 32); 6907 if wback then R[n] = offset_addr; 6908 #endif 6909 6910 bool success = false; 6911 6912 if (ConditionPassed(opcode)) 6913 { 6914 uint32_t t; 6915 uint32_t n; 6916 uint32_t imm32; 6917 bool index; 6918 bool add; 6919 bool wback; 6920 6921 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6922 switch (encoding) 6923 { 6924 case eEncodingT1: 6925 // if Rt == '1111' then SEE PLI; 6926 // if Rn == '1111' then SEE LDRSB (literal); 6927 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6928 t = Bits32 (opcode, 15, 12); 6929 n = Bits32 (opcode, 19, 16); 6930 imm32 = Bits32 (opcode, 11, 0); 6931 6932 // index = TRUE; add = TRUE; wback = FALSE; 6933 index = true; 6934 add = true; 6935 wback = false; 6936 6937 // if t == 13 then UNPREDICTABLE; 6938 if (t == 13) 6939 return false; 6940 6941 break; 6942 6943 case eEncodingT2: 6944 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 6945 // if Rn == '1111' then SEE LDRSB (literal); 6946 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 6947 // if P == '0' && W == '0' then UNDEFINED; 6948 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6949 return false; 6950 6951 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6952 t = Bits32 (opcode, 15, 12); 6953 n = Bits32 (opcode, 19, 16); 6954 imm32 = Bits32 (opcode, 7, 0); 6955 6956 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6957 index = BitIsSet (opcode, 10); 6958 add = BitIsSet (opcode, 9); 6959 wback = BitIsSet (opcode, 8); 6960 6961 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6962 if (((t == 13) || ((t == 15) 6963 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 6964 || (wback && (n == t))) 6965 return false; 6966 6967 break; 6968 6969 case eEncodingA1: 6970 { 6971 // if Rn == '1111' then SEE LDRSB (literal); 6972 // if P == '0' && W == '1' then SEE LDRSBT; 6973 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 6974 t = Bits32 (opcode, 15, 12); 6975 n = Bits32 (opcode, 19, 16); 6976 6977 uint32_t imm4H = Bits32 (opcode, 11, 8); 6978 uint32_t imm4L = Bits32 (opcode, 3, 0); 6979 imm32 = (imm4H << 4) | imm4L; 6980 6981 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6982 index = BitIsSet (opcode, 24); 6983 add = BitIsSet (opcode, 23); 6984 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6985 6986 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 6987 if ((t == 15) || (wback && (n == t))) 6988 return false; 6989 6990 break; 6991 } 6992 6993 default: 6994 return false; 6995 } 6996 6997 uint64_t Rn = ReadCoreReg (n, &success); 6998 if (!success) 6999 return false; 7000 7001 addr_t offset_addr; 7002 addr_t address; 7003 7004 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7005 if (add) 7006 offset_addr = Rn + imm32; 7007 else 7008 offset_addr = Rn - imm32; 7009 7010 // address = if index then offset_addr else R[n]; 7011 if (index) 7012 address = offset_addr; 7013 else 7014 address = Rn; 7015 7016 // R[t] = SignExtend(MemU[address,1], 32); 7017 RegisterInfo base_reg; 7018 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7019 7020 EmulateInstruction::Context context; 7021 context.type = eContextRegisterLoad; 7022 context.SetRegisterPlusOffset (base_reg, address - Rn); 7023 7024 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7025 if (!success) 7026 return false; 7027 7028 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7029 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7030 return false; 7031 7032 // if wback then R[n] = offset_addr; 7033 if (wback) 7034 { 7035 context.type = eContextAdjustBaseRegister; 7036 context.SetAddress (offset_addr); 7037 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7038 return false; 7039 } 7040 } 7041 7042 return true; 7043 } 7044 7045 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7046 // sign-extends it to form a 32-bit word, and writes tit to a register. 7047 bool 7048 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7049 { 7050 #if 0 7051 if ConditionPassed() then 7052 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7053 base = Align(PC,4); 7054 address = if add then (base + imm32) else (base - imm32); 7055 R[t] = SignExtend(MemU[address,1], 32); 7056 #endif 7057 7058 bool success = false; 7059 7060 if (ConditionPassed(opcode)) 7061 { 7062 uint32_t t; 7063 uint32_t imm32; 7064 bool add; 7065 7066 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7067 switch (encoding) 7068 { 7069 case eEncodingT1: 7070 // if Rt == '1111' then SEE PLI; 7071 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7072 t = Bits32 (opcode, 15, 12); 7073 imm32 = Bits32 (opcode, 11, 0); 7074 add = BitIsSet (opcode, 23); 7075 7076 // if t == 13 then UNPREDICTABLE; 7077 if (t == 13) 7078 return false; 7079 7080 break; 7081 7082 case eEncodingA1: 7083 { 7084 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7085 t = Bits32 (opcode, 15, 12); 7086 uint32_t imm4H = Bits32 (opcode, 11, 8); 7087 uint32_t imm4L = Bits32 (opcode, 3, 0); 7088 imm32 = (imm4H << 4) | imm4L; 7089 add = BitIsSet (opcode, 23); 7090 7091 // if t == 15 then UNPREDICTABLE; 7092 if (t == 15) 7093 return false; 7094 7095 break; 7096 } 7097 7098 default: 7099 return false; 7100 } 7101 7102 // base = Align(PC,4); 7103 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7104 if (!success) 7105 return false; 7106 uint64_t base = AlignPC (pc_value); 7107 7108 // address = if add then (base + imm32) else (base - imm32); 7109 addr_t address; 7110 if (add) 7111 address = base + imm32; 7112 else 7113 address = base - imm32; 7114 7115 // R[t] = SignExtend(MemU[address,1], 32); 7116 RegisterInfo base_reg; 7117 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7118 7119 EmulateInstruction::Context context; 7120 context.type = eContextRegisterLoad; 7121 context.SetRegisterPlusOffset (base_reg, address - base); 7122 7123 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7124 if (!success) 7125 return false; 7126 7127 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7128 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7129 return false; 7130 } 7131 return true; 7132 } 7133 7134 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7135 // memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7136 // shifted left by 0, 1, 2, or 3 bits. 7137 bool 7138 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7139 { 7140 #if 0 7141 if ConditionPassed() then 7142 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7143 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7144 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7145 address = if index then offset_addr else R[n]; 7146 R[t] = SignExtend(MemU[address,1], 32); 7147 if wback then R[n] = offset_addr; 7148 #endif 7149 7150 bool success = false; 7151 7152 if (ConditionPassed(opcode)) 7153 { 7154 uint32_t t; 7155 uint32_t n; 7156 uint32_t m; 7157 bool index; 7158 bool add; 7159 bool wback; 7160 ARM_ShifterType shift_t; 7161 uint32_t shift_n; 7162 7163 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7164 switch (encoding) 7165 { 7166 case eEncodingT1: 7167 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7168 t = Bits32 (opcode, 2, 0); 7169 n = Bits32 (opcode, 5, 3); 7170 m = Bits32 (opcode, 8, 6); 7171 7172 // index = TRUE; add = TRUE; wback = FALSE; 7173 index = true; 7174 add = true; 7175 wback = false; 7176 7177 // (shift_t, shift_n) = (SRType_LSL, 0); 7178 shift_t = SRType_LSL; 7179 shift_n = 0; 7180 7181 break; 7182 7183 case eEncodingT2: 7184 // if Rt == '1111' then SEE PLI; 7185 // if Rn == '1111' then SEE LDRSB (literal); 7186 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7187 t = Bits32 (opcode, 15, 12); 7188 n = Bits32 (opcode, 19, 16); 7189 m = Bits32 (opcode, 3, 0); 7190 7191 // index = TRUE; add = TRUE; wback = FALSE; 7192 index = true; 7193 add = true; 7194 wback = false; 7195 7196 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7197 shift_t = SRType_LSL; 7198 shift_n = Bits32 (opcode, 5, 4); 7199 7200 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7201 if ((t == 13) || BadReg (m)) 7202 return false; 7203 break; 7204 7205 case eEncodingA1: 7206 // if P == '0' && W == '1' then SEE LDRSBT; 7207 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7208 t = Bits32 (opcode, 15, 12); 7209 n = Bits32 (opcode, 19, 16); 7210 m = Bits32 (opcode, 3, 0); 7211 7212 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7213 index = BitIsSet (opcode, 24); 7214 add = BitIsSet (opcode, 23); 7215 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7216 7217 // (shift_t, shift_n) = (SRType_LSL, 0); 7218 shift_t = SRType_LSL; 7219 shift_n = 0; 7220 7221 // if t == 15 || m == 15 then UNPREDICTABLE; 7222 if ((t == 15) || (m == 15)) 7223 return false; 7224 7225 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7226 if (wback && ((n == 15) || (n == t))) 7227 return false; 7228 break; 7229 7230 default: 7231 return false; 7232 } 7233 7234 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7235 if (!success) 7236 return false; 7237 7238 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7239 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7240 if (!success) 7241 return false; 7242 7243 addr_t offset_addr; 7244 addr_t address; 7245 7246 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7247 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7248 if (!success) 7249 return false; 7250 7251 if (add) 7252 offset_addr = Rn + offset; 7253 else 7254 offset_addr = Rn - offset; 7255 7256 // address = if index then offset_addr else R[n]; 7257 if (index) 7258 address = offset_addr; 7259 else 7260 address = Rn; 7261 7262 // R[t] = SignExtend(MemU[address,1], 32); 7263 RegisterInfo base_reg; 7264 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7265 RegisterInfo offset_reg; 7266 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7267 7268 EmulateInstruction::Context context; 7269 context.type = eContextRegisterLoad; 7270 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7271 7272 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7273 if (!success) 7274 return false; 7275 7276 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7277 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7278 return false; 7279 7280 // if wback then R[n] = offset_addr; 7281 if (wback) 7282 { 7283 context.type = eContextAdjustBaseRegister; 7284 context.SetAddress (offset_addr); 7285 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7286 return false; 7287 } 7288 } 7289 return true; 7290 } 7291 7292 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7293 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7294 // pre-indexed addressing. 7295 bool 7296 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7297 { 7298 #if 0 7299 if ConditionPassed() then 7300 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7301 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7302 address = if index then offset_addr else R[n]; 7303 data = MemU[address,2]; 7304 if wback then R[n] = offset_addr; 7305 if UnalignedSupport() || address<0> = '0' then 7306 R[t] = SignExtend(data, 32); 7307 else // Can only apply before ARMv7 7308 R[t] = bits(32) UNKNOWN; 7309 #endif 7310 7311 bool success = false; 7312 7313 if (ConditionPassed(opcode)) 7314 { 7315 uint32_t t; 7316 uint32_t n; 7317 uint32_t imm32; 7318 bool index; 7319 bool add; 7320 bool wback; 7321 7322 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7323 switch (encoding) 7324 { 7325 case eEncodingT1: 7326 // if Rn == '1111' then SEE LDRSH (literal); 7327 // if Rt == '1111' then SEE "Unallocated memory hints"; 7328 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7329 t = Bits32 (opcode, 15, 12); 7330 n = Bits32 (opcode, 19, 16); 7331 imm32 = Bits32 (opcode, 11, 0); 7332 7333 // index = TRUE; add = TRUE; wback = FALSE; 7334 index = true; 7335 add = true; 7336 wback = false; 7337 7338 // if t == 13 then UNPREDICTABLE; 7339 if (t == 13) 7340 return false; 7341 7342 break; 7343 7344 case eEncodingT2: 7345 // if Rn == '1111' then SEE LDRSH (literal); 7346 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7347 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7348 // if P == '0' && W == '0' then UNDEFINED; 7349 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7350 return false; 7351 7352 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7353 t = Bits32 (opcode, 15, 12); 7354 n = Bits32 (opcode, 19, 16); 7355 imm32 = Bits32 (opcode, 7, 0); 7356 7357 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7358 index = BitIsSet (opcode, 10); 7359 add = BitIsSet (opcode, 9); 7360 wback = BitIsSet (opcode, 8); 7361 7362 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7363 if (BadReg (t) || (wback && (n == t))) 7364 return false; 7365 7366 break; 7367 7368 case eEncodingA1: 7369 { 7370 // if Rn == '1111' then SEE LDRSH (literal); 7371 // if P == '0' && W == '1' then SEE LDRSHT; 7372 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7373 t = Bits32 (opcode, 15, 12); 7374 n = Bits32 (opcode, 19, 16); 7375 uint32_t imm4H = Bits32 (opcode, 11,8); 7376 uint32_t imm4L = Bits32 (opcode, 3, 0); 7377 imm32 = (imm4H << 4) | imm4L; 7378 7379 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7380 index = BitIsSet (opcode, 24); 7381 add = BitIsSet (opcode, 23); 7382 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7383 7384 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7385 if ((t == 15) || (wback && (n == t))) 7386 return false; 7387 7388 break; 7389 } 7390 7391 default: 7392 return false; 7393 } 7394 7395 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7396 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7397 if (!success) 7398 return false; 7399 7400 addr_t offset_addr; 7401 if (add) 7402 offset_addr = Rn + imm32; 7403 else 7404 offset_addr = Rn - imm32; 7405 7406 // address = if index then offset_addr else R[n]; 7407 addr_t address; 7408 if (index) 7409 address = offset_addr; 7410 else 7411 address = Rn; 7412 7413 // data = MemU[address,2]; 7414 RegisterInfo base_reg; 7415 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7416 7417 EmulateInstruction::Context context; 7418 context.type = eContextRegisterLoad; 7419 context.SetRegisterPlusOffset (base_reg, address - Rn); 7420 7421 uint64_t data = MemURead (context, address, 2, 0, &success); 7422 if (!success) 7423 return false; 7424 7425 // if wback then R[n] = offset_addr; 7426 if (wback) 7427 { 7428 context.type = eContextAdjustBaseRegister; 7429 context.SetAddress (offset_addr); 7430 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7431 return false; 7432 } 7433 7434 // if UnalignedSupport() || address<0> = '0' then 7435 if (UnalignedSupport() || BitIsClear (address, 0)) 7436 { 7437 // R[t] = SignExtend(data, 32); 7438 int64_t signed_data = llvm::SignExtend64<16>(data); 7439 context.type = eContextRegisterLoad; 7440 context.SetRegisterPlusOffset (base_reg, address - Rn); 7441 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7442 return false; 7443 } 7444 else // Can only apply before ARMv7 7445 { 7446 // R[t] = bits(32) UNKNOWN; 7447 WriteBits32Unknown (t); 7448 } 7449 } 7450 return true; 7451 } 7452 7453 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7454 // sign-extends it to from a 32-bit word, and writes it to a register. 7455 bool 7456 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7457 { 7458 #if 0 7459 if ConditionPassed() then 7460 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7461 base = Align(PC,4); 7462 address = if add then (base + imm32) else (base - imm32); 7463 data = MemU[address,2]; 7464 if UnalignedSupport() || address<0> = '0' then 7465 R[t] = SignExtend(data, 32); 7466 else // Can only apply before ARMv7 7467 R[t] = bits(32) UNKNOWN; 7468 #endif 7469 7470 bool success = false; 7471 7472 if (ConditionPassed(opcode)) 7473 { 7474 uint32_t t; 7475 uint32_t imm32; 7476 bool add; 7477 7478 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7479 switch (encoding) 7480 { 7481 case eEncodingT1: 7482 // if Rt == '1111' then SEE "Unallocated memory hints"; 7483 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7484 t = Bits32 (opcode, 15, 12); 7485 imm32 = Bits32 (opcode, 11, 0); 7486 add = BitIsSet (opcode, 23); 7487 7488 // if t == 13 then UNPREDICTABLE; 7489 if (t == 13) 7490 return false; 7491 7492 break; 7493 7494 case eEncodingA1: 7495 { 7496 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7497 t = Bits32 (opcode, 15, 12); 7498 uint32_t imm4H = Bits32 (opcode, 11, 8); 7499 uint32_t imm4L = Bits32 (opcode, 3, 0); 7500 imm32 = (imm4H << 4) | imm4L; 7501 add = BitIsSet (opcode, 23); 7502 7503 // if t == 15 then UNPREDICTABLE; 7504 if (t == 15) 7505 return false; 7506 7507 break; 7508 } 7509 default: 7510 return false; 7511 } 7512 7513 // base = Align(PC,4); 7514 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7515 if (!success) 7516 return false; 7517 7518 uint64_t base = AlignPC (pc_value); 7519 7520 addr_t address; 7521 // address = if add then (base + imm32) else (base - imm32); 7522 if (add) 7523 address = base + imm32; 7524 else 7525 address = base - imm32; 7526 7527 // data = MemU[address,2]; 7528 RegisterInfo base_reg; 7529 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7530 7531 EmulateInstruction::Context context; 7532 context.type = eContextRegisterLoad; 7533 context.SetRegisterPlusOffset (base_reg, imm32); 7534 7535 uint64_t data = MemURead (context, address, 2, 0, &success); 7536 if (!success) 7537 return false; 7538 7539 // if UnalignedSupport() || address<0> = '0' then 7540 if (UnalignedSupport() || BitIsClear (address, 0)) 7541 { 7542 // R[t] = SignExtend(data, 32); 7543 int64_t signed_data = llvm::SignExtend64<16>(data); 7544 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7545 return false; 7546 } 7547 else // Can only apply before ARMv7 7548 { 7549 // R[t] = bits(32) UNKNOWN; 7550 WriteBits32Unknown (t); 7551 } 7552 } 7553 return true; 7554 } 7555 7556 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7557 // from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7558 // shifted left by 0, 1, 2, or 3 bits. 7559 bool 7560 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7561 { 7562 #if 0 7563 if ConditionPassed() then 7564 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7565 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7566 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7567 address = if index then offset_addr else R[n]; 7568 data = MemU[address,2]; 7569 if wback then R[n] = offset_addr; 7570 if UnalignedSupport() || address<0> = '0' then 7571 R[t] = SignExtend(data, 32); 7572 else // Can only apply before ARMv7 7573 R[t] = bits(32) UNKNOWN; 7574 #endif 7575 7576 bool success = false; 7577 7578 if (ConditionPassed(opcode)) 7579 { 7580 uint32_t t; 7581 uint32_t n; 7582 uint32_t m; 7583 bool index; 7584 bool add; 7585 bool wback; 7586 ARM_ShifterType shift_t; 7587 uint32_t shift_n; 7588 7589 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7590 switch (encoding) 7591 { 7592 case eEncodingT1: 7593 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7594 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7595 t = Bits32 (opcode, 2, 0); 7596 n = Bits32 (opcode, 5, 3); 7597 m = Bits32 (opcode, 8, 6); 7598 7599 // index = TRUE; add = TRUE; wback = FALSE; 7600 index = true; 7601 add = true; 7602 wback = false; 7603 7604 // (shift_t, shift_n) = (SRType_LSL, 0); 7605 shift_t = SRType_LSL; 7606 shift_n = 0; 7607 7608 break; 7609 7610 case eEncodingT2: 7611 // if Rn == '1111' then SEE LDRSH (literal); 7612 // if Rt == '1111' then SEE "Unallocated memory hints"; 7613 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7614 t = Bits32 (opcode, 15, 12); 7615 n = Bits32 (opcode, 19, 16); 7616 m = Bits32 (opcode, 3, 0); 7617 7618 // index = TRUE; add = TRUE; wback = FALSE; 7619 index = true; 7620 add = true; 7621 wback = false; 7622 7623 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7624 shift_t = SRType_LSL; 7625 shift_n = Bits32 (opcode, 5, 4); 7626 7627 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7628 if ((t == 13) || BadReg (m)) 7629 return false; 7630 7631 break; 7632 7633 case eEncodingA1: 7634 // if P == '0' && W == '1' then SEE LDRSHT; 7635 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7636 t = Bits32 (opcode, 15, 12); 7637 n = Bits32 (opcode, 19, 16); 7638 m = Bits32 (opcode, 3, 0); 7639 7640 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7641 index = BitIsSet (opcode, 24); 7642 add = BitIsSet (opcode, 23); 7643 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7644 7645 // (shift_t, shift_n) = (SRType_LSL, 0); 7646 shift_t = SRType_LSL; 7647 shift_n = 0; 7648 7649 // if t == 15 || m == 15 then UNPREDICTABLE; 7650 if ((t == 15) || (m == 15)) 7651 return false; 7652 7653 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7654 if (wback && ((n == 15) || (n == t))) 7655 return false; 7656 7657 break; 7658 7659 default: 7660 return false; 7661 } 7662 7663 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7664 if (!success) 7665 return false; 7666 7667 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7668 if (!success) 7669 return false; 7670 7671 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7672 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7673 if (!success) 7674 return false; 7675 7676 addr_t offset_addr; 7677 addr_t address; 7678 7679 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7680 if (add) 7681 offset_addr = Rn + offset; 7682 else 7683 offset_addr = Rn - offset; 7684 7685 // address = if index then offset_addr else R[n]; 7686 if (index) 7687 address = offset_addr; 7688 else 7689 address = Rn; 7690 7691 // data = MemU[address,2]; 7692 RegisterInfo base_reg; 7693 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7694 7695 RegisterInfo offset_reg; 7696 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7697 7698 EmulateInstruction::Context context; 7699 context.type = eContextRegisterLoad; 7700 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7701 7702 uint64_t data = MemURead (context, address, 2, 0, &success); 7703 if (!success) 7704 return false; 7705 7706 // if wback then R[n] = offset_addr; 7707 if (wback) 7708 { 7709 context.type = eContextAdjustBaseRegister; 7710 context.SetAddress (offset_addr); 7711 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7712 return false; 7713 } 7714 7715 // if UnalignedSupport() || address<0> = '0' then 7716 if (UnalignedSupport() || BitIsClear (address, 0)) 7717 { 7718 // R[t] = SignExtend(data, 32); 7719 context.type = eContextRegisterLoad; 7720 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7721 7722 int64_t signed_data = llvm::SignExtend64<16>(data); 7723 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7724 return false; 7725 } 7726 else // Can only apply before ARMv7 7727 { 7728 // R[t] = bits(32) UNKNOWN; 7729 WriteBits32Unknown (t); 7730 } 7731 } 7732 return true; 7733 } 7734 7735 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7736 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7737 bool 7738 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7739 { 7740 #if 0 7741 if ConditionPassed() then 7742 EncodingSpecificOperations(); 7743 rotated = ROR(R[m], rotation); 7744 R[d] = SignExtend(rotated<7:0>, 32); 7745 #endif 7746 7747 bool success = false; 7748 7749 if (ConditionPassed(opcode)) 7750 { 7751 uint32_t d; 7752 uint32_t m; 7753 uint32_t rotation; 7754 7755 // EncodingSpecificOperations(); 7756 switch (encoding) 7757 { 7758 case eEncodingT1: 7759 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7760 d = Bits32 (opcode, 2, 0); 7761 m = Bits32 (opcode, 5, 3); 7762 rotation = 0; 7763 7764 break; 7765 7766 case eEncodingT2: 7767 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7768 d = Bits32 (opcode, 11, 8); 7769 m = Bits32 (opcode, 3, 0); 7770 rotation = Bits32 (opcode, 5, 4) << 3; 7771 7772 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7773 if (BadReg (d) || BadReg (m)) 7774 return false; 7775 7776 break; 7777 7778 case eEncodingA1: 7779 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7780 d = Bits32 (opcode, 15, 12); 7781 m = Bits32 (opcode, 3, 0); 7782 rotation = Bits32 (opcode, 11, 10) << 3; 7783 7784 // if d == 15 || m == 15 then UNPREDICTABLE; 7785 if ((d == 15) || (m == 15)) 7786 return false; 7787 7788 break; 7789 7790 default: 7791 return false; 7792 } 7793 7794 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7795 if (!success) 7796 return false; 7797 7798 // rotated = ROR(R[m], rotation); 7799 uint64_t rotated = ROR (Rm, rotation, &success); 7800 if (!success) 7801 return false; 7802 7803 // R[d] = SignExtend(rotated<7:0>, 32); 7804 int64_t data = llvm::SignExtend64<8>(rotated); 7805 7806 RegisterInfo source_reg; 7807 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7808 7809 EmulateInstruction::Context context; 7810 context.type = eContextRegisterLoad; 7811 context.SetRegister (source_reg); 7812 7813 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7814 return false; 7815 } 7816 return true; 7817 } 7818 7819 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7820 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7821 bool 7822 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7823 { 7824 #if 0 7825 if ConditionPassed() then 7826 EncodingSpecificOperations(); 7827 rotated = ROR(R[m], rotation); 7828 R[d] = SignExtend(rotated<15:0>, 32); 7829 #endif 7830 7831 bool success = false; 7832 7833 if (ConditionPassed(opcode)) 7834 { 7835 uint32_t d; 7836 uint32_t m; 7837 uint32_t rotation; 7838 7839 // EncodingSpecificOperations(); 7840 switch (encoding) 7841 { 7842 case eEncodingT1: 7843 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7844 d = Bits32 (opcode, 2, 0); 7845 m = Bits32 (opcode, 5, 3); 7846 rotation = 0; 7847 7848 break; 7849 7850 case eEncodingT2: 7851 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7852 d = Bits32 (opcode, 11, 8); 7853 m = Bits32 (opcode, 3, 0); 7854 rotation = Bits32 (opcode, 5, 4) << 3; 7855 7856 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7857 if (BadReg (d) || BadReg (m)) 7858 return false; 7859 7860 break; 7861 7862 case eEncodingA1: 7863 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7864 d = Bits32 (opcode, 15, 12); 7865 m = Bits32 (opcode, 3, 0); 7866 rotation = Bits32 (opcode, 11, 10) << 3; 7867 7868 // if d == 15 || m == 15 then UNPREDICTABLE; 7869 if ((d == 15) || (m == 15)) 7870 return false; 7871 7872 break; 7873 7874 default: 7875 return false; 7876 } 7877 7878 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7879 if (!success) 7880 return false; 7881 7882 // rotated = ROR(R[m], rotation); 7883 uint64_t rotated = ROR (Rm, rotation, &success); 7884 if (!success) 7885 return false; 7886 7887 // R[d] = SignExtend(rotated<15:0>, 32); 7888 RegisterInfo source_reg; 7889 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7890 7891 EmulateInstruction::Context context; 7892 context.type = eContextRegisterLoad; 7893 context.SetRegister (source_reg); 7894 7895 int64_t data = llvm::SignExtend64<16> (rotated); 7896 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7897 return false; 7898 } 7899 7900 return true; 7901 } 7902 7903 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 7904 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7905 bool 7906 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 7907 { 7908 #if 0 7909 if ConditionPassed() then 7910 EncodingSpecificOperations(); 7911 rotated = ROR(R[m], rotation); 7912 R[d] = ZeroExtend(rotated<7:0>, 32); 7913 #endif 7914 7915 bool success = false; 7916 7917 if (ConditionPassed(opcode)) 7918 { 7919 uint32_t d; 7920 uint32_t m; 7921 uint32_t rotation; 7922 7923 // EncodingSpecificOperations(); 7924 switch (encoding) 7925 { 7926 case eEncodingT1: 7927 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7928 d = Bits32 (opcode, 2, 0); 7929 m = Bits32 (opcode, 5, 3); 7930 rotation = 0; 7931 7932 break; 7933 7934 case eEncodingT2: 7935 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7936 d = Bits32 (opcode, 11, 8); 7937 m = Bits32 (opcode, 3, 0); 7938 rotation = Bits32 (opcode, 5, 4) << 3; 7939 7940 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7941 if (BadReg (d) || BadReg (m)) 7942 return false; 7943 7944 break; 7945 7946 case eEncodingA1: 7947 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7948 d = Bits32 (opcode, 15, 12); 7949 m = Bits32 (opcode, 3, 0); 7950 rotation = Bits32 (opcode, 11, 10) << 3; 7951 7952 // if d == 15 || m == 15 then UNPREDICTABLE; 7953 if ((d == 15) || (m == 15)) 7954 return false; 7955 7956 break; 7957 7958 default: 7959 return false; 7960 } 7961 7962 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7963 if (!success) 7964 return false; 7965 7966 // rotated = ROR(R[m], rotation); 7967 uint64_t rotated = ROR (Rm, rotation, &success); 7968 if (!success) 7969 return false; 7970 7971 // R[d] = ZeroExtend(rotated<7:0>, 32); 7972 RegisterInfo source_reg; 7973 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7974 7975 EmulateInstruction::Context context; 7976 context.type = eContextRegisterLoad; 7977 context.SetRegister (source_reg); 7978 7979 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 7980 return false; 7981 } 7982 return true; 7983 } 7984 7985 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 7986 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7987 bool 7988 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 7989 { 7990 #if 0 7991 if ConditionPassed() then 7992 EncodingSpecificOperations(); 7993 rotated = ROR(R[m], rotation); 7994 R[d] = ZeroExtend(rotated<15:0>, 32); 7995 #endif 7996 7997 bool success = false; 7998 7999 if (ConditionPassed(opcode)) 8000 { 8001 uint32_t d; 8002 uint32_t m; 8003 uint32_t rotation; 8004 8005 switch (encoding) 8006 { 8007 case eEncodingT1: 8008 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8009 d = Bits32 (opcode, 2, 0); 8010 m = Bits32 (opcode, 5, 3); 8011 rotation = 0; 8012 8013 break; 8014 8015 case eEncodingT2: 8016 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8017 d = Bits32 (opcode, 11, 8); 8018 m = Bits32 (opcode, 3, 0); 8019 rotation = Bits32 (opcode, 5, 4) << 3; 8020 8021 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8022 if (BadReg (d) || BadReg (m)) 8023 return false; 8024 8025 break; 8026 8027 case eEncodingA1: 8028 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8029 d = Bits32 (opcode, 15, 12); 8030 m = Bits32 (opcode, 3, 0); 8031 rotation = Bits32 (opcode, 11, 10) << 3; 8032 8033 // if d == 15 || m == 15 then UNPREDICTABLE; 8034 if ((d == 15) || (m == 15)) 8035 return false; 8036 8037 break; 8038 8039 default: 8040 return false; 8041 } 8042 8043 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8044 if (!success) 8045 return false; 8046 8047 // rotated = ROR(R[m], rotation); 8048 uint64_t rotated = ROR (Rm, rotation, &success); 8049 if (!success) 8050 return false; 8051 8052 // R[d] = ZeroExtend(rotated<15:0>, 32); 8053 RegisterInfo source_reg; 8054 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8055 8056 EmulateInstruction::Context context; 8057 context.type = eContextRegisterLoad; 8058 context.SetRegister (source_reg); 8059 8060 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8061 return false; 8062 } 8063 return true; 8064 } 8065 8066 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8067 // word respectively. 8068 bool 8069 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8070 { 8071 #if 0 8072 if ConditionPassed() then 8073 EncodingSpecificOperations(); 8074 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8075 UNPREDICTABLE; 8076 else 8077 address = if increment then R[n] else R[n]-8; 8078 if wordhigher then address = address+4; 8079 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8080 BranchWritePC(MemA[address,4]); 8081 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8082 #endif 8083 8084 bool success = false; 8085 8086 if (ConditionPassed(opcode)) 8087 { 8088 uint32_t n; 8089 bool wback; 8090 bool increment; 8091 bool wordhigher; 8092 8093 // EncodingSpecificOperations(); 8094 switch (encoding) 8095 { 8096 case eEncodingT1: 8097 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8098 n = Bits32 (opcode, 19, 16); 8099 wback = BitIsSet (opcode, 21); 8100 increment = false; 8101 wordhigher = false; 8102 8103 // if n == 15 then UNPREDICTABLE; 8104 if (n == 15) 8105 return false; 8106 8107 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8108 if (InITBlock() && !LastInITBlock()) 8109 return false; 8110 8111 break; 8112 8113 case eEncodingT2: 8114 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8115 n = Bits32 (opcode, 19, 16); 8116 wback = BitIsSet (opcode, 21); 8117 increment = true; 8118 wordhigher = false; 8119 8120 // if n == 15 then UNPREDICTABLE; 8121 if (n == 15) 8122 return false; 8123 8124 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8125 if (InITBlock() && !LastInITBlock()) 8126 return false; 8127 8128 break; 8129 8130 case eEncodingA1: 8131 // n = UInt(Rn); 8132 n = Bits32 (opcode, 19, 16); 8133 8134 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8135 wback = BitIsSet (opcode, 21); 8136 increment = BitIsSet (opcode, 23); 8137 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8138 8139 // if n == 15 then UNPREDICTABLE; 8140 if (n == 15) 8141 return false; 8142 8143 break; 8144 8145 default: 8146 return false; 8147 } 8148 8149 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8150 if (!CurrentModeIsPrivileged ()) 8151 // UNPREDICTABLE; 8152 return false; 8153 else 8154 { 8155 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8156 if (!success) 8157 return false; 8158 8159 addr_t address; 8160 // address = if increment then R[n] else R[n]-8; 8161 if (increment) 8162 address = Rn; 8163 else 8164 address = Rn - 8; 8165 8166 // if wordhigher then address = address+4; 8167 if (wordhigher) 8168 address = address + 4; 8169 8170 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8171 RegisterInfo base_reg; 8172 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8173 8174 EmulateInstruction::Context context; 8175 context.type = eContextReturnFromException; 8176 context.SetRegisterPlusOffset (base_reg, address - Rn); 8177 8178 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8179 if (!success) 8180 return false; 8181 8182 CPSRWriteByInstr (data, 15, true); 8183 8184 // BranchWritePC(MemA[address,4]); 8185 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8186 if (!success) 8187 return false; 8188 8189 BranchWritePC (context, data2); 8190 8191 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8192 if (wback) 8193 { 8194 context.type = eContextAdjustBaseRegister; 8195 if (increment) 8196 { 8197 context.SetOffset (8); 8198 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8199 return false; 8200 } 8201 else 8202 { 8203 context.SetOffset (-8); 8204 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8205 return false; 8206 } 8207 } // if wback 8208 } 8209 } // if ConditionPassed() 8210 return true; 8211 } 8212 8213 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8214 // and writes the result to the destination register. It can optionally update the condition flags based on 8215 // the result. 8216 bool 8217 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8218 { 8219 #if 0 8220 // ARM pseudo code... 8221 if ConditionPassed() then 8222 EncodingSpecificOperations(); 8223 result = R[n] EOR imm32; 8224 if d == 15 then // Can only occur for ARM encoding 8225 ALUWritePC(result); // setflags is always FALSE here 8226 else 8227 R[d] = result; 8228 if setflags then 8229 APSR.N = result<31>; 8230 APSR.Z = IsZeroBit(result); 8231 APSR.C = carry; 8232 // APSR.V unchanged 8233 #endif 8234 8235 bool success = false; 8236 8237 if (ConditionPassed(opcode)) 8238 { 8239 uint32_t Rd, Rn; 8240 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8241 bool setflags; 8242 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8243 switch (encoding) 8244 { 8245 case eEncodingT1: 8246 Rd = Bits32(opcode, 11, 8); 8247 Rn = Bits32(opcode, 19, 16); 8248 setflags = BitIsSet(opcode, 20); 8249 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8250 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8251 if (Rd == 15 && setflags) 8252 return EmulateTEQImm (opcode, eEncodingT1); 8253 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8254 return false; 8255 break; 8256 case eEncodingA1: 8257 Rd = Bits32(opcode, 15, 12); 8258 Rn = Bits32(opcode, 19, 16); 8259 setflags = BitIsSet(opcode, 20); 8260 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8261 8262 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8263 if (Rd == 15 && setflags) 8264 return EmulateSUBSPcLrEtc (opcode, encoding); 8265 break; 8266 default: 8267 return false; 8268 } 8269 8270 // Read the first operand. 8271 uint32_t val1 = ReadCoreReg(Rn, &success); 8272 if (!success) 8273 return false; 8274 8275 uint32_t result = val1 ^ imm32; 8276 8277 EmulateInstruction::Context context; 8278 context.type = EmulateInstruction::eContextImmediate; 8279 context.SetNoArgs (); 8280 8281 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8282 return false; 8283 } 8284 return true; 8285 } 8286 8287 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8288 // optionally-shifted register value, and writes the result to the destination register. 8289 // It can optionally update the condition flags based on the result. 8290 bool 8291 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8292 { 8293 #if 0 8294 // ARM pseudo code... 8295 if ConditionPassed() then 8296 EncodingSpecificOperations(); 8297 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8298 result = R[n] EOR shifted; 8299 if d == 15 then // Can only occur for ARM encoding 8300 ALUWritePC(result); // setflags is always FALSE here 8301 else 8302 R[d] = result; 8303 if setflags then 8304 APSR.N = result<31>; 8305 APSR.Z = IsZeroBit(result); 8306 APSR.C = carry; 8307 // APSR.V unchanged 8308 #endif 8309 8310 bool success = false; 8311 8312 if (ConditionPassed(opcode)) 8313 { 8314 uint32_t Rd, Rn, Rm; 8315 ARM_ShifterType shift_t; 8316 uint32_t shift_n; // the shift applied to the value read from Rm 8317 bool setflags; 8318 uint32_t carry; 8319 switch (encoding) 8320 { 8321 case eEncodingT1: 8322 Rd = Rn = Bits32(opcode, 2, 0); 8323 Rm = Bits32(opcode, 5, 3); 8324 setflags = !InITBlock(); 8325 shift_t = SRType_LSL; 8326 shift_n = 0; 8327 break; 8328 case eEncodingT2: 8329 Rd = Bits32(opcode, 11, 8); 8330 Rn = Bits32(opcode, 19, 16); 8331 Rm = Bits32(opcode, 3, 0); 8332 setflags = BitIsSet(opcode, 20); 8333 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8334 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8335 if (Rd == 15 && setflags) 8336 return EmulateTEQReg (opcode, eEncodingT1); 8337 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8338 return false; 8339 break; 8340 case eEncodingA1: 8341 Rd = Bits32(opcode, 15, 12); 8342 Rn = Bits32(opcode, 19, 16); 8343 Rm = Bits32(opcode, 3, 0); 8344 setflags = BitIsSet(opcode, 20); 8345 shift_n = DecodeImmShiftARM(opcode, shift_t); 8346 8347 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8348 if (Rd == 15 && setflags) 8349 return EmulateSUBSPcLrEtc (opcode, encoding); 8350 break; 8351 default: 8352 return false; 8353 } 8354 8355 // Read the first operand. 8356 uint32_t val1 = ReadCoreReg(Rn, &success); 8357 if (!success) 8358 return false; 8359 8360 // Read the second operand. 8361 uint32_t val2 = ReadCoreReg(Rm, &success); 8362 if (!success) 8363 return false; 8364 8365 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8366 if (!success) 8367 return false; 8368 uint32_t result = val1 ^ shifted; 8369 8370 EmulateInstruction::Context context; 8371 context.type = EmulateInstruction::eContextImmediate; 8372 context.SetNoArgs (); 8373 8374 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8375 return false; 8376 } 8377 return true; 8378 } 8379 8380 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8381 // writes the result to the destination register. It can optionally update the condition flags based 8382 // on the result. 8383 bool 8384 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8385 { 8386 #if 0 8387 // ARM pseudo code... 8388 if ConditionPassed() then 8389 EncodingSpecificOperations(); 8390 result = R[n] OR imm32; 8391 if d == 15 then // Can only occur for ARM encoding 8392 ALUWritePC(result); // setflags is always FALSE here 8393 else 8394 R[d] = result; 8395 if setflags then 8396 APSR.N = result<31>; 8397 APSR.Z = IsZeroBit(result); 8398 APSR.C = carry; 8399 // APSR.V unchanged 8400 #endif 8401 8402 bool success = false; 8403 8404 if (ConditionPassed(opcode)) 8405 { 8406 uint32_t Rd, Rn; 8407 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8408 bool setflags; 8409 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8410 switch (encoding) 8411 { 8412 case eEncodingT1: 8413 Rd = Bits32(opcode, 11, 8); 8414 Rn = Bits32(opcode, 19, 16); 8415 setflags = BitIsSet(opcode, 20); 8416 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8417 // if Rn == '1111' then SEE MOV (immediate); 8418 if (Rn == 15) 8419 return EmulateMOVRdImm (opcode, eEncodingT2); 8420 if (BadReg(Rd) || Rn == 13) 8421 return false; 8422 break; 8423 case eEncodingA1: 8424 Rd = Bits32(opcode, 15, 12); 8425 Rn = Bits32(opcode, 19, 16); 8426 setflags = BitIsSet(opcode, 20); 8427 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8428 8429 if (Rd == 15 && setflags) 8430 return EmulateSUBSPcLrEtc (opcode, encoding); 8431 break; 8432 default: 8433 return false; 8434 } 8435 8436 // Read the first operand. 8437 uint32_t val1 = ReadCoreReg(Rn, &success); 8438 if (!success) 8439 return false; 8440 8441 uint32_t result = val1 | imm32; 8442 8443 EmulateInstruction::Context context; 8444 context.type = EmulateInstruction::eContextImmediate; 8445 context.SetNoArgs (); 8446 8447 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8448 return false; 8449 } 8450 return true; 8451 } 8452 8453 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8454 // value, and writes the result to the destination register. It can optionally update the condition flags based 8455 // on the result. 8456 bool 8457 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8458 { 8459 #if 0 8460 // ARM pseudo code... 8461 if ConditionPassed() then 8462 EncodingSpecificOperations(); 8463 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8464 result = R[n] OR shifted; 8465 if d == 15 then // Can only occur for ARM encoding 8466 ALUWritePC(result); // setflags is always FALSE here 8467 else 8468 R[d] = result; 8469 if setflags then 8470 APSR.N = result<31>; 8471 APSR.Z = IsZeroBit(result); 8472 APSR.C = carry; 8473 // APSR.V unchanged 8474 #endif 8475 8476 bool success = false; 8477 8478 if (ConditionPassed(opcode)) 8479 { 8480 uint32_t Rd, Rn, Rm; 8481 ARM_ShifterType shift_t; 8482 uint32_t shift_n; // the shift applied to the value read from Rm 8483 bool setflags; 8484 uint32_t carry; 8485 switch (encoding) 8486 { 8487 case eEncodingT1: 8488 Rd = Rn = Bits32(opcode, 2, 0); 8489 Rm = Bits32(opcode, 5, 3); 8490 setflags = !InITBlock(); 8491 shift_t = SRType_LSL; 8492 shift_n = 0; 8493 break; 8494 case eEncodingT2: 8495 Rd = Bits32(opcode, 11, 8); 8496 Rn = Bits32(opcode, 19, 16); 8497 Rm = Bits32(opcode, 3, 0); 8498 setflags = BitIsSet(opcode, 20); 8499 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8500 // if Rn == '1111' then SEE MOV (register); 8501 if (Rn == 15) 8502 return EmulateMOVRdRm (opcode, eEncodingT3); 8503 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8504 return false; 8505 break; 8506 case eEncodingA1: 8507 Rd = Bits32(opcode, 15, 12); 8508 Rn = Bits32(opcode, 19, 16); 8509 Rm = Bits32(opcode, 3, 0); 8510 setflags = BitIsSet(opcode, 20); 8511 shift_n = DecodeImmShiftARM(opcode, shift_t); 8512 8513 if (Rd == 15 && setflags) 8514 return EmulateSUBSPcLrEtc (opcode, encoding); 8515 break; 8516 default: 8517 return false; 8518 } 8519 8520 // Read the first operand. 8521 uint32_t val1 = ReadCoreReg(Rn, &success); 8522 if (!success) 8523 return false; 8524 8525 // Read the second operand. 8526 uint32_t val2 = ReadCoreReg(Rm, &success); 8527 if (!success) 8528 return false; 8529 8530 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8531 if (!success) 8532 return false; 8533 uint32_t result = val1 | shifted; 8534 8535 EmulateInstruction::Context context; 8536 context.type = EmulateInstruction::eContextImmediate; 8537 context.SetNoArgs (); 8538 8539 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8540 return false; 8541 } 8542 return true; 8543 } 8544 8545 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8546 // the destination register. It can optionally update the condition flags based on the result. 8547 bool 8548 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8549 { 8550 #if 0 8551 // ARM pseudo code... 8552 if ConditionPassed() then 8553 EncodingSpecificOperations(); 8554 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8555 if d == 15 then // Can only occur for ARM encoding 8556 ALUWritePC(result); // setflags is always FALSE here 8557 else 8558 R[d] = result; 8559 if setflags then 8560 APSR.N = result<31>; 8561 APSR.Z = IsZeroBit(result); 8562 APSR.C = carry; 8563 APSR.V = overflow; 8564 #endif 8565 8566 bool success = false; 8567 8568 uint32_t Rd; // the destination register 8569 uint32_t Rn; // the first operand 8570 bool setflags; 8571 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8572 switch (encoding) { 8573 case eEncodingT1: 8574 Rd = Bits32(opcode, 2, 0); 8575 Rn = Bits32(opcode, 5, 3); 8576 setflags = !InITBlock(); 8577 imm32 = 0; 8578 break; 8579 case eEncodingT2: 8580 Rd = Bits32(opcode, 11, 8); 8581 Rn = Bits32(opcode, 19, 16); 8582 setflags = BitIsSet(opcode, 20); 8583 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8584 if (BadReg(Rd) || BadReg(Rn)) 8585 return false; 8586 break; 8587 case eEncodingA1: 8588 Rd = Bits32(opcode, 15, 12); 8589 Rn = Bits32(opcode, 19, 16); 8590 setflags = BitIsSet(opcode, 20); 8591 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8592 8593 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8594 if (Rd == 15 && setflags) 8595 return EmulateSUBSPcLrEtc (opcode, encoding); 8596 break; 8597 default: 8598 return false; 8599 } 8600 // Read the register value from the operand register Rn. 8601 uint32_t reg_val = ReadCoreReg(Rn, &success); 8602 if (!success) 8603 return false; 8604 8605 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8606 8607 EmulateInstruction::Context context; 8608 context.type = EmulateInstruction::eContextImmediate; 8609 context.SetNoArgs (); 8610 8611 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8612 return false; 8613 8614 return true; 8615 } 8616 8617 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8618 // result to the destination register. It can optionally update the condition flags based on the result. 8619 bool 8620 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8621 { 8622 #if 0 8623 // ARM pseudo code... 8624 if ConditionPassed() then 8625 EncodingSpecificOperations(); 8626 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8627 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8628 if d == 15 then // Can only occur for ARM encoding 8629 ALUWritePC(result); // setflags is always FALSE here 8630 else 8631 R[d] = result; 8632 if setflags then 8633 APSR.N = result<31>; 8634 APSR.Z = IsZeroBit(result); 8635 APSR.C = carry; 8636 APSR.V = overflow; 8637 #endif 8638 8639 bool success = false; 8640 8641 uint32_t Rd; // the destination register 8642 uint32_t Rn; // the first operand 8643 uint32_t Rm; // the second operand 8644 bool setflags; 8645 ARM_ShifterType shift_t; 8646 uint32_t shift_n; // the shift applied to the value read from Rm 8647 switch (encoding) { 8648 case eEncodingT1: 8649 Rd = Bits32(opcode, 11, 8); 8650 Rn = Bits32(opcode, 19, 16); 8651 Rm = Bits32(opcode, 3, 0); 8652 setflags = BitIsSet(opcode, 20); 8653 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8654 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8655 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8656 return false; 8657 break; 8658 case eEncodingA1: 8659 Rd = Bits32(opcode, 15, 12); 8660 Rn = Bits32(opcode, 19, 16); 8661 Rm = Bits32(opcode, 3, 0); 8662 setflags = BitIsSet(opcode, 20); 8663 shift_n = DecodeImmShiftARM(opcode, shift_t); 8664 8665 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8666 if (Rd == 15 && setflags) 8667 return EmulateSUBSPcLrEtc (opcode, encoding); 8668 break; 8669 default: 8670 return false; 8671 } 8672 // Read the register value from register Rn. 8673 uint32_t val1 = ReadCoreReg(Rn, &success); 8674 if (!success) 8675 return false; 8676 8677 // Read the register value from register Rm. 8678 uint32_t val2 = ReadCoreReg(Rm, &success); 8679 if (!success) 8680 return false; 8681 8682 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8683 if (!success) 8684 return false; 8685 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8686 8687 EmulateInstruction::Context context; 8688 context.type = EmulateInstruction::eContextImmediate; 8689 context.SetNoArgs(); 8690 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8691 return false; 8692 8693 return true; 8694 } 8695 8696 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8697 // an immediate value, and writes the result to the destination register. It can optionally update the condition 8698 // flags based on the result. 8699 bool 8700 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8701 { 8702 #if 0 8703 // ARM pseudo code... 8704 if ConditionPassed() then 8705 EncodingSpecificOperations(); 8706 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8707 if d == 15 then 8708 ALUWritePC(result); // setflags is always FALSE here 8709 else 8710 R[d] = result; 8711 if setflags then 8712 APSR.N = result<31>; 8713 APSR.Z = IsZeroBit(result); 8714 APSR.C = carry; 8715 APSR.V = overflow; 8716 #endif 8717 8718 bool success = false; 8719 8720 uint32_t Rd; // the destination register 8721 uint32_t Rn; // the first operand 8722 bool setflags; 8723 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8724 switch (encoding) { 8725 case eEncodingA1: 8726 Rd = Bits32(opcode, 15, 12); 8727 Rn = Bits32(opcode, 19, 16); 8728 setflags = BitIsSet(opcode, 20); 8729 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8730 8731 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8732 if (Rd == 15 && setflags) 8733 return EmulateSUBSPcLrEtc (opcode, encoding); 8734 break; 8735 default: 8736 return false; 8737 } 8738 // Read the register value from the operand register Rn. 8739 uint32_t reg_val = ReadCoreReg(Rn, &success); 8740 if (!success) 8741 return false; 8742 8743 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8744 8745 EmulateInstruction::Context context; 8746 context.type = EmulateInstruction::eContextImmediate; 8747 context.SetNoArgs (); 8748 8749 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8750 return false; 8751 8752 return true; 8753 } 8754 8755 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8756 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8757 // condition flags based on the result. 8758 bool 8759 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8760 { 8761 #if 0 8762 // ARM pseudo code... 8763 if ConditionPassed() then 8764 EncodingSpecificOperations(); 8765 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8766 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8767 if d == 15 then 8768 ALUWritePC(result); // setflags is always FALSE here 8769 else 8770 R[d] = result; 8771 if setflags then 8772 APSR.N = result<31>; 8773 APSR.Z = IsZeroBit(result); 8774 APSR.C = carry; 8775 APSR.V = overflow; 8776 #endif 8777 8778 bool success = false; 8779 8780 uint32_t Rd; // the destination register 8781 uint32_t Rn; // the first operand 8782 uint32_t Rm; // the second operand 8783 bool setflags; 8784 ARM_ShifterType shift_t; 8785 uint32_t shift_n; // the shift applied to the value read from Rm 8786 switch (encoding) { 8787 case eEncodingA1: 8788 Rd = Bits32(opcode, 15, 12); 8789 Rn = Bits32(opcode, 19, 16); 8790 Rm = Bits32(opcode, 3, 0); 8791 setflags = BitIsSet(opcode, 20); 8792 shift_n = DecodeImmShiftARM(opcode, shift_t); 8793 8794 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8795 if (Rd == 15 && setflags) 8796 return EmulateSUBSPcLrEtc (opcode, encoding); 8797 break; 8798 default: 8799 return false; 8800 } 8801 // Read the register value from register Rn. 8802 uint32_t val1 = ReadCoreReg(Rn, &success); 8803 if (!success) 8804 return false; 8805 8806 // Read the register value from register Rm. 8807 uint32_t val2 = ReadCoreReg(Rm, &success); 8808 if (!success) 8809 return false; 8810 8811 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8812 if (!success) 8813 return false; 8814 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8815 8816 EmulateInstruction::Context context; 8817 context.type = EmulateInstruction::eContextImmediate; 8818 context.SetNoArgs(); 8819 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8820 return false; 8821 8822 return true; 8823 } 8824 8825 // Subtract with Carry (immediate) subtracts an immediate value and the value of 8826 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8827 // It can optionally update the condition flags based on the result. 8828 bool 8829 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8830 { 8831 #if 0 8832 // ARM pseudo code... 8833 if ConditionPassed() then 8834 EncodingSpecificOperations(); 8835 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8836 if d == 15 then // Can only occur for ARM encoding 8837 ALUWritePC(result); // setflags is always FALSE here 8838 else 8839 R[d] = result; 8840 if setflags then 8841 APSR.N = result<31>; 8842 APSR.Z = IsZeroBit(result); 8843 APSR.C = carry; 8844 APSR.V = overflow; 8845 #endif 8846 8847 bool success = false; 8848 8849 uint32_t Rd; // the destination register 8850 uint32_t Rn; // the first operand 8851 bool setflags; 8852 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8853 switch (encoding) { 8854 case eEncodingT1: 8855 Rd = Bits32(opcode, 11, 8); 8856 Rn = Bits32(opcode, 19, 16); 8857 setflags = BitIsSet(opcode, 20); 8858 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8859 if (BadReg(Rd) || BadReg(Rn)) 8860 return false; 8861 break; 8862 case eEncodingA1: 8863 Rd = Bits32(opcode, 15, 12); 8864 Rn = Bits32(opcode, 19, 16); 8865 setflags = BitIsSet(opcode, 20); 8866 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8867 8868 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8869 if (Rd == 15 && setflags) 8870 return EmulateSUBSPcLrEtc (opcode, encoding); 8871 break; 8872 default: 8873 return false; 8874 } 8875 // Read the register value from the operand register Rn. 8876 uint32_t reg_val = ReadCoreReg(Rn, &success); 8877 if (!success) 8878 return false; 8879 8880 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 8881 8882 EmulateInstruction::Context context; 8883 context.type = EmulateInstruction::eContextImmediate; 8884 context.SetNoArgs (); 8885 8886 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8887 return false; 8888 8889 return true; 8890 } 8891 8892 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 8893 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8894 // It can optionally update the condition flags based on the result. 8895 bool 8896 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 8897 { 8898 #if 0 8899 // ARM pseudo code... 8900 if ConditionPassed() then 8901 EncodingSpecificOperations(); 8902 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8903 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 8904 if d == 15 then // Can only occur for ARM encoding 8905 ALUWritePC(result); // setflags is always FALSE here 8906 else 8907 R[d] = result; 8908 if setflags then 8909 APSR.N = result<31>; 8910 APSR.Z = IsZeroBit(result); 8911 APSR.C = carry; 8912 APSR.V = overflow; 8913 #endif 8914 8915 bool success = false; 8916 8917 uint32_t Rd; // the destination register 8918 uint32_t Rn; // the first operand 8919 uint32_t Rm; // the second operand 8920 bool setflags; 8921 ARM_ShifterType shift_t; 8922 uint32_t shift_n; // the shift applied to the value read from Rm 8923 switch (encoding) { 8924 case eEncodingT1: 8925 Rd = Rn = Bits32(opcode, 2, 0); 8926 Rm = Bits32(opcode, 5, 3); 8927 setflags = !InITBlock(); 8928 shift_t = SRType_LSL; 8929 shift_n = 0; 8930 break; 8931 case eEncodingT2: 8932 Rd = Bits32(opcode, 11, 8); 8933 Rn = Bits32(opcode, 19, 16); 8934 Rm = Bits32(opcode, 3, 0); 8935 setflags = BitIsSet(opcode, 20); 8936 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8937 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8938 return false; 8939 break; 8940 case eEncodingA1: 8941 Rd = Bits32(opcode, 15, 12); 8942 Rn = Bits32(opcode, 19, 16); 8943 Rm = Bits32(opcode, 3, 0); 8944 setflags = BitIsSet(opcode, 20); 8945 shift_n = DecodeImmShiftARM(opcode, shift_t); 8946 8947 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8948 if (Rd == 15 && setflags) 8949 return EmulateSUBSPcLrEtc (opcode, encoding); 8950 break; 8951 default: 8952 return false; 8953 } 8954 // Read the register value from register Rn. 8955 uint32_t val1 = ReadCoreReg(Rn, &success); 8956 if (!success) 8957 return false; 8958 8959 // Read the register value from register Rm. 8960 uint32_t val2 = ReadCoreReg(Rm, &success); 8961 if (!success) 8962 return false; 8963 8964 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8965 if (!success) 8966 return false; 8967 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 8968 8969 EmulateInstruction::Context context; 8970 context.type = EmulateInstruction::eContextImmediate; 8971 context.SetNoArgs(); 8972 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8973 return false; 8974 8975 return true; 8976 } 8977 8978 // This instruction subtracts an immediate value from a register value, and writes the result 8979 // to the destination register. It can optionally update the condition flags based on the result. 8980 bool 8981 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 8982 { 8983 #if 0 8984 // ARM pseudo code... 8985 if ConditionPassed() then 8986 EncodingSpecificOperations(); 8987 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 8988 R[d] = result; 8989 if setflags then 8990 APSR.N = result<31>; 8991 APSR.Z = IsZeroBit(result); 8992 APSR.C = carry; 8993 APSR.V = overflow; 8994 #endif 8995 8996 bool success = false; 8997 8998 uint32_t Rd; // the destination register 8999 uint32_t Rn; // the first operand 9000 bool setflags; 9001 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9002 switch (encoding) { 9003 case eEncodingT1: 9004 Rd = Bits32(opcode, 2, 0); 9005 Rn = Bits32(opcode, 5, 3); 9006 setflags = !InITBlock(); 9007 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9008 break; 9009 case eEncodingT2: 9010 Rd = Rn = Bits32(opcode, 10, 8); 9011 setflags = !InITBlock(); 9012 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9013 break; 9014 case eEncodingT3: 9015 Rd = Bits32(opcode, 11, 8); 9016 Rn = Bits32(opcode, 19, 16); 9017 setflags = BitIsSet(opcode, 20); 9018 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9019 9020 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9021 if (Rd == 15 && setflags) 9022 return EmulateCMPImm (opcode, eEncodingT2); 9023 9024 // if Rn == '1101' then SEE SUB (SP minus immediate); 9025 if (Rn == 13) 9026 return EmulateSUBSPImm (opcode, eEncodingT2); 9027 9028 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9029 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9030 return false; 9031 break; 9032 case eEncodingT4: 9033 Rd = Bits32(opcode, 11, 8); 9034 Rn = Bits32(opcode, 19, 16); 9035 setflags = BitIsSet(opcode, 20); 9036 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9037 9038 // if Rn == '1111' then SEE ADR; 9039 if (Rn == 15) 9040 return EmulateADR (opcode, eEncodingT2); 9041 9042 // if Rn == '1101' then SEE SUB (SP minus immediate); 9043 if (Rn == 13) 9044 return EmulateSUBSPImm (opcode, eEncodingT3); 9045 9046 if (BadReg(Rd)) 9047 return false; 9048 break; 9049 default: 9050 return false; 9051 } 9052 // Read the register value from the operand register Rn. 9053 uint32_t reg_val = ReadCoreReg(Rn, &success); 9054 if (!success) 9055 return false; 9056 9057 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9058 9059 EmulateInstruction::Context context; 9060 context.type = EmulateInstruction::eContextImmediate; 9061 context.SetNoArgs (); 9062 9063 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9064 return false; 9065 9066 return true; 9067 } 9068 9069 // This instruction subtracts an immediate value from a register value, and writes the result 9070 // to the destination register. It can optionally update the condition flags based on the result. 9071 bool 9072 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9073 { 9074 #if 0 9075 // ARM pseudo code... 9076 if ConditionPassed() then 9077 EncodingSpecificOperations(); 9078 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9079 if d == 15 then 9080 ALUWritePC(result); // setflags is always FALSE here 9081 else 9082 R[d] = result; 9083 if setflags then 9084 APSR.N = result<31>; 9085 APSR.Z = IsZeroBit(result); 9086 APSR.C = carry; 9087 APSR.V = overflow; 9088 #endif 9089 9090 bool success = false; 9091 9092 uint32_t Rd; // the destination register 9093 uint32_t Rn; // the first operand 9094 bool setflags; 9095 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9096 switch (encoding) { 9097 case eEncodingA1: 9098 Rd = Bits32(opcode, 15, 12); 9099 Rn = Bits32(opcode, 19, 16); 9100 setflags = BitIsSet(opcode, 20); 9101 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9102 9103 // if Rn == '1111' && S == '0' then SEE ADR; 9104 if (Rn == 15 && !setflags) 9105 return EmulateADR (opcode, eEncodingA2); 9106 9107 // if Rn == '1101' then SEE SUB (SP minus immediate); 9108 if (Rn == 13) 9109 return EmulateSUBSPImm (opcode, eEncodingA1); 9110 9111 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9112 if (Rd == 15 && setflags) 9113 return EmulateSUBSPcLrEtc (opcode, encoding); 9114 break; 9115 default: 9116 return false; 9117 } 9118 // Read the register value from the operand register Rn. 9119 uint32_t reg_val = ReadCoreReg(Rn, &success); 9120 if (!success) 9121 return false; 9122 9123 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9124 9125 EmulateInstruction::Context context; 9126 context.type = EmulateInstruction::eContextImmediate; 9127 context.SetNoArgs (); 9128 9129 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9130 return false; 9131 9132 return true; 9133 } 9134 9135 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9136 // immediate value. It updates the condition flags based on the result, and discards the result. 9137 bool 9138 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9139 { 9140 #if 0 9141 // ARM pseudo code... 9142 if ConditionPassed() then 9143 EncodingSpecificOperations(); 9144 result = R[n] EOR imm32; 9145 APSR.N = result<31>; 9146 APSR.Z = IsZeroBit(result); 9147 APSR.C = carry; 9148 // APSR.V unchanged 9149 #endif 9150 9151 bool success = false; 9152 9153 if (ConditionPassed(opcode)) 9154 { 9155 uint32_t Rn; 9156 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9157 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9158 switch (encoding) 9159 { 9160 case eEncodingT1: 9161 Rn = Bits32(opcode, 19, 16); 9162 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9163 if (BadReg(Rn)) 9164 return false; 9165 break; 9166 case eEncodingA1: 9167 Rn = Bits32(opcode, 19, 16); 9168 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9169 break; 9170 default: 9171 return false; 9172 } 9173 9174 // Read the first operand. 9175 uint32_t val1 = ReadCoreReg(Rn, &success); 9176 if (!success) 9177 return false; 9178 9179 uint32_t result = val1 ^ imm32; 9180 9181 EmulateInstruction::Context context; 9182 context.type = EmulateInstruction::eContextImmediate; 9183 context.SetNoArgs (); 9184 9185 if (!WriteFlags(context, result, carry)) 9186 return false; 9187 } 9188 return true; 9189 } 9190 9191 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9192 // optionally-shifted register value. It updates the condition flags based on the result, and discards 9193 // the result. 9194 bool 9195 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9196 { 9197 #if 0 9198 // ARM pseudo code... 9199 if ConditionPassed() then 9200 EncodingSpecificOperations(); 9201 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9202 result = R[n] EOR shifted; 9203 APSR.N = result<31>; 9204 APSR.Z = IsZeroBit(result); 9205 APSR.C = carry; 9206 // APSR.V unchanged 9207 #endif 9208 9209 bool success = false; 9210 9211 if (ConditionPassed(opcode)) 9212 { 9213 uint32_t Rn, Rm; 9214 ARM_ShifterType shift_t; 9215 uint32_t shift_n; // the shift applied to the value read from Rm 9216 uint32_t carry; 9217 switch (encoding) 9218 { 9219 case eEncodingT1: 9220 Rn = Bits32(opcode, 19, 16); 9221 Rm = Bits32(opcode, 3, 0); 9222 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9223 if (BadReg(Rn) || BadReg(Rm)) 9224 return false; 9225 break; 9226 case eEncodingA1: 9227 Rn = Bits32(opcode, 19, 16); 9228 Rm = Bits32(opcode, 3, 0); 9229 shift_n = DecodeImmShiftARM(opcode, shift_t); 9230 break; 9231 default: 9232 return false; 9233 } 9234 9235 // Read the first operand. 9236 uint32_t val1 = ReadCoreReg(Rn, &success); 9237 if (!success) 9238 return false; 9239 9240 // Read the second operand. 9241 uint32_t val2 = ReadCoreReg(Rm, &success); 9242 if (!success) 9243 return false; 9244 9245 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9246 if (!success) 9247 return false; 9248 uint32_t result = val1 ^ shifted; 9249 9250 EmulateInstruction::Context context; 9251 context.type = EmulateInstruction::eContextImmediate; 9252 context.SetNoArgs (); 9253 9254 if (!WriteFlags(context, result, carry)) 9255 return false; 9256 } 9257 return true; 9258 } 9259 9260 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9261 // It updates the condition flags based on the result, and discards the result. 9262 bool 9263 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9264 { 9265 #if 0 9266 // ARM pseudo code... 9267 if ConditionPassed() then 9268 EncodingSpecificOperations(); 9269 result = R[n] AND imm32; 9270 APSR.N = result<31>; 9271 APSR.Z = IsZeroBit(result); 9272 APSR.C = carry; 9273 // APSR.V unchanged 9274 #endif 9275 9276 bool success = false; 9277 9278 if (ConditionPassed(opcode)) 9279 { 9280 uint32_t Rn; 9281 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9282 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9283 switch (encoding) 9284 { 9285 case eEncodingT1: 9286 Rn = Bits32(opcode, 19, 16); 9287 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9288 if (BadReg(Rn)) 9289 return false; 9290 break; 9291 case eEncodingA1: 9292 Rn = Bits32(opcode, 19, 16); 9293 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9294 break; 9295 default: 9296 return false; 9297 } 9298 9299 // Read the first operand. 9300 uint32_t val1 = ReadCoreReg(Rn, &success); 9301 if (!success) 9302 return false; 9303 9304 uint32_t result = val1 & imm32; 9305 9306 EmulateInstruction::Context context; 9307 context.type = EmulateInstruction::eContextImmediate; 9308 context.SetNoArgs (); 9309 9310 if (!WriteFlags(context, result, carry)) 9311 return false; 9312 } 9313 return true; 9314 } 9315 9316 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9317 // It updates the condition flags based on the result, and discards the result. 9318 bool 9319 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9320 { 9321 #if 0 9322 // ARM pseudo code... 9323 if ConditionPassed() then 9324 EncodingSpecificOperations(); 9325 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9326 result = R[n] AND shifted; 9327 APSR.N = result<31>; 9328 APSR.Z = IsZeroBit(result); 9329 APSR.C = carry; 9330 // APSR.V unchanged 9331 #endif 9332 9333 bool success = false; 9334 9335 if (ConditionPassed(opcode)) 9336 { 9337 uint32_t Rn, Rm; 9338 ARM_ShifterType shift_t; 9339 uint32_t shift_n; // the shift applied to the value read from Rm 9340 uint32_t carry; 9341 switch (encoding) 9342 { 9343 case eEncodingT1: 9344 Rn = Bits32(opcode, 2, 0); 9345 Rm = Bits32(opcode, 5, 3); 9346 shift_t = SRType_LSL; 9347 shift_n = 0; 9348 break; 9349 case eEncodingT2: 9350 Rn = Bits32(opcode, 19, 16); 9351 Rm = Bits32(opcode, 3, 0); 9352 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9353 if (BadReg(Rn) || BadReg(Rm)) 9354 return false; 9355 break; 9356 case eEncodingA1: 9357 Rn = Bits32(opcode, 19, 16); 9358 Rm = Bits32(opcode, 3, 0); 9359 shift_n = DecodeImmShiftARM(opcode, shift_t); 9360 break; 9361 default: 9362 return false; 9363 } 9364 9365 // Read the first operand. 9366 uint32_t val1 = ReadCoreReg(Rn, &success); 9367 if (!success) 9368 return false; 9369 9370 // Read the second operand. 9371 uint32_t val2 = ReadCoreReg(Rm, &success); 9372 if (!success) 9373 return false; 9374 9375 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9376 if (!success) 9377 return false; 9378 uint32_t result = val1 & shifted; 9379 9380 EmulateInstruction::Context context; 9381 context.type = EmulateInstruction::eContextImmediate; 9382 context.SetNoArgs (); 9383 9384 if (!WriteFlags(context, result, carry)) 9385 return false; 9386 } 9387 return true; 9388 } 9389 9390 // A8.6.216 SUB (SP minus register) 9391 bool 9392 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9393 { 9394 #if 0 9395 if ConditionPassed() then 9396 EncodingSpecificOperations(); 9397 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9398 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9399 if d == 15 then // Can only occur for ARM encoding 9400 ALUWritePC(result); // setflags is always FALSE here 9401 else 9402 R[d] = result; 9403 if setflags then 9404 APSR.N = result<31>; 9405 APSR.Z = IsZeroBit(result); 9406 APSR.C = carry; 9407 APSR.V = overflow; 9408 #endif 9409 9410 bool success = false; 9411 9412 if (ConditionPassed(opcode)) 9413 { 9414 uint32_t d; 9415 uint32_t m; 9416 bool setflags; 9417 ARM_ShifterType shift_t; 9418 uint32_t shift_n; 9419 9420 switch (encoding) 9421 { 9422 case eEncodingT1: 9423 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9424 d = Bits32 (opcode, 11, 8); 9425 m = Bits32 (opcode, 3, 0); 9426 setflags = BitIsSet (opcode, 20); 9427 9428 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9429 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9430 9431 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9432 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9433 return false; 9434 9435 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9436 if ((d == 15) || BadReg (m)) 9437 return false; 9438 break; 9439 9440 case eEncodingA1: 9441 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9442 d = Bits32 (opcode, 15, 12); 9443 m = Bits32 (opcode, 3, 0); 9444 setflags = BitIsSet (opcode, 20); 9445 9446 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9447 if (d == 15 && setflags) 9448 EmulateSUBSPcLrEtc (opcode, encoding); 9449 9450 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9451 shift_n = DecodeImmShiftARM (opcode, shift_t); 9452 break; 9453 9454 default: 9455 return false; 9456 } 9457 9458 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9459 uint32_t Rm = ReadCoreReg (m, &success); 9460 if (!success) 9461 return false; 9462 9463 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9464 if (!success) 9465 return false; 9466 9467 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9468 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9469 if (!success) 9470 return false; 9471 9472 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9473 9474 EmulateInstruction::Context context; 9475 context.type = eContextArithmetic; 9476 RegisterInfo sp_reg; 9477 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9478 RegisterInfo dwarf_reg; 9479 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9480 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9481 9482 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9483 return false; 9484 } 9485 return true; 9486 } 9487 9488 9489 // A8.6.7 ADD (register-shifted register) 9490 bool 9491 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9492 { 9493 #if 0 9494 if ConditionPassed() then 9495 EncodingSpecificOperations(); 9496 shift_n = UInt(R[s]<7:0>); 9497 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9498 (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9499 R[d] = result; 9500 if setflags then 9501 APSR.N = result<31>; 9502 APSR.Z = IsZeroBit(result); 9503 APSR.C = carry; 9504 APSR.V = overflow; 9505 #endif 9506 9507 bool success = false; 9508 9509 if (ConditionPassed(opcode)) 9510 { 9511 uint32_t d; 9512 uint32_t n; 9513 uint32_t m; 9514 uint32_t s; 9515 bool setflags; 9516 ARM_ShifterType shift_t; 9517 9518 switch (encoding) 9519 { 9520 case eEncodingA1: 9521 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9522 d = Bits32 (opcode, 15, 12); 9523 n = Bits32 (opcode, 19, 16); 9524 m = Bits32 (opcode, 3, 0); 9525 s = Bits32 (opcode, 11, 8); 9526 9527 // setflags = (S == �1�); shift_t = DecodeRegShift(type); 9528 setflags = BitIsSet (opcode, 20); 9529 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9530 9531 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9532 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9533 return false; 9534 break; 9535 9536 default: 9537 return false; 9538 } 9539 9540 // shift_n = UInt(R[s]<7:0>); 9541 uint32_t Rs = ReadCoreReg (s, &success); 9542 if (!success) 9543 return false; 9544 9545 uint32_t shift_n = Bits32 (Rs, 7, 0); 9546 9547 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9548 uint32_t Rm = ReadCoreReg (m, &success); 9549 if (!success) 9550 return false; 9551 9552 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9553 if (!success) 9554 return false; 9555 9556 // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9557 uint32_t Rn = ReadCoreReg (n, &success); 9558 if (!success) 9559 return false; 9560 9561 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9562 9563 // R[d] = result; 9564 EmulateInstruction::Context context; 9565 context.type = eContextArithmetic; 9566 RegisterInfo reg_n; 9567 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9568 RegisterInfo reg_m; 9569 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9570 9571 context.SetRegisterRegisterOperands (reg_n, reg_m); 9572 9573 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9574 return false; 9575 9576 // if setflags then 9577 // APSR.N = result<31>; 9578 // APSR.Z = IsZeroBit(result); 9579 // APSR.C = carry; 9580 // APSR.V = overflow; 9581 if (setflags) 9582 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9583 } 9584 return true; 9585 } 9586 9587 // A8.6.213 SUB (register) 9588 bool 9589 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9590 { 9591 #if 0 9592 if ConditionPassed() then 9593 EncodingSpecificOperations(); 9594 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9595 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9596 if d == 15 then // Can only occur for ARM encoding 9597 ALUWritePC(result); // setflags is always FALSE here 9598 else 9599 R[d] = result; 9600 if setflags then 9601 APSR.N = result<31>; 9602 APSR.Z = IsZeroBit(result); 9603 APSR.C = carry; 9604 APSR.V = overflow; 9605 #endif 9606 9607 bool success = false; 9608 9609 if (ConditionPassed(opcode)) 9610 { 9611 uint32_t d; 9612 uint32_t n; 9613 uint32_t m; 9614 bool setflags; 9615 ARM_ShifterType shift_t; 9616 uint32_t shift_n; 9617 9618 switch (encoding) 9619 { 9620 case eEncodingT1: 9621 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9622 d = Bits32 (opcode, 2, 0); 9623 n = Bits32 (opcode, 5, 3); 9624 m = Bits32 (opcode, 8, 6); 9625 setflags = !InITBlock(); 9626 9627 // (shift_t, shift_n) = (SRType_LSL, 0); 9628 shift_t = SRType_LSL; 9629 shift_n = 0; 9630 9631 break; 9632 9633 case eEncodingT2: 9634 // if Rd == �1111� && S == �1� then SEE CMP (register); 9635 // if Rn == �1101� then SEE SUB (SP minus register); 9636 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9637 d = Bits32 (opcode, 11, 8); 9638 n = Bits32 (opcode, 19, 16); 9639 m = Bits32 (opcode, 3, 0); 9640 setflags = BitIsSet (opcode, 20); 9641 9642 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9643 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9644 9645 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9646 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9647 return false; 9648 9649 break; 9650 9651 case eEncodingA1: 9652 // if Rn == �1101� then SEE SUB (SP minus register); 9653 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9654 d = Bits32 (opcode, 15, 12); 9655 n = Bits32 (opcode, 19, 16); 9656 m = Bits32 (opcode, 3, 0); 9657 setflags = BitIsSet (opcode, 20); 9658 9659 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9660 if ((d == 15) && setflags) 9661 EmulateSUBSPcLrEtc (opcode, encoding); 9662 9663 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9664 shift_n = DecodeImmShiftARM (opcode, shift_t); 9665 9666 break; 9667 9668 default: 9669 return false; 9670 } 9671 9672 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9673 uint32_t Rm = ReadCoreReg (m, &success); 9674 if (!success) 9675 return false; 9676 9677 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9678 if (!success) 9679 return false; 9680 9681 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9682 uint32_t Rn = ReadCoreReg (n, &success); 9683 if (!success) 9684 return false; 9685 9686 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9687 9688 // if d == 15 then // Can only occur for ARM encoding 9689 // ALUWritePC(result); // setflags is always FALSE here 9690 // else 9691 // R[d] = result; 9692 // if setflags then 9693 // APSR.N = result<31>; 9694 // APSR.Z = IsZeroBit(result); 9695 // APSR.C = carry; 9696 // APSR.V = overflow; 9697 9698 EmulateInstruction::Context context; 9699 context.type = eContextArithmetic; 9700 RegisterInfo reg_n; 9701 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9702 RegisterInfo reg_m; 9703 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9704 context.SetRegisterRegisterOperands (reg_n, reg_m); 9705 9706 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9707 return false; 9708 } 9709 return true; 9710 } 9711 9712 // A8.6.202 STREX 9713 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9714 // word from a register to memory if the executing processor has exclusive access to the memory addressed. 9715 bool 9716 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9717 { 9718 #if 0 9719 if ConditionPassed() then 9720 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9721 address = R[n] + imm32; 9722 if ExclusiveMonitorsPass(address,4) then 9723 MemA[address,4] = R[t]; 9724 R[d] = 0; 9725 else 9726 R[d] = 1; 9727 #endif 9728 9729 bool success = false; 9730 9731 if (ConditionPassed(opcode)) 9732 { 9733 uint32_t d; 9734 uint32_t t; 9735 uint32_t n; 9736 uint32_t imm32; 9737 const uint32_t addr_byte_size = GetAddressByteSize(); 9738 9739 switch (encoding) 9740 { 9741 case eEncodingT1: 9742 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 9743 d = Bits32 (opcode, 11, 8); 9744 t = Bits32 (opcode, 15, 12); 9745 n = Bits32 (opcode, 19, 16); 9746 imm32 = Bits32 (opcode, 7, 0) << 2; 9747 9748 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9749 if (BadReg (d) || BadReg (t) || (n == 15)) 9750 return false; 9751 9752 // if d == n || d == t then UNPREDICTABLE; 9753 if ((d == n) || (d == t)) 9754 return false; 9755 9756 break; 9757 9758 case eEncodingA1: 9759 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9760 d = Bits32 (opcode, 15, 12); 9761 t = Bits32 (opcode, 3, 0); 9762 n = Bits32 (opcode, 19, 16); 9763 imm32 = 0; 9764 9765 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9766 if ((d == 15) || (t == 15) || (n == 15)) 9767 return false; 9768 9769 // if d == n || d == t then UNPREDICTABLE; 9770 if ((d == n) || (d == t)) 9771 return false; 9772 9773 break; 9774 9775 default: 9776 return false; 9777 } 9778 9779 // address = R[n] + imm32; 9780 uint32_t Rn = ReadCoreReg (n, &success); 9781 if (!success) 9782 return false; 9783 9784 addr_t address = Rn + imm32; 9785 9786 RegisterInfo base_reg; 9787 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9788 RegisterInfo data_reg; 9789 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9790 EmulateInstruction::Context context; 9791 context.type = eContextRegisterStore; 9792 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9793 9794 // if ExclusiveMonitorsPass(address,4) then 9795 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9796 // always return true. 9797 if (true) 9798 { 9799 // MemA[address,4] = R[t]; 9800 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9801 if (!success) 9802 return false; 9803 9804 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9805 return false; 9806 9807 // R[d] = 0; 9808 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9809 return false; 9810 } 9811 else 9812 { 9813 // R[d] = 1; 9814 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9815 return false; 9816 } 9817 } 9818 return true; 9819 } 9820 9821 // A8.6.197 STRB (immediate, ARM) 9822 bool 9823 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9824 { 9825 #if 0 9826 if ConditionPassed() then 9827 EncodingSpecificOperations(); 9828 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9829 address = if index then offset_addr else R[n]; 9830 MemU[address,1] = R[t]<7:0>; 9831 if wback then R[n] = offset_addr; 9832 #endif 9833 9834 bool success = false; 9835 9836 if (ConditionPassed(opcode)) 9837 { 9838 uint32_t t; 9839 uint32_t n; 9840 uint32_t imm32; 9841 bool index; 9842 bool add; 9843 bool wback; 9844 9845 switch (encoding) 9846 { 9847 case eEncodingA1: 9848 // if P == �0� && W == �1� then SEE STRBT; 9849 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9850 t = Bits32 (opcode, 15, 12); 9851 n = Bits32 (opcode, 19, 16); 9852 imm32 = Bits32 (opcode, 11, 0); 9853 9854 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9855 index = BitIsSet (opcode, 24); 9856 add = BitIsSet (opcode, 23); 9857 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9858 9859 // if t == 15 then UNPREDICTABLE; 9860 if (t == 15) 9861 return false; 9862 9863 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9864 if (wback && ((n == 15) || (n == t))) 9865 return false; 9866 9867 break; 9868 9869 default: 9870 return false; 9871 } 9872 9873 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9874 uint32_t Rn = ReadCoreReg (n, &success); 9875 if (!success) 9876 return false; 9877 9878 addr_t offset_addr; 9879 if (add) 9880 offset_addr = Rn + imm32; 9881 else 9882 offset_addr = Rn - imm32; 9883 9884 // address = if index then offset_addr else R[n]; 9885 addr_t address; 9886 if (index) 9887 address = offset_addr; 9888 else 9889 address = Rn; 9890 9891 // MemU[address,1] = R[t]<7:0>; 9892 uint32_t Rt = ReadCoreReg (t, &success); 9893 if (!success) 9894 return false; 9895 9896 RegisterInfo base_reg; 9897 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9898 RegisterInfo data_reg; 9899 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9900 EmulateInstruction::Context context; 9901 context.type = eContextRegisterStore; 9902 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9903 9904 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 9905 return false; 9906 9907 // if wback then R[n] = offset_addr; 9908 if (wback) 9909 { 9910 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9911 return false; 9912 } 9913 } 9914 return true; 9915 } 9916 9917 // A8.6.194 STR (immediate, ARM) 9918 bool 9919 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9920 { 9921 #if 0 9922 if ConditionPassed() then 9923 EncodingSpecificOperations(); 9924 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9925 address = if index then offset_addr else R[n]; 9926 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9927 if wback then R[n] = offset_addr; 9928 #endif 9929 9930 bool success = false; 9931 9932 if (ConditionPassed(opcode)) 9933 { 9934 uint32_t t; 9935 uint32_t n; 9936 uint32_t imm32; 9937 bool index; 9938 bool add; 9939 bool wback; 9940 9941 const uint32_t addr_byte_size = GetAddressByteSize(); 9942 9943 switch (encoding) 9944 { 9945 case eEncodingA1: 9946 // if P == �0� && W == �1� then SEE STRT; 9947 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH; 9948 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9949 t = Bits32 (opcode, 15, 12); 9950 n = Bits32 (opcode, 19, 16); 9951 imm32 = Bits32 (opcode, 11, 0); 9952 9953 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9954 index = BitIsSet (opcode, 24); 9955 add = BitIsSet (opcode, 23); 9956 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9957 9958 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9959 if (wback && ((n == 15) || (n == t))) 9960 return false; 9961 9962 break; 9963 9964 default: 9965 return false; 9966 } 9967 9968 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9969 uint32_t Rn = ReadCoreReg (n, &success); 9970 if (!success) 9971 return false; 9972 9973 addr_t offset_addr; 9974 if (add) 9975 offset_addr = Rn + imm32; 9976 else 9977 offset_addr = Rn - imm32; 9978 9979 // address = if index then offset_addr else R[n]; 9980 addr_t address; 9981 if (index) 9982 address = offset_addr; 9983 else 9984 address = Rn; 9985 9986 RegisterInfo base_reg; 9987 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9988 RegisterInfo data_reg; 9989 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9990 EmulateInstruction::Context context; 9991 context.type = eContextRegisterStore; 9992 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9993 9994 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9995 uint32_t Rt = ReadCoreReg (t, &success); 9996 if (!success) 9997 return false; 9998 9999 if (t == 15) 10000 { 10001 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10002 if (!success) 10003 return false; 10004 10005 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10006 return false; 10007 } 10008 else 10009 { 10010 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10011 return false; 10012 } 10013 10014 // if wback then R[n] = offset_addr; 10015 if (wback) 10016 { 10017 context.type = eContextAdjustBaseRegister; 10018 context.SetImmediate (offset_addr); 10019 10020 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10021 return false; 10022 } 10023 } 10024 return true; 10025 } 10026 10027 // A8.6.66 LDRD (immediate) 10028 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10029 // words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10030 bool 10031 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10032 { 10033 #if 0 10034 if ConditionPassed() then 10035 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10036 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10037 address = if index then offset_addr else R[n]; 10038 R[t] = MemA[address,4]; 10039 R[t2] = MemA[address+4,4]; 10040 if wback then R[n] = offset_addr; 10041 #endif 10042 10043 bool success = false; 10044 10045 if (ConditionPassed(opcode)) 10046 { 10047 uint32_t t; 10048 uint32_t t2; 10049 uint32_t n; 10050 uint32_t imm32; 10051 bool index; 10052 bool add; 10053 bool wback; 10054 10055 switch (encoding) 10056 { 10057 case eEncodingT1: 10058 //if P == �0� && W == �0� then SEE �Related encodings�; 10059 //if Rn == �1111� then SEE LDRD (literal); 10060 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10061 t = Bits32 (opcode, 15, 12); 10062 t2 = Bits32 (opcode, 11, 8); 10063 n = Bits32 (opcode, 19, 16); 10064 imm32 = Bits32 (opcode, 7, 0) << 2; 10065 10066 //index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10067 index = BitIsSet (opcode, 24); 10068 add = BitIsSet (opcode, 23); 10069 wback = BitIsSet (opcode, 21); 10070 10071 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10072 if (wback && ((n == t) || (n == t2))) 10073 return false; 10074 10075 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10076 if (BadReg (t) || BadReg (t2) || (t == t2)) 10077 return false; 10078 10079 break; 10080 10081 case eEncodingA1: 10082 //if Rn == �1111� then SEE LDRD (literal); 10083 //if Rt<0> == �1� then UNPREDICTABLE; 10084 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10085 t = Bits32 (opcode, 15, 12); 10086 if (BitIsSet (t, 0)) 10087 return false; 10088 t2 = t + 1; 10089 n = Bits32 (opcode, 19, 16); 10090 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10091 10092 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10093 index = BitIsSet (opcode, 24); 10094 add = BitIsSet (opcode, 23); 10095 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10096 10097 //if P == �0� && W == �1� then UNPREDICTABLE; 10098 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10099 return false; 10100 10101 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10102 if (wback && ((n == t) || (n == t2))) 10103 return false; 10104 10105 //if t2 == 15 then UNPREDICTABLE; 10106 if (t2 == 15) 10107 return false; 10108 10109 break; 10110 10111 default: 10112 return false; 10113 } 10114 10115 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10116 uint32_t Rn = ReadCoreReg (n, &success); 10117 if (!success) 10118 return false; 10119 10120 addr_t offset_addr; 10121 if (add) 10122 offset_addr = Rn + imm32; 10123 else 10124 offset_addr = Rn - imm32; 10125 10126 //address = if index then offset_addr else R[n]; 10127 addr_t address; 10128 if (index) 10129 address = offset_addr; 10130 else 10131 address = Rn; 10132 10133 //R[t] = MemA[address,4]; 10134 RegisterInfo base_reg; 10135 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10136 10137 EmulateInstruction::Context context; 10138 context.type = eContextRegisterLoad; 10139 context.SetRegisterPlusOffset (base_reg, address - Rn); 10140 10141 const uint32_t addr_byte_size = GetAddressByteSize(); 10142 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10143 if (!success) 10144 return false; 10145 10146 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10147 return false; 10148 10149 //R[t2] = MemA[address+4,4]; 10150 10151 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10152 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10153 if (!success) 10154 return false; 10155 10156 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10157 return false; 10158 10159 //if wback then R[n] = offset_addr; 10160 if (wback) 10161 { 10162 context.type = eContextAdjustBaseRegister; 10163 context.SetAddress (offset_addr); 10164 10165 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10166 return false; 10167 } 10168 } 10169 return true; 10170 } 10171 10172 // A8.6.68 LDRD (register) 10173 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10174 // words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10175 bool 10176 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10177 { 10178 #if 0 10179 if ConditionPassed() then 10180 EncodingSpecificOperations(); 10181 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10182 address = if index then offset_addr else R[n]; 10183 R[t] = MemA[address,4]; 10184 R[t2] = MemA[address+4,4]; 10185 if wback then R[n] = offset_addr; 10186 #endif 10187 10188 bool success = false; 10189 10190 if (ConditionPassed(opcode)) 10191 { 10192 uint32_t t; 10193 uint32_t t2; 10194 uint32_t n; 10195 uint32_t m; 10196 bool index; 10197 bool add; 10198 bool wback; 10199 10200 switch (encoding) 10201 { 10202 case eEncodingA1: 10203 // if Rt<0> == �1� then UNPREDICTABLE; 10204 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10205 t = Bits32 (opcode, 15, 12); 10206 if (BitIsSet (t, 0)) 10207 return false; 10208 t2 = t + 1; 10209 n = Bits32 (opcode, 19, 16); 10210 m = Bits32 (opcode, 3, 0); 10211 10212 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10213 index = BitIsSet (opcode, 24); 10214 add = BitIsSet (opcode, 23); 10215 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10216 10217 // if P == �0� && W == �1� then UNPREDICTABLE; 10218 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10219 return false; 10220 10221 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10222 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10223 return false; 10224 10225 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10226 if (wback && ((n == 15) || (n == t) || (n == t2))) 10227 return false; 10228 10229 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10230 if ((ArchVersion() < 6) && wback && (m == n)) 10231 return false; 10232 break; 10233 10234 default: 10235 return false; 10236 } 10237 10238 uint32_t Rn = ReadCoreReg (n, &success); 10239 if (!success) 10240 return false; 10241 RegisterInfo base_reg; 10242 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10243 10244 uint32_t Rm = ReadCoreReg (m, &success); 10245 if (!success) 10246 return false; 10247 RegisterInfo offset_reg; 10248 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10249 10250 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10251 addr_t offset_addr; 10252 if (add) 10253 offset_addr = Rn + Rm; 10254 else 10255 offset_addr = Rn - Rm; 10256 10257 // address = if index then offset_addr else R[n]; 10258 addr_t address; 10259 if (index) 10260 address = offset_addr; 10261 else 10262 address = Rn; 10263 10264 EmulateInstruction::Context context; 10265 context.type = eContextRegisterLoad; 10266 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10267 10268 // R[t] = MemA[address,4]; 10269 const uint32_t addr_byte_size = GetAddressByteSize(); 10270 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10271 if (!success) 10272 return false; 10273 10274 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10275 return false; 10276 10277 // R[t2] = MemA[address+4,4]; 10278 10279 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10280 if (!success) 10281 return false; 10282 10283 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10284 return false; 10285 10286 // if wback then R[n] = offset_addr; 10287 if (wback) 10288 { 10289 context.type = eContextAdjustBaseRegister; 10290 context.SetAddress (offset_addr); 10291 10292 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10293 return false; 10294 } 10295 } 10296 return true; 10297 } 10298 10299 // A8.6.200 STRD (immediate) 10300 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10301 // stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10302 bool 10303 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10304 { 10305 #if 0 10306 if ConditionPassed() then 10307 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10308 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10309 address = if index then offset_addr else R[n]; 10310 MemA[address,4] = R[t]; 10311 MemA[address+4,4] = R[t2]; 10312 if wback then R[n] = offset_addr; 10313 #endif 10314 10315 bool success = false; 10316 10317 if (ConditionPassed(opcode)) 10318 { 10319 uint32_t t; 10320 uint32_t t2; 10321 uint32_t n; 10322 uint32_t imm32; 10323 bool index; 10324 bool add; 10325 bool wback; 10326 10327 switch (encoding) 10328 { 10329 case eEncodingT1: 10330 // if P == �0� && W == �0� then SEE �Related encodings�; 10331 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10332 t = Bits32 (opcode, 15, 12); 10333 t2 = Bits32 (opcode, 11, 8); 10334 n = Bits32 (opcode, 19, 16); 10335 imm32 = Bits32 (opcode, 7, 0) << 2; 10336 10337 // index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10338 index = BitIsSet (opcode, 24); 10339 add = BitIsSet (opcode, 23); 10340 wback = BitIsSet (opcode, 21); 10341 10342 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10343 if (wback && ((n == t) || (n == t2))) 10344 return false; 10345 10346 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10347 if ((n == 15) || BadReg (t) || BadReg (t2)) 10348 return false; 10349 10350 break; 10351 10352 case eEncodingA1: 10353 // if Rt<0> == �1� then UNPREDICTABLE; 10354 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10355 t = Bits32 (opcode, 15, 12); 10356 if (BitIsSet (t, 0)) 10357 return false; 10358 10359 t2 = t + 1; 10360 n = Bits32 (opcode, 19, 16); 10361 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10362 10363 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10364 index = BitIsSet (opcode, 24); 10365 add = BitIsSet (opcode, 23); 10366 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10367 10368 // if P == �0� && W == �1� then UNPREDICTABLE; 10369 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10370 return false; 10371 10372 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10373 if (wback && ((n == 15) || (n == t) || (n == t2))) 10374 return false; 10375 10376 // if t2 == 15 then UNPREDICTABLE; 10377 if (t2 == 15) 10378 return false; 10379 10380 break; 10381 10382 default: 10383 return false; 10384 } 10385 10386 RegisterInfo base_reg; 10387 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10388 10389 uint32_t Rn = ReadCoreReg (n, &success); 10390 if (!success) 10391 return false; 10392 10393 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10394 addr_t offset_addr; 10395 if (add) 10396 offset_addr = Rn + imm32; 10397 else 10398 offset_addr = Rn - imm32; 10399 10400 //address = if index then offset_addr else R[n]; 10401 addr_t address; 10402 if (index) 10403 address = offset_addr; 10404 else 10405 address = Rn; 10406 10407 //MemA[address,4] = R[t]; 10408 RegisterInfo data_reg; 10409 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10410 10411 uint32_t data = ReadCoreReg (t, &success); 10412 if (!success) 10413 return false; 10414 10415 EmulateInstruction::Context context; 10416 context.type = eContextRegisterStore; 10417 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10418 10419 const uint32_t addr_byte_size = GetAddressByteSize(); 10420 10421 if (!MemAWrite (context, address, data, addr_byte_size)) 10422 return false; 10423 10424 //MemA[address+4,4] = R[t2]; 10425 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10426 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10427 10428 data = ReadCoreReg (t2, &success); 10429 if (!success) 10430 return false; 10431 10432 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10433 return false; 10434 10435 //if wback then R[n] = offset_addr; 10436 if (wback) 10437 { 10438 context.type = eContextAdjustBaseRegister; 10439 context.SetAddress (offset_addr); 10440 10441 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10442 return false; 10443 } 10444 } 10445 return true; 10446 } 10447 10448 10449 // A8.6.201 STRD (register) 10450 bool 10451 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10452 { 10453 #if 0 10454 if ConditionPassed() then 10455 EncodingSpecificOperations(); 10456 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10457 address = if index then offset_addr else R[n]; 10458 MemA[address,4] = R[t]; 10459 MemA[address+4,4] = R[t2]; 10460 if wback then R[n] = offset_addr; 10461 #endif 10462 10463 bool success = false; 10464 10465 if (ConditionPassed(opcode)) 10466 { 10467 uint32_t t; 10468 uint32_t t2; 10469 uint32_t n; 10470 uint32_t m; 10471 bool index; 10472 bool add; 10473 bool wback; 10474 10475 switch (encoding) 10476 { 10477 case eEncodingA1: 10478 // if Rt<0> == �1� then UNPREDICTABLE; 10479 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10480 t = Bits32 (opcode, 15, 12); 10481 if (BitIsSet (t, 0)) 10482 return false; 10483 10484 t2 = t+1; 10485 n = Bits32 (opcode, 19, 16); 10486 m = Bits32 (opcode, 3, 0); 10487 10488 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10489 index = BitIsSet (opcode, 24); 10490 add = BitIsSet (opcode, 23); 10491 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10492 10493 // if P == �0� && W == �1� then UNPREDICTABLE; 10494 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10495 return false; 10496 10497 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10498 if ((t2 == 15) || (m == 15)) 10499 return false; 10500 10501 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10502 if (wback && ((n == 15) || (n == t) || (n == t2))) 10503 return false; 10504 10505 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10506 if ((ArchVersion() < 6) && wback && (m == n)) 10507 return false; 10508 10509 break; 10510 10511 default: 10512 return false; 10513 } 10514 10515 RegisterInfo base_reg; 10516 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10517 RegisterInfo offset_reg; 10518 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10519 RegisterInfo data_reg; 10520 10521 uint32_t Rn = ReadCoreReg (n, &success); 10522 if (!success) 10523 return false; 10524 10525 uint32_t Rm = ReadCoreReg (m, &success); 10526 if (!success) 10527 return false; 10528 10529 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10530 addr_t offset_addr; 10531 if (add) 10532 offset_addr = Rn + Rm; 10533 else 10534 offset_addr = Rn - Rm; 10535 10536 // address = if index then offset_addr else R[n]; 10537 addr_t address; 10538 if (index) 10539 address = offset_addr; 10540 else 10541 address = Rn; 10542 // MemA[address,4] = R[t]; 10543 uint32_t Rt = ReadCoreReg (t, &success); 10544 if (!success) 10545 return false; 10546 10547 EmulateInstruction::Context context; 10548 context.type = eContextRegisterStore; 10549 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10550 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10551 10552 const uint32_t addr_byte_size = GetAddressByteSize(); 10553 10554 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10555 return false; 10556 10557 // MemA[address+4,4] = R[t2]; 10558 uint32_t Rt2 = ReadCoreReg (t2, &success); 10559 if (!success) 10560 return false; 10561 10562 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10563 10564 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10565 10566 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10567 return false; 10568 10569 // if wback then R[n] = offset_addr; 10570 if (wback) 10571 { 10572 context.type = eContextAdjustBaseRegister; 10573 context.SetAddress (offset_addr); 10574 10575 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10576 return false; 10577 10578 } 10579 } 10580 return true; 10581 } 10582 10583 // A8.6.319 VLDM 10584 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10585 // an ARM core register. 10586 bool 10587 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10588 { 10589 #if 0 10590 if ConditionPassed() then 10591 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10592 address = if add then R[n] else R[n]-imm32; 10593 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10594 for r = 0 to regs-1 10595 if single_regs then 10596 S[d+r] = MemA[address,4]; address = address+4; 10597 else 10598 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10599 // Combine the word-aligned words in the correct order for current endianness. 10600 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10601 #endif 10602 10603 bool success = false; 10604 10605 if (ConditionPassed(opcode)) 10606 { 10607 bool single_regs; 10608 bool add; 10609 bool wback; 10610 uint32_t d; 10611 uint32_t n; 10612 uint32_t imm32; 10613 uint32_t regs; 10614 10615 switch (encoding) 10616 { 10617 case eEncodingT1: 10618 case eEncodingA1: 10619 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10620 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10621 // if P == �1� && W == �0� then SEE VLDR; 10622 // if P == U && W == �1� then UNDEFINED; 10623 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10624 return false; 10625 10626 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10627 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10628 single_regs = false; 10629 add = BitIsSet (opcode, 23); 10630 wback = BitIsSet (opcode, 21); 10631 10632 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10633 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10634 n = Bits32 (opcode, 19, 16); 10635 imm32 = Bits32 (opcode, 7, 0) << 2; 10636 10637 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�. 10638 regs = Bits32 (opcode, 7, 0) / 2; 10639 10640 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10641 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10642 return false; 10643 10644 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10645 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10646 return false; 10647 10648 break; 10649 10650 case eEncodingT2: 10651 case eEncodingA2: 10652 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10653 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10654 // if P == �1� && W == �0� then SEE VLDR; 10655 // if P == U && W == �1� then UNDEFINED; 10656 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10657 return false; 10658 10659 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10660 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10661 single_regs = true; 10662 add = BitIsSet (opcode, 23); 10663 wback = BitIsSet (opcode, 21); 10664 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10665 n = Bits32 (opcode, 19, 16); 10666 10667 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10668 imm32 = Bits32 (opcode, 7, 0) << 2; 10669 regs = Bits32 (opcode, 7, 0); 10670 10671 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10672 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10673 return false; 10674 10675 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10676 if ((regs == 0) || ((d + regs) > 32)) 10677 return false; 10678 break; 10679 10680 default: 10681 return false; 10682 } 10683 10684 RegisterInfo base_reg; 10685 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10686 10687 uint32_t Rn = ReadCoreReg (n, &success); 10688 if (!success) 10689 return false; 10690 10691 // address = if add then R[n] else R[n]-imm32; 10692 addr_t address; 10693 if (add) 10694 address = Rn; 10695 else 10696 address = Rn - imm32; 10697 10698 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10699 EmulateInstruction::Context context; 10700 10701 if (wback) 10702 { 10703 uint32_t value; 10704 if (add) 10705 value = Rn + imm32; 10706 else 10707 value = Rn - imm32; 10708 10709 context.type = eContextAdjustBaseRegister; 10710 context.SetImmediateSigned (value - Rn); 10711 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10712 return false; 10713 10714 } 10715 10716 const uint32_t addr_byte_size = GetAddressByteSize(); 10717 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10718 10719 context.type = eContextRegisterLoad; 10720 10721 // for r = 0 to regs-1 10722 for (uint32_t r = 0; r < regs; ++r) 10723 { 10724 if (single_regs) 10725 { 10726 // S[d+r] = MemA[address,4]; address = address+4; 10727 context.SetRegisterPlusOffset (base_reg, address - Rn); 10728 10729 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10730 if (!success) 10731 return false; 10732 10733 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10734 return false; 10735 10736 address = address + 4; 10737 } 10738 else 10739 { 10740 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10741 context.SetRegisterPlusOffset (base_reg, address - Rn); 10742 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10743 if (!success) 10744 return false; 10745 10746 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10747 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10748 if (!success) 10749 return false; 10750 10751 address = address + 8; 10752 // // Combine the word-aligned words in the correct order for current endianness. 10753 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10754 uint64_t data; 10755 if (GetByteOrder() == eByteOrderBig) 10756 { 10757 data = word1; 10758 data = (data << 32) | word2; 10759 } 10760 else 10761 { 10762 data = word2; 10763 data = (data << 32) | word1; 10764 } 10765 10766 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10767 return false; 10768 } 10769 } 10770 } 10771 return true; 10772 } 10773 10774 // A8.6.399 VSTM 10775 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10776 // ARM core register. 10777 bool 10778 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10779 { 10780 #if 0 10781 if ConditionPassed() then 10782 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10783 address = if add then R[n] else R[n]-imm32; 10784 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10785 for r = 0 to regs-1 10786 if single_regs then 10787 MemA[address,4] = S[d+r]; address = address+4; 10788 else 10789 // Store as two word-aligned words in the correct order for current endianness. 10790 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10791 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10792 address = address+8; 10793 #endif 10794 10795 bool success = false; 10796 10797 if (ConditionPassed (opcode)) 10798 { 10799 bool single_regs; 10800 bool add; 10801 bool wback; 10802 uint32_t d; 10803 uint32_t n; 10804 uint32_t imm32; 10805 uint32_t regs; 10806 10807 switch (encoding) 10808 { 10809 case eEncodingT1: 10810 case eEncodingA1: 10811 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10812 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10813 // if P == �1� && W == �0� then SEE VSTR; 10814 // if P == U && W == �1� then UNDEFINED; 10815 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10816 return false; 10817 10818 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10819 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10820 single_regs = false; 10821 add = BitIsSet (opcode, 23); 10822 wback = BitIsSet (opcode, 21); 10823 10824 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10825 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10826 n = Bits32 (opcode, 19, 16); 10827 imm32 = Bits32 (opcode, 7, 0) << 2; 10828 10829 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�. 10830 regs = Bits32 (opcode, 7, 0) / 2; 10831 10832 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10833 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10834 return false; 10835 10836 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10837 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10838 return false; 10839 10840 break; 10841 10842 case eEncodingT2: 10843 case eEncodingA2: 10844 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10845 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10846 // if P == �1� && W == �0� then SEE VSTR; 10847 // if P == U && W == �1� then UNDEFINED; 10848 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10849 return false; 10850 10851 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10852 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10853 single_regs = true; 10854 add = BitIsSet (opcode, 23); 10855 wback = BitIsSet (opcode, 21); 10856 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10857 n = Bits32 (opcode, 19, 16); 10858 10859 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10860 imm32 = Bits32 (opcode, 7, 0) << 2; 10861 regs = Bits32 (opcode, 7, 0); 10862 10863 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10864 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 10865 return false; 10866 10867 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10868 if ((regs == 0) || ((d + regs) > 32)) 10869 return false; 10870 10871 break; 10872 10873 default: 10874 return false; 10875 } 10876 10877 RegisterInfo base_reg; 10878 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10879 10880 uint32_t Rn = ReadCoreReg (n, &success); 10881 if (!success) 10882 return false; 10883 10884 // address = if add then R[n] else R[n]-imm32; 10885 addr_t address; 10886 if (add) 10887 address = Rn; 10888 else 10889 address = Rn - imm32; 10890 10891 EmulateInstruction::Context context; 10892 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10893 if (wback) 10894 { 10895 uint32_t value; 10896 if (add) 10897 value = Rn + imm32; 10898 else 10899 value = Rn - imm32; 10900 10901 context.type = eContextAdjustBaseRegister; 10902 context.SetRegisterPlusOffset (base_reg, value - Rn); 10903 10904 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10905 return false; 10906 } 10907 10908 const uint32_t addr_byte_size = GetAddressByteSize(); 10909 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10910 10911 context.type = eContextRegisterStore; 10912 // for r = 0 to regs-1 10913 for (int r = 0; r < regs; ++r) 10914 { 10915 10916 if (single_regs) 10917 { 10918 // MemA[address,4] = S[d+r]; address = address+4; 10919 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10920 if (!success) 10921 return false; 10922 10923 RegisterInfo data_reg; 10924 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10925 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10926 if (!MemAWrite (context, address, data, addr_byte_size)) 10927 return false; 10928 10929 address = address + 4; 10930 } 10931 else 10932 { 10933 // // Store as two word-aligned words in the correct order for current endianness. 10934 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10935 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10936 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10937 if (!success) 10938 return false; 10939 10940 RegisterInfo data_reg; 10941 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10942 10943 if (GetByteOrder() == eByteOrderBig) 10944 { 10945 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10946 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 10947 return false; 10948 10949 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10950 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 10951 return false; 10952 } 10953 else 10954 { 10955 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10956 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 10957 return false; 10958 10959 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10960 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 10961 return false; 10962 } 10963 // address = address+8; 10964 address = address + 8; 10965 } 10966 } 10967 } 10968 return true; 10969 } 10970 10971 // A8.6.320 10972 // This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with 10973 // an optional offset. 10974 bool 10975 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 10976 { 10977 #if 0 10978 if ConditionPassed() then 10979 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10980 base = if n == 15 then Align(PC,4) else R[n]; 10981 address = if add then (base + imm32) else (base - imm32); 10982 if single_reg then 10983 S[d] = MemA[address,4]; 10984 else 10985 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 10986 // Combine the word-aligned words in the correct order for current endianness. 10987 D[d] = if BigEndian() then word1:word2 else word2:word1; 10988 #endif 10989 10990 bool success = false; 10991 10992 if (ConditionPassed (opcode)) 10993 { 10994 bool single_reg; 10995 bool add; 10996 uint32_t imm32; 10997 uint32_t d; 10998 uint32_t n; 10999 11000 switch (encoding) 11001 { 11002 case eEncodingT1: 11003 case eEncodingA1: 11004 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11005 single_reg = false; 11006 add = BitIsSet (opcode, 23); 11007 imm32 = Bits32 (opcode, 7, 0) << 2; 11008 11009 // d = UInt(D:Vd); n = UInt(Rn); 11010 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11011 n = Bits32 (opcode, 19, 16); 11012 11013 break; 11014 11015 case eEncodingT2: 11016 case eEncodingA2: 11017 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11018 single_reg = true; 11019 add = BitIsSet (opcode, 23); 11020 imm32 = Bits32 (opcode, 7, 0) << 2; 11021 11022 // d = UInt(Vd:D); n = UInt(Rn); 11023 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11024 n = Bits32 (opcode, 19, 16); 11025 11026 break; 11027 11028 default: 11029 return false; 11030 } 11031 RegisterInfo base_reg; 11032 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11033 11034 uint32_t Rn = ReadCoreReg (n, &success); 11035 if (!success) 11036 return false; 11037 11038 // base = if n == 15 then Align(PC,4) else R[n]; 11039 uint32_t base; 11040 if (n == 15) 11041 base = AlignPC (Rn); 11042 else 11043 base = Rn; 11044 11045 // address = if add then (base + imm32) else (base - imm32); 11046 addr_t address; 11047 if (add) 11048 address = base + imm32; 11049 else 11050 address = base - imm32; 11051 11052 const uint32_t addr_byte_size = GetAddressByteSize(); 11053 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11054 11055 EmulateInstruction::Context context; 11056 context.type = eContextRegisterLoad; 11057 context.SetRegisterPlusOffset (base_reg, address - base); 11058 11059 if (single_reg) 11060 { 11061 // S[d] = MemA[address,4]; 11062 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11063 if (!success) 11064 return false; 11065 11066 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11067 return false; 11068 } 11069 else 11070 { 11071 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11072 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11073 if (!success) 11074 return false; 11075 11076 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11077 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11078 if (!success) 11079 return false; 11080 // // Combine the word-aligned words in the correct order for current endianness. 11081 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11082 uint64_t data64; 11083 if (GetByteOrder() == eByteOrderBig) 11084 { 11085 data64 = word1; 11086 data64 = (data64 << 32) | word2; 11087 } 11088 else 11089 { 11090 data64 = word2; 11091 data64 = (data64 << 32) | word1; 11092 } 11093 11094 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11095 return false; 11096 } 11097 } 11098 return true; 11099 } 11100 11101 // A8.6.400 VSTR 11102 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11103 // optional offset. 11104 bool 11105 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11106 { 11107 #if 0 11108 if ConditionPassed() then 11109 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11110 address = if add then (R[n] + imm32) else (R[n] - imm32); 11111 if single_reg then 11112 MemA[address,4] = S[d]; 11113 else 11114 // Store as two word-aligned words in the correct order for current endianness. 11115 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11116 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11117 #endif 11118 11119 bool success = false; 11120 11121 if (ConditionPassed (opcode)) 11122 { 11123 bool single_reg; 11124 bool add; 11125 uint32_t imm32; 11126 uint32_t d; 11127 uint32_t n; 11128 11129 switch (encoding) 11130 { 11131 case eEncodingT1: 11132 case eEncodingA1: 11133 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11134 single_reg = false; 11135 add = BitIsSet (opcode, 23); 11136 imm32 = Bits32 (opcode, 7, 0) << 2; 11137 11138 // d = UInt(D:Vd); n = UInt(Rn); 11139 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11140 n = Bits32 (opcode, 19, 16); 11141 11142 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11143 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11144 return false; 11145 11146 break; 11147 11148 case eEncodingT2: 11149 case eEncodingA2: 11150 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11151 single_reg = true; 11152 add = BitIsSet (opcode, 23); 11153 imm32 = Bits32 (opcode, 7, 0) << 2; 11154 11155 // d = UInt(Vd:D); n = UInt(Rn); 11156 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11157 n = Bits32 (opcode, 19, 16); 11158 11159 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11160 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11161 return false; 11162 11163 break; 11164 11165 default: 11166 return false; 11167 } 11168 11169 RegisterInfo base_reg; 11170 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11171 11172 uint32_t Rn = ReadCoreReg (n, &success); 11173 if (!success) 11174 return false; 11175 11176 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11177 addr_t address; 11178 if (add) 11179 address = Rn + imm32; 11180 else 11181 address = Rn - imm32; 11182 11183 const uint32_t addr_byte_size = GetAddressByteSize(); 11184 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11185 11186 RegisterInfo data_reg; 11187 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11188 EmulateInstruction::Context context; 11189 context.type = eContextRegisterStore; 11190 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11191 11192 if (single_reg) 11193 { 11194 // MemA[address,4] = S[d]; 11195 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11196 if (!success) 11197 return false; 11198 11199 if (!MemAWrite (context, address, data, addr_byte_size)) 11200 return false; 11201 } 11202 else 11203 { 11204 // // Store as two word-aligned words in the correct order for current endianness. 11205 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11206 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11207 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11208 if (!success) 11209 return false; 11210 11211 if (GetByteOrder() == eByteOrderBig) 11212 { 11213 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11214 return false; 11215 11216 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11217 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11218 return false; 11219 } 11220 else 11221 { 11222 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11223 return false; 11224 11225 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11226 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11227 return false; 11228 } 11229 } 11230 } 11231 return true; 11232 } 11233 11234 // A8.6.307 VLDI1 (multiple single elements) 11235 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11236 // element of each register is loaded. 11237 bool 11238 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11239 { 11240 #if 0 11241 if ConditionPassed() then 11242 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11243 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11244 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11245 for r = 0 to regs-1 11246 for e = 0 to elements-1 11247 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11248 address = address + ebytes; 11249 #endif 11250 11251 bool success = false; 11252 11253 if (ConditionPassed (opcode)) 11254 { 11255 uint32_t regs; 11256 uint32_t alignment; 11257 uint32_t ebytes; 11258 uint32_t esize; 11259 uint32_t elements; 11260 uint32_t d; 11261 uint32_t n; 11262 uint32_t m; 11263 bool wback; 11264 bool register_index; 11265 11266 switch (encoding) 11267 { 11268 case eEncodingT1: 11269 case eEncodingA1: 11270 { 11271 // case type of 11272 // when �0111� 11273 // regs = 1; if align<1> == �1� then UNDEFINED; 11274 // when �1010� 11275 // regs = 2; if align == �11� then UNDEFINED; 11276 // when �0110� 11277 // regs = 3; if align<1> == �1� then UNDEFINED; 11278 // when �0010� 11279 // regs = 4; 11280 // otherwise 11281 // SEE �Related encodings�; 11282 uint32_t type = Bits32 (opcode, 11, 8); 11283 uint32_t align = Bits32 (opcode, 5, 4); 11284 if (type == 7) // '0111' 11285 { 11286 regs = 1; 11287 if (BitIsSet (align, 1)) 11288 return false; 11289 } 11290 else if (type == 10) // '1010' 11291 { 11292 regs = 2; 11293 if (align == 3) 11294 return false; 11295 11296 } 11297 else if (type == 6) // '0110' 11298 { 11299 regs = 3; 11300 if (BitIsSet (align, 1)) 11301 return false; 11302 } 11303 else if (type == 2) // '0010' 11304 { 11305 regs = 4; 11306 } 11307 else 11308 return false; 11309 11310 // alignment = if align == �00� then 1 else 4 << UInt(align); 11311 if (align == 0) 11312 alignment = 1; 11313 else 11314 alignment = 4 << align; 11315 11316 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11317 ebytes = 1 << Bits32 (opcode, 7, 6); 11318 esize = 8 * ebytes; 11319 elements = 8 / ebytes; 11320 11321 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11322 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11323 n = Bits32 (opcode, 19, 15); 11324 m = Bits32 (opcode, 3, 0); 11325 11326 // wback = (m != 15); register_index = (m != 15 && m != 13); 11327 wback = (m != 15); 11328 register_index = ((m != 15) && (m != 13)); 11329 11330 // if d+regs > 32 then UNPREDICTABLE; 11331 if ((d + regs) > 32) 11332 return false; 11333 } 11334 break; 11335 11336 default: 11337 return false; 11338 } 11339 11340 RegisterInfo base_reg; 11341 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11342 11343 uint32_t Rn = ReadCoreReg (n, &success); 11344 if (!success) 11345 return false; 11346 11347 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11348 addr_t address = Rn; 11349 if ((address % alignment) != 0) 11350 return false; 11351 11352 EmulateInstruction::Context context; 11353 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11354 if (wback) 11355 { 11356 uint32_t Rm = ReadCoreReg (m, &success); 11357 if (!success) 11358 return false; 11359 11360 uint32_t offset; 11361 if (register_index) 11362 offset = Rm; 11363 else 11364 offset = 8 * regs; 11365 11366 uint32_t value = Rn + offset; 11367 context.type = eContextAdjustBaseRegister; 11368 context.SetRegisterPlusOffset (base_reg, offset); 11369 11370 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11371 return false; 11372 11373 } 11374 11375 // for r = 0 to regs-1 11376 for (int r = 0; r < regs; ++r) 11377 { 11378 // for e = 0 to elements-1 11379 uint64_t assembled_data = 0; 11380 for (int e = 0; e < elements; ++e) 11381 { 11382 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11383 context.type = eContextRegisterLoad; 11384 context.SetRegisterPlusOffset (base_reg, address - Rn); 11385 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11386 if (!success) 11387 return false; 11388 11389 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11390 11391 // address = address + ebytes; 11392 address = address + ebytes; 11393 } 11394 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11395 return false; 11396 } 11397 } 11398 return true; 11399 } 11400 11401 // A8.6.308 VLD1 (single element to one lane) 11402 // 11403 bool 11404 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11405 { 11406 #if 0 11407 if ConditionPassed() then 11408 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11409 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11410 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11411 Elem[D[d],index,esize] = MemU[address,ebytes]; 11412 #endif 11413 11414 bool success = false; 11415 11416 if (ConditionPassed (opcode)) 11417 { 11418 uint32_t ebytes; 11419 uint32_t esize; 11420 uint32_t index; 11421 uint32_t alignment; 11422 uint32_t d; 11423 uint32_t n; 11424 uint32_t m; 11425 bool wback; 11426 bool register_index; 11427 11428 switch (encoding) 11429 { 11430 case eEncodingT1: 11431 case eEncodingA1: 11432 { 11433 uint32_t size = Bits32 (opcode, 11, 10); 11434 uint32_t index_align = Bits32 (opcode, 7, 4); 11435 // if size == �11� then SEE VLD1 (single element to all lanes); 11436 if (size == 3) 11437 return EmulateVLD1SingleAll (opcode, encoding); 11438 // case size of 11439 if (size == 0) // when '00' 11440 { 11441 // if index_align<0> != �0� then UNDEFINED; 11442 if (BitIsClear (index_align, 0)) 11443 return false; 11444 11445 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11446 ebytes = 1; 11447 esize = 8; 11448 index = Bits32 (index_align, 3, 1); 11449 alignment = 1; 11450 } 11451 else if (size == 1) // when �01� 11452 { 11453 // if index_align<1> != �0� then UNDEFINED; 11454 if (BitIsClear (index_align, 1)) 11455 return false; 11456 11457 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11458 ebytes = 2; 11459 esize = 16; 11460 index = Bits32 (index_align, 3, 2); 11461 11462 // alignment = if index_align<0> == �0� then 1 else 2; 11463 if (BitIsClear (index_align, 0)) 11464 alignment = 1; 11465 else 11466 alignment = 2; 11467 } 11468 else if (size == 2) // when �10� 11469 { 11470 // if index_align<2> != �0� then UNDEFINED; 11471 if (BitIsClear (index_align, 2)) 11472 return false; 11473 11474 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11475 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11476 return false; 11477 11478 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11479 ebytes = 4; 11480 esize = 32; 11481 index = Bit32 (index_align, 3); 11482 11483 // alignment = if index_align<1:0> == �00� then 1 else 4; 11484 if (Bits32 (index_align, 1, 0) == 0) 11485 alignment = 1; 11486 else 11487 alignment = 4; 11488 } 11489 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11490 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11491 n = Bits32 (opcode, 19, 16); 11492 m = Bits32 (opcode, 3, 0); 11493 11494 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11495 wback = (m != 15); 11496 register_index = ((m != 15) && (m != 13)); 11497 11498 if (n == 15) 11499 return false; 11500 11501 } 11502 break; 11503 11504 default: 11505 return false; 11506 } 11507 11508 RegisterInfo base_reg; 11509 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11510 11511 uint32_t Rn = ReadCoreReg (n, &success); 11512 if (!success) 11513 return false; 11514 11515 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11516 addr_t address = Rn; 11517 if ((address % alignment) != 0) 11518 return false; 11519 11520 EmulateInstruction::Context context; 11521 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11522 if (wback) 11523 { 11524 uint32_t Rm = ReadCoreReg (m, &success); 11525 if (!success) 11526 return false; 11527 11528 uint32_t offset; 11529 if (register_index) 11530 offset = Rm; 11531 else 11532 offset = ebytes; 11533 11534 uint32_t value = Rn + offset; 11535 11536 context.type = eContextAdjustBaseRegister; 11537 context.SetRegisterPlusOffset (base_reg, offset); 11538 11539 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11540 return false; 11541 } 11542 11543 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11544 uint32_t element = MemURead (context, address, esize, 0, &success); 11545 if (!success) 11546 return false; 11547 11548 element = element << (index * esize); 11549 11550 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11551 if (!success) 11552 return false; 11553 11554 uint64_t all_ones = -1; 11555 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11556 // at element & to the right of element. 11557 if (index > 0) 11558 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11559 // now mask should be 0's where element goes & 1's 11560 // everywhere else. 11561 11562 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11563 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11564 11565 context.type = eContextRegisterLoad; 11566 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11567 return false; 11568 } 11569 return true; 11570 } 11571 11572 // A8.6.391 VST1 (multiple single elements) 11573 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without 11574 // interleaving. Every element of each register is stored. 11575 bool 11576 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11577 { 11578 #if 0 11579 if ConditionPassed() then 11580 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11581 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11582 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11583 for r = 0 to regs-1 11584 for e = 0 to elements-1 11585 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11586 address = address + ebytes; 11587 #endif 11588 11589 bool success = false; 11590 11591 if (ConditionPassed (opcode)) 11592 { 11593 uint32_t regs; 11594 uint32_t alignment; 11595 uint32_t ebytes; 11596 uint32_t esize; 11597 uint32_t elements; 11598 uint32_t d; 11599 uint32_t n; 11600 uint32_t m; 11601 bool wback; 11602 bool register_index; 11603 11604 switch (encoding) 11605 { 11606 case eEncodingT1: 11607 case eEncodingA1: 11608 { 11609 uint32_t type = Bits32 (opcode, 11, 8); 11610 uint32_t align = Bits32 (opcode, 5, 4); 11611 11612 // case type of 11613 if (type == 7) // when �0111� 11614 { 11615 // regs = 1; if align<1> == �1� then UNDEFINED; 11616 regs = 1; 11617 if (BitIsSet (align, 1)) 11618 return false; 11619 } 11620 else if (type == 10) // when �1010� 11621 { 11622 // regs = 2; if align == �11� then UNDEFINED; 11623 regs = 2; 11624 if (align == 3) 11625 return false; 11626 } 11627 else if (type == 6) // when �0110� 11628 { 11629 // regs = 3; if align<1> == �1� then UNDEFINED; 11630 regs = 3; 11631 if (BitIsSet (align, 1)) 11632 return false; 11633 } 11634 else if (type == 2) // when �0010� 11635 // regs = 4; 11636 regs = 4; 11637 else // otherwise 11638 // SEE �Related encodings�; 11639 return false; 11640 11641 // alignment = if align == �00� then 1 else 4 << UInt(align); 11642 if (align == 0) 11643 alignment = 1; 11644 else 11645 alignment = 4 << align; 11646 11647 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11648 ebytes = 1 << Bits32 (opcode,7, 6); 11649 esize = 8 * ebytes; 11650 elements = 8 / ebytes; 11651 11652 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11653 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11654 n = Bits32 (opcode, 19, 16); 11655 m = Bits32 (opcode, 3, 0); 11656 11657 // wback = (m != 15); register_index = (m != 15 && m != 13); 11658 wback = (m != 15); 11659 register_index = ((m != 15) && (m != 13)); 11660 11661 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11662 if ((d + regs) > 32) 11663 return false; 11664 11665 if (n == 15) 11666 return false; 11667 11668 } 11669 break; 11670 11671 default: 11672 return false; 11673 } 11674 11675 RegisterInfo base_reg; 11676 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11677 11678 uint32_t Rn = ReadCoreReg (n, &success); 11679 if (!success) 11680 return false; 11681 11682 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11683 addr_t address = Rn; 11684 if ((address % alignment) != 0) 11685 return false; 11686 11687 EmulateInstruction::Context context; 11688 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11689 if (wback) 11690 { 11691 uint32_t Rm = ReadCoreReg (m, &success); 11692 if (!success) 11693 return false; 11694 11695 uint32_t offset; 11696 if (register_index) 11697 offset = Rm; 11698 else 11699 offset = 8 * regs; 11700 11701 context.type = eContextAdjustBaseRegister; 11702 context.SetRegisterPlusOffset (base_reg, offset); 11703 11704 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11705 return false; 11706 } 11707 11708 RegisterInfo data_reg; 11709 context.type = eContextRegisterStore; 11710 // for r = 0 to regs-1 11711 for (int r = 0; r < regs; ++r) 11712 { 11713 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11714 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11715 if (!success) 11716 return false; 11717 11718 // for e = 0 to elements-1 11719 for (int e = 0; e < elements; ++e) 11720 { 11721 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11722 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11723 11724 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11725 if (!MemUWrite (context, address, word, ebytes)) 11726 return false; 11727 11728 // address = address + ebytes; 11729 address = address + ebytes; 11730 } 11731 } 11732 } 11733 return true; 11734 } 11735 11736 // A8.6.392 VST1 (single element from one lane) 11737 // This instruction stores one element to memory from one element of a register. 11738 bool 11739 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11740 { 11741 #if 0 11742 if ConditionPassed() then 11743 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11744 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11745 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11746 MemU[address,ebytes] = Elem[D[d],index,esize]; 11747 #endif 11748 11749 bool success = false; 11750 11751 if (ConditionPassed (opcode)) 11752 { 11753 uint32_t ebytes; 11754 uint32_t esize; 11755 uint32_t index; 11756 uint32_t alignment; 11757 uint32_t d; 11758 uint32_t n; 11759 uint32_t m; 11760 bool wback; 11761 bool register_index; 11762 11763 switch (encoding) 11764 { 11765 case eEncodingT1: 11766 case eEncodingA1: 11767 { 11768 uint32_t size = Bits32 (opcode, 11, 10); 11769 uint32_t index_align = Bits32 (opcode, 7, 4); 11770 11771 // if size == �11� then UNDEFINED; 11772 if (size == 3) 11773 return false; 11774 11775 // case size of 11776 if (size == 0) // when �00� 11777 { 11778 // if index_align<0> != �0� then UNDEFINED; 11779 if (BitIsClear (index_align, 0)) 11780 return false; 11781 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11782 ebytes = 1; 11783 esize = 8; 11784 index = Bits32 (index_align, 3, 1); 11785 alignment = 1; 11786 } 11787 else if (size == 1) // when �01� 11788 { 11789 // if index_align<1> != �0� then UNDEFINED; 11790 if (BitIsClear (index_align, 1)) 11791 return false; 11792 11793 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11794 ebytes = 2; 11795 esize = 16; 11796 index = Bits32 (index_align, 3, 2); 11797 11798 // alignment = if index_align<0> == �0� then 1 else 2; 11799 if (BitIsClear (index_align, 0)) 11800 alignment = 1; 11801 else 11802 alignment = 2; 11803 } 11804 else if (size == 2) // when �10� 11805 { 11806 // if index_align<2> != �0� then UNDEFINED; 11807 if (BitIsClear (index_align, 2)) 11808 return false; 11809 11810 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11811 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11812 return false; 11813 11814 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11815 ebytes = 4; 11816 esize = 32; 11817 index = Bit32 (index_align, 3); 11818 11819 // alignment = if index_align<1:0> == �00� then 1 else 4; 11820 if (Bits32 (index_align, 1, 0) == 0) 11821 alignment = 1; 11822 else 11823 alignment = 4; 11824 } 11825 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11826 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11827 n = Bits32 (opcode, 19, 16); 11828 m = Bits32 (opcode, 3, 0); 11829 11830 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11831 wback = (m != 15); 11832 register_index = ((m != 15) && (m != 13)); 11833 11834 if (n == 15) 11835 return false; 11836 } 11837 break; 11838 11839 default: 11840 return false; 11841 } 11842 11843 RegisterInfo base_reg; 11844 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11845 11846 uint32_t Rn = ReadCoreReg (n, &success); 11847 if (!success) 11848 return false; 11849 11850 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11851 addr_t address = Rn; 11852 if ((address % alignment) != 0) 11853 return false; 11854 11855 EmulateInstruction::Context context; 11856 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11857 if (wback) 11858 { 11859 uint32_t Rm = ReadCoreReg (m, &success); 11860 if (!success) 11861 return false; 11862 11863 uint32_t offset; 11864 if (register_index) 11865 offset = Rm; 11866 else 11867 offset = ebytes; 11868 11869 context.type = eContextAdjustBaseRegister; 11870 context.SetRegisterPlusOffset (base_reg, offset); 11871 11872 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11873 return false; 11874 } 11875 11876 // MemU[address,ebytes] = Elem[D[d],index,esize]; 11877 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11878 if (!success) 11879 return false; 11880 11881 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 11882 11883 RegisterInfo data_reg; 11884 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 11885 context.type = eContextRegisterStore; 11886 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11887 11888 if (!MemUWrite (context, address, word, ebytes)) 11889 return false; 11890 } 11891 return true; 11892 } 11893 11894 // A8.6.309 VLD1 (single element to all lanes) 11895 // This instruction loads one element from memory into every element of one or two vectors. 11896 bool 11897 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 11898 { 11899 #if 0 11900 if ConditionPassed() then 11901 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11902 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11903 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11904 replicated_element = Replicate(MemU[address,ebytes], elements); 11905 for r = 0 to regs-1 11906 D[d+r] = replicated_element; 11907 #endif 11908 11909 bool success = false; 11910 11911 if (ConditionPassed (opcode)) 11912 { 11913 uint32_t ebytes; 11914 uint32_t elements; 11915 uint32_t regs; 11916 uint32_t alignment; 11917 uint32_t d; 11918 uint32_t n; 11919 uint32_t m; 11920 bool wback; 11921 bool register_index; 11922 11923 switch (encoding) 11924 { 11925 case eEncodingT1: 11926 case eEncodingA1: 11927 { 11928 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED; 11929 uint32_t size = Bits32 (opcode, 7, 6); 11930 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 11931 return false; 11932 11933 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2; 11934 ebytes = 1 << size; 11935 elements = 8 / ebytes; 11936 if (BitIsClear (opcode, 5)) 11937 regs = 1; 11938 else 11939 regs = 2; 11940 11941 //alignment = if a == �0� then 1 else ebytes; 11942 if (BitIsClear (opcode, 4)) 11943 alignment = 1; 11944 else 11945 alignment = ebytes; 11946 11947 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11948 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11949 n = Bits32 (opcode, 19, 16); 11950 m = Bits32 (opcode, 3, 0); 11951 11952 //wback = (m != 15); register_index = (m != 15 && m != 13); 11953 wback = (m != 15); 11954 register_index = ((m != 15) && (m != 13)); 11955 11956 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11957 if ((d + regs) > 32) 11958 return false; 11959 11960 if (n == 15) 11961 return false; 11962 } 11963 break; 11964 11965 default: 11966 return false; 11967 } 11968 11969 RegisterInfo base_reg; 11970 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11971 11972 uint32_t Rn = ReadCoreReg (n, &success); 11973 if (!success) 11974 return false; 11975 11976 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11977 addr_t address = Rn; 11978 if ((address % alignment) != 0) 11979 return false; 11980 11981 EmulateInstruction::Context context; 11982 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11983 if (wback) 11984 { 11985 uint32_t Rm = ReadCoreReg (m, &success); 11986 if (!success) 11987 return false; 11988 11989 uint32_t offset; 11990 if (register_index) 11991 offset = Rm; 11992 else 11993 offset = ebytes; 11994 11995 context.type = eContextAdjustBaseRegister; 11996 context.SetRegisterPlusOffset (base_reg, offset); 11997 11998 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11999 return false; 12000 } 12001 12002 // replicated_element = Replicate(MemU[address,ebytes], elements); 12003 12004 context.type = eContextRegisterLoad; 12005 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12006 if (!success) 12007 return false; 12008 12009 uint64_t replicated_element = 0; 12010 uint32_t esize = ebytes * 8; 12011 for (int e = 0; e < elements; ++e) 12012 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12013 12014 // for r = 0 to regs-1 12015 for (int r = 0; r < regs; ++r) 12016 { 12017 // D[d+r] = replicated_element; 12018 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12019 return false; 12020 } 12021 } 12022 return true; 12023 } 12024 12025 // B6.2.13 SUBS PC, LR and related instructions 12026 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12027 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12028 bool 12029 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12030 { 12031 #if 0 12032 if ConditionPassed() then 12033 EncodingSpecificOperations(); 12034 if CurrentInstrSet() == InstrSet_ThumbEE then 12035 UNPREDICTABLE; 12036 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12037 case opcode of 12038 when �0000� result = R[n] AND operand2; // AND 12039 when �0001� result = R[n] EOR operand2; // EOR 12040 when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12041 when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12042 when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12043 when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12044 when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12045 when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12046 when �1100� result = R[n] OR operand2; // ORR 12047 when �1101� result = operand2; // MOV 12048 when �1110� result = R[n] AND NOT(operand2); // BIC 12049 when �1111� result = NOT(operand2); // MVN 12050 CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12051 BranchWritePC(result); 12052 #endif 12053 12054 bool success = false; 12055 12056 if (ConditionPassed (opcode)) 12057 { 12058 uint32_t n; 12059 uint32_t m; 12060 uint32_t imm32; 12061 bool register_form; 12062 ARM_ShifterType shift_t; 12063 uint32_t shift_n; 12064 uint32_t code; 12065 12066 switch (encoding) 12067 { 12068 case eEncodingT1: 12069 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12070 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB 12071 n = 14; 12072 imm32 = Bits32 (opcode, 7, 0); 12073 register_form = false; 12074 code = 2; 12075 12076 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12077 if (InITBlock() && !LastInITBlock()) 12078 return false; 12079 12080 break; 12081 12082 case eEncodingA1: 12083 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12084 n = Bits32 (opcode, 19, 16); 12085 imm32 = ARMExpandImm (opcode); 12086 register_form = false; 12087 code = Bits32 (opcode, 24, 21); 12088 12089 break; 12090 12091 case eEncodingA2: 12092 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12093 n = Bits32 (opcode, 19, 16); 12094 m = Bits32 (opcode, 3, 0); 12095 register_form = true; 12096 12097 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12098 shift_n = DecodeImmShiftARM (opcode, shift_t); 12099 12100 break; 12101 12102 default: 12103 return false; 12104 } 12105 12106 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12107 uint32_t operand2; 12108 if (register_form) 12109 { 12110 uint32_t Rm = ReadCoreReg (m, &success); 12111 if (!success) 12112 return false; 12113 12114 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12115 if (!success) 12116 return false; 12117 } 12118 else 12119 { 12120 operand2 = imm32; 12121 } 12122 12123 uint32_t Rn = ReadCoreReg (n, &success); 12124 if (!success) 12125 return false; 12126 12127 AddWithCarryResult result; 12128 12129 // case opcode of 12130 switch (code) 12131 { 12132 case 0: // when �0000� 12133 // result = R[n] AND operand2; // AND 12134 result.result = Rn & operand2; 12135 break; 12136 12137 case 1: // when �0001� 12138 // result = R[n] EOR operand2; // EOR 12139 result.result = Rn ^ operand2; 12140 break; 12141 12142 case 2: // when �0010� 12143 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12144 result = AddWithCarry (Rn, ~(operand2), 1); 12145 break; 12146 12147 case 3: // when �0011� 12148 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12149 result = AddWithCarry (~(Rn), operand2, 1); 12150 break; 12151 12152 case 4: // when �0100� 12153 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12154 result = AddWithCarry (Rn, operand2, 0); 12155 break; 12156 12157 case 5: // when �0101� 12158 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12159 result = AddWithCarry (Rn, operand2, APSR_C); 12160 break; 12161 12162 case 6: // when �0110� 12163 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12164 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12165 break; 12166 12167 case 7: // when �0111� 12168 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12169 result = AddWithCarry (~(Rn), operand2, APSR_C); 12170 break; 12171 12172 case 10: // when �1100� 12173 // result = R[n] OR operand2; // ORR 12174 result.result = Rn | operand2; 12175 break; 12176 12177 case 11: // when �1101� 12178 // result = operand2; // MOV 12179 result.result = operand2; 12180 break; 12181 12182 case 12: // when �1110� 12183 // result = R[n] AND NOT(operand2); // BIC 12184 result.result = Rn & ~(operand2); 12185 break; 12186 12187 case 15: // when �1111� 12188 // result = NOT(operand2); // MVN 12189 result.result = ~(operand2); 12190 break; 12191 12192 default: 12193 return false; 12194 } 12195 // CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12196 12197 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12198 // the best. 12199 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12200 if (!success) 12201 return false; 12202 12203 CPSRWriteByInstr (spsr, 15, true); 12204 12205 // BranchWritePC(result); 12206 EmulateInstruction::Context context; 12207 context.type = eContextAdjustPC; 12208 context.SetImmediate (result.result); 12209 12210 BranchWritePC (context, result.result); 12211 } 12212 return true; 12213 } 12214 12215 EmulateInstructionARM::ARMOpcode* 12216 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12217 { 12218 static ARMOpcode 12219 g_arm_opcodes[] = 12220 { 12221 //---------------------------------------------------------------------- 12222 // Prologue instructions 12223 //---------------------------------------------------------------------- 12224 12225 // push register(s) 12226 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12227 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12228 12229 // set r7 to point to a stack offset 12230 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12231 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12232 // copy the stack pointer to ip 12233 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12234 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12235 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12236 12237 // adjust the stack pointer 12238 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12239 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12240 12241 // push one register 12242 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12243 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12244 12245 // vector push consecutive extension register(s) 12246 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12247 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12248 12249 //---------------------------------------------------------------------- 12250 // Epilogue instructions 12251 //---------------------------------------------------------------------- 12252 12253 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12254 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12255 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12256 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12257 12258 //---------------------------------------------------------------------- 12259 // Supervisor Call (previously Software Interrupt) 12260 //---------------------------------------------------------------------- 12261 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12262 12263 //---------------------------------------------------------------------- 12264 // Branch instructions 12265 //---------------------------------------------------------------------- 12266 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12267 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 12268 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12269 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12270 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12271 // for example, "bx lr" 12272 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12273 // bxj 12274 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12275 12276 //---------------------------------------------------------------------- 12277 // Data-processing instructions 12278 //---------------------------------------------------------------------- 12279 // adc (immediate) 12280 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12281 // adc (register) 12282 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12283 // add (immediate) 12284 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12285 // add (register) 12286 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12287 // add (register-shifted register) 12288 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12289 // adr 12290 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12291 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12292 // and (immediate) 12293 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12294 // and (register) 12295 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12296 // bic (immediate) 12297 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12298 // bic (register) 12299 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12300 // eor (immediate) 12301 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12302 // eor (register) 12303 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12304 // orr (immediate) 12305 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12306 // orr (register) 12307 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12308 // rsb (immediate) 12309 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12310 // rsb (register) 12311 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12312 // rsc (immediate) 12313 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12314 // rsc (register) 12315 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12316 // sbc (immediate) 12317 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12318 // sbc (register) 12319 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12320 // sub (immediate, ARM) 12321 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12322 // sub (sp minus immediate) 12323 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12324 // sub (register) 12325 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12326 // teq (immediate) 12327 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12328 // teq (register) 12329 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12330 // tst (immediate) 12331 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12332 // tst (register) 12333 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12334 12335 // mov (immediate) 12336 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12337 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12338 // mov (register) 12339 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12340 // mvn (immediate) 12341 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12342 // mvn (register) 12343 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12344 // cmn (immediate) 12345 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12346 // cmn (register) 12347 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12348 // cmp (immediate) 12349 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12350 // cmp (register) 12351 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12352 // asr (immediate) 12353 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12354 // asr (register) 12355 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12356 // lsl (immediate) 12357 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12358 // lsl (register) 12359 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12360 // lsr (immediate) 12361 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12362 // lsr (register) 12363 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12364 // rrx is a special case encoding of ror (immediate) 12365 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12366 // ror (immediate) 12367 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12368 // ror (register) 12369 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12370 // mul 12371 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12372 12373 // subs pc, lr and related instructions 12374 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12375 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12376 12377 //---------------------------------------------------------------------- 12378 // Load instructions 12379 //---------------------------------------------------------------------- 12380 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12381 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12382 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12383 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12384 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12385 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12386 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12387 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12388 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12389 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12390 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12391 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12392 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12393 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12394 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12395 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12396 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12397 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12398 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12399 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12400 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12401 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12402 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12403 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12404 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12405 12406 //---------------------------------------------------------------------- 12407 // Store instructions 12408 //---------------------------------------------------------------------- 12409 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12410 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12411 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12412 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12413 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12414 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12415 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12416 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12417 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12418 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12419 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12420 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12421 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12422 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12423 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12424 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12425 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12426 12427 //---------------------------------------------------------------------- 12428 // Other instructions 12429 //---------------------------------------------------------------------- 12430 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12431 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12432 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12433 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12434 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12435 12436 }; 12437 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 12438 12439 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12440 { 12441 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12442 (g_arm_opcodes[i].variants & arm_isa) != 0) 12443 return &g_arm_opcodes[i]; 12444 } 12445 return NULL; 12446 } 12447 12448 12449 EmulateInstructionARM::ARMOpcode* 12450 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12451 { 12452 12453 static ARMOpcode 12454 g_thumb_opcodes[] = 12455 { 12456 //---------------------------------------------------------------------- 12457 // Prologue instructions 12458 //---------------------------------------------------------------------- 12459 12460 // push register(s) 12461 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12462 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12463 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12464 12465 // set r7 to point to a stack offset 12466 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12467 // copy the stack pointer to r7 12468 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12469 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12470 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12471 12472 // PC-relative load into register (see also EmulateADDSPRm) 12473 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12474 12475 // adjust the stack pointer 12476 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12477 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12478 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12479 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12480 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12481 12482 // vector push consecutive extension register(s) 12483 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12484 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12485 12486 //---------------------------------------------------------------------- 12487 // Epilogue instructions 12488 //---------------------------------------------------------------------- 12489 12490 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12491 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12492 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12493 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12494 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12495 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12496 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12497 12498 //---------------------------------------------------------------------- 12499 // Supervisor Call (previously Software Interrupt) 12500 //---------------------------------------------------------------------- 12501 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12502 12503 //---------------------------------------------------------------------- 12504 // If Then makes up to four following instructions conditional. 12505 //---------------------------------------------------------------------- 12506 // The next 5 opcode _must_ come before the if then instruction 12507 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12508 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12509 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12510 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12511 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12512 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12513 12514 //---------------------------------------------------------------------- 12515 // Branch instructions 12516 //---------------------------------------------------------------------- 12517 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12518 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12519 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12520 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12521 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12522 // J1 == J2 == 1 12523 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12524 // J1 == J2 == 1 12525 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12526 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12527 // for example, "bx lr" 12528 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12529 // bxj 12530 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12531 // compare and branch 12532 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12533 // table branch byte 12534 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12535 // table branch halfword 12536 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12537 12538 //---------------------------------------------------------------------- 12539 // Data-processing instructions 12540 //---------------------------------------------------------------------- 12541 // adc (immediate) 12542 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12543 // adc (register) 12544 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12545 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12546 // add (register) 12547 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12548 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12549 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12550 // adr 12551 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12552 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12553 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12554 // and (immediate) 12555 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12556 // and (register) 12557 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12558 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12559 // bic (immediate) 12560 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12561 // bic (register) 12562 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12563 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12564 // eor (immediate) 12565 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12566 // eor (register) 12567 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12568 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12569 // orr (immediate) 12570 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12571 // orr (register) 12572 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12573 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12574 // rsb (immediate) 12575 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12576 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12577 // rsb (register) 12578 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12579 // sbc (immediate) 12580 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12581 // sbc (register) 12582 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12583 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12584 // add (immediate, Thumb) 12585 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12586 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12587 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12588 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12589 // sub (immediate, Thumb) 12590 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12591 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12592 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12593 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12594 // sub (sp minus immediate) 12595 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12596 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12597 // sub (register) 12598 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12599 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12600 // teq (immediate) 12601 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12602 // teq (register) 12603 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12604 // tst (immediate) 12605 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12606 // tst (register) 12607 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12608 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12609 12610 12611 // move from high register to high register 12612 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12613 // move from low register to low register 12614 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12615 // mov{s}<c>.w <Rd>, <Rm> 12616 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12617 // move immediate 12618 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12619 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12620 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12621 // mvn (immediate) 12622 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12623 // mvn (register) 12624 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12625 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12626 // cmn (immediate) 12627 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12628 // cmn (register) 12629 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12630 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12631 // cmp (immediate) 12632 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12633 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12634 // cmp (register) (Rn and Rm both from r0-r7) 12635 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12636 // cmp (register) (Rn and Rm not both from r0-r7) 12637 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12638 // asr (immediate) 12639 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12640 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12641 // asr (register) 12642 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12643 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12644 // lsl (immediate) 12645 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12646 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12647 // lsl (register) 12648 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12649 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12650 // lsr (immediate) 12651 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12652 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12653 // lsr (register) 12654 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12655 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12656 // rrx is a special case encoding of ror (immediate) 12657 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12658 // ror (immediate) 12659 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12660 // ror (register) 12661 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12662 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12663 // mul 12664 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12665 // mul 12666 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12667 12668 // subs pc, lr and related instructions 12669 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12670 12671 //---------------------------------------------------------------------- 12672 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12673 // otherwise the wrong instructions will be selected. 12674 //---------------------------------------------------------------------- 12675 12676 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12677 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12678 12679 //---------------------------------------------------------------------- 12680 // Load instructions 12681 //---------------------------------------------------------------------- 12682 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12683 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12684 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12685 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12686 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12687 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12688 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12689 // Thumb2 PC-relative load into register 12690 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12691 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12692 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12693 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12694 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12695 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12696 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12697 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12698 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12699 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12700 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12701 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12702 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12703 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12704 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12705 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12706 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12707 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12708 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12709 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12710 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12711 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12712 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12713 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12714 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12715 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12716 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12717 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12718 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12719 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12720 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12721 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12722 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12723 12724 //---------------------------------------------------------------------- 12725 // Store instructions 12726 //---------------------------------------------------------------------- 12727 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12728 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12729 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12730 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12731 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12732 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12733 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12734 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12735 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12736 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12737 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12738 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12739 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12740 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12741 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12742 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12743 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12744 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12745 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12746 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12747 { 0xffb00000, 0xfa000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12748 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12749 12750 //---------------------------------------------------------------------- 12751 // Other instructions 12752 //---------------------------------------------------------------------- 12753 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12754 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12755 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12756 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12757 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12758 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12759 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12760 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12761 }; 12762 12763 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 12764 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12765 { 12766 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12767 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12768 return &g_thumb_opcodes[i]; 12769 } 12770 return NULL; 12771 } 12772 12773 bool 12774 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12775 { 12776 m_arch = arch; 12777 m_arm_isa = 0; 12778 const char *arch_cstr = arch.GetArchitectureName (); 12779 if (arch_cstr) 12780 { 12781 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12782 else if (0 == ::strcasecmp(arch_cstr, "armv4")) m_arm_isa = ARMv4; 12783 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12784 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12785 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12786 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12787 else if (0 == ::strcasecmp(arch_cstr, "armv6")) m_arm_isa = ARMv6; 12788 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12789 else if (0 == ::strcasecmp(arch_cstr, "armv7")) m_arm_isa = ARMv7; 12790 else if (0 == ::strcasecmp(arch_cstr, "armv8")) m_arm_isa = ARMv8; 12791 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12792 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12793 } 12794 return m_arm_isa != 0; 12795 } 12796 12797 bool 12798 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12799 { 12800 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12801 { 12802 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12803 m_opcode_mode = eModeThumb; 12804 else 12805 { 12806 AddressClass addr_class = inst_addr.GetAddressClass(); 12807 12808 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 12809 m_opcode_mode = eModeARM; 12810 else if (addr_class == eAddressClassCodeAlternateISA) 12811 m_opcode_mode = eModeThumb; 12812 else 12813 return false; 12814 } 12815 if (m_opcode_mode == eModeThumb) 12816 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 12817 else 12818 m_opcode_cpsr = CPSR_MODE_USR; 12819 return true; 12820 } 12821 return false; 12822 } 12823 12824 bool 12825 EmulateInstructionARM::ReadInstruction () 12826 { 12827 bool success = false; 12828 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 12829 if (success) 12830 { 12831 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 12832 if (success) 12833 { 12834 Context read_inst_context; 12835 read_inst_context.type = eContextReadOpcode; 12836 read_inst_context.SetNoArgs (); 12837 12838 if (m_opcode_cpsr & MASK_CPSR_T) 12839 { 12840 m_opcode_mode = eModeThumb; 12841 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 12842 12843 if (success) 12844 { 12845 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 12846 { 12847 m_opcode.SetOpcode16 (thumb_opcode); 12848 } 12849 else 12850 { 12851 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success)); 12852 } 12853 } 12854 } 12855 else 12856 { 12857 m_opcode_mode = eModeARM; 12858 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success)); 12859 } 12860 } 12861 } 12862 if (!success) 12863 { 12864 m_opcode_mode = eModeInvalid; 12865 m_addr = LLDB_INVALID_ADDRESS; 12866 } 12867 return success; 12868 } 12869 12870 uint32_t 12871 EmulateInstructionARM::ArchVersion () 12872 { 12873 return m_arm_isa; 12874 } 12875 12876 bool 12877 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) 12878 { 12879 // If we are ignoring conditions, then always return true. 12880 // this allows us to iterate over disassembly code and still 12881 // emulate an instruction even if we don't have all the right 12882 // bits set in the CPSR register... 12883 if (m_ignore_conditions) 12884 return true; 12885 12886 if (is_conditional) 12887 *is_conditional = true; 12888 12889 const uint32_t cond = CurrentCond (opcode); 12890 12891 if (cond == UINT32_MAX) 12892 return false; 12893 12894 bool result = false; 12895 switch (UnsignedBits(cond, 3, 1)) 12896 { 12897 case 0: 12898 if (m_opcode_cpsr == 0) 12899 result = true; 12900 else 12901 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 12902 break; 12903 case 1: 12904 if (m_opcode_cpsr == 0) 12905 result = true; 12906 else 12907 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 12908 break; 12909 case 2: 12910 if (m_opcode_cpsr == 0) 12911 result = true; 12912 else 12913 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 12914 break; 12915 case 3: 12916 if (m_opcode_cpsr == 0) 12917 result = true; 12918 else 12919 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 12920 break; 12921 case 4: 12922 if (m_opcode_cpsr == 0) 12923 result = true; 12924 else 12925 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12926 break; 12927 case 5: 12928 if (m_opcode_cpsr == 0) 12929 result = true; 12930 else 12931 { 12932 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12933 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12934 result = n == v; 12935 } 12936 break; 12937 case 6: 12938 if (m_opcode_cpsr == 0) 12939 result = true; 12940 else 12941 { 12942 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12943 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12944 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12945 } 12946 break; 12947 case 7: 12948 // Always execute (cond == 0b1110, or the special 0b1111 which gives 12949 // opcodes different meanings, but always means execution happpens. 12950 if (is_conditional) 12951 *is_conditional = false; 12952 result = true; 12953 break; 12954 } 12955 12956 if (cond & 1) 12957 result = !result; 12958 return result; 12959 } 12960 12961 uint32_t 12962 EmulateInstructionARM::CurrentCond (const uint32_t opcode) 12963 { 12964 switch (m_opcode_mode) 12965 { 12966 default: 12967 case eModeInvalid: 12968 break; 12969 12970 case eModeARM: 12971 return UnsignedBits(opcode, 31, 28); 12972 12973 case eModeThumb: 12974 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 12975 // 'cond' field of the encoding. 12976 { 12977 const uint32_t byte_size = m_opcode.GetByteSize(); 12978 if (byte_size == 2) 12979 { 12980 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 12981 return Bits32(opcode, 11, 7); 12982 } 12983 else if (byte_size == 4) 12984 { 12985 if (Bits32(opcode, 31, 27) == 0x1e && 12986 Bits32(opcode, 15, 14) == 0x02 && 12987 Bits32(opcode, 12, 12) == 0x00 && 12988 Bits32(opcode, 25, 22) <= 0x0d) 12989 { 12990 return Bits32(opcode, 25, 22); 12991 } 12992 } 12993 else 12994 // We have an invalid thumb instruction, let's bail out. 12995 break; 12996 12997 return m_it_session.GetCond(); 12998 } 12999 } 13000 return UINT32_MAX; // Return invalid value 13001 } 13002 13003 bool 13004 EmulateInstructionARM::InITBlock() 13005 { 13006 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13007 } 13008 13009 bool 13010 EmulateInstructionARM::LastInITBlock() 13011 { 13012 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13013 } 13014 13015 bool 13016 EmulateInstructionARM::BadMode (uint32_t mode) 13017 { 13018 13019 switch (mode) 13020 { 13021 case 16: return false; // '10000' 13022 case 17: return false; // '10001' 13023 case 18: return false; // '10010' 13024 case 19: return false; // '10011' 13025 case 22: return false; // '10110' 13026 case 23: return false; // '10111' 13027 case 27: return false; // '11011' 13028 case 31: return false; // '11111' 13029 default: return true; 13030 } 13031 return true; 13032 } 13033 13034 bool 13035 EmulateInstructionARM::CurrentModeIsPrivileged () 13036 { 13037 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13038 13039 if (BadMode (mode)) 13040 return false; 13041 13042 if (mode == 16) 13043 return false; 13044 13045 return true; 13046 } 13047 13048 void 13049 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13050 { 13051 bool privileged = CurrentModeIsPrivileged(); 13052 13053 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13054 13055 if (BitIsSet (bytemask, 3)) 13056 { 13057 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13058 if (affect_execstate) 13059 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13060 } 13061 13062 if (BitIsSet (bytemask, 2)) 13063 { 13064 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13065 } 13066 13067 if (BitIsSet (bytemask, 1)) 13068 { 13069 if (affect_execstate) 13070 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13071 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13072 if (privileged) 13073 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13074 } 13075 13076 if (BitIsSet (bytemask, 0)) 13077 { 13078 if (privileged) 13079 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13080 if (affect_execstate) 13081 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13082 if (privileged) 13083 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13084 } 13085 13086 m_opcode_cpsr = tmp_cpsr; 13087 } 13088 13089 13090 bool 13091 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13092 { 13093 addr_t target; 13094 13095 // Check the current instruction set. 13096 if (CurrentInstrSet() == eModeARM) 13097 target = addr & 0xfffffffc; 13098 else 13099 target = addr & 0xfffffffe; 13100 13101 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13102 return false; 13103 13104 return true; 13105 } 13106 13107 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13108 bool 13109 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13110 { 13111 addr_t target; 13112 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13113 // we want to record it and issue a WriteRegister callback so the clients 13114 // can track the mode changes accordingly. 13115 bool cpsr_changed = false; 13116 13117 if (BitIsSet(addr, 0)) 13118 { 13119 if (CurrentInstrSet() != eModeThumb) 13120 { 13121 SelectInstrSet(eModeThumb); 13122 cpsr_changed = true; 13123 } 13124 target = addr & 0xfffffffe; 13125 context.SetISA (eModeThumb); 13126 } 13127 else if (BitIsClear(addr, 1)) 13128 { 13129 if (CurrentInstrSet() != eModeARM) 13130 { 13131 SelectInstrSet(eModeARM); 13132 cpsr_changed = true; 13133 } 13134 target = addr & 0xfffffffc; 13135 context.SetISA (eModeARM); 13136 } 13137 else 13138 return false; // address<1:0> == '10' => UNPREDICTABLE 13139 13140 if (cpsr_changed) 13141 { 13142 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13143 return false; 13144 } 13145 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13146 return false; 13147 13148 return true; 13149 } 13150 13151 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13152 bool 13153 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13154 { 13155 if (ArchVersion() >= ARMv5T) 13156 return BXWritePC(context, addr); 13157 else 13158 return BranchWritePC((const Context)context, addr); 13159 } 13160 13161 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13162 bool 13163 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13164 { 13165 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13166 return BXWritePC(context, addr); 13167 else 13168 return BranchWritePC((const Context)context, addr); 13169 } 13170 13171 EmulateInstructionARM::Mode 13172 EmulateInstructionARM::CurrentInstrSet () 13173 { 13174 return m_opcode_mode; 13175 } 13176 13177 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13178 // ReadInstruction() is performed. This function has a side effect of updating 13179 // the m_new_inst_cpsr member variable if necessary. 13180 bool 13181 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13182 { 13183 m_new_inst_cpsr = m_opcode_cpsr; 13184 switch (arm_or_thumb) 13185 { 13186 default: 13187 return false; 13188 eModeARM: 13189 // Clear the T bit. 13190 m_new_inst_cpsr &= ~MASK_CPSR_T; 13191 break; 13192 eModeThumb: 13193 // Set the T bit. 13194 m_new_inst_cpsr |= MASK_CPSR_T; 13195 break; 13196 } 13197 return true; 13198 } 13199 13200 // This function returns TRUE if the processor currently provides support for 13201 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13202 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13203 bool 13204 EmulateInstructionARM::UnalignedSupport() 13205 { 13206 return (ArchVersion() >= ARMv7); 13207 } 13208 13209 // The main addition and subtraction instructions can produce status information 13210 // about both unsigned carry and signed overflow conditions. This status 13211 // information can be used to synthesize multi-word additions and subtractions. 13212 EmulateInstructionARM::AddWithCarryResult 13213 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13214 { 13215 uint32_t result; 13216 uint8_t carry_out; 13217 uint8_t overflow; 13218 13219 uint64_t unsigned_sum = x + y + carry_in; 13220 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13221 13222 result = UnsignedBits(unsigned_sum, 31, 0); 13223 // carry_out = (result == unsigned_sum ? 0 : 1); 13224 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13225 13226 if (carry_in) 13227 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13228 else 13229 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13230 13231 AddWithCarryResult res = { result, carry_out, overflow }; 13232 return res; 13233 } 13234 13235 uint32_t 13236 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13237 { 13238 uint32_t reg_kind, reg_num; 13239 switch (num) 13240 { 13241 case SP_REG: 13242 reg_kind = eRegisterKindGeneric; 13243 reg_num = LLDB_REGNUM_GENERIC_SP; 13244 break; 13245 case LR_REG: 13246 reg_kind = eRegisterKindGeneric; 13247 reg_num = LLDB_REGNUM_GENERIC_RA; 13248 break; 13249 case PC_REG: 13250 reg_kind = eRegisterKindGeneric; 13251 reg_num = LLDB_REGNUM_GENERIC_PC; 13252 break; 13253 default: 13254 if (num < SP_REG) 13255 { 13256 reg_kind = eRegisterKindDWARF; 13257 reg_num = dwarf_r0 + num; 13258 } 13259 else 13260 { 13261 //assert(0 && "Invalid register number"); 13262 *success = false; 13263 return UINT32_MAX; 13264 } 13265 break; 13266 } 13267 13268 // Read our register. 13269 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13270 13271 // When executing an ARM instruction , PC reads as the address of the current 13272 // instruction plus 8. 13273 // When executing a Thumb instruction , PC reads as the address of the current 13274 // instruction plus 4. 13275 if (num == 15) 13276 { 13277 if (CurrentInstrSet() == eModeARM) 13278 val += 8; 13279 else 13280 val += 4; 13281 } 13282 13283 return val; 13284 } 13285 13286 // Write the result to the ARM core register Rd, and optionally update the 13287 // condition flags based on the result. 13288 // 13289 // This helper method tries to encapsulate the following pseudocode from the 13290 // ARM Architecture Reference Manual: 13291 // 13292 // if d == 15 then // Can only occur for encoding A1 13293 // ALUWritePC(result); // setflags is always FALSE here 13294 // else 13295 // R[d] = result; 13296 // if setflags then 13297 // APSR.N = result<31>; 13298 // APSR.Z = IsZeroBit(result); 13299 // APSR.C = carry; 13300 // // APSR.V unchanged 13301 // 13302 // In the above case, the API client does not pass in the overflow arg, which 13303 // defaults to ~0u. 13304 bool 13305 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13306 const uint32_t result, 13307 const uint32_t Rd, 13308 bool setflags, 13309 const uint32_t carry, 13310 const uint32_t overflow) 13311 { 13312 if (Rd == 15) 13313 { 13314 if (!ALUWritePC (context, result)) 13315 return false; 13316 } 13317 else 13318 { 13319 uint32_t reg_kind, reg_num; 13320 switch (Rd) 13321 { 13322 case SP_REG: 13323 reg_kind = eRegisterKindGeneric; 13324 reg_num = LLDB_REGNUM_GENERIC_SP; 13325 break; 13326 case LR_REG: 13327 reg_kind = eRegisterKindGeneric; 13328 reg_num = LLDB_REGNUM_GENERIC_RA; 13329 break; 13330 default: 13331 reg_kind = eRegisterKindDWARF; 13332 reg_num = dwarf_r0 + Rd; 13333 } 13334 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13335 return false; 13336 if (setflags) 13337 return WriteFlags (context, result, carry, overflow); 13338 } 13339 return true; 13340 } 13341 13342 // This helper method tries to encapsulate the following pseudocode from the 13343 // ARM Architecture Reference Manual: 13344 // 13345 // APSR.N = result<31>; 13346 // APSR.Z = IsZeroBit(result); 13347 // APSR.C = carry; 13348 // APSR.V = overflow 13349 // 13350 // Default arguments can be specified for carry and overflow parameters, which means 13351 // not to update the respective flags. 13352 bool 13353 EmulateInstructionARM::WriteFlags (Context &context, 13354 const uint32_t result, 13355 const uint32_t carry, 13356 const uint32_t overflow) 13357 { 13358 m_new_inst_cpsr = m_opcode_cpsr; 13359 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13360 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13361 if (carry != ~0u) 13362 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13363 if (overflow != ~0u) 13364 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13365 if (m_new_inst_cpsr != m_opcode_cpsr) 13366 { 13367 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13368 return false; 13369 } 13370 return true; 13371 } 13372 13373 bool 13374 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13375 { 13376 // Advance the ITSTATE bits to their values for the next instruction. 13377 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13378 m_it_session.ITAdvance(); 13379 13380 ARMOpcode *opcode_data = NULL; 13381 13382 if (m_opcode_mode == eModeThumb) 13383 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13384 else if (m_opcode_mode == eModeARM) 13385 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13386 13387 if (opcode_data == NULL) 13388 return false; 13389 13390 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13391 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13392 13393 bool success = false; 13394 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13395 { 13396 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13397 dwarf_cpsr, 13398 0, 13399 &success); 13400 } 13401 13402 // Only return false if we are unable to read the CPSR if we care about conditions 13403 if (success == false && m_ignore_conditions == false) 13404 return false; 13405 13406 uint32_t orig_pc_value = 0; 13407 if (auto_advance_pc) 13408 { 13409 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13410 if (!success) 13411 return false; 13412 } 13413 13414 // Call the Emulate... function. 13415 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13416 if (!success) 13417 return false; 13418 13419 if (auto_advance_pc) 13420 { 13421 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13422 if (!success) 13423 return false; 13424 13425 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13426 { 13427 if (opcode_data->size == eSize32) 13428 after_pc_value += 4; 13429 else if (opcode_data->size == eSize16) 13430 after_pc_value += 2; 13431 13432 EmulateInstruction::Context context; 13433 context.type = eContextAdvancePC; 13434 context.SetNoArgs(); 13435 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13436 return false; 13437 13438 } 13439 } 13440 return true; 13441 } 13442 13443 bool 13444 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13445 { 13446 if (!test_data) 13447 { 13448 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13449 return false; 13450 } 13451 13452 static ConstString opcode_key ("opcode"); 13453 static ConstString before_key ("before_state"); 13454 static ConstString after_key ("after_state"); 13455 13456 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13457 13458 uint32_t test_opcode; 13459 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13460 { 13461 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13462 return false; 13463 } 13464 test_opcode = value_sp->GetUInt64Value (); 13465 13466 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13467 { 13468 m_opcode_mode = eModeARM; 13469 m_opcode.SetOpcode32 (test_opcode); 13470 } 13471 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13472 { 13473 m_opcode_mode = eModeThumb; 13474 if (test_opcode < 0x10000) 13475 m_opcode.SetOpcode16 (test_opcode); 13476 else 13477 m_opcode.SetOpcode32 (test_opcode); 13478 13479 } 13480 else 13481 { 13482 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13483 return false; 13484 } 13485 13486 EmulationStateARM before_state; 13487 EmulationStateARM after_state; 13488 13489 value_sp = test_data->GetValueForKey (before_key); 13490 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13491 { 13492 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13493 return false; 13494 } 13495 13496 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13497 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13498 { 13499 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13500 return false; 13501 } 13502 13503 value_sp = test_data->GetValueForKey (after_key); 13504 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13505 { 13506 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13507 return false; 13508 } 13509 13510 state_dictionary = value_sp->GetAsDictionary (); 13511 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13512 { 13513 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13514 return false; 13515 } 13516 13517 SetBaton ((void *) &before_state); 13518 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13519 &EmulationStateARM::WritePseudoMemory, 13520 &EmulationStateARM::ReadPseudoRegister, 13521 &EmulationStateARM::WritePseudoRegister); 13522 13523 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13524 if (!success) 13525 { 13526 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13527 return false; 13528 } 13529 13530 success = before_state.CompareState (after_state); 13531 if (!success) 13532 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13533 13534 return success; 13535 } 13536 // 13537 // 13538 //const char * 13539 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13540 //{ 13541 // if (reg_kind == eRegisterKindGeneric) 13542 // { 13543 // switch (reg_num) 13544 // { 13545 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 13546 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 13547 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 13548 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 13549 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13550 // default: return NULL; 13551 // } 13552 // } 13553 // else if (reg_kind == eRegisterKindDWARF) 13554 // { 13555 // return GetARMDWARFRegisterName (reg_num); 13556 // } 13557 // return NULL; 13558 //} 13559 // 13560 bool 13561 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13562 { 13563 unwind_plan.Clear(); 13564 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13565 13566 UnwindPlan::Row row; 13567 13568 // Our previous Call Frame Address is the stack pointer 13569 row.SetCFARegister (dwarf_sp); 13570 13571 // Our previous PC is in the LR 13572 row.SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true); 13573 unwind_plan.AppendRow (row); 13574 13575 // All other registers are the same. 13576 13577 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13578 return true; 13579 } 13580 13581 13582 13583 13584