EmulateInstructionARM.cpp revision 314564
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/Address.h" 15#include "lldb/Core/ArchSpec.h" 16#include "lldb/Core/ConstString.h" 17#include "lldb/Core/PluginManager.h" 18#include "lldb/Core/Stream.h" 19#include "lldb/Host/PosixApi.h" 20#include "lldb/Interpreter/OptionValueArray.h" 21#include "lldb/Interpreter/OptionValueDictionary.h" 22#include "lldb/Symbol/UnwindPlan.h" 23 24#include "Plugins/Process/Utility/ARMDefines.h" 25#include "Plugins/Process/Utility/ARMUtils.h" 26#include "Utility/ARM_DWARF_Registers.h" 27 28#include "llvm/ADT/STLExtras.h" 29#include "llvm/Support/MathExtras.h" // for SignExtend32 template function 30 // and countTrailingZeros function 31 32using namespace lldb; 33using namespace lldb_private; 34 35// Convenient macro definitions. 36#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 37#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 38 39#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 40 41//---------------------------------------------------------------------- 42// 43// ITSession implementation 44// 45//---------------------------------------------------------------------- 46 47// A8.6.50 48// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 49static uint32_t CountITSize(uint32_t ITMask) { 50 // First count the trailing zeros of the IT mask. 51 uint32_t TZ = llvm::countTrailingZeros(ITMask); 52 if (TZ > 3) { 53#ifdef LLDB_CONFIGURATION_DEBUG 54 printf("Encoding error: IT Mask '0000'\n"); 55#endif 56 return 0; 57 } 58 return (4 - TZ); 59} 60 61// Init ITState. Note that at least one bit is always 1 in mask. 62bool ITSession::InitIT(uint32_t bits7_0) { 63 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 64 if (ITCounter == 0) 65 return false; 66 67 // A8.6.50 IT 68 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 69 if (FirstCond == 0xF) { 70#ifdef LLDB_CONFIGURATION_DEBUG 71 printf("Encoding error: IT FirstCond '1111'\n"); 72#endif 73 return false; 74 } 75 if (FirstCond == 0xE && ITCounter != 1) { 76#ifdef LLDB_CONFIGURATION_DEBUG 77 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 78#endif 79 return false; 80 } 81 82 ITState = bits7_0; 83 return true; 84} 85 86// Update ITState if necessary. 87void ITSession::ITAdvance() { 88 // assert(ITCounter); 89 --ITCounter; 90 if (ITCounter == 0) 91 ITState = 0; 92 else { 93 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 94 SetBits32(ITState, 4, 0, NewITState4_0); 95 } 96} 97 98// Return true if we're inside an IT Block. 99bool ITSession::InITBlock() { return ITCounter != 0; } 100 101// Return true if we're the last instruction inside an IT Block. 102bool ITSession::LastInITBlock() { return ITCounter == 1; } 103 104// Get condition bits for the current thumb instruction. 105uint32_t ITSession::GetCond() { 106 if (InITBlock()) 107 return Bits32(ITState, 7, 4); 108 else 109 return COND_AL; 110} 111 112// ARM constants used during decoding 113#define REG_RD 0 114#define LDM_REGLIST 1 115#define SP_REG 13 116#define LR_REG 14 117#define PC_REG 15 118#define PC_REGLIST_BIT 0x8000 119 120#define ARMv4 (1u << 0) 121#define ARMv4T (1u << 1) 122#define ARMv5T (1u << 2) 123#define ARMv5TE (1u << 3) 124#define ARMv5TEJ (1u << 4) 125#define ARMv6 (1u << 5) 126#define ARMv6K (1u << 6) 127#define ARMv6T2 (1u << 7) 128#define ARMv7 (1u << 8) 129#define ARMv7S (1u << 9) 130#define ARMv8 (1u << 10) 131#define ARMvAll (0xffffffffu) 132 133#define ARMV4T_ABOVE \ 134 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \ 135 ARMv7S | ARMv8) 136#define ARMV5_ABOVE \ 137 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \ 138 ARMv8) 139#define ARMV5TE_ABOVE \ 140 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 141#define ARMV5J_ABOVE \ 142 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 143#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 144#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 145#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8) 146 147#define No_VFP 0 148#define VFPv1 (1u << 1) 149#define VFPv2 (1u << 2) 150#define VFPv3 (1u << 3) 151#define AdvancedSIMD (1u << 4) 152 153#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 154#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 155#define VFPv2v3 (VFPv2 | VFPv3) 156 157//---------------------------------------------------------------------- 158// 159// EmulateInstructionARM implementation 160// 161//---------------------------------------------------------------------- 162 163void EmulateInstructionARM::Initialize() { 164 PluginManager::RegisterPlugin(GetPluginNameStatic(), 165 GetPluginDescriptionStatic(), CreateInstance); 166} 167 168void EmulateInstructionARM::Terminate() { 169 PluginManager::UnregisterPlugin(CreateInstance); 170} 171 172ConstString EmulateInstructionARM::GetPluginNameStatic() { 173 static ConstString g_name("arm"); 174 return g_name; 175} 176 177const char *EmulateInstructionARM::GetPluginDescriptionStatic() { 178 return "Emulate instructions for the ARM architecture."; 179} 180 181EmulateInstruction * 182EmulateInstructionARM::CreateInstance(const ArchSpec &arch, 183 InstructionType inst_type) { 184 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic( 185 inst_type)) { 186 if (arch.GetTriple().getArch() == llvm::Triple::arm) { 187 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap( 188 new EmulateInstructionARM(arch)); 189 190 if (emulate_insn_ap.get()) 191 return emulate_insn_ap.release(); 192 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) { 193 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap( 194 new EmulateInstructionARM(arch)); 195 196 if (emulate_insn_ap.get()) 197 return emulate_insn_ap.release(); 198 } 199 } 200 201 return NULL; 202} 203 204bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) { 205 if (arch.GetTriple().getArch() == llvm::Triple::arm) 206 return true; 207 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 208 return true; 209 210 return false; 211} 212 213// Write "bits (32) UNKNOWN" to memory address "address". Helper function for 214// many ARM instructions. 215bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) { 216 EmulateInstruction::Context context; 217 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 218 context.SetNoArgs(); 219 220 uint32_t random_data = rand(); 221 const uint32_t addr_byte_size = GetAddressByteSize(); 222 223 if (!MemAWrite(context, address, random_data, addr_byte_size)) 224 return false; 225 226 return true; 227} 228 229// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM 230// instructions. 231bool EmulateInstructionARM::WriteBits32Unknown(int n) { 232 EmulateInstruction::Context context; 233 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 234 context.SetNoArgs(); 235 236 bool success; 237 uint32_t data = 238 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 239 240 if (!success) 241 return false; 242 243 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data)) 244 return false; 245 246 return true; 247} 248 249bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind, 250 uint32_t reg_num, 251 RegisterInfo ®_info) { 252 if (reg_kind == eRegisterKindGeneric) { 253 switch (reg_num) { 254 case LLDB_REGNUM_GENERIC_PC: 255 reg_kind = eRegisterKindDWARF; 256 reg_num = dwarf_pc; 257 break; 258 case LLDB_REGNUM_GENERIC_SP: 259 reg_kind = eRegisterKindDWARF; 260 reg_num = dwarf_sp; 261 break; 262 case LLDB_REGNUM_GENERIC_FP: 263 reg_kind = eRegisterKindDWARF; 264 reg_num = dwarf_r7; 265 break; 266 case LLDB_REGNUM_GENERIC_RA: 267 reg_kind = eRegisterKindDWARF; 268 reg_num = dwarf_lr; 269 break; 270 case LLDB_REGNUM_GENERIC_FLAGS: 271 reg_kind = eRegisterKindDWARF; 272 reg_num = dwarf_cpsr; 273 break; 274 default: 275 return false; 276 } 277 } 278 279 if (reg_kind == eRegisterKindDWARF) 280 return GetARMDWARFRegisterInfo(reg_num, reg_info); 281 return false; 282} 283 284uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const { 285 if (m_arch.GetTriple().isAndroid()) 286 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 287 bool is_apple = false; 288 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 289 is_apple = true; 290 switch (m_arch.GetTriple().getOS()) { 291 case llvm::Triple::Darwin: 292 case llvm::Triple::MacOSX: 293 case llvm::Triple::IOS: 294 case llvm::Triple::TvOS: 295 case llvm::Triple::WatchOS: 296 is_apple = true; 297 break; 298 default: 299 break; 300 } 301 302 /* On Apple iOS et al, the frame pointer register is always r7. 303 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 304 */ 305 306 uint32_t fp_regnum = 11; 307 308 if (is_apple) 309 fp_regnum = 7; 310 311 if (m_opcode_mode == eModeThumb) 312 fp_regnum = 7; 313 314 return fp_regnum; 315} 316 317uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const { 318 bool is_apple = false; 319 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 320 is_apple = true; 321 switch (m_arch.GetTriple().getOS()) { 322 case llvm::Triple::Darwin: 323 case llvm::Triple::MacOSX: 324 case llvm::Triple::IOS: 325 is_apple = true; 326 break; 327 default: 328 break; 329 } 330 331 /* On Apple iOS et al, the frame pointer register is always r7. 332 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 333 */ 334 335 uint32_t fp_regnum = dwarf_r11; 336 337 if (is_apple) 338 fp_regnum = dwarf_r7; 339 340 if (m_opcode_mode == eModeThumb) 341 fp_regnum = dwarf_r7; 342 343 return fp_regnum; 344} 345 346// Push Multiple Registers stores multiple registers to the stack, storing to 347// consecutive memory locations ending just below the address in SP, and updates 348// SP to point to the start of the stored data. 349bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode, 350 const ARMEncoding encoding) { 351#if 0 352 // ARM pseudo code... 353 if (ConditionPassed()) 354 { 355 EncodingSpecificOperations(); 356 NullCheckIfThumbEE(13); 357 address = SP - 4*BitCount(registers); 358 359 for (i = 0 to 14) 360 { 361 if (registers<i> == '1') 362 { 363 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 364 MemA[address,4] = bits(32) UNKNOWN; 365 else 366 MemA[address,4] = R[i]; 367 address = address + 4; 368 } 369 } 370 371 if (registers<15> == '1') // Only possible for encoding A1 or A2 372 MemA[address,4] = PCStoreValue(); 373 374 SP = SP - 4*BitCount(registers); 375 } 376#endif 377 378 bool success = false; 379 if (ConditionPassed(opcode)) { 380 const uint32_t addr_byte_size = GetAddressByteSize(); 381 const addr_t sp = ReadCoreReg(SP_REG, &success); 382 if (!success) 383 return false; 384 uint32_t registers = 0; 385 uint32_t Rt; // the source register 386 switch (encoding) { 387 case eEncodingT1: 388 registers = Bits32(opcode, 7, 0); 389 // The M bit represents LR. 390 if (Bit32(opcode, 8)) 391 registers |= (1u << 14); 392 // if BitCount(registers) < 1 then UNPREDICTABLE; 393 if (BitCount(registers) < 1) 394 return false; 395 break; 396 case eEncodingT2: 397 // Ignore bits 15 & 13. 398 registers = Bits32(opcode, 15, 0) & ~0xa000; 399 // if BitCount(registers) < 2 then UNPREDICTABLE; 400 if (BitCount(registers) < 2) 401 return false; 402 break; 403 case eEncodingT3: 404 Rt = Bits32(opcode, 15, 12); 405 // if BadReg(t) then UNPREDICTABLE; 406 if (BadReg(Rt)) 407 return false; 408 registers = (1u << Rt); 409 break; 410 case eEncodingA1: 411 registers = Bits32(opcode, 15, 0); 412 // Instead of return false, let's handle the following case as well, 413 // which amounts to pushing one reg onto the full descending stacks. 414 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 415 break; 416 case eEncodingA2: 417 Rt = Bits32(opcode, 15, 12); 418 // if t == 13 then UNPREDICTABLE; 419 if (Rt == dwarf_sp) 420 return false; 421 registers = (1u << Rt); 422 break; 423 default: 424 return false; 425 } 426 addr_t sp_offset = addr_byte_size * BitCount(registers); 427 addr_t addr = sp - sp_offset; 428 uint32_t i; 429 430 EmulateInstruction::Context context; 431 context.type = EmulateInstruction::eContextPushRegisterOnStack; 432 RegisterInfo reg_info; 433 RegisterInfo sp_reg; 434 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 435 for (i = 0; i < 15; ++i) { 436 if (BitIsSet(registers, i)) { 437 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info); 438 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 439 uint32_t reg_value = ReadCoreReg(i, &success); 440 if (!success) 441 return false; 442 if (!MemAWrite(context, addr, reg_value, addr_byte_size)) 443 return false; 444 addr += addr_byte_size; 445 } 446 } 447 448 if (BitIsSet(registers, 15)) { 449 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info); 450 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 451 const uint32_t pc = ReadCoreReg(PC_REG, &success); 452 if (!success) 453 return false; 454 if (!MemAWrite(context, addr, pc, addr_byte_size)) 455 return false; 456 } 457 458 context.type = EmulateInstruction::eContextAdjustStackPointer; 459 context.SetImmediateSigned(-sp_offset); 460 461 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 462 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 463 return false; 464 } 465 return true; 466} 467 468// Pop Multiple Registers loads multiple registers from the stack, loading from 469// consecutive memory locations staring at the address in SP, and updates 470// SP to point just above the loaded data. 471bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode, 472 const ARMEncoding encoding) { 473#if 0 474 // ARM pseudo code... 475 if (ConditionPassed()) 476 { 477 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 478 address = SP; 479 for i = 0 to 14 480 if registers<i> == '1' then 481 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 482 if registers<15> == '1' then 483 if UnalignedAllowed then 484 LoadWritePC(MemU[address,4]); 485 else 486 LoadWritePC(MemA[address,4]); 487 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 488 if registers<13> == '1' then SP = bits(32) UNKNOWN; 489 } 490#endif 491 492 bool success = false; 493 494 if (ConditionPassed(opcode)) { 495 const uint32_t addr_byte_size = GetAddressByteSize(); 496 const addr_t sp = ReadCoreReg(SP_REG, &success); 497 if (!success) 498 return false; 499 uint32_t registers = 0; 500 uint32_t Rt; // the destination register 501 switch (encoding) { 502 case eEncodingT1: 503 registers = Bits32(opcode, 7, 0); 504 // The P bit represents PC. 505 if (Bit32(opcode, 8)) 506 registers |= (1u << 15); 507 // if BitCount(registers) < 1 then UNPREDICTABLE; 508 if (BitCount(registers) < 1) 509 return false; 510 break; 511 case eEncodingT2: 512 // Ignore bit 13. 513 registers = Bits32(opcode, 15, 0) & ~0x2000; 514 // if BitCount(registers) < 2 || (P == '1' && M == '1') then 515 // UNPREDICTABLE; 516 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 517 return false; 518 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 519 // UNPREDICTABLE; 520 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 521 return false; 522 break; 523 case eEncodingT3: 524 Rt = Bits32(opcode, 15, 12); 525 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then 526 // UNPREDICTABLE; 527 if (Rt == 13) 528 return false; 529 if (Rt == 15 && InITBlock() && !LastInITBlock()) 530 return false; 531 registers = (1u << Rt); 532 break; 533 case eEncodingA1: 534 registers = Bits32(opcode, 15, 0); 535 // Instead of return false, let's handle the following case as well, 536 // which amounts to popping one reg from the full descending stacks. 537 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 538 539 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 540 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 541 return false; 542 break; 543 case eEncodingA2: 544 Rt = Bits32(opcode, 15, 12); 545 // if t == 13 then UNPREDICTABLE; 546 if (Rt == dwarf_sp) 547 return false; 548 registers = (1u << Rt); 549 break; 550 default: 551 return false; 552 } 553 addr_t sp_offset = addr_byte_size * BitCount(registers); 554 addr_t addr = sp; 555 uint32_t i, data; 556 557 EmulateInstruction::Context context; 558 context.type = EmulateInstruction::eContextPopRegisterOffStack; 559 560 RegisterInfo sp_reg; 561 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 562 563 for (i = 0; i < 15; ++i) { 564 if (BitIsSet(registers, i)) { 565 context.SetAddress(addr); 566 data = MemARead(context, addr, 4, 0, &success); 567 if (!success) 568 return false; 569 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 570 data)) 571 return false; 572 addr += addr_byte_size; 573 } 574 } 575 576 if (BitIsSet(registers, 15)) { 577 context.SetRegisterPlusOffset(sp_reg, addr - sp); 578 data = MemARead(context, addr, 4, 0, &success); 579 if (!success) 580 return false; 581 // In ARMv5T and above, this is an interworking branch. 582 if (!LoadWritePC(context, data)) 583 return false; 584 // addr += addr_byte_size; 585 } 586 587 context.type = EmulateInstruction::eContextAdjustStackPointer; 588 context.SetImmediateSigned(sp_offset); 589 590 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 591 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 592 return false; 593 } 594 return true; 595} 596 597// Set r7 or ip to point to saved value residing within the stack. 598// ADD (SP plus immediate) 599bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode, 600 const ARMEncoding encoding) { 601#if 0 602 // ARM pseudo code... 603 if (ConditionPassed()) 604 { 605 EncodingSpecificOperations(); 606 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 607 if d == 15 then 608 ALUWritePC(result); // setflags is always FALSE here 609 else 610 R[d] = result; 611 if setflags then 612 APSR.N = result<31>; 613 APSR.Z = IsZeroBit(result); 614 APSR.C = carry; 615 APSR.V = overflow; 616 } 617#endif 618 619 bool success = false; 620 621 if (ConditionPassed(opcode)) { 622 const addr_t sp = ReadCoreReg(SP_REG, &success); 623 if (!success) 624 return false; 625 uint32_t Rd; // the destination register 626 uint32_t imm32; 627 switch (encoding) { 628 case eEncodingT1: 629 Rd = 7; 630 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 631 break; 632 case eEncodingA1: 633 Rd = Bits32(opcode, 15, 12); 634 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 635 break; 636 default: 637 return false; 638 } 639 addr_t sp_offset = imm32; 640 addr_t addr = sp + sp_offset; // a pointer to the stack area 641 642 EmulateInstruction::Context context; 643 if (Rd == GetFramePointerRegisterNumber()) 644 context.type = eContextSetFramePointer; 645 else 646 context.type = EmulateInstruction::eContextRegisterPlusOffset; 647 RegisterInfo sp_reg; 648 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 649 context.SetRegisterPlusOffset(sp_reg, sp_offset); 650 651 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, 652 addr)) 653 return false; 654 } 655 return true; 656} 657 658// Set r7 or ip to the current stack pointer. 659// MOV (register) 660bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode, 661 const ARMEncoding encoding) { 662#if 0 663 // ARM pseudo code... 664 if (ConditionPassed()) 665 { 666 EncodingSpecificOperations(); 667 result = R[m]; 668 if d == 15 then 669 ALUWritePC(result); // setflags is always FALSE here 670 else 671 R[d] = result; 672 if setflags then 673 APSR.N = result<31>; 674 APSR.Z = IsZeroBit(result); 675 // APSR.C unchanged 676 // APSR.V unchanged 677 } 678#endif 679 680 bool success = false; 681 682 if (ConditionPassed(opcode)) { 683 const addr_t sp = ReadCoreReg(SP_REG, &success); 684 if (!success) 685 return false; 686 uint32_t Rd; // the destination register 687 switch (encoding) { 688 case eEncodingT1: 689 Rd = 7; 690 break; 691 case eEncodingA1: 692 Rd = 12; 693 break; 694 default: 695 return false; 696 } 697 698 EmulateInstruction::Context context; 699 if (Rd == GetFramePointerRegisterNumber()) 700 context.type = EmulateInstruction::eContextSetFramePointer; 701 else 702 context.type = EmulateInstruction::eContextRegisterPlusOffset; 703 RegisterInfo sp_reg; 704 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 705 context.SetRegisterPlusOffset(sp_reg, 0); 706 707 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 708 return false; 709 } 710 return true; 711} 712 713// Move from high register (r8-r15) to low register (r0-r7). 714// MOV (register) 715bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode, 716 const ARMEncoding encoding) { 717 return EmulateMOVRdRm(opcode, encoding); 718} 719 720// Move from register to register. 721// MOV (register) 722bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode, 723 const ARMEncoding encoding) { 724#if 0 725 // ARM pseudo code... 726 if (ConditionPassed()) 727 { 728 EncodingSpecificOperations(); 729 result = R[m]; 730 if d == 15 then 731 ALUWritePC(result); // setflags is always FALSE here 732 else 733 R[d] = result; 734 if setflags then 735 APSR.N = result<31>; 736 APSR.Z = IsZeroBit(result); 737 // APSR.C unchanged 738 // APSR.V unchanged 739 } 740#endif 741 742 bool success = false; 743 744 if (ConditionPassed(opcode)) { 745 uint32_t Rm; // the source register 746 uint32_t Rd; // the destination register 747 bool setflags; 748 switch (encoding) { 749 case eEncodingT1: 750 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 751 Rm = Bits32(opcode, 6, 3); 752 setflags = false; 753 if (Rd == 15 && InITBlock() && !LastInITBlock()) 754 return false; 755 break; 756 case eEncodingT2: 757 Rd = Bits32(opcode, 2, 0); 758 Rm = Bits32(opcode, 5, 3); 759 setflags = true; 760 if (InITBlock()) 761 return false; 762 break; 763 case eEncodingT3: 764 Rd = Bits32(opcode, 11, 8); 765 Rm = Bits32(opcode, 3, 0); 766 setflags = BitIsSet(opcode, 20); 767 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 768 if (setflags && (BadReg(Rd) || BadReg(Rm))) 769 return false; 770 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then 771 // UNPREDICTABLE; 772 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 773 return false; 774 break; 775 case eEncodingA1: 776 Rd = Bits32(opcode, 15, 12); 777 Rm = Bits32(opcode, 3, 0); 778 setflags = BitIsSet(opcode, 20); 779 780 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 781 // instructions; 782 if (Rd == 15 && setflags) 783 return EmulateSUBSPcLrEtc(opcode, encoding); 784 break; 785 default: 786 return false; 787 } 788 uint32_t result = ReadCoreReg(Rm, &success); 789 if (!success) 790 return false; 791 792 // The context specifies that Rm is to be moved into Rd. 793 EmulateInstruction::Context context; 794 if (Rd == 13) 795 context.type = EmulateInstruction::eContextAdjustStackPointer; 796 else 797 context.type = EmulateInstruction::eContextRegisterPlusOffset; 798 RegisterInfo dwarf_reg; 799 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 800 context.SetRegisterPlusOffset(dwarf_reg, 0); 801 802 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 803 return false; 804 } 805 return true; 806} 807 808// Move (immediate) writes an immediate value to the destination register. It 809// can optionally update the condition flags based on the value. 810// MOV (immediate) 811bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode, 812 const ARMEncoding encoding) { 813#if 0 814 // ARM pseudo code... 815 if (ConditionPassed()) 816 { 817 EncodingSpecificOperations(); 818 result = imm32; 819 if d == 15 then // Can only occur for ARM encoding 820 ALUWritePC(result); // setflags is always FALSE here 821 else 822 R[d] = result; 823 if setflags then 824 APSR.N = result<31>; 825 APSR.Z = IsZeroBit(result); 826 APSR.C = carry; 827 // APSR.V unchanged 828 } 829#endif 830 831 if (ConditionPassed(opcode)) { 832 uint32_t Rd; // the destination register 833 uint32_t imm32; // the immediate value to be written to Rd 834 uint32_t carry = 835 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 836 // for setflags == false, this value is a don't care 837 // initialized to 0 to silence the static analyzer 838 bool setflags; 839 switch (encoding) { 840 case eEncodingT1: 841 Rd = Bits32(opcode, 10, 8); 842 setflags = !InITBlock(); 843 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 844 carry = APSR_C; 845 846 break; 847 848 case eEncodingT2: 849 Rd = Bits32(opcode, 11, 8); 850 setflags = BitIsSet(opcode, 20); 851 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 852 if (BadReg(Rd)) 853 return false; 854 855 break; 856 857 case eEncodingT3: { 858 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 859 // 32); 860 Rd = Bits32(opcode, 11, 8); 861 setflags = false; 862 uint32_t imm4 = Bits32(opcode, 19, 16); 863 uint32_t imm3 = Bits32(opcode, 14, 12); 864 uint32_t i = Bit32(opcode, 26); 865 uint32_t imm8 = Bits32(opcode, 7, 0); 866 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 867 868 // if BadReg(d) then UNPREDICTABLE; 869 if (BadReg(Rd)) 870 return false; 871 } break; 872 873 case eEncodingA1: 874 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = 875 // ARMExpandImm_C(imm12, APSR.C); 876 Rd = Bits32(opcode, 15, 12); 877 setflags = BitIsSet(opcode, 20); 878 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 879 880 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 881 // instructions; 882 if ((Rd == 15) && setflags) 883 return EmulateSUBSPcLrEtc(opcode, encoding); 884 885 break; 886 887 case eEncodingA2: { 888 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 889 Rd = Bits32(opcode, 15, 12); 890 setflags = false; 891 uint32_t imm4 = Bits32(opcode, 19, 16); 892 uint32_t imm12 = Bits32(opcode, 11, 0); 893 imm32 = (imm4 << 12) | imm12; 894 895 // if d == 15 then UNPREDICTABLE; 896 if (Rd == 15) 897 return false; 898 } break; 899 900 default: 901 return false; 902 } 903 uint32_t result = imm32; 904 905 // The context specifies that an immediate is to be moved into Rd. 906 EmulateInstruction::Context context; 907 context.type = EmulateInstruction::eContextImmediate; 908 context.SetNoArgs(); 909 910 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 911 return false; 912 } 913 return true; 914} 915 916// MUL multiplies two register values. The least significant 32 bits of the 917// result are written to the destination 918// register. These 32 bits do not depend on whether the source register values 919// are considered to be signed values or 920// unsigned values. 921// 922// Optionally, it can update the condition flags based on the result. In the 923// Thumb instruction set, this option is 924// limited to only a few forms of the instruction. 925bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode, 926 const ARMEncoding encoding) { 927#if 0 928 if ConditionPassed() then 929 EncodingSpecificOperations(); 930 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 931 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 932 result = operand1 * operand2; 933 R[d] = result<31:0>; 934 if setflags then 935 APSR.N = result<31>; 936 APSR.Z = IsZeroBit(result); 937 if ArchVersion() == 4 then 938 APSR.C = bit UNKNOWN; 939 // else APSR.C unchanged 940 // APSR.V always unchanged 941#endif 942 943 if (ConditionPassed(opcode)) { 944 uint32_t d; 945 uint32_t n; 946 uint32_t m; 947 bool setflags; 948 949 // EncodingSpecificOperations(); 950 switch (encoding) { 951 case eEncodingT1: 952 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 953 d = Bits32(opcode, 2, 0); 954 n = Bits32(opcode, 5, 3); 955 m = Bits32(opcode, 2, 0); 956 setflags = !InITBlock(); 957 958 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 959 if ((ArchVersion() < ARMv6) && (d == n)) 960 return false; 961 962 break; 963 964 case eEncodingT2: 965 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 966 d = Bits32(opcode, 11, 8); 967 n = Bits32(opcode, 19, 16); 968 m = Bits32(opcode, 3, 0); 969 setflags = false; 970 971 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 972 if (BadReg(d) || BadReg(n) || BadReg(m)) 973 return false; 974 975 break; 976 977 case eEncodingA1: 978 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 979 d = Bits32(opcode, 19, 16); 980 n = Bits32(opcode, 3, 0); 981 m = Bits32(opcode, 11, 8); 982 setflags = BitIsSet(opcode, 20); 983 984 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 985 if ((d == 15) || (n == 15) || (m == 15)) 986 return false; 987 988 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 989 if ((ArchVersion() < ARMv6) && (d == n)) 990 return false; 991 992 break; 993 994 default: 995 return false; 996 } 997 998 bool success = false; 999 1000 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final 1001 // results 1002 uint64_t operand1 = 1003 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1004 if (!success) 1005 return false; 1006 1007 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final 1008 // results 1009 uint64_t operand2 = 1010 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1011 if (!success) 1012 return false; 1013 1014 // result = operand1 * operand2; 1015 uint64_t result = operand1 * operand2; 1016 1017 // R[d] = result<31:0>; 1018 RegisterInfo op1_reg; 1019 RegisterInfo op2_reg; 1020 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1021 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1022 1023 EmulateInstruction::Context context; 1024 context.type = eContextArithmetic; 1025 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 1026 1027 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 1028 (0x0000ffff & result))) 1029 return false; 1030 1031 // if setflags then 1032 if (setflags) { 1033 // APSR.N = result<31>; 1034 // APSR.Z = IsZeroBit(result); 1035 m_new_inst_cpsr = m_opcode_cpsr; 1036 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31)); 1037 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1038 if (m_new_inst_cpsr != m_opcode_cpsr) { 1039 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1040 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1041 return false; 1042 } 1043 1044 // if ArchVersion() == 4 then 1045 // APSR.C = bit UNKNOWN; 1046 } 1047 } 1048 return true; 1049} 1050 1051// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 1052// the destination register. 1053// It can optionally update the condition flags based on the value. 1054bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode, 1055 const ARMEncoding encoding) { 1056#if 0 1057 // ARM pseudo code... 1058 if (ConditionPassed()) 1059 { 1060 EncodingSpecificOperations(); 1061 result = NOT(imm32); 1062 if d == 15 then // Can only occur for ARM encoding 1063 ALUWritePC(result); // setflags is always FALSE here 1064 else 1065 R[d] = result; 1066 if setflags then 1067 APSR.N = result<31>; 1068 APSR.Z = IsZeroBit(result); 1069 APSR.C = carry; 1070 // APSR.V unchanged 1071 } 1072#endif 1073 1074 if (ConditionPassed(opcode)) { 1075 uint32_t Rd; // the destination register 1076 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1077 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1078 bool setflags; 1079 switch (encoding) { 1080 case eEncodingT1: 1081 Rd = Bits32(opcode, 11, 8); 1082 setflags = BitIsSet(opcode, 20); 1083 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1084 break; 1085 case eEncodingA1: 1086 Rd = Bits32(opcode, 15, 12); 1087 setflags = BitIsSet(opcode, 20); 1088 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1089 1090 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1091 // instructions; 1092 if (Rd == 15 && setflags) 1093 return EmulateSUBSPcLrEtc(opcode, encoding); 1094 break; 1095 default: 1096 return false; 1097 } 1098 uint32_t result = ~imm32; 1099 1100 // The context specifies that an immediate is to be moved into Rd. 1101 EmulateInstruction::Context context; 1102 context.type = EmulateInstruction::eContextImmediate; 1103 context.SetNoArgs(); 1104 1105 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1106 return false; 1107 } 1108 return true; 1109} 1110 1111// Bitwise NOT (register) writes the bitwise inverse of a register value to the 1112// destination register. 1113// It can optionally update the condition flags based on the result. 1114bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode, 1115 const ARMEncoding encoding) { 1116#if 0 1117 // ARM pseudo code... 1118 if (ConditionPassed()) 1119 { 1120 EncodingSpecificOperations(); 1121 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1122 result = NOT(shifted); 1123 if d == 15 then // Can only occur for ARM encoding 1124 ALUWritePC(result); // setflags is always FALSE here 1125 else 1126 R[d] = result; 1127 if setflags then 1128 APSR.N = result<31>; 1129 APSR.Z = IsZeroBit(result); 1130 APSR.C = carry; 1131 // APSR.V unchanged 1132 } 1133#endif 1134 1135 if (ConditionPassed(opcode)) { 1136 uint32_t Rm; // the source register 1137 uint32_t Rd; // the destination register 1138 ARM_ShifterType shift_t; 1139 uint32_t shift_n; // the shift applied to the value read from Rm 1140 bool setflags; 1141 uint32_t carry; // the carry bit after the shift operation 1142 switch (encoding) { 1143 case eEncodingT1: 1144 Rd = Bits32(opcode, 2, 0); 1145 Rm = Bits32(opcode, 5, 3); 1146 setflags = !InITBlock(); 1147 shift_t = SRType_LSL; 1148 shift_n = 0; 1149 if (InITBlock()) 1150 return false; 1151 break; 1152 case eEncodingT2: 1153 Rd = Bits32(opcode, 11, 8); 1154 Rm = Bits32(opcode, 3, 0); 1155 setflags = BitIsSet(opcode, 20); 1156 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1157 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1158 if (BadReg(Rd) || BadReg(Rm)) 1159 return false; 1160 break; 1161 case eEncodingA1: 1162 Rd = Bits32(opcode, 15, 12); 1163 Rm = Bits32(opcode, 3, 0); 1164 setflags = BitIsSet(opcode, 20); 1165 shift_n = DecodeImmShiftARM(opcode, shift_t); 1166 break; 1167 default: 1168 return false; 1169 } 1170 bool success = false; 1171 uint32_t value = ReadCoreReg(Rm, &success); 1172 if (!success) 1173 return false; 1174 1175 uint32_t shifted = 1176 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1177 if (!success) 1178 return false; 1179 uint32_t result = ~shifted; 1180 1181 // The context specifies that an immediate is to be moved into Rd. 1182 EmulateInstruction::Context context; 1183 context.type = EmulateInstruction::eContextImmediate; 1184 context.SetNoArgs(); 1185 1186 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1187 return false; 1188 } 1189 return true; 1190} 1191 1192// PC relative immediate load into register, possibly followed by ADD (SP plus 1193// register). 1194// LDR (literal) 1195bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode, 1196 const ARMEncoding encoding) { 1197#if 0 1198 // ARM pseudo code... 1199 if (ConditionPassed()) 1200 { 1201 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1202 base = Align(PC,4); 1203 address = if add then (base + imm32) else (base - imm32); 1204 data = MemU[address,4]; 1205 if t == 15 then 1206 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1207 elsif UnalignedSupport() || address<1:0> = '00' then 1208 R[t] = data; 1209 else // Can only apply before ARMv7 1210 if CurrentInstrSet() == InstrSet_ARM then 1211 R[t] = ROR(data, 8*UInt(address<1:0>)); 1212 else 1213 R[t] = bits(32) UNKNOWN; 1214 } 1215#endif 1216 1217 if (ConditionPassed(opcode)) { 1218 bool success = false; 1219 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1220 if (!success) 1221 return false; 1222 1223 // PC relative immediate load context 1224 EmulateInstruction::Context context; 1225 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1226 RegisterInfo pc_reg; 1227 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 1228 context.SetRegisterPlusOffset(pc_reg, 0); 1229 1230 uint32_t Rt; // the destination register 1231 uint32_t imm32; // immediate offset from the PC 1232 bool add; // +imm32 or -imm32? 1233 addr_t base; // the base address 1234 addr_t address; // the PC relative address 1235 uint32_t data; // the literal data value from the PC relative load 1236 switch (encoding) { 1237 case eEncodingT1: 1238 Rt = Bits32(opcode, 10, 8); 1239 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1240 add = true; 1241 break; 1242 case eEncodingT2: 1243 Rt = Bits32(opcode, 15, 12); 1244 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1245 add = BitIsSet(opcode, 23); 1246 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1247 return false; 1248 break; 1249 default: 1250 return false; 1251 } 1252 1253 base = Align(pc, 4); 1254 if (add) 1255 address = base + imm32; 1256 else 1257 address = base - imm32; 1258 1259 context.SetRegisterPlusOffset(pc_reg, address - base); 1260 data = MemURead(context, address, 4, 0, &success); 1261 if (!success) 1262 return false; 1263 1264 if (Rt == 15) { 1265 if (Bits32(address, 1, 0) == 0) { 1266 // In ARMv5T and above, this is an interworking branch. 1267 if (!LoadWritePC(context, data)) 1268 return false; 1269 } else 1270 return false; 1271 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 1272 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 1273 data)) 1274 return false; 1275 } else // We don't handle ARM for now. 1276 return false; 1277 } 1278 return true; 1279} 1280 1281// An add operation to adjust the SP. 1282// ADD (SP plus immediate) 1283bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode, 1284 const ARMEncoding encoding) { 1285#if 0 1286 // ARM pseudo code... 1287 if (ConditionPassed()) 1288 { 1289 EncodingSpecificOperations(); 1290 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1291 if d == 15 then // Can only occur for ARM encoding 1292 ALUWritePC(result); // setflags is always FALSE here 1293 else 1294 R[d] = result; 1295 if setflags then 1296 APSR.N = result<31>; 1297 APSR.Z = IsZeroBit(result); 1298 APSR.C = carry; 1299 APSR.V = overflow; 1300 } 1301#endif 1302 1303 bool success = false; 1304 1305 if (ConditionPassed(opcode)) { 1306 const addr_t sp = ReadCoreReg(SP_REG, &success); 1307 if (!success) 1308 return false; 1309 uint32_t imm32; // the immediate operand 1310 uint32_t d; 1311 bool setflags; 1312 switch (encoding) { 1313 case eEncodingT1: 1314 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1315 d = Bits32(opcode, 10, 8); 1316 imm32 = (Bits32(opcode, 7, 0) << 2); 1317 setflags = false; 1318 break; 1319 1320 case eEncodingT2: 1321 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1322 d = 13; 1323 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1324 setflags = false; 1325 break; 1326 1327 case eEncodingT3: 1328 // d = UInt(Rd); setflags = (S == "1"); imm32 = 1329 // ThumbExpandImm(i:imm3:imm8); 1330 d = Bits32(opcode, 11, 8); 1331 imm32 = ThumbExpandImm(opcode); 1332 setflags = Bit32(opcode, 20); 1333 1334 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1335 if (d == 15 && setflags == 1) 1336 return false; // CMN (immediate) not yet supported 1337 1338 // if d == 15 && S == "0" then UNPREDICTABLE; 1339 if (d == 15 && setflags == 0) 1340 return false; 1341 break; 1342 1343 case eEncodingT4: { 1344 // if Rn == '1111' then SEE ADR; 1345 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1346 d = Bits32(opcode, 11, 8); 1347 setflags = false; 1348 uint32_t i = Bit32(opcode, 26); 1349 uint32_t imm3 = Bits32(opcode, 14, 12); 1350 uint32_t imm8 = Bits32(opcode, 7, 0); 1351 imm32 = (i << 11) | (imm3 << 8) | imm8; 1352 1353 // if d == 15 then UNPREDICTABLE; 1354 if (d == 15) 1355 return false; 1356 } break; 1357 1358 default: 1359 return false; 1360 } 1361 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1362 AddWithCarryResult res = AddWithCarry(sp, imm32, 0); 1363 1364 EmulateInstruction::Context context; 1365 if (d == 13) 1366 context.type = EmulateInstruction::eContextAdjustStackPointer; 1367 else 1368 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1369 1370 RegisterInfo sp_reg; 1371 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1372 context.SetRegisterPlusOffset(sp_reg, res.result - sp); 1373 1374 if (d == 15) { 1375 if (!ALUWritePC(context, res.result)) 1376 return false; 1377 } else { 1378 // R[d] = result; 1379 // if setflags then 1380 // APSR.N = result<31>; 1381 // APSR.Z = IsZeroBit(result); 1382 // APSR.C = carry; 1383 // APSR.V = overflow; 1384 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 1385 res.carry_out, res.overflow)) 1386 return false; 1387 } 1388 } 1389 return true; 1390} 1391 1392// An add operation to adjust the SP. 1393// ADD (SP plus register) 1394bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode, 1395 const ARMEncoding encoding) { 1396#if 0 1397 // ARM pseudo code... 1398 if (ConditionPassed()) 1399 { 1400 EncodingSpecificOperations(); 1401 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1402 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1403 if d == 15 then 1404 ALUWritePC(result); // setflags is always FALSE here 1405 else 1406 R[d] = result; 1407 if setflags then 1408 APSR.N = result<31>; 1409 APSR.Z = IsZeroBit(result); 1410 APSR.C = carry; 1411 APSR.V = overflow; 1412 } 1413#endif 1414 1415 bool success = false; 1416 1417 if (ConditionPassed(opcode)) { 1418 const addr_t sp = ReadCoreReg(SP_REG, &success); 1419 if (!success) 1420 return false; 1421 uint32_t Rm; // the second operand 1422 switch (encoding) { 1423 case eEncodingT2: 1424 Rm = Bits32(opcode, 6, 3); 1425 break; 1426 default: 1427 return false; 1428 } 1429 int32_t reg_value = ReadCoreReg(Rm, &success); 1430 if (!success) 1431 return false; 1432 1433 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1434 1435 EmulateInstruction::Context context; 1436 context.type = eContextArithmetic; 1437 RegisterInfo sp_reg; 1438 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1439 1440 RegisterInfo other_reg; 1441 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1442 context.SetRegisterRegisterOperands(sp_reg, other_reg); 1443 1444 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1445 LLDB_REGNUM_GENERIC_SP, addr)) 1446 return false; 1447 } 1448 return true; 1449} 1450 1451// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1452// at a PC-relative address, and changes instruction set from ARM to Thumb, or 1453// from Thumb to ARM. 1454// BLX (immediate) 1455bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode, 1456 const ARMEncoding encoding) { 1457#if 0 1458 // ARM pseudo code... 1459 if (ConditionPassed()) 1460 { 1461 EncodingSpecificOperations(); 1462 if CurrentInstrSet() == InstrSet_ARM then 1463 LR = PC - 4; 1464 else 1465 LR = PC<31:1> : '1'; 1466 if targetInstrSet == InstrSet_ARM then 1467 targetAddress = Align(PC,4) + imm32; 1468 else 1469 targetAddress = PC + imm32; 1470 SelectInstrSet(targetInstrSet); 1471 BranchWritePC(targetAddress); 1472 } 1473#endif 1474 1475 bool success = true; 1476 1477 if (ConditionPassed(opcode)) { 1478 EmulateInstruction::Context context; 1479 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1480 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1481 if (!success) 1482 return false; 1483 addr_t lr; // next instruction address 1484 addr_t target; // target address 1485 int32_t imm32; // PC-relative offset 1486 switch (encoding) { 1487 case eEncodingT1: { 1488 lr = pc | 1u; // return address 1489 uint32_t S = Bit32(opcode, 26); 1490 uint32_t imm10 = Bits32(opcode, 25, 16); 1491 uint32_t J1 = Bit32(opcode, 13); 1492 uint32_t J2 = Bit32(opcode, 11); 1493 uint32_t imm11 = Bits32(opcode, 10, 0); 1494 uint32_t I1 = !(J1 ^ S); 1495 uint32_t I2 = !(J2 ^ S); 1496 uint32_t imm25 = 1497 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1498 imm32 = llvm::SignExtend32<25>(imm25); 1499 target = pc + imm32; 1500 SelectInstrSet(eModeThumb); 1501 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 1502 if (InITBlock() && !LastInITBlock()) 1503 return false; 1504 break; 1505 } 1506 case eEncodingT2: { 1507 lr = pc | 1u; // return address 1508 uint32_t S = Bit32(opcode, 26); 1509 uint32_t imm10H = Bits32(opcode, 25, 16); 1510 uint32_t J1 = Bit32(opcode, 13); 1511 uint32_t J2 = Bit32(opcode, 11); 1512 uint32_t imm10L = Bits32(opcode, 10, 1); 1513 uint32_t I1 = !(J1 ^ S); 1514 uint32_t I2 = !(J2 ^ S); 1515 uint32_t imm25 = 1516 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1517 imm32 = llvm::SignExtend32<25>(imm25); 1518 target = Align(pc, 4) + imm32; 1519 SelectInstrSet(eModeARM); 1520 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32); 1521 if (InITBlock() && !LastInITBlock()) 1522 return false; 1523 break; 1524 } 1525 case eEncodingA1: 1526 lr = pc - 4; // return address 1527 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1528 target = Align(pc, 4) + imm32; 1529 SelectInstrSet(eModeARM); 1530 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 1531 break; 1532 case eEncodingA2: 1533 lr = pc - 4; // return address 1534 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | 1535 Bits32(opcode, 24, 24) << 1); 1536 target = pc + imm32; 1537 SelectInstrSet(eModeThumb); 1538 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32); 1539 break; 1540 default: 1541 return false; 1542 } 1543 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1544 LLDB_REGNUM_GENERIC_RA, lr)) 1545 return false; 1546 if (!BranchWritePC(context, target)) 1547 return false; 1548 if (m_opcode_cpsr != m_new_inst_cpsr) 1549 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1550 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1551 return false; 1552 } 1553 return true; 1554} 1555 1556// Branch with Link and Exchange (register) calls a subroutine at an address and 1557// instruction set specified by a register. 1558// BLX (register) 1559bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode, 1560 const ARMEncoding encoding) { 1561#if 0 1562 // ARM pseudo code... 1563 if (ConditionPassed()) 1564 { 1565 EncodingSpecificOperations(); 1566 target = R[m]; 1567 if CurrentInstrSet() == InstrSet_ARM then 1568 next_instr_addr = PC - 4; 1569 LR = next_instr_addr; 1570 else 1571 next_instr_addr = PC - 2; 1572 LR = next_instr_addr<31:1> : '1'; 1573 BXWritePC(target); 1574 } 1575#endif 1576 1577 bool success = false; 1578 1579 if (ConditionPassed(opcode)) { 1580 EmulateInstruction::Context context; 1581 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1582 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1583 addr_t lr; // next instruction address 1584 if (!success) 1585 return false; 1586 uint32_t Rm; // the register with the target address 1587 switch (encoding) { 1588 case eEncodingT1: 1589 lr = (pc - 2) | 1u; // return address 1590 Rm = Bits32(opcode, 6, 3); 1591 // if m == 15 then UNPREDICTABLE; 1592 if (Rm == 15) 1593 return false; 1594 if (InITBlock() && !LastInITBlock()) 1595 return false; 1596 break; 1597 case eEncodingA1: 1598 lr = pc - 4; // return address 1599 Rm = Bits32(opcode, 3, 0); 1600 // if m == 15 then UNPREDICTABLE; 1601 if (Rm == 15) 1602 return false; 1603 break; 1604 default: 1605 return false; 1606 } 1607 addr_t target = ReadCoreReg(Rm, &success); 1608 if (!success) 1609 return false; 1610 RegisterInfo dwarf_reg; 1611 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1612 context.SetRegister(dwarf_reg); 1613 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1614 LLDB_REGNUM_GENERIC_RA, lr)) 1615 return false; 1616 if (!BXWritePC(context, target)) 1617 return false; 1618 } 1619 return true; 1620} 1621 1622// Branch and Exchange causes a branch to an address and instruction set 1623// specified by a register. 1624bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode, 1625 const ARMEncoding encoding) { 1626#if 0 1627 // ARM pseudo code... 1628 if (ConditionPassed()) 1629 { 1630 EncodingSpecificOperations(); 1631 BXWritePC(R[m]); 1632 } 1633#endif 1634 1635 if (ConditionPassed(opcode)) { 1636 EmulateInstruction::Context context; 1637 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1638 uint32_t Rm; // the register with the target address 1639 switch (encoding) { 1640 case eEncodingT1: 1641 Rm = Bits32(opcode, 6, 3); 1642 if (InITBlock() && !LastInITBlock()) 1643 return false; 1644 break; 1645 case eEncodingA1: 1646 Rm = Bits32(opcode, 3, 0); 1647 break; 1648 default: 1649 return false; 1650 } 1651 bool success = false; 1652 addr_t target = ReadCoreReg(Rm, &success); 1653 if (!success) 1654 return false; 1655 1656 RegisterInfo dwarf_reg; 1657 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1658 context.SetRegister(dwarf_reg); 1659 if (!BXWritePC(context, target)) 1660 return false; 1661 } 1662 return true; 1663} 1664 1665// Branch and Exchange Jazelle attempts to change to Jazelle state. If the 1666// attempt fails, it branches to an 1667// address and instruction set specified by a register as though it were a BX 1668// instruction. 1669// 1670// TODO: Emulate Jazelle architecture? 1671// We currently assume that switching to Jazelle state fails, thus 1672// treating BXJ as a BX operation. 1673bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode, 1674 const ARMEncoding encoding) { 1675#if 0 1676 // ARM pseudo code... 1677 if (ConditionPassed()) 1678 { 1679 EncodingSpecificOperations(); 1680 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1681 BXWritePC(R[m]); 1682 else 1683 if JazelleAcceptsExecution() then 1684 SwitchToJazelleExecution(); 1685 else 1686 SUBARCHITECTURE_DEFINED handler call; 1687 } 1688#endif 1689 1690 if (ConditionPassed(opcode)) { 1691 EmulateInstruction::Context context; 1692 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1693 uint32_t Rm; // the register with the target address 1694 switch (encoding) { 1695 case eEncodingT1: 1696 Rm = Bits32(opcode, 19, 16); 1697 if (BadReg(Rm)) 1698 return false; 1699 if (InITBlock() && !LastInITBlock()) 1700 return false; 1701 break; 1702 case eEncodingA1: 1703 Rm = Bits32(opcode, 3, 0); 1704 if (Rm == 15) 1705 return false; 1706 break; 1707 default: 1708 return false; 1709 } 1710 bool success = false; 1711 addr_t target = ReadCoreReg(Rm, &success); 1712 if (!success) 1713 return false; 1714 1715 RegisterInfo dwarf_reg; 1716 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1717 context.SetRegister(dwarf_reg); 1718 if (!BXWritePC(context, target)) 1719 return false; 1720 } 1721 return true; 1722} 1723 1724// Set r7 to point to some ip offset. 1725// SUB (immediate) 1726bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode, 1727 const ARMEncoding encoding) { 1728#if 0 1729 // ARM pseudo code... 1730 if (ConditionPassed()) 1731 { 1732 EncodingSpecificOperations(); 1733 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1734 if d == 15 then // Can only occur for ARM encoding 1735 ALUWritePC(result); // setflags is always FALSE here 1736 else 1737 R[d] = result; 1738 if setflags then 1739 APSR.N = result<31>; 1740 APSR.Z = IsZeroBit(result); 1741 APSR.C = carry; 1742 APSR.V = overflow; 1743 } 1744#endif 1745 1746 if (ConditionPassed(opcode)) { 1747 bool success = false; 1748 const addr_t ip = ReadCoreReg(12, &success); 1749 if (!success) 1750 return false; 1751 uint32_t imm32; 1752 switch (encoding) { 1753 case eEncodingA1: 1754 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1755 break; 1756 default: 1757 return false; 1758 } 1759 addr_t ip_offset = imm32; 1760 addr_t addr = ip - ip_offset; // the adjusted ip value 1761 1762 EmulateInstruction::Context context; 1763 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1764 RegisterInfo dwarf_reg; 1765 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1766 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset); 1767 1768 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr)) 1769 return false; 1770 } 1771 return true; 1772} 1773 1774// Set ip to point to some stack offset. 1775// SUB (SP minus immediate) 1776bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode, 1777 const ARMEncoding encoding) { 1778#if 0 1779 // ARM pseudo code... 1780 if (ConditionPassed()) 1781 { 1782 EncodingSpecificOperations(); 1783 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1784 if d == 15 then // Can only occur for ARM encoding 1785 ALUWritePC(result); // setflags is always FALSE here 1786 else 1787 R[d] = result; 1788 if setflags then 1789 APSR.N = result<31>; 1790 APSR.Z = IsZeroBit(result); 1791 APSR.C = carry; 1792 APSR.V = overflow; 1793 } 1794#endif 1795 1796 if (ConditionPassed(opcode)) { 1797 bool success = false; 1798 const addr_t sp = ReadCoreReg(SP_REG, &success); 1799 if (!success) 1800 return false; 1801 uint32_t imm32; 1802 switch (encoding) { 1803 case eEncodingA1: 1804 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1805 break; 1806 default: 1807 return false; 1808 } 1809 addr_t sp_offset = imm32; 1810 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1811 1812 EmulateInstruction::Context context; 1813 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1814 RegisterInfo dwarf_reg; 1815 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1816 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset); 1817 1818 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr)) 1819 return false; 1820 } 1821 return true; 1822} 1823 1824// This instruction subtracts an immediate value from the SP value, and writes 1825// the result to the destination register. 1826// 1827// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local 1828// storage. 1829bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode, 1830 const ARMEncoding encoding) { 1831#if 0 1832 // ARM pseudo code... 1833 if (ConditionPassed()) 1834 { 1835 EncodingSpecificOperations(); 1836 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1837 if d == 15 then // Can only occur for ARM encoding 1838 ALUWritePC(result); // setflags is always FALSE here 1839 else 1840 R[d] = result; 1841 if setflags then 1842 APSR.N = result<31>; 1843 APSR.Z = IsZeroBit(result); 1844 APSR.C = carry; 1845 APSR.V = overflow; 1846 } 1847#endif 1848 1849 bool success = false; 1850 if (ConditionPassed(opcode)) { 1851 const addr_t sp = ReadCoreReg(SP_REG, &success); 1852 if (!success) 1853 return false; 1854 1855 uint32_t Rd; 1856 bool setflags; 1857 uint32_t imm32; 1858 switch (encoding) { 1859 case eEncodingT1: 1860 Rd = 13; 1861 setflags = false; 1862 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1863 break; 1864 case eEncodingT2: 1865 Rd = Bits32(opcode, 11, 8); 1866 setflags = BitIsSet(opcode, 20); 1867 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1868 if (Rd == 15 && setflags) 1869 return EmulateCMPImm(opcode, eEncodingT2); 1870 if (Rd == 15 && !setflags) 1871 return false; 1872 break; 1873 case eEncodingT3: 1874 Rd = Bits32(opcode, 11, 8); 1875 setflags = false; 1876 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1877 if (Rd == 15) 1878 return false; 1879 break; 1880 case eEncodingA1: 1881 Rd = Bits32(opcode, 15, 12); 1882 setflags = BitIsSet(opcode, 20); 1883 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1884 1885 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1886 // instructions; 1887 if (Rd == 15 && setflags) 1888 return EmulateSUBSPcLrEtc(opcode, encoding); 1889 break; 1890 default: 1891 return false; 1892 } 1893 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1894 1895 EmulateInstruction::Context context; 1896 if (Rd == 13) { 1897 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting 1898 // to negate it, or the wrong 1899 // value gets passed down to context.SetImmediateSigned. 1900 context.type = EmulateInstruction::eContextAdjustStackPointer; 1901 context.SetImmediateSigned(-imm64); // the stack pointer offset 1902 } else { 1903 context.type = EmulateInstruction::eContextImmediate; 1904 context.SetNoArgs(); 1905 } 1906 1907 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 1908 res.carry_out, res.overflow)) 1909 return false; 1910 } 1911 return true; 1912} 1913 1914// A store operation to the stack that also updates the SP. 1915bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode, 1916 const ARMEncoding encoding) { 1917#if 0 1918 // ARM pseudo code... 1919 if (ConditionPassed()) 1920 { 1921 EncodingSpecificOperations(); 1922 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1923 address = if index then offset_addr else R[n]; 1924 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1925 if wback then R[n] = offset_addr; 1926 } 1927#endif 1928 1929 bool success = false; 1930 if (ConditionPassed(opcode)) { 1931 const uint32_t addr_byte_size = GetAddressByteSize(); 1932 const addr_t sp = ReadCoreReg(SP_REG, &success); 1933 if (!success) 1934 return false; 1935 uint32_t Rt; // the source register 1936 uint32_t imm12; 1937 uint32_t 1938 Rn; // This function assumes Rn is the SP, but we should verify that. 1939 1940 bool index; 1941 bool add; 1942 bool wback; 1943 switch (encoding) { 1944 case eEncodingA1: 1945 Rt = Bits32(opcode, 15, 12); 1946 imm12 = Bits32(opcode, 11, 0); 1947 Rn = Bits32(opcode, 19, 16); 1948 1949 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1950 return false; 1951 1952 index = BitIsSet(opcode, 24); 1953 add = BitIsSet(opcode, 23); 1954 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 1955 1956 if (wback && ((Rn == 15) || (Rn == Rt))) 1957 return false; 1958 break; 1959 default: 1960 return false; 1961 } 1962 addr_t offset_addr; 1963 if (add) 1964 offset_addr = sp + imm12; 1965 else 1966 offset_addr = sp - imm12; 1967 1968 addr_t addr; 1969 if (index) 1970 addr = offset_addr; 1971 else 1972 addr = sp; 1973 1974 EmulateInstruction::Context context; 1975 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1976 RegisterInfo sp_reg; 1977 RegisterInfo dwarf_reg; 1978 1979 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1980 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 1981 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 1982 if (Rt != 15) { 1983 uint32_t reg_value = ReadCoreReg(Rt, &success); 1984 if (!success) 1985 return false; 1986 if (!MemUWrite(context, addr, reg_value, addr_byte_size)) 1987 return false; 1988 } else { 1989 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1990 if (!success) 1991 return false; 1992 if (!MemUWrite(context, addr, pc, addr_byte_size)) 1993 return false; 1994 } 1995 1996 if (wback) { 1997 context.type = EmulateInstruction::eContextAdjustStackPointer; 1998 context.SetImmediateSigned(addr - sp); 1999 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2000 LLDB_REGNUM_GENERIC_SP, offset_addr)) 2001 return false; 2002 } 2003 } 2004 return true; 2005} 2006 2007// Vector Push stores multiple extension registers to the stack. 2008// It also updates SP to point to the start of the stored data. 2009bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode, 2010 const ARMEncoding encoding) { 2011#if 0 2012 // ARM pseudo code... 2013 if (ConditionPassed()) 2014 { 2015 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2016 address = SP - imm32; 2017 SP = SP - imm32; 2018 if single_regs then 2019 for r = 0 to regs-1 2020 MemA[address,4] = S[d+r]; address = address+4; 2021 else 2022 for r = 0 to regs-1 2023 // Store as two word-aligned words in the correct order for current endianness. 2024 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2025 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2026 address = address+8; 2027 } 2028#endif 2029 2030 bool success = false; 2031 if (ConditionPassed(opcode)) { 2032 const uint32_t addr_byte_size = GetAddressByteSize(); 2033 const addr_t sp = ReadCoreReg(SP_REG, &success); 2034 if (!success) 2035 return false; 2036 bool single_regs; 2037 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2038 uint32_t imm32; // stack offset 2039 uint32_t regs; // number of registers 2040 switch (encoding) { 2041 case eEncodingT1: 2042 case eEncodingA1: 2043 single_regs = false; 2044 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2045 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2046 // If UInt(imm8) is odd, see "FSTMX". 2047 regs = Bits32(opcode, 7, 0) / 2; 2048 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2049 if (regs == 0 || regs > 16 || (d + regs) > 32) 2050 return false; 2051 break; 2052 case eEncodingT2: 2053 case eEncodingA2: 2054 single_regs = true; 2055 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2056 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2057 regs = Bits32(opcode, 7, 0); 2058 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2059 if (regs == 0 || regs > 16 || (d + regs) > 32) 2060 return false; 2061 break; 2062 default: 2063 return false; 2064 } 2065 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2066 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2067 addr_t sp_offset = imm32; 2068 addr_t addr = sp - sp_offset; 2069 uint32_t i; 2070 2071 EmulateInstruction::Context context; 2072 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2073 2074 RegisterInfo dwarf_reg; 2075 RegisterInfo sp_reg; 2076 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2077 for (i = 0; i < regs; ++i) { 2078 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2079 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2080 // uint64_t to accommodate 64-bit registers. 2081 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success); 2082 if (!success) 2083 return false; 2084 if (!MemAWrite(context, addr, reg_value, reg_byte_size)) 2085 return false; 2086 addr += reg_byte_size; 2087 } 2088 2089 context.type = EmulateInstruction::eContextAdjustStackPointer; 2090 context.SetImmediateSigned(-sp_offset); 2091 2092 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2093 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2094 return false; 2095 } 2096 return true; 2097} 2098 2099// Vector Pop loads multiple extension registers from the stack. 2100// It also updates SP to point just above the loaded data. 2101bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode, 2102 const ARMEncoding encoding) { 2103#if 0 2104 // ARM pseudo code... 2105 if (ConditionPassed()) 2106 { 2107 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2108 address = SP; 2109 SP = SP + imm32; 2110 if single_regs then 2111 for r = 0 to regs-1 2112 S[d+r] = MemA[address,4]; address = address+4; 2113 else 2114 for r = 0 to regs-1 2115 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2116 // Combine the word-aligned words in the correct order for current endianness. 2117 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2118 } 2119#endif 2120 2121 bool success = false; 2122 if (ConditionPassed(opcode)) { 2123 const uint32_t addr_byte_size = GetAddressByteSize(); 2124 const addr_t sp = ReadCoreReg(SP_REG, &success); 2125 if (!success) 2126 return false; 2127 bool single_regs; 2128 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2129 uint32_t imm32; // stack offset 2130 uint32_t regs; // number of registers 2131 switch (encoding) { 2132 case eEncodingT1: 2133 case eEncodingA1: 2134 single_regs = false; 2135 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2136 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2137 // If UInt(imm8) is odd, see "FLDMX". 2138 regs = Bits32(opcode, 7, 0) / 2; 2139 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2140 if (regs == 0 || regs > 16 || (d + regs) > 32) 2141 return false; 2142 break; 2143 case eEncodingT2: 2144 case eEncodingA2: 2145 single_regs = true; 2146 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2147 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2148 regs = Bits32(opcode, 7, 0); 2149 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2150 if (regs == 0 || regs > 16 || (d + regs) > 32) 2151 return false; 2152 break; 2153 default: 2154 return false; 2155 } 2156 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2157 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2158 addr_t sp_offset = imm32; 2159 addr_t addr = sp; 2160 uint32_t i; 2161 uint64_t data; // uint64_t to accommodate 64-bit registers. 2162 2163 EmulateInstruction::Context context; 2164 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2165 2166 RegisterInfo dwarf_reg; 2167 RegisterInfo sp_reg; 2168 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2169 for (i = 0; i < regs; ++i) { 2170 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2171 context.SetAddress(addr); 2172 data = MemARead(context, addr, reg_byte_size, 0, &success); 2173 if (!success) 2174 return false; 2175 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2176 return false; 2177 addr += reg_byte_size; 2178 } 2179 2180 context.type = EmulateInstruction::eContextAdjustStackPointer; 2181 context.SetImmediateSigned(sp_offset); 2182 2183 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2184 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2185 return false; 2186 } 2187 return true; 2188} 2189 2190// SVC (previously SWI) 2191bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode, 2192 const ARMEncoding encoding) { 2193#if 0 2194 // ARM pseudo code... 2195 if (ConditionPassed()) 2196 { 2197 EncodingSpecificOperations(); 2198 CallSupervisor(); 2199 } 2200#endif 2201 2202 bool success = false; 2203 2204 if (ConditionPassed(opcode)) { 2205 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2206 addr_t lr; // next instruction address 2207 if (!success) 2208 return false; 2209 uint32_t imm32; // the immediate constant 2210 uint32_t mode; // ARM or Thumb mode 2211 switch (encoding) { 2212 case eEncodingT1: 2213 lr = (pc + 2) | 1u; // return address 2214 imm32 = Bits32(opcode, 7, 0); 2215 mode = eModeThumb; 2216 break; 2217 case eEncodingA1: 2218 lr = pc + 4; // return address 2219 imm32 = Bits32(opcode, 23, 0); 2220 mode = eModeARM; 2221 break; 2222 default: 2223 return false; 2224 } 2225 2226 EmulateInstruction::Context context; 2227 context.type = EmulateInstruction::eContextSupervisorCall; 2228 context.SetISAAndImmediate(mode, imm32); 2229 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2230 LLDB_REGNUM_GENERIC_RA, lr)) 2231 return false; 2232 } 2233 return true; 2234} 2235 2236// If Then makes up to four following instructions (the IT block) conditional. 2237bool EmulateInstructionARM::EmulateIT(const uint32_t opcode, 2238 const ARMEncoding encoding) { 2239#if 0 2240 // ARM pseudo code... 2241 EncodingSpecificOperations(); 2242 ITSTATE.IT<7:0> = firstcond:mask; 2243#endif 2244 2245 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2246 return true; 2247} 2248 2249bool EmulateInstructionARM::EmulateNop(const uint32_t opcode, 2250 const ARMEncoding encoding) { 2251 // NOP, nothing to do... 2252 return true; 2253} 2254 2255// Branch causes a branch to a target address. 2256bool EmulateInstructionARM::EmulateB(const uint32_t opcode, 2257 const ARMEncoding encoding) { 2258#if 0 2259 // ARM pseudo code... 2260 if (ConditionPassed()) 2261 { 2262 EncodingSpecificOperations(); 2263 BranchWritePC(PC + imm32); 2264 } 2265#endif 2266 2267 bool success = false; 2268 2269 if (ConditionPassed(opcode)) { 2270 EmulateInstruction::Context context; 2271 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2272 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2273 if (!success) 2274 return false; 2275 addr_t target; // target address 2276 int32_t imm32; // PC-relative offset 2277 switch (encoding) { 2278 case eEncodingT1: 2279 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2280 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2281 target = pc + imm32; 2282 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2283 break; 2284 case eEncodingT2: 2285 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2286 target = pc + imm32; 2287 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2288 break; 2289 case eEncodingT3: 2290 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2291 { 2292 if (Bits32(opcode, 25, 23) == 7) 2293 return false; // See Branches and miscellaneous control on page 2294 // A6-235. 2295 2296 uint32_t S = Bit32(opcode, 26); 2297 uint32_t imm6 = Bits32(opcode, 21, 16); 2298 uint32_t J1 = Bit32(opcode, 13); 2299 uint32_t J2 = Bit32(opcode, 11); 2300 uint32_t imm11 = Bits32(opcode, 10, 0); 2301 uint32_t imm21 = 2302 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2303 imm32 = llvm::SignExtend32<21>(imm21); 2304 target = pc + imm32; 2305 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2306 break; 2307 } 2308 case eEncodingT4: { 2309 uint32_t S = Bit32(opcode, 26); 2310 uint32_t imm10 = Bits32(opcode, 25, 16); 2311 uint32_t J1 = Bit32(opcode, 13); 2312 uint32_t J2 = Bit32(opcode, 11); 2313 uint32_t imm11 = Bits32(opcode, 10, 0); 2314 uint32_t I1 = !(J1 ^ S); 2315 uint32_t I2 = !(J2 ^ S); 2316 uint32_t imm25 = 2317 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2318 imm32 = llvm::SignExtend32<25>(imm25); 2319 target = pc + imm32; 2320 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2321 break; 2322 } 2323 case eEncodingA1: 2324 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2325 target = pc + imm32; 2326 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2327 break; 2328 default: 2329 return false; 2330 } 2331 if (!BranchWritePC(context, target)) 2332 return false; 2333 } 2334 return true; 2335} 2336 2337// Compare and Branch on Nonzero and Compare and Branch on Zero compare the 2338// value in a register with 2339// zero and conditionally branch forward a constant value. They do not affect 2340// the condition flags. 2341// CBNZ, CBZ 2342bool EmulateInstructionARM::EmulateCB(const uint32_t opcode, 2343 const ARMEncoding encoding) { 2344#if 0 2345 // ARM pseudo code... 2346 EncodingSpecificOperations(); 2347 if nonzero ^ IsZero(R[n]) then 2348 BranchWritePC(PC + imm32); 2349#endif 2350 2351 bool success = false; 2352 2353 // Read the register value from the operand register Rn. 2354 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2355 if (!success) 2356 return false; 2357 2358 EmulateInstruction::Context context; 2359 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2360 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2361 if (!success) 2362 return false; 2363 2364 addr_t target; // target address 2365 uint32_t imm32; // PC-relative offset to branch forward 2366 bool nonzero; 2367 switch (encoding) { 2368 case eEncodingT1: 2369 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2370 nonzero = BitIsSet(opcode, 11); 2371 target = pc + imm32; 2372 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2373 break; 2374 default: 2375 return false; 2376 } 2377 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2378 if (!BranchWritePC(context, target)) 2379 return false; 2380 2381 return true; 2382} 2383 2384// Table Branch Byte causes a PC-relative forward branch using a table of single 2385// byte offsets. 2386// A base register provides a pointer to the table, and a second register 2387// supplies an index into the table. 2388// The branch length is twice the value of the byte returned from the table. 2389// 2390// Table Branch Halfword causes a PC-relative forward branch using a table of 2391// single halfword offsets. 2392// A base register provides a pointer to the table, and a second register 2393// supplies an index into the table. 2394// The branch length is twice the value of the halfword returned from the table. 2395// TBB, TBH 2396bool EmulateInstructionARM::EmulateTB(const uint32_t opcode, 2397 const ARMEncoding encoding) { 2398#if 0 2399 // ARM pseudo code... 2400 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2401 if is_tbh then 2402 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2403 else 2404 halfwords = UInt(MemU[R[n]+R[m], 1]); 2405 BranchWritePC(PC + 2*halfwords); 2406#endif 2407 2408 bool success = false; 2409 2410 if (ConditionPassed(opcode)) { 2411 uint32_t Rn; // the base register which contains the address of the table of 2412 // branch lengths 2413 uint32_t Rm; // the index register which contains an integer pointing to a 2414 // byte/halfword in the table 2415 bool is_tbh; // true if table branch halfword 2416 switch (encoding) { 2417 case eEncodingT1: 2418 Rn = Bits32(opcode, 19, 16); 2419 Rm = Bits32(opcode, 3, 0); 2420 is_tbh = BitIsSet(opcode, 4); 2421 if (Rn == 13 || BadReg(Rm)) 2422 return false; 2423 if (InITBlock() && !LastInITBlock()) 2424 return false; 2425 break; 2426 default: 2427 return false; 2428 } 2429 2430 // Read the address of the table from the operand register Rn. 2431 // The PC can be used, in which case the table immediately follows this 2432 // instruction. 2433 uint32_t base = ReadCoreReg(Rn, &success); 2434 if (!success) 2435 return false; 2436 2437 // the table index 2438 uint32_t index = ReadCoreReg(Rm, &success); 2439 if (!success) 2440 return false; 2441 2442 // the offsetted table address 2443 addr_t addr = base + (is_tbh ? index * 2 : index); 2444 2445 // PC-relative offset to branch forward 2446 EmulateInstruction::Context context; 2447 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2448 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2449 if (!success) 2450 return false; 2451 2452 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2453 if (!success) 2454 return false; 2455 2456 // target address 2457 addr_t target = pc + offset; 2458 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2459 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset); 2460 2461 if (!BranchWritePC(context, target)) 2462 return false; 2463 } 2464 2465 return true; 2466} 2467 2468// This instruction adds an immediate value to a register value, and writes the 2469// result to the destination register. 2470// It can optionally update the condition flags based on the result. 2471bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode, 2472 const ARMEncoding encoding) { 2473#if 0 2474 if ConditionPassed() then 2475 EncodingSpecificOperations(); 2476 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2477 R[d] = result; 2478 if setflags then 2479 APSR.N = result<31>; 2480 APSR.Z = IsZeroBit(result); 2481 APSR.C = carry; 2482 APSR.V = overflow; 2483#endif 2484 2485 bool success = false; 2486 2487 if (ConditionPassed(opcode)) { 2488 uint32_t d; 2489 uint32_t n; 2490 bool setflags; 2491 uint32_t imm32; 2492 uint32_t carry_out; 2493 2494 // EncodingSpecificOperations(); 2495 switch (encoding) { 2496 case eEncodingT1: 2497 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = 2498 // ZeroExtend(imm3, 32); 2499 d = Bits32(opcode, 2, 0); 2500 n = Bits32(opcode, 5, 3); 2501 setflags = !InITBlock(); 2502 imm32 = Bits32(opcode, 8, 6); 2503 2504 break; 2505 2506 case eEncodingT2: 2507 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = 2508 // ZeroExtend(imm8, 32); 2509 d = Bits32(opcode, 10, 8); 2510 n = Bits32(opcode, 10, 8); 2511 setflags = !InITBlock(); 2512 imm32 = Bits32(opcode, 7, 0); 2513 2514 break; 2515 2516 case eEncodingT3: 2517 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2518 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = 2519 // ThumbExpandImm(i:imm3:imm8); 2520 d = Bits32(opcode, 11, 8); 2521 n = Bits32(opcode, 19, 16); 2522 setflags = BitIsSet(opcode, 20); 2523 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out); 2524 2525 // if Rn == '1101' then SEE ADD (SP plus immediate); 2526 if (n == 13) 2527 return EmulateADDSPImm(opcode, eEncodingT3); 2528 2529 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2530 if (BadReg(d) || (n == 15)) 2531 return false; 2532 2533 break; 2534 2535 case eEncodingT4: { 2536 // if Rn == '1111' then SEE ADR; 2537 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = 2538 // ZeroExtend(i:imm3:imm8, 32); 2539 d = Bits32(opcode, 11, 8); 2540 n = Bits32(opcode, 19, 16); 2541 setflags = false; 2542 uint32_t i = Bit32(opcode, 26); 2543 uint32_t imm3 = Bits32(opcode, 14, 12); 2544 uint32_t imm8 = Bits32(opcode, 7, 0); 2545 imm32 = (i << 11) | (imm3 << 8) | imm8; 2546 2547 // if Rn == '1101' then SEE ADD (SP plus immediate); 2548 if (n == 13) 2549 return EmulateADDSPImm(opcode, eEncodingT4); 2550 2551 // if BadReg(d) then UNPREDICTABLE; 2552 if (BadReg(d)) 2553 return false; 2554 2555 break; 2556 } 2557 2558 default: 2559 return false; 2560 } 2561 2562 uint64_t Rn = 2563 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2564 if (!success) 2565 return false; 2566 2567 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2568 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0); 2569 2570 RegisterInfo reg_n; 2571 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2572 2573 EmulateInstruction::Context context; 2574 context.type = eContextArithmetic; 2575 context.SetRegisterPlusOffset(reg_n, imm32); 2576 2577 // R[d] = result; 2578 // if setflags then 2579 // APSR.N = result<31>; 2580 // APSR.Z = IsZeroBit(result); 2581 // APSR.C = carry; 2582 // APSR.V = overflow; 2583 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 2584 res.carry_out, res.overflow)) 2585 return false; 2586 } 2587 return true; 2588} 2589 2590// This instruction adds an immediate value to a register value, and writes the 2591// result to the destination 2592// register. It can optionally update the condition flags based on the result. 2593bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode, 2594 const ARMEncoding encoding) { 2595#if 0 2596 // ARM pseudo code... 2597 if ConditionPassed() then 2598 EncodingSpecificOperations(); 2599 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2600 if d == 15 then 2601 ALUWritePC(result); // setflags is always FALSE here 2602 else 2603 R[d] = result; 2604 if setflags then 2605 APSR.N = result<31>; 2606 APSR.Z = IsZeroBit(result); 2607 APSR.C = carry; 2608 APSR.V = overflow; 2609#endif 2610 2611 bool success = false; 2612 2613 if (ConditionPassed(opcode)) { 2614 uint32_t Rd, Rn; 2615 uint32_t 2616 imm32; // the immediate value to be added to the value obtained from Rn 2617 bool setflags; 2618 switch (encoding) { 2619 case eEncodingA1: 2620 Rd = Bits32(opcode, 15, 12); 2621 Rn = Bits32(opcode, 19, 16); 2622 setflags = BitIsSet(opcode, 20); 2623 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2624 break; 2625 default: 2626 return false; 2627 } 2628 2629 // Read the first operand. 2630 uint32_t val1 = ReadCoreReg(Rn, &success); 2631 if (!success) 2632 return false; 2633 2634 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2635 2636 EmulateInstruction::Context context; 2637 if (Rd == 13) 2638 context.type = EmulateInstruction::eContextAdjustStackPointer; 2639 else if (Rd == GetFramePointerRegisterNumber()) 2640 context.type = EmulateInstruction::eContextSetFramePointer; 2641 else 2642 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2643 2644 RegisterInfo dwarf_reg; 2645 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 2646 context.SetRegisterPlusOffset(dwarf_reg, imm32); 2647 2648 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 2649 res.carry_out, res.overflow)) 2650 return false; 2651 } 2652 return true; 2653} 2654 2655// This instruction adds a register value and an optionally-shifted register 2656// value, and writes the result 2657// to the destination register. It can optionally update the condition flags 2658// based on the result. 2659bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode, 2660 const ARMEncoding encoding) { 2661#if 0 2662 // ARM pseudo code... 2663 if ConditionPassed() then 2664 EncodingSpecificOperations(); 2665 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2666 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2667 if d == 15 then 2668 ALUWritePC(result); // setflags is always FALSE here 2669 else 2670 R[d] = result; 2671 if setflags then 2672 APSR.N = result<31>; 2673 APSR.Z = IsZeroBit(result); 2674 APSR.C = carry; 2675 APSR.V = overflow; 2676#endif 2677 2678 bool success = false; 2679 2680 if (ConditionPassed(opcode)) { 2681 uint32_t Rd, Rn, Rm; 2682 ARM_ShifterType shift_t; 2683 uint32_t shift_n; // the shift applied to the value read from Rm 2684 bool setflags; 2685 switch (encoding) { 2686 case eEncodingT1: 2687 Rd = Bits32(opcode, 2, 0); 2688 Rn = Bits32(opcode, 5, 3); 2689 Rm = Bits32(opcode, 8, 6); 2690 setflags = !InITBlock(); 2691 shift_t = SRType_LSL; 2692 shift_n = 0; 2693 break; 2694 case eEncodingT2: 2695 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2696 Rm = Bits32(opcode, 6, 3); 2697 setflags = false; 2698 shift_t = SRType_LSL; 2699 shift_n = 0; 2700 if (Rn == 15 && Rm == 15) 2701 return false; 2702 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2703 return false; 2704 break; 2705 case eEncodingA1: 2706 Rd = Bits32(opcode, 15, 12); 2707 Rn = Bits32(opcode, 19, 16); 2708 Rm = Bits32(opcode, 3, 0); 2709 setflags = BitIsSet(opcode, 20); 2710 shift_n = DecodeImmShiftARM(opcode, shift_t); 2711 break; 2712 default: 2713 return false; 2714 } 2715 2716 // Read the first operand. 2717 uint32_t val1 = ReadCoreReg(Rn, &success); 2718 if (!success) 2719 return false; 2720 2721 // Read the second operand. 2722 uint32_t val2 = ReadCoreReg(Rm, &success); 2723 if (!success) 2724 return false; 2725 2726 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2727 if (!success) 2728 return false; 2729 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2730 2731 EmulateInstruction::Context context; 2732 context.type = eContextArithmetic; 2733 RegisterInfo op1_reg; 2734 RegisterInfo op2_reg; 2735 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2736 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2737 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 2738 2739 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 2740 res.carry_out, res.overflow)) 2741 return false; 2742 } 2743 return true; 2744} 2745 2746// Compare Negative (immediate) adds a register value and an immediate value. 2747// It updates the condition flags based on the result, and discards the result. 2748bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, 2749 const ARMEncoding encoding) { 2750#if 0 2751 // ARM pseudo code... 2752 if ConditionPassed() then 2753 EncodingSpecificOperations(); 2754 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2755 APSR.N = result<31>; 2756 APSR.Z = IsZeroBit(result); 2757 APSR.C = carry; 2758 APSR.V = overflow; 2759#endif 2760 2761 bool success = false; 2762 2763 uint32_t Rn; // the first operand 2764 uint32_t imm32; // the immediate value to be compared with 2765 switch (encoding) { 2766 case eEncodingT1: 2767 Rn = Bits32(opcode, 19, 16); 2768 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2769 if (Rn == 15) 2770 return false; 2771 break; 2772 case eEncodingA1: 2773 Rn = Bits32(opcode, 19, 16); 2774 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2775 break; 2776 default: 2777 return false; 2778 } 2779 // Read the register value from the operand register Rn. 2780 uint32_t reg_val = ReadCoreReg(Rn, &success); 2781 if (!success) 2782 return false; 2783 2784 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2785 2786 EmulateInstruction::Context context; 2787 context.type = EmulateInstruction::eContextImmediate; 2788 context.SetNoArgs(); 2789 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2790 return false; 2791 2792 return true; 2793} 2794 2795// Compare Negative (register) adds a register value and an optionally-shifted 2796// register value. 2797// It updates the condition flags based on the result, and discards the result. 2798bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, 2799 const ARMEncoding encoding) { 2800#if 0 2801 // ARM pseudo code... 2802 if ConditionPassed() then 2803 EncodingSpecificOperations(); 2804 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2805 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2806 APSR.N = result<31>; 2807 APSR.Z = IsZeroBit(result); 2808 APSR.C = carry; 2809 APSR.V = overflow; 2810#endif 2811 2812 bool success = false; 2813 2814 uint32_t Rn; // the first operand 2815 uint32_t Rm; // the second operand 2816 ARM_ShifterType shift_t; 2817 uint32_t shift_n; // the shift applied to the value read from Rm 2818 switch (encoding) { 2819 case eEncodingT1: 2820 Rn = Bits32(opcode, 2, 0); 2821 Rm = Bits32(opcode, 5, 3); 2822 shift_t = SRType_LSL; 2823 shift_n = 0; 2824 break; 2825 case eEncodingT2: 2826 Rn = Bits32(opcode, 19, 16); 2827 Rm = Bits32(opcode, 3, 0); 2828 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2829 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2830 if (Rn == 15 || BadReg(Rm)) 2831 return false; 2832 break; 2833 case eEncodingA1: 2834 Rn = Bits32(opcode, 19, 16); 2835 Rm = Bits32(opcode, 3, 0); 2836 shift_n = DecodeImmShiftARM(opcode, shift_t); 2837 break; 2838 default: 2839 return false; 2840 } 2841 // Read the register value from register Rn. 2842 uint32_t val1 = ReadCoreReg(Rn, &success); 2843 if (!success) 2844 return false; 2845 2846 // Read the register value from register Rm. 2847 uint32_t val2 = ReadCoreReg(Rm, &success); 2848 if (!success) 2849 return false; 2850 2851 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2852 if (!success) 2853 return false; 2854 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2855 2856 EmulateInstruction::Context context; 2857 context.type = EmulateInstruction::eContextImmediate; 2858 context.SetNoArgs(); 2859 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2860 return false; 2861 2862 return true; 2863} 2864 2865// Compare (immediate) subtracts an immediate value from a register value. 2866// It updates the condition flags based on the result, and discards the result. 2867bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, 2868 const ARMEncoding encoding) { 2869#if 0 2870 // ARM pseudo code... 2871 if ConditionPassed() then 2872 EncodingSpecificOperations(); 2873 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2874 APSR.N = result<31>; 2875 APSR.Z = IsZeroBit(result); 2876 APSR.C = carry; 2877 APSR.V = overflow; 2878#endif 2879 2880 bool success = false; 2881 2882 uint32_t Rn; // the first operand 2883 uint32_t imm32; // the immediate value to be compared with 2884 switch (encoding) { 2885 case eEncodingT1: 2886 Rn = Bits32(opcode, 10, 8); 2887 imm32 = Bits32(opcode, 7, 0); 2888 break; 2889 case eEncodingT2: 2890 Rn = Bits32(opcode, 19, 16); 2891 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2892 if (Rn == 15) 2893 return false; 2894 break; 2895 case eEncodingA1: 2896 Rn = Bits32(opcode, 19, 16); 2897 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2898 break; 2899 default: 2900 return false; 2901 } 2902 // Read the register value from the operand register Rn. 2903 uint32_t reg_val = ReadCoreReg(Rn, &success); 2904 if (!success) 2905 return false; 2906 2907 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 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// Compare (register) subtracts an optionally-shifted register value from a 2919// register value. 2920// It updates the condition flags based on the result, and discards the result. 2921bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, 2922 const ARMEncoding encoding) { 2923#if 0 2924 // ARM pseudo code... 2925 if ConditionPassed() then 2926 EncodingSpecificOperations(); 2927 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2928 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2929 APSR.N = result<31>; 2930 APSR.Z = IsZeroBit(result); 2931 APSR.C = carry; 2932 APSR.V = overflow; 2933#endif 2934 2935 bool success = false; 2936 2937 uint32_t Rn; // the first operand 2938 uint32_t Rm; // the second operand 2939 ARM_ShifterType shift_t; 2940 uint32_t shift_n; // the shift applied to the value read from Rm 2941 switch (encoding) { 2942 case eEncodingT1: 2943 Rn = Bits32(opcode, 2, 0); 2944 Rm = Bits32(opcode, 5, 3); 2945 shift_t = SRType_LSL; 2946 shift_n = 0; 2947 break; 2948 case eEncodingT2: 2949 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2950 Rm = Bits32(opcode, 6, 3); 2951 shift_t = SRType_LSL; 2952 shift_n = 0; 2953 if (Rn < 8 && Rm < 8) 2954 return false; 2955 if (Rn == 15 || Rm == 15) 2956 return false; 2957 break; 2958 case eEncodingT3: 2959 Rn = Bits32(opcode, 19, 16); 2960 Rm = Bits32(opcode, 3, 0); 2961 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2962 if (Rn == 15 || BadReg(Rm)) 2963 return false; 2964 break; 2965 case eEncodingA1: 2966 Rn = Bits32(opcode, 19, 16); 2967 Rm = Bits32(opcode, 3, 0); 2968 shift_n = DecodeImmShiftARM(opcode, shift_t); 2969 break; 2970 default: 2971 return false; 2972 } 2973 // Read the register value from register Rn. 2974 uint32_t val1 = ReadCoreReg(Rn, &success); 2975 if (!success) 2976 return false; 2977 2978 // Read the register value from register Rm. 2979 uint32_t val2 = ReadCoreReg(Rm, &success); 2980 if (!success) 2981 return false; 2982 2983 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2984 if (!success) 2985 return false; 2986 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 2987 2988 EmulateInstruction::Context context; 2989 context.type = EmulateInstruction::eContextImmediate; 2990 context.SetNoArgs(); 2991 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2992 return false; 2993 2994 return true; 2995} 2996 2997// Arithmetic Shift Right (immediate) shifts a register value right by an 2998// immediate number of bits, 2999// shifting in copies of its sign bit, and writes the result to the destination 3000// register. It can 3001// optionally update the condition flags based on the result. 3002bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode, 3003 const ARMEncoding encoding) { 3004#if 0 3005 // ARM pseudo code... 3006 if ConditionPassed() then 3007 EncodingSpecificOperations(); 3008 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3009 if d == 15 then // Can only occur for ARM encoding 3010 ALUWritePC(result); // setflags is always FALSE here 3011 else 3012 R[d] = result; 3013 if setflags then 3014 APSR.N = result<31>; 3015 APSR.Z = IsZeroBit(result); 3016 APSR.C = carry; 3017 // APSR.V unchanged 3018#endif 3019 3020 return EmulateShiftImm(opcode, encoding, SRType_ASR); 3021} 3022 3023// Arithmetic Shift Right (register) shifts a register value right by a variable 3024// number of bits, 3025// shifting in copies of its sign bit, and writes the result to the destination 3026// register. 3027// The variable number of bits is read from the bottom byte of a register. It 3028// can optionally update 3029// the condition flags based on the result. 3030bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode, 3031 const ARMEncoding encoding) { 3032#if 0 3033 // ARM pseudo code... 3034 if ConditionPassed() then 3035 EncodingSpecificOperations(); 3036 shift_n = UInt(R[m]<7:0>); 3037 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3038 R[d] = result; 3039 if setflags then 3040 APSR.N = result<31>; 3041 APSR.Z = IsZeroBit(result); 3042 APSR.C = carry; 3043 // APSR.V unchanged 3044#endif 3045 3046 return EmulateShiftReg(opcode, encoding, SRType_ASR); 3047} 3048 3049// Logical Shift Left (immediate) shifts a register value left by an immediate 3050// number of bits, 3051// shifting in zeros, and writes the result to the destination register. It can 3052// optionally 3053// update the condition flags based on the result. 3054bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode, 3055 const ARMEncoding encoding) { 3056#if 0 3057 // ARM pseudo code... 3058 if ConditionPassed() then 3059 EncodingSpecificOperations(); 3060 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3061 if d == 15 then // Can only occur for ARM encoding 3062 ALUWritePC(result); // setflags is always FALSE here 3063 else 3064 R[d] = result; 3065 if setflags then 3066 APSR.N = result<31>; 3067 APSR.Z = IsZeroBit(result); 3068 APSR.C = carry; 3069 // APSR.V unchanged 3070#endif 3071 3072 return EmulateShiftImm(opcode, encoding, SRType_LSL); 3073} 3074 3075// Logical Shift Left (register) shifts a register value left by a variable 3076// number of bits, 3077// shifting in zeros, and writes the result to the destination register. The 3078// variable number 3079// of bits is read from the bottom byte of a register. It can optionally update 3080// the condition 3081// flags based on the result. 3082bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode, 3083 const ARMEncoding encoding) { 3084#if 0 3085 // ARM pseudo code... 3086 if ConditionPassed() then 3087 EncodingSpecificOperations(); 3088 shift_n = UInt(R[m]<7:0>); 3089 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3090 R[d] = result; 3091 if setflags then 3092 APSR.N = result<31>; 3093 APSR.Z = IsZeroBit(result); 3094 APSR.C = carry; 3095 // APSR.V unchanged 3096#endif 3097 3098 return EmulateShiftReg(opcode, encoding, SRType_LSL); 3099} 3100 3101// Logical Shift Right (immediate) shifts a register value right by an immediate 3102// number of bits, 3103// shifting in zeros, and writes the result to the destination register. It can 3104// optionally 3105// update the condition flags based on the result. 3106bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode, 3107 const ARMEncoding encoding) { 3108#if 0 3109 // ARM pseudo code... 3110 if ConditionPassed() then 3111 EncodingSpecificOperations(); 3112 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3113 if d == 15 then // Can only occur for ARM encoding 3114 ALUWritePC(result); // setflags is always FALSE here 3115 else 3116 R[d] = result; 3117 if setflags then 3118 APSR.N = result<31>; 3119 APSR.Z = IsZeroBit(result); 3120 APSR.C = carry; 3121 // APSR.V unchanged 3122#endif 3123 3124 return EmulateShiftImm(opcode, encoding, SRType_LSR); 3125} 3126 3127// Logical Shift Right (register) shifts a register value right by a variable 3128// number of bits, 3129// shifting in zeros, and writes the result to the destination register. The 3130// variable number 3131// of bits is read from the bottom byte of a register. It can optionally update 3132// the condition 3133// flags based on the result. 3134bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode, 3135 const ARMEncoding encoding) { 3136#if 0 3137 // ARM pseudo code... 3138 if ConditionPassed() then 3139 EncodingSpecificOperations(); 3140 shift_n = UInt(R[m]<7:0>); 3141 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3142 R[d] = result; 3143 if setflags then 3144 APSR.N = result<31>; 3145 APSR.Z = IsZeroBit(result); 3146 APSR.C = carry; 3147 // APSR.V unchanged 3148#endif 3149 3150 return EmulateShiftReg(opcode, encoding, SRType_LSR); 3151} 3152 3153// Rotate Right (immediate) provides the value of the contents of a register 3154// rotated by a constant value. 3155// The bits that are rotated off the right end are inserted into the vacated bit 3156// positions on the left. 3157// It can optionally update the condition flags based on the result. 3158bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode, 3159 const ARMEncoding encoding) { 3160#if 0 3161 // ARM pseudo code... 3162 if ConditionPassed() then 3163 EncodingSpecificOperations(); 3164 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3165 if d == 15 then // Can only occur for ARM encoding 3166 ALUWritePC(result); // setflags is always FALSE here 3167 else 3168 R[d] = result; 3169 if setflags then 3170 APSR.N = result<31>; 3171 APSR.Z = IsZeroBit(result); 3172 APSR.C = carry; 3173 // APSR.V unchanged 3174#endif 3175 3176 return EmulateShiftImm(opcode, encoding, SRType_ROR); 3177} 3178 3179// Rotate Right (register) provides the value of the contents of a register 3180// rotated by a variable number of bits. 3181// The bits that are rotated off the right end are inserted into the vacated bit 3182// positions on the left. 3183// The variable number of bits is read from the bottom byte of a register. It 3184// can optionally update the condition 3185// flags based on the result. 3186bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode, 3187 const ARMEncoding encoding) { 3188#if 0 3189 // ARM pseudo code... 3190 if ConditionPassed() then 3191 EncodingSpecificOperations(); 3192 shift_n = UInt(R[m]<7:0>); 3193 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3194 R[d] = result; 3195 if setflags then 3196 APSR.N = result<31>; 3197 APSR.Z = IsZeroBit(result); 3198 APSR.C = carry; 3199 // APSR.V unchanged 3200#endif 3201 3202 return EmulateShiftReg(opcode, encoding, SRType_ROR); 3203} 3204 3205// Rotate Right with Extend provides the value of the contents of a register 3206// shifted right by one place, 3207// with the carry flag shifted into bit [31]. 3208// 3209// RRX can optionally update the condition flags based on the result. 3210// In that case, bit [0] is shifted into the carry flag. 3211bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode, 3212 const ARMEncoding encoding) { 3213#if 0 3214 // ARM pseudo code... 3215 if ConditionPassed() then 3216 EncodingSpecificOperations(); 3217 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3218 if d == 15 then // Can only occur for ARM encoding 3219 ALUWritePC(result); // setflags is always FALSE here 3220 else 3221 R[d] = result; 3222 if setflags then 3223 APSR.N = result<31>; 3224 APSR.Z = IsZeroBit(result); 3225 APSR.C = carry; 3226 // APSR.V unchanged 3227#endif 3228 3229 return EmulateShiftImm(opcode, encoding, SRType_RRX); 3230} 3231 3232bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode, 3233 const ARMEncoding encoding, 3234 ARM_ShifterType shift_type) { 3235 // assert(shift_type == SRType_ASR 3236 // || shift_type == SRType_LSL 3237 // || shift_type == SRType_LSR 3238 // || shift_type == SRType_ROR 3239 // || shift_type == SRType_RRX); 3240 3241 bool success = false; 3242 3243 if (ConditionPassed(opcode)) { 3244 uint32_t Rd; // the destination register 3245 uint32_t Rm; // the first operand register 3246 uint32_t imm5; // encoding for the shift amount 3247 uint32_t carry; // the carry bit after the shift operation 3248 bool setflags; 3249 3250 // Special case handling! 3251 // A8.6.139 ROR (immediate) -- Encoding T1 3252 ARMEncoding use_encoding = encoding; 3253 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) { 3254 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding 3255 // to 3256 // have the same decoding of bit fields as the other Thumb2 shift 3257 // operations. 3258 use_encoding = eEncodingT2; 3259 } 3260 3261 switch (use_encoding) { 3262 case eEncodingT1: 3263 // Due to the above special case handling! 3264 if (shift_type == SRType_ROR) 3265 return false; 3266 3267 Rd = Bits32(opcode, 2, 0); 3268 Rm = Bits32(opcode, 5, 3); 3269 setflags = !InITBlock(); 3270 imm5 = Bits32(opcode, 10, 6); 3271 break; 3272 case eEncodingT2: 3273 // A8.6.141 RRX 3274 // There's no imm form of RRX instructions. 3275 if (shift_type == SRType_RRX) 3276 return false; 3277 3278 Rd = Bits32(opcode, 11, 8); 3279 Rm = Bits32(opcode, 3, 0); 3280 setflags = BitIsSet(opcode, 20); 3281 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3282 if (BadReg(Rd) || BadReg(Rm)) 3283 return false; 3284 break; 3285 case eEncodingA1: 3286 Rd = Bits32(opcode, 15, 12); 3287 Rm = Bits32(opcode, 3, 0); 3288 setflags = BitIsSet(opcode, 20); 3289 imm5 = Bits32(opcode, 11, 7); 3290 break; 3291 default: 3292 return false; 3293 } 3294 3295 // A8.6.139 ROR (immediate) 3296 if (shift_type == SRType_ROR && imm5 == 0) 3297 shift_type = SRType_RRX; 3298 3299 // Get the first operand. 3300 uint32_t value = ReadCoreReg(Rm, &success); 3301 if (!success) 3302 return false; 3303 3304 // Decode the shift amount if not RRX. 3305 uint32_t amt = 3306 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3307 3308 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3309 if (!success) 3310 return false; 3311 3312 // The context specifies that an immediate is to be moved into Rd. 3313 EmulateInstruction::Context context; 3314 context.type = EmulateInstruction::eContextImmediate; 3315 context.SetNoArgs(); 3316 3317 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3318 return false; 3319 } 3320 return true; 3321} 3322 3323bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode, 3324 const ARMEncoding encoding, 3325 ARM_ShifterType shift_type) { 3326 // assert(shift_type == SRType_ASR 3327 // || shift_type == SRType_LSL 3328 // || shift_type == SRType_LSR 3329 // || shift_type == SRType_ROR); 3330 3331 bool success = false; 3332 3333 if (ConditionPassed(opcode)) { 3334 uint32_t Rd; // the destination register 3335 uint32_t Rn; // the first operand register 3336 uint32_t 3337 Rm; // the register whose bottom byte contains the amount to shift by 3338 uint32_t carry; // the carry bit after the shift operation 3339 bool setflags; 3340 switch (encoding) { 3341 case eEncodingT1: 3342 Rd = Bits32(opcode, 2, 0); 3343 Rn = Rd; 3344 Rm = Bits32(opcode, 5, 3); 3345 setflags = !InITBlock(); 3346 break; 3347 case eEncodingT2: 3348 Rd = Bits32(opcode, 11, 8); 3349 Rn = Bits32(opcode, 19, 16); 3350 Rm = Bits32(opcode, 3, 0); 3351 setflags = BitIsSet(opcode, 20); 3352 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3353 return false; 3354 break; 3355 case eEncodingA1: 3356 Rd = Bits32(opcode, 15, 12); 3357 Rn = Bits32(opcode, 3, 0); 3358 Rm = Bits32(opcode, 11, 8); 3359 setflags = BitIsSet(opcode, 20); 3360 if (Rd == 15 || Rn == 15 || Rm == 15) 3361 return false; 3362 break; 3363 default: 3364 return false; 3365 } 3366 3367 // Get the first operand. 3368 uint32_t value = ReadCoreReg(Rn, &success); 3369 if (!success) 3370 return false; 3371 // Get the Rm register content. 3372 uint32_t val = ReadCoreReg(Rm, &success); 3373 if (!success) 3374 return false; 3375 3376 // Get the shift amount. 3377 uint32_t amt = Bits32(val, 7, 0); 3378 3379 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3380 if (!success) 3381 return false; 3382 3383 // The context specifies that an immediate is to be moved into Rd. 3384 EmulateInstruction::Context context; 3385 context.type = EmulateInstruction::eContextImmediate; 3386 context.SetNoArgs(); 3387 3388 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3389 return false; 3390 } 3391 return true; 3392} 3393 3394// LDM loads multiple registers from consecutive memory locations, using an 3395// address from a base register. Optionally the address just above the highest 3396// of those locations 3397// can be written back to the base register. 3398bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode, 3399 const ARMEncoding encoding) { 3400#if 0 3401 // ARM pseudo code... 3402 if ConditionPassed() 3403 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3404 address = R[n]; 3405 3406 for i = 0 to 14 3407 if registers<i> == '1' then 3408 R[i] = MemA[address, 4]; address = address + 4; 3409 if registers<15> == '1' then 3410 LoadWritePC (MemA[address, 4]); 3411 3412 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3413 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3414 3415#endif 3416 3417 bool success = false; 3418 if (ConditionPassed(opcode)) { 3419 uint32_t n; 3420 uint32_t registers = 0; 3421 bool wback; 3422 const uint32_t addr_byte_size = GetAddressByteSize(); 3423 switch (encoding) { 3424 case eEncodingT1: 3425 // n = UInt(Rn); registers = '00000000':register_list; wback = 3426 // (registers<n> == '0'); 3427 n = Bits32(opcode, 10, 8); 3428 registers = Bits32(opcode, 7, 0); 3429 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3430 wback = BitIsClear(registers, n); 3431 // if BitCount(registers) < 1 then UNPREDICTABLE; 3432 if (BitCount(registers) < 1) 3433 return false; 3434 break; 3435 case eEncodingT2: 3436 // if W == '1' && Rn == '1101' then SEE POP; 3437 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3438 n = Bits32(opcode, 19, 16); 3439 registers = Bits32(opcode, 15, 0); 3440 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3441 wback = BitIsSet(opcode, 21); 3442 3443 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 3444 // UNPREDICTABLE; 3445 if ((n == 15) || (BitCount(registers) < 2) || 3446 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 3447 return false; 3448 3449 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 3450 // UNPREDICTABLE; 3451 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 3452 return false; 3453 3454 // if wback && registers<n> == '1' then UNPREDICTABLE; 3455 if (wback && BitIsSet(registers, n)) 3456 return false; 3457 break; 3458 3459 case eEncodingA1: 3460 n = Bits32(opcode, 19, 16); 3461 registers = Bits32(opcode, 15, 0); 3462 wback = BitIsSet(opcode, 21); 3463 if ((n == 15) || (BitCount(registers) < 1)) 3464 return false; 3465 break; 3466 default: 3467 return false; 3468 } 3469 3470 int32_t offset = 0; 3471 const addr_t base_address = 3472 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3473 if (!success) 3474 return false; 3475 3476 EmulateInstruction::Context context; 3477 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3478 RegisterInfo dwarf_reg; 3479 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3480 context.SetRegisterPlusOffset(dwarf_reg, offset); 3481 3482 for (int i = 0; i < 14; ++i) { 3483 if (BitIsSet(registers, i)) { 3484 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3485 context.SetRegisterPlusOffset(dwarf_reg, offset); 3486 if (wback && (n == 13)) // Pop Instruction 3487 { 3488 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3489 context.SetAddress(base_address + offset); 3490 } 3491 3492 // R[i] = MemA [address, 4]; address = address + 4; 3493 uint32_t data = MemARead(context, base_address + offset, addr_byte_size, 3494 0, &success); 3495 if (!success) 3496 return false; 3497 3498 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 3499 data)) 3500 return false; 3501 3502 offset += addr_byte_size; 3503 } 3504 } 3505 3506 if (BitIsSet(registers, 15)) { 3507 // LoadWritePC (MemA [address, 4]); 3508 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3509 context.SetRegisterPlusOffset(dwarf_reg, offset); 3510 uint32_t data = 3511 MemARead(context, base_address + offset, addr_byte_size, 0, &success); 3512 if (!success) 3513 return false; 3514 // In ARMv5T and above, this is an interworking branch. 3515 if (!LoadWritePC(context, data)) 3516 return false; 3517 } 3518 3519 if (wback && BitIsClear(registers, n)) { 3520 // R[n] = R[n] + 4 * BitCount (registers) 3521 int32_t offset = addr_byte_size * BitCount(registers); 3522 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3523 context.SetRegisterPlusOffset(dwarf_reg, offset); 3524 3525 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 3526 base_address + offset)) 3527 return false; 3528 } 3529 if (wback && BitIsSet(registers, n)) 3530 // R[n] bits(32) UNKNOWN; 3531 return WriteBits32Unknown(n); 3532 } 3533 return true; 3534} 3535 3536// LDMDA loads multiple registers from consecutive memory locations using an 3537// address from a base register. 3538// The consecutive memory locations end at this address and the address just 3539// below the lowest of those locations 3540// can optionally be written back to the base register. 3541bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode, 3542 const ARMEncoding encoding) { 3543#if 0 3544 // ARM pseudo code... 3545 if ConditionPassed() then 3546 EncodingSpecificOperations(); 3547 address = R[n] - 4*BitCount(registers) + 4; 3548 3549 for i = 0 to 14 3550 if registers<i> == '1' then 3551 R[i] = MemA[address,4]; address = address + 4; 3552 3553 if registers<15> == '1' then 3554 LoadWritePC(MemA[address,4]); 3555 3556 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3557 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3558#endif 3559 3560 bool success = false; 3561 3562 if (ConditionPassed(opcode)) { 3563 uint32_t n; 3564 uint32_t registers = 0; 3565 bool wback; 3566 const uint32_t addr_byte_size = GetAddressByteSize(); 3567 3568 // EncodingSpecificOperations(); 3569 switch (encoding) { 3570 case eEncodingA1: 3571 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3572 n = Bits32(opcode, 19, 16); 3573 registers = Bits32(opcode, 15, 0); 3574 wback = BitIsSet(opcode, 21); 3575 3576 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3577 if ((n == 15) || (BitCount(registers) < 1)) 3578 return false; 3579 3580 break; 3581 3582 default: 3583 return false; 3584 } 3585 // address = R[n] - 4*BitCount(registers) + 4; 3586 3587 int32_t offset = 0; 3588 addr_t Rn = ReadCoreReg(n, &success); 3589 3590 if (!success) 3591 return false; 3592 3593 addr_t address = 3594 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size; 3595 3596 EmulateInstruction::Context context; 3597 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3598 RegisterInfo dwarf_reg; 3599 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3600 context.SetRegisterPlusOffset(dwarf_reg, offset); 3601 3602 // for i = 0 to 14 3603 for (int i = 0; i < 14; ++i) { 3604 // if registers<i> == '1' then 3605 if (BitIsSet(registers, i)) { 3606 // R[i] = MemA[address,4]; address = address + 4; 3607 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 3608 uint32_t data = 3609 MemARead(context, address + offset, addr_byte_size, 0, &success); 3610 if (!success) 3611 return false; 3612 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 3613 data)) 3614 return false; 3615 offset += addr_byte_size; 3616 } 3617 } 3618 3619 // if registers<15> == '1' then 3620 // LoadWritePC(MemA[address,4]); 3621 if (BitIsSet(registers, 15)) { 3622 context.SetRegisterPlusOffset(dwarf_reg, offset); 3623 uint32_t data = 3624 MemARead(context, address + offset, addr_byte_size, 0, &success); 3625 if (!success) 3626 return false; 3627 // In ARMv5T and above, this is an interworking branch. 3628 if (!LoadWritePC(context, data)) 3629 return false; 3630 } 3631 3632 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3633 if (wback && BitIsClear(registers, n)) { 3634 if (!success) 3635 return false; 3636 3637 offset = (addr_byte_size * BitCount(registers)) * -1; 3638 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3639 context.SetImmediateSigned(offset); 3640 addr_t addr = Rn + offset; 3641 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 3642 addr)) 3643 return false; 3644 } 3645 3646 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3647 if (wback && BitIsSet(registers, n)) 3648 return WriteBits32Unknown(n); 3649 } 3650 return true; 3651} 3652 3653// LDMDB loads multiple registers from consecutive memory locations using an 3654// address from a base register. The 3655// consecutive memory locations end just below this address, and the address of 3656// the lowest of those locations can 3657// be optionally written back to the base register. 3658bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode, 3659 const ARMEncoding encoding) { 3660#if 0 3661 // ARM pseudo code... 3662 if ConditionPassed() then 3663 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3664 address = R[n] - 4*BitCount(registers); 3665 3666 for i = 0 to 14 3667 if registers<i> == '1' then 3668 R[i] = MemA[address,4]; address = address + 4; 3669 if registers<15> == '1' then 3670 LoadWritePC(MemA[address,4]); 3671 3672 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3673 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3674#endif 3675 3676 bool success = false; 3677 3678 if (ConditionPassed(opcode)) { 3679 uint32_t n; 3680 uint32_t registers = 0; 3681 bool wback; 3682 const uint32_t addr_byte_size = GetAddressByteSize(); 3683 switch (encoding) { 3684 case eEncodingT1: 3685 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3686 n = Bits32(opcode, 19, 16); 3687 registers = Bits32(opcode, 15, 0); 3688 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3689 wback = BitIsSet(opcode, 21); 3690 3691 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 3692 // UNPREDICTABLE; 3693 if ((n == 15) || (BitCount(registers) < 2) || 3694 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 3695 return false; 3696 3697 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 3698 // UNPREDICTABLE; 3699 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 3700 return false; 3701 3702 // if wback && registers<n> == '1' then UNPREDICTABLE; 3703 if (wback && BitIsSet(registers, n)) 3704 return false; 3705 3706 break; 3707 3708 case eEncodingA1: 3709 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3710 n = Bits32(opcode, 19, 16); 3711 registers = Bits32(opcode, 15, 0); 3712 wback = BitIsSet(opcode, 21); 3713 3714 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3715 if ((n == 15) || (BitCount(registers) < 1)) 3716 return false; 3717 3718 break; 3719 3720 default: 3721 return false; 3722 } 3723 3724 // address = R[n] - 4*BitCount(registers); 3725 3726 int32_t offset = 0; 3727 addr_t Rn = 3728 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3729 3730 if (!success) 3731 return false; 3732 3733 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 3734 EmulateInstruction::Context context; 3735 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3736 RegisterInfo dwarf_reg; 3737 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3738 context.SetRegisterPlusOffset(dwarf_reg, Rn - address); 3739 3740 for (int i = 0; i < 14; ++i) { 3741 if (BitIsSet(registers, i)) { 3742 // R[i] = MemA[address,4]; address = address + 4; 3743 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 3744 uint32_t data = 3745 MemARead(context, address + offset, addr_byte_size, 0, &success); 3746 if (!success) 3747 return false; 3748 3749 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 3750 data)) 3751 return false; 3752 3753 offset += addr_byte_size; 3754 } 3755 } 3756 3757 // if registers<15> == '1' then 3758 // LoadWritePC(MemA[address,4]); 3759 if (BitIsSet(registers, 15)) { 3760 context.SetRegisterPlusOffset(dwarf_reg, offset); 3761 uint32_t data = 3762 MemARead(context, address + offset, addr_byte_size, 0, &success); 3763 if (!success) 3764 return false; 3765 // In ARMv5T and above, this is an interworking branch. 3766 if (!LoadWritePC(context, data)) 3767 return false; 3768 } 3769 3770 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3771 if (wback && BitIsClear(registers, n)) { 3772 if (!success) 3773 return false; 3774 3775 offset = (addr_byte_size * BitCount(registers)) * -1; 3776 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3777 context.SetImmediateSigned(offset); 3778 addr_t addr = Rn + offset; 3779 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 3780 addr)) 3781 return false; 3782 } 3783 3784 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 3785 // possible for encoding A1 3786 if (wback && BitIsSet(registers, n)) 3787 return WriteBits32Unknown(n); 3788 } 3789 return true; 3790} 3791 3792// LDMIB loads multiple registers from consecutive memory locations using an 3793// address from a base register. The 3794// consecutive memory locations start just above this address, and thea ddress 3795// of the last of those locations can 3796// optinoally be written back to the base register. 3797bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode, 3798 const ARMEncoding encoding) { 3799#if 0 3800 if ConditionPassed() then 3801 EncodingSpecificOperations(); 3802 address = R[n] + 4; 3803 3804 for i = 0 to 14 3805 if registers<i> == '1' then 3806 R[i] = MemA[address,4]; address = address + 4; 3807 if registers<15> == '1' then 3808 LoadWritePC(MemA[address,4]); 3809 3810 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3811 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3812#endif 3813 3814 bool success = false; 3815 3816 if (ConditionPassed(opcode)) { 3817 uint32_t n; 3818 uint32_t registers = 0; 3819 bool wback; 3820 const uint32_t addr_byte_size = GetAddressByteSize(); 3821 switch (encoding) { 3822 case eEncodingA1: 3823 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3824 n = Bits32(opcode, 19, 16); 3825 registers = Bits32(opcode, 15, 0); 3826 wback = BitIsSet(opcode, 21); 3827 3828 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3829 if ((n == 15) || (BitCount(registers) < 1)) 3830 return false; 3831 3832 break; 3833 default: 3834 return false; 3835 } 3836 // address = R[n] + 4; 3837 3838 int32_t offset = 0; 3839 addr_t Rn = 3840 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3841 3842 if (!success) 3843 return false; 3844 3845 addr_t address = Rn + addr_byte_size; 3846 3847 EmulateInstruction::Context context; 3848 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3849 RegisterInfo dwarf_reg; 3850 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3851 context.SetRegisterPlusOffset(dwarf_reg, offset); 3852 3853 for (int i = 0; i < 14; ++i) { 3854 if (BitIsSet(registers, i)) { 3855 // R[i] = MemA[address,4]; address = address + 4; 3856 3857 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size); 3858 uint32_t data = 3859 MemARead(context, address + offset, addr_byte_size, 0, &success); 3860 if (!success) 3861 return false; 3862 3863 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 3864 data)) 3865 return false; 3866 3867 offset += addr_byte_size; 3868 } 3869 } 3870 3871 // if registers<15> == '1' then 3872 // LoadWritePC(MemA[address,4]); 3873 if (BitIsSet(registers, 15)) { 3874 context.SetRegisterPlusOffset(dwarf_reg, offset); 3875 uint32_t data = 3876 MemARead(context, address + offset, addr_byte_size, 0, &success); 3877 if (!success) 3878 return false; 3879 // In ARMv5T and above, this is an interworking branch. 3880 if (!LoadWritePC(context, data)) 3881 return false; 3882 } 3883 3884 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3885 if (wback && BitIsClear(registers, n)) { 3886 if (!success) 3887 return false; 3888 3889 offset = addr_byte_size * BitCount(registers); 3890 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3891 context.SetImmediateSigned(offset); 3892 addr_t addr = Rn + offset; 3893 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 3894 addr)) 3895 return false; 3896 } 3897 3898 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 3899 // possible for encoding A1 3900 if (wback && BitIsSet(registers, n)) 3901 return WriteBits32Unknown(n); 3902 } 3903 return true; 3904} 3905 3906// Load Register (immediate) calculates an address from a base register value 3907// and 3908// an immediate offset, loads a word from memory, and writes to a register. 3909// LDR (immediate, Thumb) 3910bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode, 3911 const ARMEncoding encoding) { 3912#if 0 3913 // ARM pseudo code... 3914 if (ConditionPassed()) 3915 { 3916 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3917 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3918 address = if index then offset_addr else R[n]; 3919 data = MemU[address,4]; 3920 if wback then R[n] = offset_addr; 3921 if t == 15 then 3922 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3923 elsif UnalignedSupport() || address<1:0> = '00' then 3924 R[t] = data; 3925 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3926 } 3927#endif 3928 3929 bool success = false; 3930 3931 if (ConditionPassed(opcode)) { 3932 uint32_t Rt; // the destination register 3933 uint32_t Rn; // the base register 3934 uint32_t imm32; // the immediate offset used to form the address 3935 addr_t offset_addr; // the offset address 3936 addr_t address; // the calculated address 3937 uint32_t data; // the literal data value from memory load 3938 bool add, index, wback; 3939 switch (encoding) { 3940 case eEncodingT1: 3941 Rt = Bits32(opcode, 2, 0); 3942 Rn = Bits32(opcode, 5, 3); 3943 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3944 // index = TRUE; add = TRUE; wback = FALSE 3945 add = true; 3946 index = true; 3947 wback = false; 3948 3949 break; 3950 3951 case eEncodingT2: 3952 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3953 Rt = Bits32(opcode, 10, 8); 3954 Rn = 13; 3955 imm32 = Bits32(opcode, 7, 0) << 2; 3956 3957 // index = TRUE; add = TRUE; wback = FALSE; 3958 index = true; 3959 add = true; 3960 wback = false; 3961 3962 break; 3963 3964 case eEncodingT3: 3965 // if Rn == '1111' then SEE LDR (literal); 3966 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3967 Rt = Bits32(opcode, 15, 12); 3968 Rn = Bits32(opcode, 19, 16); 3969 imm32 = Bits32(opcode, 11, 0); 3970 3971 // index = TRUE; add = TRUE; wback = FALSE; 3972 index = true; 3973 add = true; 3974 wback = false; 3975 3976 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3977 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3978 return false; 3979 3980 break; 3981 3982 case eEncodingT4: 3983 // if Rn == '1111' then SEE LDR (literal); 3984 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3985 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == 3986 // '00000100' then SEE POP; 3987 // if P == '0' && W == '0' then UNDEFINED; 3988 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 3989 return false; 3990 3991 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3992 Rt = Bits32(opcode, 15, 12); 3993 Rn = Bits32(opcode, 19, 16); 3994 imm32 = Bits32(opcode, 7, 0); 3995 3996 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3997 index = BitIsSet(opcode, 10); 3998 add = BitIsSet(opcode, 9); 3999 wback = BitIsSet(opcode, 8); 4000 4001 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) 4002 // then UNPREDICTABLE; 4003 if ((wback && (Rn == Rt)) || 4004 ((Rt == 15) && InITBlock() && !LastInITBlock())) 4005 return false; 4006 4007 break; 4008 4009 default: 4010 return false; 4011 } 4012 uint32_t base = ReadCoreReg(Rn, &success); 4013 if (!success) 4014 return false; 4015 if (add) 4016 offset_addr = base + imm32; 4017 else 4018 offset_addr = base - imm32; 4019 4020 address = (index ? offset_addr : base); 4021 4022 RegisterInfo base_reg; 4023 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4024 if (wback) { 4025 EmulateInstruction::Context ctx; 4026 if (Rn == 13) { 4027 ctx.type = eContextAdjustStackPointer; 4028 ctx.SetImmediateSigned((int32_t)(offset_addr - base)); 4029 } else if (Rn == GetFramePointerRegisterNumber()) { 4030 ctx.type = eContextSetFramePointer; 4031 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4032 } else { 4033 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4034 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4035 } 4036 4037 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn, 4038 offset_addr)) 4039 return false; 4040 } 4041 4042 // Prepare to write to the Rt register. 4043 EmulateInstruction::Context context; 4044 context.type = EmulateInstruction::eContextRegisterLoad; 4045 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4046 4047 // Read memory from the address. 4048 data = MemURead(context, address, 4, 0, &success); 4049 if (!success) 4050 return false; 4051 4052 if (Rt == 15) { 4053 if (Bits32(address, 1, 0) == 0) { 4054 if (!LoadWritePC(context, data)) 4055 return false; 4056 } else 4057 return false; 4058 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 4059 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 4060 data)) 4061 return false; 4062 } else 4063 WriteBits32Unknown(Rt); 4064 } 4065 return true; 4066} 4067 4068// STM (Store Multiple Increment After) stores multiple registers to consecutive 4069// memory locations using an address 4070// from a base register. The consecutive memory locations start at this 4071// address, and the address just above the last 4072// of those locations can optionally be written back to the base register. 4073bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode, 4074 const ARMEncoding encoding) { 4075#if 0 4076 if ConditionPassed() then 4077 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4078 address = R[n]; 4079 4080 for i = 0 to 14 4081 if registers<i> == '1' then 4082 if i == n && wback && i != LowestSetBit(registers) then 4083 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4084 else 4085 MemA[address,4] = R[i]; 4086 address = address + 4; 4087 4088 if registers<15> == '1' then // Only possible for encoding A1 4089 MemA[address,4] = PCStoreValue(); 4090 if wback then R[n] = R[n] + 4*BitCount(registers); 4091#endif 4092 4093 bool success = false; 4094 4095 if (ConditionPassed(opcode)) { 4096 uint32_t n; 4097 uint32_t registers = 0; 4098 bool wback; 4099 const uint32_t addr_byte_size = GetAddressByteSize(); 4100 4101 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4102 switch (encoding) { 4103 case eEncodingT1: 4104 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4105 n = Bits32(opcode, 10, 8); 4106 registers = Bits32(opcode, 7, 0); 4107 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4108 wback = true; 4109 4110 // if BitCount(registers) < 1 then UNPREDICTABLE; 4111 if (BitCount(registers) < 1) 4112 return false; 4113 4114 break; 4115 4116 case eEncodingT2: 4117 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4118 n = Bits32(opcode, 19, 16); 4119 registers = Bits32(opcode, 15, 0); 4120 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4121 wback = BitIsSet(opcode, 21); 4122 4123 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4124 if ((n == 15) || (BitCount(registers) < 2)) 4125 return false; 4126 4127 // if wback && registers<n> == '1' then UNPREDICTABLE; 4128 if (wback && BitIsSet(registers, n)) 4129 return false; 4130 4131 break; 4132 4133 case eEncodingA1: 4134 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4135 n = Bits32(opcode, 19, 16); 4136 registers = Bits32(opcode, 15, 0); 4137 wback = BitIsSet(opcode, 21); 4138 4139 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4140 if ((n == 15) || (BitCount(registers) < 1)) 4141 return false; 4142 4143 break; 4144 4145 default: 4146 return false; 4147 } 4148 4149 // address = R[n]; 4150 int32_t offset = 0; 4151 const addr_t address = 4152 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4153 if (!success) 4154 return false; 4155 4156 EmulateInstruction::Context context; 4157 context.type = EmulateInstruction::eContextRegisterStore; 4158 RegisterInfo base_reg; 4159 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4160 4161 // for i = 0 to 14 4162 uint32_t lowest_set_bit = 14; 4163 for (uint32_t i = 0; i < 14; ++i) { 4164 // if registers<i> == '1' then 4165 if (BitIsSet(registers, i)) { 4166 if (i < lowest_set_bit) 4167 lowest_set_bit = i; 4168 // if i == n && wback && i != LowestSetBit(registers) then 4169 if ((i == n) && wback && (i != lowest_set_bit)) 4170 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings 4171 // T1 and A1 4172 WriteBits32UnknownToMemory(address + offset); 4173 else { 4174 // MemA[address,4] = R[i]; 4175 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4176 0, &success); 4177 if (!success) 4178 return false; 4179 4180 RegisterInfo data_reg; 4181 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4182 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 4183 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4184 return false; 4185 } 4186 4187 // address = address + 4; 4188 offset += addr_byte_size; 4189 } 4190 } 4191 4192 // if registers<15> == '1' then // Only possible for encoding A1 4193 // MemA[address,4] = PCStoreValue(); 4194 if (BitIsSet(registers, 15)) { 4195 RegisterInfo pc_reg; 4196 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4197 context.SetRegisterPlusOffset(pc_reg, 8); 4198 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4199 if (!success) 4200 return false; 4201 4202 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4203 return false; 4204 } 4205 4206 // if wback then R[n] = R[n] + 4*BitCount(registers); 4207 if (wback) { 4208 offset = addr_byte_size * BitCount(registers); 4209 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4210 context.SetImmediateSigned(offset); 4211 addr_t data = address + offset; 4212 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4213 data)) 4214 return false; 4215 } 4216 } 4217 return true; 4218} 4219 4220// STMDA (Store Multiple Decrement After) stores multiple registers to 4221// consecutive memory locations using an address 4222// from a base register. The consecutive memory locations end at this address, 4223// and the address just below the lowest 4224// of those locations can optionally be written back to the base register. 4225bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode, 4226 const ARMEncoding encoding) { 4227#if 0 4228 if ConditionPassed() then 4229 EncodingSpecificOperations(); 4230 address = R[n] - 4*BitCount(registers) + 4; 4231 4232 for i = 0 to 14 4233 if registers<i> == '1' then 4234 if i == n && wback && i != LowestSetBit(registers) then 4235 MemA[address,4] = bits(32) UNKNOWN; 4236 else 4237 MemA[address,4] = R[i]; 4238 address = address + 4; 4239 4240 if registers<15> == '1' then 4241 MemA[address,4] = PCStoreValue(); 4242 4243 if wback then R[n] = R[n] - 4*BitCount(registers); 4244#endif 4245 4246 bool success = false; 4247 4248 if (ConditionPassed(opcode)) { 4249 uint32_t n; 4250 uint32_t registers = 0; 4251 bool wback; 4252 const uint32_t addr_byte_size = GetAddressByteSize(); 4253 4254 // EncodingSpecificOperations(); 4255 switch (encoding) { 4256 case eEncodingA1: 4257 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4258 n = Bits32(opcode, 19, 16); 4259 registers = Bits32(opcode, 15, 0); 4260 wback = BitIsSet(opcode, 21); 4261 4262 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4263 if ((n == 15) || (BitCount(registers) < 1)) 4264 return false; 4265 break; 4266 default: 4267 return false; 4268 } 4269 4270 // address = R[n] - 4*BitCount(registers) + 4; 4271 int32_t offset = 0; 4272 addr_t Rn = ReadCoreReg(n, &success); 4273 if (!success) 4274 return false; 4275 4276 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4; 4277 4278 EmulateInstruction::Context context; 4279 context.type = EmulateInstruction::eContextRegisterStore; 4280 RegisterInfo base_reg; 4281 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4282 4283 // for i = 0 to 14 4284 uint32_t lowest_bit_set = 14; 4285 for (uint32_t i = 0; i < 14; ++i) { 4286 // if registers<i> == '1' then 4287 if (BitIsSet(registers, i)) { 4288 if (i < lowest_bit_set) 4289 lowest_bit_set = i; 4290 // if i == n && wback && i != LowestSetBit(registers) then 4291 if ((i == n) && wback && (i != lowest_bit_set)) 4292 // MemA[address,4] = bits(32) UNKNOWN; 4293 WriteBits32UnknownToMemory(address + offset); 4294 else { 4295 // MemA[address,4] = R[i]; 4296 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4297 0, &success); 4298 if (!success) 4299 return false; 4300 4301 RegisterInfo data_reg; 4302 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4303 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4304 Rn - (address + offset)); 4305 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4306 return false; 4307 } 4308 4309 // address = address + 4; 4310 offset += addr_byte_size; 4311 } 4312 } 4313 4314 // if registers<15> == '1' then 4315 // MemA[address,4] = PCStoreValue(); 4316 if (BitIsSet(registers, 15)) { 4317 RegisterInfo pc_reg; 4318 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4319 context.SetRegisterPlusOffset(pc_reg, 8); 4320 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4321 if (!success) 4322 return false; 4323 4324 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4325 return false; 4326 } 4327 4328 // if wback then R[n] = R[n] - 4*BitCount(registers); 4329 if (wback) { 4330 offset = (addr_byte_size * BitCount(registers)) * -1; 4331 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4332 context.SetImmediateSigned(offset); 4333 addr_t data = Rn + offset; 4334 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4335 data)) 4336 return false; 4337 } 4338 } 4339 return true; 4340} 4341 4342// STMDB (Store Multiple Decrement Before) stores multiple registers to 4343// consecutive memory locations using an address 4344// from a base register. The consecutive memory locations end just below this 4345// address, and the address of the first of 4346// those locations can optionally be written back to the base register. 4347bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode, 4348 const ARMEncoding encoding) { 4349#if 0 4350 if ConditionPassed() then 4351 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4352 address = R[n] - 4*BitCount(registers); 4353 4354 for i = 0 to 14 4355 if registers<i> == '1' then 4356 if i == n && wback && i != LowestSetBit(registers) then 4357 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4358 else 4359 MemA[address,4] = R[i]; 4360 address = address + 4; 4361 4362 if registers<15> == '1' then // Only possible for encoding A1 4363 MemA[address,4] = PCStoreValue(); 4364 4365 if wback then R[n] = R[n] - 4*BitCount(registers); 4366#endif 4367 4368 bool success = false; 4369 4370 if (ConditionPassed(opcode)) { 4371 uint32_t n; 4372 uint32_t registers = 0; 4373 bool wback; 4374 const uint32_t addr_byte_size = GetAddressByteSize(); 4375 4376 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4377 switch (encoding) { 4378 case eEncodingT1: 4379 // if W == '1' && Rn == '1101' then SEE PUSH; 4380 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) { 4381 // See PUSH 4382 } 4383 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4384 n = Bits32(opcode, 19, 16); 4385 registers = Bits32(opcode, 15, 0); 4386 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4387 wback = BitIsSet(opcode, 21); 4388 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4389 if ((n == 15) || BitCount(registers) < 2) 4390 return false; 4391 // if wback && registers<n> == '1' then UNPREDICTABLE; 4392 if (wback && BitIsSet(registers, n)) 4393 return false; 4394 break; 4395 4396 case eEncodingA1: 4397 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE 4398 // PUSH; 4399 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) && 4400 BitCount(Bits32(opcode, 15, 0)) >= 2) { 4401 // See Push 4402 } 4403 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4404 n = Bits32(opcode, 19, 16); 4405 registers = Bits32(opcode, 15, 0); 4406 wback = BitIsSet(opcode, 21); 4407 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4408 if ((n == 15) || BitCount(registers) < 1) 4409 return false; 4410 break; 4411 4412 default: 4413 return false; 4414 } 4415 4416 // address = R[n] - 4*BitCount(registers); 4417 4418 int32_t offset = 0; 4419 addr_t Rn = 4420 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4421 if (!success) 4422 return false; 4423 4424 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4425 4426 EmulateInstruction::Context context; 4427 context.type = EmulateInstruction::eContextRegisterStore; 4428 RegisterInfo base_reg; 4429 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4430 4431 // for i = 0 to 14 4432 uint32_t lowest_set_bit = 14; 4433 for (uint32_t i = 0; i < 14; ++i) { 4434 // if registers<i> == '1' then 4435 if (BitIsSet(registers, i)) { 4436 if (i < lowest_set_bit) 4437 lowest_set_bit = i; 4438 // if i == n && wback && i != LowestSetBit(registers) then 4439 if ((i == n) && wback && (i != lowest_set_bit)) 4440 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding 4441 // A1 4442 WriteBits32UnknownToMemory(address + offset); 4443 else { 4444 // MemA[address,4] = R[i]; 4445 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4446 0, &success); 4447 if (!success) 4448 return false; 4449 4450 RegisterInfo data_reg; 4451 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4452 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4453 Rn - (address + offset)); 4454 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4455 return false; 4456 } 4457 4458 // address = address + 4; 4459 offset += addr_byte_size; 4460 } 4461 } 4462 4463 // if registers<15> == '1' then // Only possible for encoding A1 4464 // MemA[address,4] = PCStoreValue(); 4465 if (BitIsSet(registers, 15)) { 4466 RegisterInfo pc_reg; 4467 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4468 context.SetRegisterPlusOffset(pc_reg, 8); 4469 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4470 if (!success) 4471 return false; 4472 4473 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4474 return false; 4475 } 4476 4477 // if wback then R[n] = R[n] - 4*BitCount(registers); 4478 if (wback) { 4479 offset = (addr_byte_size * BitCount(registers)) * -1; 4480 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4481 context.SetImmediateSigned(offset); 4482 addr_t data = Rn + offset; 4483 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4484 data)) 4485 return false; 4486 } 4487 } 4488 return true; 4489} 4490 4491// STMIB (Store Multiple Increment Before) stores multiple registers to 4492// consecutive memory locations using an address 4493// from a base register. The consecutive memory locations start just above this 4494// address, and the address of the last 4495// of those locations can optionally be written back to the base register. 4496bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode, 4497 const ARMEncoding encoding) { 4498#if 0 4499 if ConditionPassed() then 4500 EncodingSpecificOperations(); 4501 address = R[n] + 4; 4502 4503 for i = 0 to 14 4504 if registers<i> == '1' then 4505 if i == n && wback && i != LowestSetBit(registers) then 4506 MemA[address,4] = bits(32) UNKNOWN; 4507 else 4508 MemA[address,4] = R[i]; 4509 address = address + 4; 4510 4511 if registers<15> == '1' then 4512 MemA[address,4] = PCStoreValue(); 4513 4514 if wback then R[n] = R[n] + 4*BitCount(registers); 4515#endif 4516 4517 bool success = false; 4518 4519 if (ConditionPassed(opcode)) { 4520 uint32_t n; 4521 uint32_t registers = 0; 4522 bool wback; 4523 const uint32_t addr_byte_size = GetAddressByteSize(); 4524 4525 // EncodingSpecificOperations(); 4526 switch (encoding) { 4527 case eEncodingA1: 4528 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4529 n = Bits32(opcode, 19, 16); 4530 registers = Bits32(opcode, 15, 0); 4531 wback = BitIsSet(opcode, 21); 4532 4533 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4534 if ((n == 15) && (BitCount(registers) < 1)) 4535 return false; 4536 break; 4537 default: 4538 return false; 4539 } 4540 // address = R[n] + 4; 4541 4542 int32_t offset = 0; 4543 addr_t Rn = ReadCoreReg(n, &success); 4544 if (!success) 4545 return false; 4546 4547 addr_t address = Rn + addr_byte_size; 4548 4549 EmulateInstruction::Context context; 4550 context.type = EmulateInstruction::eContextRegisterStore; 4551 RegisterInfo base_reg; 4552 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4553 4554 uint32_t lowest_set_bit = 14; 4555 // for i = 0 to 14 4556 for (uint32_t i = 0; i < 14; ++i) { 4557 // if registers<i> == '1' then 4558 if (BitIsSet(registers, i)) { 4559 if (i < lowest_set_bit) 4560 lowest_set_bit = i; 4561 // if i == n && wback && i != LowestSetBit(registers) then 4562 if ((i == n) && wback && (i != lowest_set_bit)) 4563 // MemA[address,4] = bits(32) UNKNOWN; 4564 WriteBits32UnknownToMemory(address + offset); 4565 // else 4566 else { 4567 // MemA[address,4] = R[i]; 4568 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4569 0, &success); 4570 if (!success) 4571 return false; 4572 4573 RegisterInfo data_reg; 4574 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4575 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4576 offset + addr_byte_size); 4577 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4578 return false; 4579 } 4580 4581 // address = address + 4; 4582 offset += addr_byte_size; 4583 } 4584 } 4585 4586 // if registers<15> == '1' then 4587 // MemA[address,4] = PCStoreValue(); 4588 if (BitIsSet(registers, 15)) { 4589 RegisterInfo pc_reg; 4590 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4591 context.SetRegisterPlusOffset(pc_reg, 8); 4592 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4593 if (!success) 4594 return false; 4595 4596 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4597 return false; 4598 } 4599 4600 // if wback then R[n] = R[n] + 4*BitCount(registers); 4601 if (wback) { 4602 offset = addr_byte_size * BitCount(registers); 4603 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4604 context.SetImmediateSigned(offset); 4605 addr_t data = Rn + offset; 4606 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4607 data)) 4608 return false; 4609 } 4610 } 4611 return true; 4612} 4613 4614// STR (store immediate) calculates an address from a base register value and an 4615// immediate offset, and stores a word 4616// from a register to memory. It can use offset, post-indexed, or pre-indexed 4617// addressing. 4618bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode, 4619 const ARMEncoding encoding) { 4620#if 0 4621 if ConditionPassed() then 4622 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4623 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4624 address = if index then offset_addr else R[n]; 4625 if UnalignedSupport() || address<1:0> == '00' then 4626 MemU[address,4] = R[t]; 4627 else // Can only occur before ARMv7 4628 MemU[address,4] = bits(32) UNKNOWN; 4629 if wback then R[n] = offset_addr; 4630#endif 4631 4632 bool success = false; 4633 4634 if (ConditionPassed(opcode)) { 4635 const uint32_t addr_byte_size = GetAddressByteSize(); 4636 4637 uint32_t t; 4638 uint32_t n; 4639 uint32_t imm32; 4640 bool index; 4641 bool add; 4642 bool wback; 4643 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4644 switch (encoding) { 4645 case eEncodingT1: 4646 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4647 t = Bits32(opcode, 2, 0); 4648 n = Bits32(opcode, 5, 3); 4649 imm32 = Bits32(opcode, 10, 6) << 2; 4650 4651 // index = TRUE; add = TRUE; wback = FALSE; 4652 index = true; 4653 add = false; 4654 wback = false; 4655 break; 4656 4657 case eEncodingT2: 4658 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4659 t = Bits32(opcode, 10, 8); 4660 n = 13; 4661 imm32 = Bits32(opcode, 7, 0) << 2; 4662 4663 // index = TRUE; add = TRUE; wback = FALSE; 4664 index = true; 4665 add = true; 4666 wback = false; 4667 break; 4668 4669 case eEncodingT3: 4670 // if Rn == '1111' then UNDEFINED; 4671 if (Bits32(opcode, 19, 16) == 15) 4672 return false; 4673 4674 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4675 t = Bits32(opcode, 15, 12); 4676 n = Bits32(opcode, 19, 16); 4677 imm32 = Bits32(opcode, 11, 0); 4678 4679 // index = TRUE; add = TRUE; wback = FALSE; 4680 index = true; 4681 add = true; 4682 wback = false; 4683 4684 // if t == 15 then UNPREDICTABLE; 4685 if (t == 15) 4686 return false; 4687 break; 4688 4689 case eEncodingT4: 4690 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4691 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == 4692 // '00000100' then SEE PUSH; 4693 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4694 if ((Bits32(opcode, 19, 16) == 15) || 4695 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))) 4696 return false; 4697 4698 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4699 t = Bits32(opcode, 15, 12); 4700 n = Bits32(opcode, 19, 16); 4701 imm32 = Bits32(opcode, 7, 0); 4702 4703 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4704 index = BitIsSet(opcode, 10); 4705 add = BitIsSet(opcode, 9); 4706 wback = BitIsSet(opcode, 8); 4707 4708 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4709 if ((t == 15) || (wback && (n == t))) 4710 return false; 4711 break; 4712 4713 default: 4714 return false; 4715 } 4716 4717 addr_t offset_addr; 4718 addr_t address; 4719 4720 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4721 uint32_t base_address = ReadCoreReg(n, &success); 4722 if (!success) 4723 return false; 4724 4725 if (add) 4726 offset_addr = base_address + imm32; 4727 else 4728 offset_addr = base_address - imm32; 4729 4730 // address = if index then offset_addr else R[n]; 4731 if (index) 4732 address = offset_addr; 4733 else 4734 address = base_address; 4735 4736 EmulateInstruction::Context context; 4737 if (n == 13) 4738 context.type = eContextPushRegisterOnStack; 4739 else 4740 context.type = eContextRegisterStore; 4741 4742 RegisterInfo base_reg; 4743 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4744 4745 // if UnalignedSupport() || address<1:0> == '00' then 4746 if (UnalignedSupport() || 4747 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 4748 // MemU[address,4] = R[t]; 4749 uint32_t data = 4750 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4751 if (!success) 4752 return false; 4753 4754 RegisterInfo data_reg; 4755 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4756 int32_t offset = address - base_address; 4757 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 4758 if (!MemUWrite(context, address, data, addr_byte_size)) 4759 return false; 4760 } else { 4761 // MemU[address,4] = bits(32) UNKNOWN; 4762 WriteBits32UnknownToMemory(address); 4763 } 4764 4765 // if wback then R[n] = offset_addr; 4766 if (wback) { 4767 if (n == 13) 4768 context.type = eContextAdjustStackPointer; 4769 else 4770 context.type = eContextAdjustBaseRegister; 4771 context.SetAddress(offset_addr); 4772 4773 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4774 offset_addr)) 4775 return false; 4776 } 4777 } 4778 return true; 4779} 4780 4781// STR (Store Register) calculates an address from a base register value and an 4782// offset register value, stores a 4783// word from a register to memory. The offset register value can optionally be 4784// shifted. 4785bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode, 4786 const ARMEncoding encoding) { 4787#if 0 4788 if ConditionPassed() then 4789 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4790 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4791 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4792 address = if index then offset_addr else R[n]; 4793 if t == 15 then // Only possible for encoding A1 4794 data = PCStoreValue(); 4795 else 4796 data = R[t]; 4797 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4798 MemU[address,4] = data; 4799 else // Can only occur before ARMv7 4800 MemU[address,4] = bits(32) UNKNOWN; 4801 if wback then R[n] = offset_addr; 4802#endif 4803 4804 bool success = false; 4805 4806 if (ConditionPassed(opcode)) { 4807 const uint32_t addr_byte_size = GetAddressByteSize(); 4808 4809 uint32_t t; 4810 uint32_t n; 4811 uint32_t m; 4812 ARM_ShifterType shift_t; 4813 uint32_t shift_n; 4814 bool index; 4815 bool add; 4816 bool wback; 4817 4818 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4819 switch (encoding) { 4820 case eEncodingT1: 4821 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 4822 // in ThumbEE"; 4823 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4824 t = Bits32(opcode, 2, 0); 4825 n = Bits32(opcode, 5, 3); 4826 m = Bits32(opcode, 8, 6); 4827 4828 // index = TRUE; add = TRUE; wback = FALSE; 4829 index = true; 4830 add = true; 4831 wback = false; 4832 4833 // (shift_t, shift_n) = (SRType_LSL, 0); 4834 shift_t = SRType_LSL; 4835 shift_n = 0; 4836 break; 4837 4838 case eEncodingT2: 4839 // if Rn == '1111' then UNDEFINED; 4840 if (Bits32(opcode, 19, 16) == 15) 4841 return false; 4842 4843 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4844 t = Bits32(opcode, 15, 12); 4845 n = Bits32(opcode, 19, 16); 4846 m = Bits32(opcode, 3, 0); 4847 4848 // index = TRUE; add = TRUE; wback = FALSE; 4849 index = true; 4850 add = true; 4851 wback = false; 4852 4853 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4854 shift_t = SRType_LSL; 4855 shift_n = Bits32(opcode, 5, 4); 4856 4857 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4858 if ((t == 15) || (BadReg(m))) 4859 return false; 4860 break; 4861 4862 case eEncodingA1: { 4863 // if P == '0' && W == '1' then SEE STRT; 4864 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4865 t = Bits32(opcode, 15, 12); 4866 n = Bits32(opcode, 19, 16); 4867 m = Bits32(opcode, 3, 0); 4868 4869 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 4870 // (W == '1'); 4871 index = BitIsSet(opcode, 24); 4872 add = BitIsSet(opcode, 23); 4873 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 4874 4875 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4876 uint32_t typ = Bits32(opcode, 6, 5); 4877 uint32_t imm5 = Bits32(opcode, 11, 7); 4878 shift_n = DecodeImmShift(typ, imm5, shift_t); 4879 4880 // if m == 15 then UNPREDICTABLE; 4881 if (m == 15) 4882 return false; 4883 4884 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4885 if (wback && ((n == 15) || (n == t))) 4886 return false; 4887 4888 break; 4889 } 4890 default: 4891 return false; 4892 } 4893 4894 addr_t offset_addr; 4895 addr_t address; 4896 int32_t offset = 0; 4897 4898 addr_t base_address = 4899 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4900 if (!success) 4901 return false; 4902 4903 uint32_t Rm_data = 4904 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4905 if (!success) 4906 return false; 4907 4908 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4909 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success); 4910 if (!success) 4911 return false; 4912 4913 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4914 if (add) 4915 offset_addr = base_address + offset; 4916 else 4917 offset_addr = base_address - offset; 4918 4919 // address = if index then offset_addr else R[n]; 4920 if (index) 4921 address = offset_addr; 4922 else 4923 address = base_address; 4924 4925 uint32_t data; 4926 // if t == 15 then // Only possible for encoding A1 4927 if (t == 15) 4928 // data = PCStoreValue(); 4929 data = ReadCoreReg(PC_REG, &success); 4930 else 4931 // data = R[t]; 4932 data = 4933 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4934 4935 if (!success) 4936 return false; 4937 4938 EmulateInstruction::Context context; 4939 context.type = eContextRegisterStore; 4940 4941 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == 4942 // InstrSet_ARM then 4943 if (UnalignedSupport() || 4944 (BitIsClear(address, 1) && BitIsClear(address, 0)) || 4945 CurrentInstrSet() == eModeARM) { 4946 // MemU[address,4] = data; 4947 4948 RegisterInfo base_reg; 4949 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4950 4951 RegisterInfo data_reg; 4952 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4953 4954 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4955 address - base_address); 4956 if (!MemUWrite(context, address, data, addr_byte_size)) 4957 return false; 4958 4959 } else 4960 // MemU[address,4] = bits(32) UNKNOWN; 4961 WriteBits32UnknownToMemory(address); 4962 4963 // if wback then R[n] = offset_addr; 4964 if (wback) { 4965 context.type = eContextRegisterLoad; 4966 context.SetAddress(offset_addr); 4967 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4968 offset_addr)) 4969 return false; 4970 } 4971 } 4972 return true; 4973} 4974 4975bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode, 4976 const ARMEncoding encoding) { 4977#if 0 4978 if ConditionPassed() then 4979 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4980 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4981 address = if index then offset_addr else R[n]; 4982 MemU[address,1] = R[t]<7:0>; 4983 if wback then R[n] = offset_addr; 4984#endif 4985 4986 bool success = false; 4987 4988 if (ConditionPassed(opcode)) { 4989 uint32_t t; 4990 uint32_t n; 4991 uint32_t imm32; 4992 bool index; 4993 bool add; 4994 bool wback; 4995 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4996 switch (encoding) { 4997 case eEncodingT1: 4998 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4999 t = Bits32(opcode, 2, 0); 5000 n = Bits32(opcode, 5, 3); 5001 imm32 = Bits32(opcode, 10, 6); 5002 5003 // index = TRUE; add = TRUE; wback = FALSE; 5004 index = true; 5005 add = true; 5006 wback = false; 5007 break; 5008 5009 case eEncodingT2: 5010 // if Rn == '1111' then UNDEFINED; 5011 if (Bits32(opcode, 19, 16) == 15) 5012 return false; 5013 5014 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5015 t = Bits32(opcode, 15, 12); 5016 n = Bits32(opcode, 19, 16); 5017 imm32 = Bits32(opcode, 11, 0); 5018 5019 // index = TRUE; add = TRUE; wback = FALSE; 5020 index = true; 5021 add = true; 5022 wback = false; 5023 5024 // if BadReg(t) then UNPREDICTABLE; 5025 if (BadReg(t)) 5026 return false; 5027 break; 5028 5029 case eEncodingT3: 5030 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5031 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5032 if (Bits32(opcode, 19, 16) == 15) 5033 return false; 5034 5035 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5036 t = Bits32(opcode, 15, 12); 5037 n = Bits32(opcode, 19, 16); 5038 imm32 = Bits32(opcode, 7, 0); 5039 5040 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5041 index = BitIsSet(opcode, 10); 5042 add = BitIsSet(opcode, 9); 5043 wback = BitIsSet(opcode, 8); 5044 5045 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5046 if ((BadReg(t)) || (wback && (n == t))) 5047 return false; 5048 break; 5049 5050 default: 5051 return false; 5052 } 5053 5054 addr_t offset_addr; 5055 addr_t address; 5056 addr_t base_address = 5057 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5058 if (!success) 5059 return false; 5060 5061 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5062 if (add) 5063 offset_addr = base_address + imm32; 5064 else 5065 offset_addr = base_address - imm32; 5066 5067 // address = if index then offset_addr else R[n]; 5068 if (index) 5069 address = offset_addr; 5070 else 5071 address = base_address; 5072 5073 // MemU[address,1] = R[t]<7:0> 5074 RegisterInfo base_reg; 5075 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5076 5077 RegisterInfo data_reg; 5078 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5079 5080 EmulateInstruction::Context context; 5081 context.type = eContextRegisterStore; 5082 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5083 address - base_address); 5084 5085 uint32_t data = 5086 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5087 if (!success) 5088 return false; 5089 5090 data = Bits32(data, 7, 0); 5091 5092 if (!MemUWrite(context, address, data, 1)) 5093 return false; 5094 5095 // if wback then R[n] = offset_addr; 5096 if (wback) { 5097 context.type = eContextRegisterLoad; 5098 context.SetAddress(offset_addr); 5099 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5100 offset_addr)) 5101 return false; 5102 } 5103 } 5104 5105 return true; 5106} 5107 5108// STRH (register) calculates an address from a base register value and an 5109// offset register value, and stores a 5110// halfword from a register to memory. The offset register value can be shifted 5111// left by 0, 1, 2, or 3 bits. 5112bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode, 5113 const ARMEncoding encoding) { 5114#if 0 5115 if ConditionPassed() then 5116 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5117 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5118 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5119 address = if index then offset_addr else R[n]; 5120 if UnalignedSupport() || address<0> == '0' then 5121 MemU[address,2] = R[t]<15:0>; 5122 else // Can only occur before ARMv7 5123 MemU[address,2] = bits(16) UNKNOWN; 5124 if wback then R[n] = offset_addr; 5125#endif 5126 5127 bool success = false; 5128 5129 if (ConditionPassed(opcode)) { 5130 uint32_t t; 5131 uint32_t n; 5132 uint32_t m; 5133 bool index; 5134 bool add; 5135 bool wback; 5136 ARM_ShifterType shift_t; 5137 uint32_t shift_n; 5138 5139 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5140 switch (encoding) { 5141 case eEncodingT1: 5142 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5143 // in ThumbEE"; 5144 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5145 t = Bits32(opcode, 2, 0); 5146 n = Bits32(opcode, 5, 3); 5147 m = Bits32(opcode, 8, 6); 5148 5149 // index = TRUE; add = TRUE; wback = FALSE; 5150 index = true; 5151 add = true; 5152 wback = false; 5153 5154 // (shift_t, shift_n) = (SRType_LSL, 0); 5155 shift_t = SRType_LSL; 5156 shift_n = 0; 5157 5158 break; 5159 5160 case eEncodingT2: 5161 // if Rn == '1111' then UNDEFINED; 5162 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5163 t = Bits32(opcode, 15, 12); 5164 n = Bits32(opcode, 19, 16); 5165 m = Bits32(opcode, 3, 0); 5166 if (n == 15) 5167 return false; 5168 5169 // index = TRUE; add = TRUE; wback = FALSE; 5170 index = true; 5171 add = true; 5172 wback = false; 5173 5174 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5175 shift_t = SRType_LSL; 5176 shift_n = Bits32(opcode, 5, 4); 5177 5178 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5179 if (BadReg(t) || BadReg(m)) 5180 return false; 5181 5182 break; 5183 5184 case eEncodingA1: 5185 // if P == '0' && W == '1' then SEE STRHT; 5186 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5187 t = Bits32(opcode, 15, 12); 5188 n = Bits32(opcode, 19, 16); 5189 m = Bits32(opcode, 3, 0); 5190 5191 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5192 // (W == '1'); 5193 index = BitIsSet(opcode, 24); 5194 add = BitIsSet(opcode, 23); 5195 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5196 5197 // (shift_t, shift_n) = (SRType_LSL, 0); 5198 shift_t = SRType_LSL; 5199 shift_n = 0; 5200 5201 // if t == 15 || m == 15 then UNPREDICTABLE; 5202 if ((t == 15) || (m == 15)) 5203 return false; 5204 5205 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5206 if (wback && ((n == 15) || (n == t))) 5207 return false; 5208 5209 break; 5210 5211 default: 5212 return false; 5213 } 5214 5215 uint32_t Rm = ReadCoreReg(m, &success); 5216 if (!success) 5217 return false; 5218 5219 uint32_t Rn = ReadCoreReg(n, &success); 5220 if (!success) 5221 return false; 5222 5223 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5224 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 5225 if (!success) 5226 return false; 5227 5228 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5229 addr_t offset_addr; 5230 if (add) 5231 offset_addr = Rn + offset; 5232 else 5233 offset_addr = Rn - offset; 5234 5235 // address = if index then offset_addr else R[n]; 5236 addr_t address; 5237 if (index) 5238 address = offset_addr; 5239 else 5240 address = Rn; 5241 5242 EmulateInstruction::Context context; 5243 context.type = eContextRegisterStore; 5244 RegisterInfo base_reg; 5245 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5246 RegisterInfo offset_reg; 5247 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5248 5249 // if UnalignedSupport() || address<0> == '0' then 5250 if (UnalignedSupport() || BitIsClear(address, 0)) { 5251 // MemU[address,2] = R[t]<15:0>; 5252 uint32_t Rt = ReadCoreReg(t, &success); 5253 if (!success) 5254 return false; 5255 5256 EmulateInstruction::Context context; 5257 context.type = eContextRegisterStore; 5258 RegisterInfo base_reg; 5259 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5260 RegisterInfo offset_reg; 5261 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5262 RegisterInfo data_reg; 5263 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5264 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 5265 data_reg); 5266 5267 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2)) 5268 return false; 5269 } else // Can only occur before ARMv7 5270 { 5271 // MemU[address,2] = bits(16) UNKNOWN; 5272 } 5273 5274 // if wback then R[n] = offset_addr; 5275 if (wback) { 5276 context.type = eContextAdjustBaseRegister; 5277 context.SetAddress(offset_addr); 5278 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5279 offset_addr)) 5280 return false; 5281 } 5282 } 5283 5284 return true; 5285} 5286 5287// Add with Carry (immediate) adds an immediate value and the carry flag value 5288// to a register value, 5289// and writes the result to the destination register. It can optionally update 5290// the condition flags 5291// based on the result. 5292bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode, 5293 const ARMEncoding encoding) { 5294#if 0 5295 // ARM pseudo code... 5296 if ConditionPassed() then 5297 EncodingSpecificOperations(); 5298 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5299 if d == 15 then // Can only occur for ARM encoding 5300 ALUWritePC(result); // setflags is always FALSE here 5301 else 5302 R[d] = result; 5303 if setflags then 5304 APSR.N = result<31>; 5305 APSR.Z = IsZeroBit(result); 5306 APSR.C = carry; 5307 APSR.V = overflow; 5308#endif 5309 5310 bool success = false; 5311 5312 if (ConditionPassed(opcode)) { 5313 uint32_t Rd, Rn; 5314 uint32_t 5315 imm32; // the immediate value to be added to the value obtained from Rn 5316 bool setflags; 5317 switch (encoding) { 5318 case eEncodingT1: 5319 Rd = Bits32(opcode, 11, 8); 5320 Rn = Bits32(opcode, 19, 16); 5321 setflags = BitIsSet(opcode, 20); 5322 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5323 if (BadReg(Rd) || BadReg(Rn)) 5324 return false; 5325 break; 5326 case eEncodingA1: 5327 Rd = Bits32(opcode, 15, 12); 5328 Rn = Bits32(opcode, 19, 16); 5329 setflags = BitIsSet(opcode, 20); 5330 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5331 5332 if (Rd == 15 && setflags) 5333 return EmulateSUBSPcLrEtc(opcode, encoding); 5334 break; 5335 default: 5336 return false; 5337 } 5338 5339 // Read the first operand. 5340 int32_t val1 = ReadCoreReg(Rn, &success); 5341 if (!success) 5342 return false; 5343 5344 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5345 5346 EmulateInstruction::Context context; 5347 context.type = EmulateInstruction::eContextImmediate; 5348 context.SetNoArgs(); 5349 5350 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5351 res.carry_out, res.overflow)) 5352 return false; 5353 } 5354 return true; 5355} 5356 5357// Add with Carry (register) adds a register value, the carry flag value, and an 5358// optionally-shifted 5359// register value, and writes the result to the destination register. It can 5360// optionally update the 5361// condition flags based on the result. 5362bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode, 5363 const ARMEncoding encoding) { 5364#if 0 5365 // ARM pseudo code... 5366 if ConditionPassed() then 5367 EncodingSpecificOperations(); 5368 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5369 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5370 if d == 15 then // Can only occur for ARM encoding 5371 ALUWritePC(result); // setflags is always FALSE here 5372 else 5373 R[d] = result; 5374 if setflags then 5375 APSR.N = result<31>; 5376 APSR.Z = IsZeroBit(result); 5377 APSR.C = carry; 5378 APSR.V = overflow; 5379#endif 5380 5381 bool success = false; 5382 5383 if (ConditionPassed(opcode)) { 5384 uint32_t Rd, Rn, Rm; 5385 ARM_ShifterType shift_t; 5386 uint32_t shift_n; // the shift applied to the value read from Rm 5387 bool setflags; 5388 switch (encoding) { 5389 case eEncodingT1: 5390 Rd = Rn = Bits32(opcode, 2, 0); 5391 Rm = Bits32(opcode, 5, 3); 5392 setflags = !InITBlock(); 5393 shift_t = SRType_LSL; 5394 shift_n = 0; 5395 break; 5396 case eEncodingT2: 5397 Rd = Bits32(opcode, 11, 8); 5398 Rn = Bits32(opcode, 19, 16); 5399 Rm = Bits32(opcode, 3, 0); 5400 setflags = BitIsSet(opcode, 20); 5401 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5402 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5403 return false; 5404 break; 5405 case eEncodingA1: 5406 Rd = Bits32(opcode, 15, 12); 5407 Rn = Bits32(opcode, 19, 16); 5408 Rm = Bits32(opcode, 3, 0); 5409 setflags = BitIsSet(opcode, 20); 5410 shift_n = DecodeImmShiftARM(opcode, shift_t); 5411 5412 if (Rd == 15 && setflags) 5413 return EmulateSUBSPcLrEtc(opcode, encoding); 5414 break; 5415 default: 5416 return false; 5417 } 5418 5419 // Read the first operand. 5420 int32_t val1 = ReadCoreReg(Rn, &success); 5421 if (!success) 5422 return false; 5423 5424 // Read the second operand. 5425 int32_t val2 = ReadCoreReg(Rm, &success); 5426 if (!success) 5427 return false; 5428 5429 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5430 if (!success) 5431 return false; 5432 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5433 5434 EmulateInstruction::Context context; 5435 context.type = EmulateInstruction::eContextImmediate; 5436 context.SetNoArgs(); 5437 5438 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5439 res.carry_out, res.overflow)) 5440 return false; 5441 } 5442 return true; 5443} 5444 5445// This instruction adds an immediate value to the PC value to form a 5446// PC-relative address, 5447// and writes the result to the destination register. 5448bool EmulateInstructionARM::EmulateADR(const uint32_t opcode, 5449 const ARMEncoding encoding) { 5450#if 0 5451 // ARM pseudo code... 5452 if ConditionPassed() then 5453 EncodingSpecificOperations(); 5454 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5455 if d == 15 then // Can only occur for ARM encodings 5456 ALUWritePC(result); 5457 else 5458 R[d] = result; 5459#endif 5460 5461 bool success = false; 5462 5463 if (ConditionPassed(opcode)) { 5464 uint32_t Rd; 5465 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5466 bool add; 5467 switch (encoding) { 5468 case eEncodingT1: 5469 Rd = Bits32(opcode, 10, 8); 5470 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5471 add = true; 5472 break; 5473 case eEncodingT2: 5474 case eEncodingT3: 5475 Rd = Bits32(opcode, 11, 8); 5476 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5477 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5478 if (BadReg(Rd)) 5479 return false; 5480 break; 5481 case eEncodingA1: 5482 case eEncodingA2: 5483 Rd = Bits32(opcode, 15, 12); 5484 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5485 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5486 break; 5487 default: 5488 return false; 5489 } 5490 5491 // Read the PC value. 5492 uint32_t pc = ReadCoreReg(PC_REG, &success); 5493 if (!success) 5494 return false; 5495 5496 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5497 5498 EmulateInstruction::Context context; 5499 context.type = EmulateInstruction::eContextImmediate; 5500 context.SetNoArgs(); 5501 5502 if (!WriteCoreReg(context, result, Rd)) 5503 return false; 5504 } 5505 return true; 5506} 5507 5508// This instruction performs a bitwise AND of a register value and an immediate 5509// value, and writes the result 5510// to the destination register. It can optionally update the condition flags 5511// based on the result. 5512bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode, 5513 const ARMEncoding encoding) { 5514#if 0 5515 // ARM pseudo code... 5516 if ConditionPassed() then 5517 EncodingSpecificOperations(); 5518 result = R[n] AND imm32; 5519 if d == 15 then // Can only occur for ARM encoding 5520 ALUWritePC(result); // setflags is always FALSE here 5521 else 5522 R[d] = result; 5523 if setflags then 5524 APSR.N = result<31>; 5525 APSR.Z = IsZeroBit(result); 5526 APSR.C = carry; 5527 // APSR.V unchanged 5528#endif 5529 5530 bool success = false; 5531 5532 if (ConditionPassed(opcode)) { 5533 uint32_t Rd, Rn; 5534 uint32_t 5535 imm32; // the immediate value to be ANDed to the value obtained from Rn 5536 bool setflags; 5537 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5538 switch (encoding) { 5539 case eEncodingT1: 5540 Rd = Bits32(opcode, 11, 8); 5541 Rn = Bits32(opcode, 19, 16); 5542 setflags = BitIsSet(opcode, 20); 5543 imm32 = ThumbExpandImm_C( 5544 opcode, APSR_C, 5545 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5546 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5547 if (Rd == 15 && setflags) 5548 return EmulateTSTImm(opcode, eEncodingT1); 5549 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5550 return false; 5551 break; 5552 case eEncodingA1: 5553 Rd = Bits32(opcode, 15, 12); 5554 Rn = Bits32(opcode, 19, 16); 5555 setflags = BitIsSet(opcode, 20); 5556 imm32 = 5557 ARMExpandImm_C(opcode, APSR_C, 5558 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5559 5560 if (Rd == 15 && setflags) 5561 return EmulateSUBSPcLrEtc(opcode, encoding); 5562 break; 5563 default: 5564 return false; 5565 } 5566 5567 // Read the first operand. 5568 uint32_t val1 = ReadCoreReg(Rn, &success); 5569 if (!success) 5570 return false; 5571 5572 uint32_t result = val1 & imm32; 5573 5574 EmulateInstruction::Context context; 5575 context.type = EmulateInstruction::eContextImmediate; 5576 context.SetNoArgs(); 5577 5578 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5579 return false; 5580 } 5581 return true; 5582} 5583 5584// This instruction performs a bitwise AND of a register value and an 5585// optionally-shifted register value, 5586// and writes the result to the destination register. It can optionally update 5587// the condition flags 5588// based on the result. 5589bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode, 5590 const ARMEncoding encoding) { 5591#if 0 5592 // ARM pseudo code... 5593 if ConditionPassed() then 5594 EncodingSpecificOperations(); 5595 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5596 result = R[n] AND shifted; 5597 if d == 15 then // Can only occur for ARM encoding 5598 ALUWritePC(result); // setflags is always FALSE here 5599 else 5600 R[d] = result; 5601 if setflags then 5602 APSR.N = result<31>; 5603 APSR.Z = IsZeroBit(result); 5604 APSR.C = carry; 5605 // APSR.V unchanged 5606#endif 5607 5608 bool success = false; 5609 5610 if (ConditionPassed(opcode)) { 5611 uint32_t Rd, Rn, Rm; 5612 ARM_ShifterType shift_t; 5613 uint32_t shift_n; // the shift applied to the value read from Rm 5614 bool setflags; 5615 uint32_t carry; 5616 switch (encoding) { 5617 case eEncodingT1: 5618 Rd = Rn = Bits32(opcode, 2, 0); 5619 Rm = Bits32(opcode, 5, 3); 5620 setflags = !InITBlock(); 5621 shift_t = SRType_LSL; 5622 shift_n = 0; 5623 break; 5624 case eEncodingT2: 5625 Rd = Bits32(opcode, 11, 8); 5626 Rn = Bits32(opcode, 19, 16); 5627 Rm = Bits32(opcode, 3, 0); 5628 setflags = BitIsSet(opcode, 20); 5629 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5630 // if Rd == '1111' && S == '1' then SEE TST (register); 5631 if (Rd == 15 && setflags) 5632 return EmulateTSTReg(opcode, eEncodingT2); 5633 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5634 return false; 5635 break; 5636 case eEncodingA1: 5637 Rd = Bits32(opcode, 15, 12); 5638 Rn = Bits32(opcode, 19, 16); 5639 Rm = Bits32(opcode, 3, 0); 5640 setflags = BitIsSet(opcode, 20); 5641 shift_n = DecodeImmShiftARM(opcode, shift_t); 5642 5643 if (Rd == 15 && setflags) 5644 return EmulateSUBSPcLrEtc(opcode, encoding); 5645 break; 5646 default: 5647 return false; 5648 } 5649 5650 // Read the first operand. 5651 uint32_t val1 = ReadCoreReg(Rn, &success); 5652 if (!success) 5653 return false; 5654 5655 // Read the second operand. 5656 uint32_t val2 = ReadCoreReg(Rm, &success); 5657 if (!success) 5658 return false; 5659 5660 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5661 if (!success) 5662 return false; 5663 uint32_t result = val1 & shifted; 5664 5665 EmulateInstruction::Context context; 5666 context.type = EmulateInstruction::eContextImmediate; 5667 context.SetNoArgs(); 5668 5669 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5670 return false; 5671 } 5672 return true; 5673} 5674 5675// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and 5676// the complement of an 5677// immediate value, and writes the result to the destination register. It can 5678// optionally update the 5679// condition flags based on the result. 5680bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode, 5681 const ARMEncoding encoding) { 5682#if 0 5683 // ARM pseudo code... 5684 if ConditionPassed() then 5685 EncodingSpecificOperations(); 5686 result = R[n] AND NOT(imm32); 5687 if d == 15 then // Can only occur for ARM encoding 5688 ALUWritePC(result); // setflags is always FALSE here 5689 else 5690 R[d] = result; 5691 if setflags then 5692 APSR.N = result<31>; 5693 APSR.Z = IsZeroBit(result); 5694 APSR.C = carry; 5695 // APSR.V unchanged 5696#endif 5697 5698 bool success = false; 5699 5700 if (ConditionPassed(opcode)) { 5701 uint32_t Rd, Rn; 5702 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to 5703 // the value obtained from Rn 5704 bool setflags; 5705 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5706 switch (encoding) { 5707 case eEncodingT1: 5708 Rd = Bits32(opcode, 11, 8); 5709 Rn = Bits32(opcode, 19, 16); 5710 setflags = BitIsSet(opcode, 20); 5711 imm32 = ThumbExpandImm_C( 5712 opcode, APSR_C, 5713 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5714 if (BadReg(Rd) || BadReg(Rn)) 5715 return false; 5716 break; 5717 case eEncodingA1: 5718 Rd = Bits32(opcode, 15, 12); 5719 Rn = Bits32(opcode, 19, 16); 5720 setflags = BitIsSet(opcode, 20); 5721 imm32 = 5722 ARMExpandImm_C(opcode, APSR_C, 5723 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5724 5725 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 5726 // instructions; 5727 if (Rd == 15 && setflags) 5728 return EmulateSUBSPcLrEtc(opcode, encoding); 5729 break; 5730 default: 5731 return false; 5732 } 5733 5734 // Read the first operand. 5735 uint32_t val1 = ReadCoreReg(Rn, &success); 5736 if (!success) 5737 return false; 5738 5739 uint32_t result = val1 & ~imm32; 5740 5741 EmulateInstruction::Context context; 5742 context.type = EmulateInstruction::eContextImmediate; 5743 context.SetNoArgs(); 5744 5745 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5746 return false; 5747 } 5748 return true; 5749} 5750 5751// Bitwise Bit Clear (register) performs a bitwise AND of a register value and 5752// the complement of an 5753// optionally-shifted register value, and writes the result to the destination 5754// register. 5755// It can optionally update the condition flags based on the result. 5756bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode, 5757 const ARMEncoding encoding) { 5758#if 0 5759 // ARM pseudo code... 5760 if ConditionPassed() then 5761 EncodingSpecificOperations(); 5762 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5763 result = R[n] AND NOT(shifted); 5764 if d == 15 then // Can only occur for ARM encoding 5765 ALUWritePC(result); // setflags is always FALSE here 5766 else 5767 R[d] = result; 5768 if setflags then 5769 APSR.N = result<31>; 5770 APSR.Z = IsZeroBit(result); 5771 APSR.C = carry; 5772 // APSR.V unchanged 5773#endif 5774 5775 bool success = false; 5776 5777 if (ConditionPassed(opcode)) { 5778 uint32_t Rd, Rn, Rm; 5779 ARM_ShifterType shift_t; 5780 uint32_t shift_n; // the shift applied to the value read from Rm 5781 bool setflags; 5782 uint32_t carry; 5783 switch (encoding) { 5784 case eEncodingT1: 5785 Rd = Rn = Bits32(opcode, 2, 0); 5786 Rm = Bits32(opcode, 5, 3); 5787 setflags = !InITBlock(); 5788 shift_t = SRType_LSL; 5789 shift_n = 0; 5790 break; 5791 case eEncodingT2: 5792 Rd = Bits32(opcode, 11, 8); 5793 Rn = Bits32(opcode, 19, 16); 5794 Rm = Bits32(opcode, 3, 0); 5795 setflags = BitIsSet(opcode, 20); 5796 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5797 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5798 return false; 5799 break; 5800 case eEncodingA1: 5801 Rd = Bits32(opcode, 15, 12); 5802 Rn = Bits32(opcode, 19, 16); 5803 Rm = Bits32(opcode, 3, 0); 5804 setflags = BitIsSet(opcode, 20); 5805 shift_n = DecodeImmShiftARM(opcode, shift_t); 5806 5807 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 5808 // instructions; 5809 if (Rd == 15 && setflags) 5810 return EmulateSUBSPcLrEtc(opcode, encoding); 5811 break; 5812 default: 5813 return false; 5814 } 5815 5816 // Read the first operand. 5817 uint32_t val1 = ReadCoreReg(Rn, &success); 5818 if (!success) 5819 return false; 5820 5821 // Read the second operand. 5822 uint32_t val2 = ReadCoreReg(Rm, &success); 5823 if (!success) 5824 return false; 5825 5826 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5827 if (!success) 5828 return false; 5829 uint32_t result = val1 & ~shifted; 5830 5831 EmulateInstruction::Context context; 5832 context.type = EmulateInstruction::eContextImmediate; 5833 context.SetNoArgs(); 5834 5835 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5836 return false; 5837 } 5838 return true; 5839} 5840 5841// LDR (immediate, ARM) calculates an address from a base register value and an 5842// immediate offset, loads a word 5843// from memory, and writes it to a register. It can use offset, post-indexed, 5844// or pre-indexed addressing. 5845bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode, 5846 const ARMEncoding encoding) { 5847#if 0 5848 if ConditionPassed() then 5849 EncodingSpecificOperations(); 5850 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5851 address = if index then offset_addr else R[n]; 5852 data = MemU[address,4]; 5853 if wback then R[n] = offset_addr; 5854 if t == 15 then 5855 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5856 elsif UnalignedSupport() || address<1:0> = '00' then 5857 R[t] = data; 5858 else // Can only apply before ARMv7 5859 R[t] = ROR(data, 8*UInt(address<1:0>)); 5860#endif 5861 5862 bool success = false; 5863 5864 if (ConditionPassed(opcode)) { 5865 const uint32_t addr_byte_size = GetAddressByteSize(); 5866 5867 uint32_t t; 5868 uint32_t n; 5869 uint32_t imm32; 5870 bool index; 5871 bool add; 5872 bool wback; 5873 5874 switch (encoding) { 5875 case eEncodingA1: 5876 // if Rn == '1111' then SEE LDR (literal); 5877 // if P == '0' && W == '1' then SEE LDRT; 5878 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == 5879 // '000000000100' then SEE POP; 5880 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5881 t = Bits32(opcode, 15, 12); 5882 n = Bits32(opcode, 19, 16); 5883 imm32 = Bits32(opcode, 11, 0); 5884 5885 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5886 // (W == '1'); 5887 index = BitIsSet(opcode, 24); 5888 add = BitIsSet(opcode, 23); 5889 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5890 5891 // if wback && n == t then UNPREDICTABLE; 5892 if (wback && (n == t)) 5893 return false; 5894 5895 break; 5896 5897 default: 5898 return false; 5899 } 5900 5901 addr_t address; 5902 addr_t offset_addr; 5903 addr_t base_address = ReadCoreReg(n, &success); 5904 if (!success) 5905 return false; 5906 5907 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5908 if (add) 5909 offset_addr = base_address + imm32; 5910 else 5911 offset_addr = base_address - imm32; 5912 5913 // address = if index then offset_addr else R[n]; 5914 if (index) 5915 address = offset_addr; 5916 else 5917 address = base_address; 5918 5919 // data = MemU[address,4]; 5920 5921 RegisterInfo base_reg; 5922 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5923 5924 EmulateInstruction::Context context; 5925 context.type = eContextRegisterLoad; 5926 context.SetRegisterPlusOffset(base_reg, address - base_address); 5927 5928 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 5929 if (!success) 5930 return false; 5931 5932 // if wback then R[n] = offset_addr; 5933 if (wback) { 5934 context.type = eContextAdjustBaseRegister; 5935 context.SetAddress(offset_addr); 5936 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5937 offset_addr)) 5938 return false; 5939 } 5940 5941 // if t == 15 then 5942 if (t == 15) { 5943 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5944 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 5945 // LoadWritePC (data); 5946 context.type = eContextRegisterLoad; 5947 context.SetRegisterPlusOffset(base_reg, address - base_address); 5948 LoadWritePC(context, data); 5949 } else 5950 return false; 5951 } 5952 // elsif UnalignedSupport() || address<1:0> = '00' then 5953 else if (UnalignedSupport() || 5954 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 5955 // R[t] = data; 5956 context.type = eContextRegisterLoad; 5957 context.SetRegisterPlusOffset(base_reg, address - base_address); 5958 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 5959 data)) 5960 return false; 5961 } 5962 // else // Can only apply before ARMv7 5963 else { 5964 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5965 data = ROR(data, Bits32(address, 1, 0), &success); 5966 if (!success) 5967 return false; 5968 context.type = eContextRegisterLoad; 5969 context.SetImmediate(data); 5970 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 5971 data)) 5972 return false; 5973 } 5974 } 5975 return true; 5976} 5977 5978// LDR (register) calculates an address from a base register value and an offset 5979// register value, loads a word 5980// from memory, and writes it to a register. The offset register value can 5981// optionally be shifted. 5982bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode, 5983 const ARMEncoding encoding) { 5984#if 0 5985 if ConditionPassed() then 5986 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5987 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5988 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5989 address = if index then offset_addr else R[n]; 5990 data = MemU[address,4]; 5991 if wback then R[n] = offset_addr; 5992 if t == 15 then 5993 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5994 elsif UnalignedSupport() || address<1:0> = '00' then 5995 R[t] = data; 5996 else // Can only apply before ARMv7 5997 if CurrentInstrSet() == InstrSet_ARM then 5998 R[t] = ROR(data, 8*UInt(address<1:0>)); 5999 else 6000 R[t] = bits(32) UNKNOWN; 6001#endif 6002 6003 bool success = false; 6004 6005 if (ConditionPassed(opcode)) { 6006 const uint32_t addr_byte_size = GetAddressByteSize(); 6007 6008 uint32_t t; 6009 uint32_t n; 6010 uint32_t m; 6011 bool index; 6012 bool add; 6013 bool wback; 6014 ARM_ShifterType shift_t; 6015 uint32_t shift_n; 6016 6017 switch (encoding) { 6018 case eEncodingT1: 6019 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6020 // in ThumbEE"; 6021 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6022 t = Bits32(opcode, 2, 0); 6023 n = Bits32(opcode, 5, 3); 6024 m = Bits32(opcode, 8, 6); 6025 6026 // index = TRUE; add = TRUE; wback = FALSE; 6027 index = true; 6028 add = true; 6029 wback = false; 6030 6031 // (shift_t, shift_n) = (SRType_LSL, 0); 6032 shift_t = SRType_LSL; 6033 shift_n = 0; 6034 6035 break; 6036 6037 case eEncodingT2: 6038 // if Rn == '1111' then SEE LDR (literal); 6039 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6040 t = Bits32(opcode, 15, 12); 6041 n = Bits32(opcode, 19, 16); 6042 m = Bits32(opcode, 3, 0); 6043 6044 // index = TRUE; add = TRUE; wback = FALSE; 6045 index = true; 6046 add = true; 6047 wback = false; 6048 6049 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6050 shift_t = SRType_LSL; 6051 shift_n = Bits32(opcode, 5, 4); 6052 6053 // if BadReg(m) then UNPREDICTABLE; 6054 if (BadReg(m)) 6055 return false; 6056 6057 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6058 if ((t == 15) && InITBlock() && !LastInITBlock()) 6059 return false; 6060 6061 break; 6062 6063 case eEncodingA1: { 6064 // if P == '0' && W == '1' then SEE LDRT; 6065 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6066 t = Bits32(opcode, 15, 12); 6067 n = Bits32(opcode, 19, 16); 6068 m = Bits32(opcode, 3, 0); 6069 6070 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6071 // (W == '1'); 6072 index = BitIsSet(opcode, 24); 6073 add = BitIsSet(opcode, 23); 6074 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6075 6076 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6077 uint32_t type = Bits32(opcode, 6, 5); 6078 uint32_t imm5 = Bits32(opcode, 11, 7); 6079 shift_n = DecodeImmShift(type, imm5, shift_t); 6080 6081 // if m == 15 then UNPREDICTABLE; 6082 if (m == 15) 6083 return false; 6084 6085 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6086 if (wback && ((n == 15) || (n == t))) 6087 return false; 6088 } break; 6089 6090 default: 6091 return false; 6092 } 6093 6094 uint32_t Rm = 6095 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6096 if (!success) 6097 return false; 6098 6099 uint32_t Rn = 6100 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6101 if (!success) 6102 return false; 6103 6104 addr_t offset_addr; 6105 addr_t address; 6106 6107 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an 6108 // application level alias for the CPSR". 6109 addr_t offset = 6110 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success); 6111 if (!success) 6112 return false; 6113 6114 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6115 if (add) 6116 offset_addr = Rn + offset; 6117 else 6118 offset_addr = Rn - offset; 6119 6120 // address = if index then offset_addr else R[n]; 6121 if (index) 6122 address = offset_addr; 6123 else 6124 address = Rn; 6125 6126 // data = MemU[address,4]; 6127 RegisterInfo base_reg; 6128 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6129 6130 EmulateInstruction::Context context; 6131 context.type = eContextRegisterLoad; 6132 context.SetRegisterPlusOffset(base_reg, address - Rn); 6133 6134 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6135 if (!success) 6136 return false; 6137 6138 // if wback then R[n] = offset_addr; 6139 if (wback) { 6140 context.type = eContextAdjustBaseRegister; 6141 context.SetAddress(offset_addr); 6142 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6143 offset_addr)) 6144 return false; 6145 } 6146 6147 // if t == 15 then 6148 if (t == 15) { 6149 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6150 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6151 context.type = eContextRegisterLoad; 6152 context.SetRegisterPlusOffset(base_reg, address - Rn); 6153 LoadWritePC(context, data); 6154 } else 6155 return false; 6156 } 6157 // elsif UnalignedSupport() || address<1:0> = '00' then 6158 else if (UnalignedSupport() || 6159 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6160 // R[t] = data; 6161 context.type = eContextRegisterLoad; 6162 context.SetRegisterPlusOffset(base_reg, address - Rn); 6163 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6164 data)) 6165 return false; 6166 } else // Can only apply before ARMv7 6167 { 6168 // if CurrentInstrSet() == InstrSet_ARM then 6169 if (CurrentInstrSet() == eModeARM) { 6170 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6171 data = ROR(data, Bits32(address, 1, 0), &success); 6172 if (!success) 6173 return false; 6174 context.type = eContextRegisterLoad; 6175 context.SetImmediate(data); 6176 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6177 data)) 6178 return false; 6179 } else { 6180 // R[t] = bits(32) UNKNOWN; 6181 WriteBits32Unknown(t); 6182 } 6183 } 6184 } 6185 return true; 6186} 6187 6188// LDRB (immediate, Thumb) 6189bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode, 6190 const ARMEncoding encoding) { 6191#if 0 6192 if ConditionPassed() then 6193 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6194 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6195 address = if index then offset_addr else R[n]; 6196 R[t] = ZeroExtend(MemU[address,1], 32); 6197 if wback then R[n] = offset_addr; 6198#endif 6199 6200 bool success = false; 6201 6202 if (ConditionPassed(opcode)) { 6203 uint32_t t; 6204 uint32_t n; 6205 uint32_t imm32; 6206 bool index; 6207 bool add; 6208 bool wback; 6209 6210 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6211 switch (encoding) { 6212 case eEncodingT1: 6213 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6214 t = Bits32(opcode, 2, 0); 6215 n = Bits32(opcode, 5, 3); 6216 imm32 = Bits32(opcode, 10, 6); 6217 6218 // index = TRUE; add = TRUE; wback = FALSE; 6219 index = true; 6220 add = true; 6221 wback = false; 6222 6223 break; 6224 6225 case eEncodingT2: 6226 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6227 t = Bits32(opcode, 15, 12); 6228 n = Bits32(opcode, 19, 16); 6229 imm32 = Bits32(opcode, 11, 0); 6230 6231 // index = TRUE; add = TRUE; wback = FALSE; 6232 index = true; 6233 add = true; 6234 wback = false; 6235 6236 // if Rt == '1111' then SEE PLD; 6237 if (t == 15) 6238 return false; // PLD is not implemented yet 6239 6240 // if Rn == '1111' then SEE LDRB (literal); 6241 if (n == 15) 6242 return EmulateLDRBLiteral(opcode, eEncodingT1); 6243 6244 // if t == 13 then UNPREDICTABLE; 6245 if (t == 13) 6246 return false; 6247 6248 break; 6249 6250 case eEncodingT3: 6251 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6252 // if P == '0' && W == '0' then UNDEFINED; 6253 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 6254 return false; 6255 6256 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6257 t = Bits32(opcode, 15, 12); 6258 n = Bits32(opcode, 19, 16); 6259 imm32 = Bits32(opcode, 7, 0); 6260 6261 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6262 index = BitIsSet(opcode, 10); 6263 add = BitIsSet(opcode, 9); 6264 wback = BitIsSet(opcode, 8); 6265 6266 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6267 if (t == 15) 6268 return false; // PLD is not implemented yet 6269 6270 // if Rn == '1111' then SEE LDRB (literal); 6271 if (n == 15) 6272 return EmulateLDRBLiteral(opcode, eEncodingT1); 6273 6274 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6275 if (BadReg(t) || (wback && (n == t))) 6276 return false; 6277 6278 break; 6279 6280 default: 6281 return false; 6282 } 6283 6284 uint32_t Rn = 6285 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6286 if (!success) 6287 return false; 6288 6289 addr_t address; 6290 addr_t offset_addr; 6291 6292 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6293 if (add) 6294 offset_addr = Rn + imm32; 6295 else 6296 offset_addr = Rn - imm32; 6297 6298 // address = if index then offset_addr else R[n]; 6299 if (index) 6300 address = offset_addr; 6301 else 6302 address = Rn; 6303 6304 // R[t] = ZeroExtend(MemU[address,1], 32); 6305 RegisterInfo base_reg; 6306 RegisterInfo data_reg; 6307 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6308 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6309 6310 EmulateInstruction::Context context; 6311 context.type = eContextRegisterLoad; 6312 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 6313 6314 uint64_t data = MemURead(context, address, 1, 0, &success); 6315 if (!success) 6316 return false; 6317 6318 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6319 return false; 6320 6321 // if wback then R[n] = offset_addr; 6322 if (wback) { 6323 context.type = eContextAdjustBaseRegister; 6324 context.SetAddress(offset_addr); 6325 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6326 offset_addr)) 6327 return false; 6328 } 6329 } 6330 return true; 6331} 6332 6333// LDRB (literal) calculates an address from the PC value and an immediate 6334// offset, loads a byte from memory, 6335// zero-extends it to form a 32-bit word and writes it to a register. 6336bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode, 6337 const ARMEncoding encoding) { 6338#if 0 6339 if ConditionPassed() then 6340 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6341 base = Align(PC,4); 6342 address = if add then (base + imm32) else (base - imm32); 6343 R[t] = ZeroExtend(MemU[address,1], 32); 6344#endif 6345 6346 bool success = false; 6347 6348 if (ConditionPassed(opcode)) { 6349 uint32_t t; 6350 uint32_t imm32; 6351 bool add; 6352 switch (encoding) { 6353 case eEncodingT1: 6354 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6355 t = Bits32(opcode, 15, 12); 6356 imm32 = Bits32(opcode, 11, 0); 6357 add = BitIsSet(opcode, 23); 6358 6359 // if Rt == '1111' then SEE PLD; 6360 if (t == 15) 6361 return false; // PLD is not implemented yet 6362 6363 // if t == 13 then UNPREDICTABLE; 6364 if (t == 13) 6365 return false; 6366 6367 break; 6368 6369 case eEncodingA1: 6370 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6371 t = Bits32(opcode, 15, 12); 6372 imm32 = Bits32(opcode, 11, 0); 6373 add = BitIsSet(opcode, 23); 6374 6375 // if t == 15 then UNPREDICTABLE; 6376 if (t == 15) 6377 return false; 6378 break; 6379 6380 default: 6381 return false; 6382 } 6383 6384 // base = Align(PC,4); 6385 uint32_t pc_val = ReadCoreReg(PC_REG, &success); 6386 if (!success) 6387 return false; 6388 6389 uint32_t base = AlignPC(pc_val); 6390 6391 addr_t address; 6392 // address = if add then (base + imm32) else (base - imm32); 6393 if (add) 6394 address = base + imm32; 6395 else 6396 address = base - imm32; 6397 6398 // R[t] = ZeroExtend(MemU[address,1], 32); 6399 EmulateInstruction::Context context; 6400 context.type = eContextRelativeBranchImmediate; 6401 context.SetImmediate(address - base); 6402 6403 uint64_t data = MemURead(context, address, 1, 0, &success); 6404 if (!success) 6405 return false; 6406 6407 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6408 return false; 6409 } 6410 return true; 6411} 6412 6413// LDRB (register) calculates an address from a base register value and an 6414// offset rigister value, loads a byte from 6415// memory, zero-extends it to form a 32-bit word, and writes it to a register. 6416// The offset register value can 6417// optionally be shifted. 6418bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode, 6419 const ARMEncoding encoding) { 6420#if 0 6421 if ConditionPassed() then 6422 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6423 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6424 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6425 address = if index then offset_addr else R[n]; 6426 R[t] = ZeroExtend(MemU[address,1],32); 6427 if wback then R[n] = offset_addr; 6428#endif 6429 6430 bool success = false; 6431 6432 if (ConditionPassed(opcode)) { 6433 uint32_t t; 6434 uint32_t n; 6435 uint32_t m; 6436 bool index; 6437 bool add; 6438 bool wback; 6439 ARM_ShifterType shift_t; 6440 uint32_t shift_n; 6441 6442 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6443 switch (encoding) { 6444 case eEncodingT1: 6445 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6446 t = Bits32(opcode, 2, 0); 6447 n = Bits32(opcode, 5, 3); 6448 m = Bits32(opcode, 8, 6); 6449 6450 // index = TRUE; add = TRUE; wback = FALSE; 6451 index = true; 6452 add = true; 6453 wback = false; 6454 6455 // (shift_t, shift_n) = (SRType_LSL, 0); 6456 shift_t = SRType_LSL; 6457 shift_n = 0; 6458 break; 6459 6460 case eEncodingT2: 6461 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6462 t = Bits32(opcode, 15, 12); 6463 n = Bits32(opcode, 19, 16); 6464 m = Bits32(opcode, 3, 0); 6465 6466 // index = TRUE; add = TRUE; wback = FALSE; 6467 index = true; 6468 add = true; 6469 wback = false; 6470 6471 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6472 shift_t = SRType_LSL; 6473 shift_n = Bits32(opcode, 5, 4); 6474 6475 // if Rt == '1111' then SEE PLD; 6476 if (t == 15) 6477 return false; // PLD is not implemented yet 6478 6479 // if Rn == '1111' then SEE LDRB (literal); 6480 if (n == 15) 6481 return EmulateLDRBLiteral(opcode, eEncodingT1); 6482 6483 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6484 if ((t == 13) || BadReg(m)) 6485 return false; 6486 break; 6487 6488 case eEncodingA1: { 6489 // if P == '0' && W == '1' then SEE LDRBT; 6490 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6491 t = Bits32(opcode, 15, 12); 6492 n = Bits32(opcode, 19, 16); 6493 m = Bits32(opcode, 3, 0); 6494 6495 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6496 // (W == '1'); 6497 index = BitIsSet(opcode, 24); 6498 add = BitIsSet(opcode, 23); 6499 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6500 6501 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6502 uint32_t type = Bits32(opcode, 6, 5); 6503 uint32_t imm5 = Bits32(opcode, 11, 7); 6504 shift_n = DecodeImmShift(type, imm5, shift_t); 6505 6506 // if t == 15 || m == 15 then UNPREDICTABLE; 6507 if ((t == 15) || (m == 15)) 6508 return false; 6509 6510 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6511 if (wback && ((n == 15) || (n == t))) 6512 return false; 6513 } break; 6514 6515 default: 6516 return false; 6517 } 6518 6519 addr_t offset_addr; 6520 addr_t address; 6521 6522 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6523 uint32_t Rm = 6524 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6525 if (!success) 6526 return false; 6527 6528 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 6529 if (!success) 6530 return false; 6531 6532 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6533 uint32_t Rn = 6534 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6535 if (!success) 6536 return false; 6537 6538 if (add) 6539 offset_addr = Rn + offset; 6540 else 6541 offset_addr = Rn - offset; 6542 6543 // address = if index then offset_addr else R[n]; 6544 if (index) 6545 address = offset_addr; 6546 else 6547 address = Rn; 6548 6549 // R[t] = ZeroExtend(MemU[address,1],32); 6550 RegisterInfo base_reg; 6551 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6552 6553 EmulateInstruction::Context context; 6554 context.type = eContextRegisterLoad; 6555 context.SetRegisterPlusOffset(base_reg, address - Rn); 6556 6557 uint64_t data = MemURead(context, address, 1, 0, &success); 6558 if (!success) 6559 return false; 6560 6561 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6562 return false; 6563 6564 // if wback then R[n] = offset_addr; 6565 if (wback) { 6566 context.type = eContextAdjustBaseRegister; 6567 context.SetAddress(offset_addr); 6568 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6569 offset_addr)) 6570 return false; 6571 } 6572 } 6573 return true; 6574} 6575 6576// LDRH (immediate, Thumb) calculates an address from a base register value and 6577// an immediate offset, loads a 6578// halfword from memory, zero-extends it to form a 32-bit word, and writes it to 6579// a register. It can use offset, 6580// post-indexed, or pre-indexed addressing. 6581bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, 6582 const ARMEncoding encoding) { 6583#if 0 6584 if ConditionPassed() then 6585 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6586 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6587 address = if index then offset_addr else R[n]; 6588 data = MemU[address,2]; 6589 if wback then R[n] = offset_addr; 6590 if UnalignedSupport() || address<0> = '0' then 6591 R[t] = ZeroExtend(data, 32); 6592 else // Can only apply before ARMv7 6593 R[t] = bits(32) UNKNOWN; 6594#endif 6595 6596 bool success = false; 6597 6598 if (ConditionPassed(opcode)) { 6599 uint32_t t; 6600 uint32_t n; 6601 uint32_t imm32; 6602 bool index; 6603 bool add; 6604 bool wback; 6605 6606 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6607 switch (encoding) { 6608 case eEncodingT1: 6609 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6610 t = Bits32(opcode, 2, 0); 6611 n = Bits32(opcode, 5, 3); 6612 imm32 = Bits32(opcode, 10, 6) << 1; 6613 6614 // index = TRUE; add = TRUE; wback = FALSE; 6615 index = true; 6616 add = true; 6617 wback = false; 6618 6619 break; 6620 6621 case eEncodingT2: 6622 // if Rt == '1111' then SEE "Unallocated memory hints"; 6623 // if Rn == '1111' then SEE LDRH (literal); 6624 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6625 t = Bits32(opcode, 15, 12); 6626 n = Bits32(opcode, 19, 16); 6627 imm32 = Bits32(opcode, 11, 0); 6628 6629 // index = TRUE; add = TRUE; wback = FALSE; 6630 index = true; 6631 add = true; 6632 wback = false; 6633 6634 // if t == 13 then UNPREDICTABLE; 6635 if (t == 13) 6636 return false; 6637 break; 6638 6639 case eEncodingT3: 6640 // if Rn == '1111' then SEE LDRH (literal); 6641 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 6642 // "Unallocated memory hints"; 6643 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6644 // if P == '0' && W == '0' then UNDEFINED; 6645 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 6646 return false; 6647 6648 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6649 t = Bits32(opcode, 15, 12); 6650 n = Bits32(opcode, 19, 16); 6651 imm32 = Bits32(opcode, 7, 0); 6652 6653 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6654 index = BitIsSet(opcode, 10); 6655 add = BitIsSet(opcode, 9); 6656 wback = BitIsSet(opcode, 8); 6657 6658 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6659 if (BadReg(t) || (wback && (n == t))) 6660 return false; 6661 break; 6662 6663 default: 6664 return false; 6665 } 6666 6667 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6668 uint32_t Rn = 6669 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6670 if (!success) 6671 return false; 6672 6673 addr_t offset_addr; 6674 addr_t address; 6675 6676 if (add) 6677 offset_addr = Rn + imm32; 6678 else 6679 offset_addr = Rn - imm32; 6680 6681 // address = if index then offset_addr else R[n]; 6682 if (index) 6683 address = offset_addr; 6684 else 6685 address = Rn; 6686 6687 // data = MemU[address,2]; 6688 RegisterInfo base_reg; 6689 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6690 6691 EmulateInstruction::Context context; 6692 context.type = eContextRegisterLoad; 6693 context.SetRegisterPlusOffset(base_reg, address - Rn); 6694 6695 uint64_t data = MemURead(context, address, 2, 0, &success); 6696 if (!success) 6697 return false; 6698 6699 // if wback then R[n] = offset_addr; 6700 if (wback) { 6701 context.type = eContextAdjustBaseRegister; 6702 context.SetAddress(offset_addr); 6703 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6704 offset_addr)) 6705 return false; 6706 } 6707 6708 // if UnalignedSupport() || address<0> = '0' then 6709 if (UnalignedSupport() || BitIsClear(address, 0)) { 6710 // R[t] = ZeroExtend(data, 32); 6711 context.type = eContextRegisterLoad; 6712 context.SetRegisterPlusOffset(base_reg, address - Rn); 6713 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6714 data)) 6715 return false; 6716 } else // Can only apply before ARMv7 6717 { 6718 // R[t] = bits(32) UNKNOWN; 6719 WriteBits32Unknown(t); 6720 } 6721 } 6722 return true; 6723} 6724 6725// LDRH (literal) caculates an address from the PC value and an immediate 6726// offset, loads a halfword from memory, 6727// zero-extends it to form a 32-bit word, and writes it to a register. 6728bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, 6729 const ARMEncoding encoding) { 6730#if 0 6731 if ConditionPassed() then 6732 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6733 base = Align(PC,4); 6734 address = if add then (base + imm32) else (base - imm32); 6735 data = MemU[address,2]; 6736 if UnalignedSupport() || address<0> = '0' then 6737 R[t] = ZeroExtend(data, 32); 6738 else // Can only apply before ARMv7 6739 R[t] = bits(32) UNKNOWN; 6740#endif 6741 6742 bool success = false; 6743 6744 if (ConditionPassed(opcode)) { 6745 uint32_t t; 6746 uint32_t imm32; 6747 bool add; 6748 6749 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6750 switch (encoding) { 6751 case eEncodingT1: 6752 // if Rt == '1111' then SEE "Unallocated memory hints"; 6753 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6754 t = Bits32(opcode, 15, 12); 6755 imm32 = Bits32(opcode, 11, 0); 6756 add = BitIsSet(opcode, 23); 6757 6758 // if t == 13 then UNPREDICTABLE; 6759 if (t == 13) 6760 return false; 6761 6762 break; 6763 6764 case eEncodingA1: { 6765 uint32_t imm4H = Bits32(opcode, 11, 8); 6766 uint32_t imm4L = Bits32(opcode, 3, 0); 6767 6768 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6769 t = Bits32(opcode, 15, 12); 6770 imm32 = (imm4H << 4) | imm4L; 6771 add = BitIsSet(opcode, 23); 6772 6773 // if t == 15 then UNPREDICTABLE; 6774 if (t == 15) 6775 return false; 6776 break; 6777 } 6778 6779 default: 6780 return false; 6781 } 6782 6783 // base = Align(PC,4); 6784 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 6785 if (!success) 6786 return false; 6787 6788 addr_t base = AlignPC(pc_value); 6789 addr_t address; 6790 6791 // address = if add then (base + imm32) else (base - imm32); 6792 if (add) 6793 address = base + imm32; 6794 else 6795 address = base - imm32; 6796 6797 // data = MemU[address,2]; 6798 RegisterInfo base_reg; 6799 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6800 6801 EmulateInstruction::Context context; 6802 context.type = eContextRegisterLoad; 6803 context.SetRegisterPlusOffset(base_reg, address - base); 6804 6805 uint64_t data = MemURead(context, address, 2, 0, &success); 6806 if (!success) 6807 return false; 6808 6809 // if UnalignedSupport() || address<0> = '0' then 6810 if (UnalignedSupport() || BitIsClear(address, 0)) { 6811 // R[t] = ZeroExtend(data, 32); 6812 context.type = eContextRegisterLoad; 6813 context.SetRegisterPlusOffset(base_reg, address - base); 6814 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6815 data)) 6816 return false; 6817 6818 } else // Can only apply before ARMv7 6819 { 6820 // R[t] = bits(32) UNKNOWN; 6821 WriteBits32Unknown(t); 6822 } 6823 } 6824 return true; 6825} 6826 6827// LDRH (literal) calculates an address from a base register value and an offset 6828// register value, loads a halfword 6829// from memory, zero-extends it to form a 32-bit word, and writes it to a 6830// register. The offset register value can 6831// be shifted left by 0, 1, 2, or 3 bits. 6832bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode, 6833 const ARMEncoding encoding) { 6834#if 0 6835 if ConditionPassed() then 6836 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6837 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6838 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6839 address = if index then offset_addr else R[n]; 6840 data = MemU[address,2]; 6841 if wback then R[n] = offset_addr; 6842 if UnalignedSupport() || address<0> = '0' then 6843 R[t] = ZeroExtend(data, 32); 6844 else // Can only apply before ARMv7 6845 R[t] = bits(32) UNKNOWN; 6846#endif 6847 6848 bool success = false; 6849 6850 if (ConditionPassed(opcode)) { 6851 uint32_t t; 6852 uint32_t n; 6853 uint32_t m; 6854 bool index; 6855 bool add; 6856 bool wback; 6857 ARM_ShifterType shift_t; 6858 uint32_t shift_n; 6859 6860 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6861 switch (encoding) { 6862 case eEncodingT1: 6863 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6864 // in ThumbEE"; 6865 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6866 t = Bits32(opcode, 2, 0); 6867 n = Bits32(opcode, 5, 3); 6868 m = Bits32(opcode, 8, 6); 6869 6870 // index = TRUE; add = TRUE; wback = FALSE; 6871 index = true; 6872 add = true; 6873 wback = false; 6874 6875 // (shift_t, shift_n) = (SRType_LSL, 0); 6876 shift_t = SRType_LSL; 6877 shift_n = 0; 6878 6879 break; 6880 6881 case eEncodingT2: 6882 // if Rn == '1111' then SEE LDRH (literal); 6883 // if Rt == '1111' then SEE "Unallocated memory hints"; 6884 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6885 t = Bits32(opcode, 15, 12); 6886 n = Bits32(opcode, 19, 16); 6887 m = Bits32(opcode, 3, 0); 6888 6889 // index = TRUE; add = TRUE; wback = FALSE; 6890 index = true; 6891 add = true; 6892 wback = false; 6893 6894 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6895 shift_t = SRType_LSL; 6896 shift_n = Bits32(opcode, 5, 4); 6897 6898 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6899 if ((t == 13) || BadReg(m)) 6900 return false; 6901 break; 6902 6903 case eEncodingA1: 6904 // if P == '0' && W == '1' then SEE LDRHT; 6905 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6906 t = Bits32(opcode, 15, 12); 6907 n = Bits32(opcode, 19, 16); 6908 m = Bits32(opcode, 3, 0); 6909 6910 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6911 // (W == '1'); 6912 index = BitIsSet(opcode, 24); 6913 add = BitIsSet(opcode, 23); 6914 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6915 6916 // (shift_t, shift_n) = (SRType_LSL, 0); 6917 shift_t = SRType_LSL; 6918 shift_n = 0; 6919 6920 // if t == 15 || m == 15 then UNPREDICTABLE; 6921 if ((t == 15) || (m == 15)) 6922 return false; 6923 6924 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6925 if (wback && ((n == 15) || (n == t))) 6926 return false; 6927 6928 break; 6929 6930 default: 6931 return false; 6932 } 6933 6934 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6935 6936 uint64_t Rm = 6937 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6938 if (!success) 6939 return false; 6940 6941 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 6942 if (!success) 6943 return false; 6944 6945 addr_t offset_addr; 6946 addr_t address; 6947 6948 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6949 uint64_t Rn = 6950 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6951 if (!success) 6952 return false; 6953 6954 if (add) 6955 offset_addr = Rn + offset; 6956 else 6957 offset_addr = Rn - offset; 6958 6959 // address = if index then offset_addr else R[n]; 6960 if (index) 6961 address = offset_addr; 6962 else 6963 address = Rn; 6964 6965 // data = MemU[address,2]; 6966 RegisterInfo base_reg; 6967 RegisterInfo offset_reg; 6968 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6969 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 6970 6971 EmulateInstruction::Context context; 6972 context.type = eContextRegisterLoad; 6973 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 6974 uint64_t data = MemURead(context, address, 2, 0, &success); 6975 if (!success) 6976 return false; 6977 6978 // if wback then R[n] = offset_addr; 6979 if (wback) { 6980 context.type = eContextAdjustBaseRegister; 6981 context.SetAddress(offset_addr); 6982 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6983 offset_addr)) 6984 return false; 6985 } 6986 6987 // if UnalignedSupport() || address<0> = '0' then 6988 if (UnalignedSupport() || BitIsClear(address, 0)) { 6989 // R[t] = ZeroExtend(data, 32); 6990 context.type = eContextRegisterLoad; 6991 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 6992 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6993 data)) 6994 return false; 6995 } else // Can only apply before ARMv7 6996 { 6997 // R[t] = bits(32) UNKNOWN; 6998 WriteBits32Unknown(t); 6999 } 7000 } 7001 return true; 7002} 7003 7004// LDRSB (immediate) calculates an address from a base register value and an 7005// immediate offset, loads a byte from 7006// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7007// It can use offset, post-indexed, 7008// or pre-indexed addressing. 7009bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode, 7010 const ARMEncoding encoding) { 7011#if 0 7012 if ConditionPassed() then 7013 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7014 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7015 address = if index then offset_addr else R[n]; 7016 R[t] = SignExtend(MemU[address,1], 32); 7017 if wback then R[n] = offset_addr; 7018#endif 7019 7020 bool success = false; 7021 7022 if (ConditionPassed(opcode)) { 7023 uint32_t t; 7024 uint32_t n; 7025 uint32_t imm32; 7026 bool index; 7027 bool add; 7028 bool wback; 7029 7030 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7031 switch (encoding) { 7032 case eEncodingT1: 7033 // if Rt == '1111' then SEE PLI; 7034 // if Rn == '1111' then SEE LDRSB (literal); 7035 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7036 t = Bits32(opcode, 15, 12); 7037 n = Bits32(opcode, 19, 16); 7038 imm32 = Bits32(opcode, 11, 0); 7039 7040 // index = TRUE; add = TRUE; wback = FALSE; 7041 index = true; 7042 add = true; 7043 wback = false; 7044 7045 // if t == 13 then UNPREDICTABLE; 7046 if (t == 13) 7047 return false; 7048 7049 break; 7050 7051 case eEncodingT2: 7052 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7053 // if Rn == '1111' then SEE LDRSB (literal); 7054 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7055 // if P == '0' && W == '0' then UNDEFINED; 7056 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7057 return false; 7058 7059 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7060 t = Bits32(opcode, 15, 12); 7061 n = Bits32(opcode, 19, 16); 7062 imm32 = Bits32(opcode, 7, 0); 7063 7064 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7065 index = BitIsSet(opcode, 10); 7066 add = BitIsSet(opcode, 9); 7067 wback = BitIsSet(opcode, 8); 7068 7069 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7070 if (((t == 13) || 7071 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) || 7072 BitIsSet(opcode, 8)))) || 7073 (wback && (n == t))) 7074 return false; 7075 7076 break; 7077 7078 case eEncodingA1: { 7079 // if Rn == '1111' then SEE LDRSB (literal); 7080 // if P == '0' && W == '1' then SEE LDRSBT; 7081 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7082 t = Bits32(opcode, 15, 12); 7083 n = Bits32(opcode, 19, 16); 7084 7085 uint32_t imm4H = Bits32(opcode, 11, 8); 7086 uint32_t imm4L = Bits32(opcode, 3, 0); 7087 imm32 = (imm4H << 4) | imm4L; 7088 7089 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7090 // (W == '1'); 7091 index = BitIsSet(opcode, 24); 7092 add = BitIsSet(opcode, 23); 7093 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7094 7095 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7096 if ((t == 15) || (wback && (n == t))) 7097 return false; 7098 7099 break; 7100 } 7101 7102 default: 7103 return false; 7104 } 7105 7106 uint64_t Rn = ReadCoreReg(n, &success); 7107 if (!success) 7108 return false; 7109 7110 addr_t offset_addr; 7111 addr_t address; 7112 7113 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7114 if (add) 7115 offset_addr = Rn + imm32; 7116 else 7117 offset_addr = Rn - imm32; 7118 7119 // address = if index then offset_addr else R[n]; 7120 if (index) 7121 address = offset_addr; 7122 else 7123 address = Rn; 7124 7125 // R[t] = SignExtend(MemU[address,1], 32); 7126 RegisterInfo base_reg; 7127 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7128 7129 EmulateInstruction::Context context; 7130 context.type = eContextRegisterLoad; 7131 context.SetRegisterPlusOffset(base_reg, address - Rn); 7132 7133 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7134 if (!success) 7135 return false; 7136 7137 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7138 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7139 (uint64_t)signed_data)) 7140 return false; 7141 7142 // if wback then R[n] = offset_addr; 7143 if (wback) { 7144 context.type = eContextAdjustBaseRegister; 7145 context.SetAddress(offset_addr); 7146 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7147 offset_addr)) 7148 return false; 7149 } 7150 } 7151 7152 return true; 7153} 7154 7155// LDRSB (literal) calculates an address from the PC value and an immediate 7156// offset, loads a byte from memory, 7157// sign-extends it to form a 32-bit word, and writes tit to a register. 7158bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode, 7159 const ARMEncoding encoding) { 7160#if 0 7161 if ConditionPassed() then 7162 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7163 base = Align(PC,4); 7164 address = if add then (base + imm32) else (base - imm32); 7165 R[t] = SignExtend(MemU[address,1], 32); 7166#endif 7167 7168 bool success = false; 7169 7170 if (ConditionPassed(opcode)) { 7171 uint32_t t; 7172 uint32_t imm32; 7173 bool add; 7174 7175 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7176 switch (encoding) { 7177 case eEncodingT1: 7178 // if Rt == '1111' then SEE PLI; 7179 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7180 t = Bits32(opcode, 15, 12); 7181 imm32 = Bits32(opcode, 11, 0); 7182 add = BitIsSet(opcode, 23); 7183 7184 // if t == 13 then UNPREDICTABLE; 7185 if (t == 13) 7186 return false; 7187 7188 break; 7189 7190 case eEncodingA1: { 7191 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7192 t = Bits32(opcode, 15, 12); 7193 uint32_t imm4H = Bits32(opcode, 11, 8); 7194 uint32_t imm4L = Bits32(opcode, 3, 0); 7195 imm32 = (imm4H << 4) | imm4L; 7196 add = BitIsSet(opcode, 23); 7197 7198 // if t == 15 then UNPREDICTABLE; 7199 if (t == 15) 7200 return false; 7201 7202 break; 7203 } 7204 7205 default: 7206 return false; 7207 } 7208 7209 // base = Align(PC,4); 7210 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7211 if (!success) 7212 return false; 7213 uint64_t base = AlignPC(pc_value); 7214 7215 // address = if add then (base + imm32) else (base - imm32); 7216 addr_t address; 7217 if (add) 7218 address = base + imm32; 7219 else 7220 address = base - imm32; 7221 7222 // R[t] = SignExtend(MemU[address,1], 32); 7223 RegisterInfo base_reg; 7224 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7225 7226 EmulateInstruction::Context context; 7227 context.type = eContextRegisterLoad; 7228 context.SetRegisterPlusOffset(base_reg, address - base); 7229 7230 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7231 if (!success) 7232 return false; 7233 7234 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7235 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7236 (uint64_t)signed_data)) 7237 return false; 7238 } 7239 return true; 7240} 7241 7242// LDRSB (register) calculates an address from a base register value and an 7243// offset register value, loadsa byte from 7244// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7245// The offset register value can be 7246// shifted left by 0, 1, 2, or 3 bits. 7247bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode, 7248 const ARMEncoding encoding) { 7249#if 0 7250 if ConditionPassed() then 7251 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7252 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7253 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7254 address = if index then offset_addr else R[n]; 7255 R[t] = SignExtend(MemU[address,1], 32); 7256 if wback then R[n] = offset_addr; 7257#endif 7258 7259 bool success = false; 7260 7261 if (ConditionPassed(opcode)) { 7262 uint32_t t; 7263 uint32_t n; 7264 uint32_t m; 7265 bool index; 7266 bool add; 7267 bool wback; 7268 ARM_ShifterType shift_t; 7269 uint32_t shift_n; 7270 7271 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7272 switch (encoding) { 7273 case eEncodingT1: 7274 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7275 t = Bits32(opcode, 2, 0); 7276 n = Bits32(opcode, 5, 3); 7277 m = Bits32(opcode, 8, 6); 7278 7279 // index = TRUE; add = TRUE; wback = FALSE; 7280 index = true; 7281 add = true; 7282 wback = false; 7283 7284 // (shift_t, shift_n) = (SRType_LSL, 0); 7285 shift_t = SRType_LSL; 7286 shift_n = 0; 7287 7288 break; 7289 7290 case eEncodingT2: 7291 // if Rt == '1111' then SEE PLI; 7292 // if Rn == '1111' then SEE LDRSB (literal); 7293 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7294 t = Bits32(opcode, 15, 12); 7295 n = Bits32(opcode, 19, 16); 7296 m = Bits32(opcode, 3, 0); 7297 7298 // index = TRUE; add = TRUE; wback = FALSE; 7299 index = true; 7300 add = true; 7301 wback = false; 7302 7303 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7304 shift_t = SRType_LSL; 7305 shift_n = Bits32(opcode, 5, 4); 7306 7307 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7308 if ((t == 13) || BadReg(m)) 7309 return false; 7310 break; 7311 7312 case eEncodingA1: 7313 // if P == '0' && W == '1' then SEE LDRSBT; 7314 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7315 t = Bits32(opcode, 15, 12); 7316 n = Bits32(opcode, 19, 16); 7317 m = Bits32(opcode, 3, 0); 7318 7319 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7320 // (W == '1'); 7321 index = BitIsSet(opcode, 24); 7322 add = BitIsSet(opcode, 23); 7323 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7324 7325 // (shift_t, shift_n) = (SRType_LSL, 0); 7326 shift_t = SRType_LSL; 7327 shift_n = 0; 7328 7329 // if t == 15 || m == 15 then UNPREDICTABLE; 7330 if ((t == 15) || (m == 15)) 7331 return false; 7332 7333 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7334 if (wback && ((n == 15) || (n == t))) 7335 return false; 7336 break; 7337 7338 default: 7339 return false; 7340 } 7341 7342 uint64_t Rm = 7343 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7344 if (!success) 7345 return false; 7346 7347 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7348 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7349 if (!success) 7350 return false; 7351 7352 addr_t offset_addr; 7353 addr_t address; 7354 7355 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7356 uint64_t Rn = 7357 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7358 if (!success) 7359 return false; 7360 7361 if (add) 7362 offset_addr = Rn + offset; 7363 else 7364 offset_addr = Rn - offset; 7365 7366 // address = if index then offset_addr else R[n]; 7367 if (index) 7368 address = offset_addr; 7369 else 7370 address = Rn; 7371 7372 // R[t] = SignExtend(MemU[address,1], 32); 7373 RegisterInfo base_reg; 7374 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7375 RegisterInfo offset_reg; 7376 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7377 7378 EmulateInstruction::Context context; 7379 context.type = eContextRegisterLoad; 7380 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7381 7382 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7383 if (!success) 7384 return false; 7385 7386 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7387 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7388 (uint64_t)signed_data)) 7389 return false; 7390 7391 // if wback then R[n] = offset_addr; 7392 if (wback) { 7393 context.type = eContextAdjustBaseRegister; 7394 context.SetAddress(offset_addr); 7395 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7396 offset_addr)) 7397 return false; 7398 } 7399 } 7400 return true; 7401} 7402 7403// LDRSH (immediate) calculates an address from a base register value and an 7404// immediate offset, loads a halfword from 7405// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7406// It can use offset, post-indexed, or 7407// pre-indexed addressing. 7408bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode, 7409 const ARMEncoding encoding) { 7410#if 0 7411 if ConditionPassed() then 7412 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7413 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7414 address = if index then offset_addr else R[n]; 7415 data = MemU[address,2]; 7416 if wback then R[n] = offset_addr; 7417 if UnalignedSupport() || address<0> = '0' then 7418 R[t] = SignExtend(data, 32); 7419 else // Can only apply before ARMv7 7420 R[t] = bits(32) UNKNOWN; 7421#endif 7422 7423 bool success = false; 7424 7425 if (ConditionPassed(opcode)) { 7426 uint32_t t; 7427 uint32_t n; 7428 uint32_t imm32; 7429 bool index; 7430 bool add; 7431 bool wback; 7432 7433 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7434 switch (encoding) { 7435 case eEncodingT1: 7436 // if Rn == '1111' then SEE LDRSH (literal); 7437 // if Rt == '1111' then SEE "Unallocated memory hints"; 7438 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7439 t = Bits32(opcode, 15, 12); 7440 n = Bits32(opcode, 19, 16); 7441 imm32 = Bits32(opcode, 11, 0); 7442 7443 // index = TRUE; add = TRUE; wback = FALSE; 7444 index = true; 7445 add = true; 7446 wback = false; 7447 7448 // if t == 13 then UNPREDICTABLE; 7449 if (t == 13) 7450 return false; 7451 7452 break; 7453 7454 case eEncodingT2: 7455 // if Rn == '1111' then SEE LDRSH (literal); 7456 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7457 // "Unallocated memory hints"; 7458 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7459 // if P == '0' && W == '0' then UNDEFINED; 7460 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7461 return false; 7462 7463 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7464 t = Bits32(opcode, 15, 12); 7465 n = Bits32(opcode, 19, 16); 7466 imm32 = Bits32(opcode, 7, 0); 7467 7468 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7469 index = BitIsSet(opcode, 10); 7470 add = BitIsSet(opcode, 9); 7471 wback = BitIsSet(opcode, 8); 7472 7473 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7474 if (BadReg(t) || (wback && (n == t))) 7475 return false; 7476 7477 break; 7478 7479 case eEncodingA1: { 7480 // if Rn == '1111' then SEE LDRSH (literal); 7481 // if P == '0' && W == '1' then SEE LDRSHT; 7482 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7483 t = Bits32(opcode, 15, 12); 7484 n = Bits32(opcode, 19, 16); 7485 uint32_t imm4H = Bits32(opcode, 11, 8); 7486 uint32_t imm4L = Bits32(opcode, 3, 0); 7487 imm32 = (imm4H << 4) | imm4L; 7488 7489 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7490 // (W == '1'); 7491 index = BitIsSet(opcode, 24); 7492 add = BitIsSet(opcode, 23); 7493 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7494 7495 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7496 if ((t == 15) || (wback && (n == t))) 7497 return false; 7498 7499 break; 7500 } 7501 7502 default: 7503 return false; 7504 } 7505 7506 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7507 uint64_t Rn = 7508 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7509 if (!success) 7510 return false; 7511 7512 addr_t offset_addr; 7513 if (add) 7514 offset_addr = Rn + imm32; 7515 else 7516 offset_addr = Rn - imm32; 7517 7518 // address = if index then offset_addr else R[n]; 7519 addr_t address; 7520 if (index) 7521 address = offset_addr; 7522 else 7523 address = Rn; 7524 7525 // data = MemU[address,2]; 7526 RegisterInfo base_reg; 7527 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7528 7529 EmulateInstruction::Context context; 7530 context.type = eContextRegisterLoad; 7531 context.SetRegisterPlusOffset(base_reg, address - Rn); 7532 7533 uint64_t data = MemURead(context, address, 2, 0, &success); 7534 if (!success) 7535 return false; 7536 7537 // if wback then R[n] = offset_addr; 7538 if (wback) { 7539 context.type = eContextAdjustBaseRegister; 7540 context.SetAddress(offset_addr); 7541 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7542 offset_addr)) 7543 return false; 7544 } 7545 7546 // if UnalignedSupport() || address<0> = '0' then 7547 if (UnalignedSupport() || BitIsClear(address, 0)) { 7548 // R[t] = SignExtend(data, 32); 7549 int64_t signed_data = llvm::SignExtend64<16>(data); 7550 context.type = eContextRegisterLoad; 7551 context.SetRegisterPlusOffset(base_reg, address - Rn); 7552 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7553 (uint64_t)signed_data)) 7554 return false; 7555 } else // Can only apply before ARMv7 7556 { 7557 // R[t] = bits(32) UNKNOWN; 7558 WriteBits32Unknown(t); 7559 } 7560 } 7561 return true; 7562} 7563 7564// LDRSH (literal) calculates an address from the PC value and an immediate 7565// offset, loads a halfword from memory, 7566// sign-extends it to from a 32-bit word, and writes it to a register. 7567bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode, 7568 const ARMEncoding encoding) { 7569#if 0 7570 if ConditionPassed() then 7571 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7572 base = Align(PC,4); 7573 address = if add then (base + imm32) else (base - imm32); 7574 data = MemU[address,2]; 7575 if UnalignedSupport() || address<0> = '0' then 7576 R[t] = SignExtend(data, 32); 7577 else // Can only apply before ARMv7 7578 R[t] = bits(32) UNKNOWN; 7579#endif 7580 7581 bool success = false; 7582 7583 if (ConditionPassed(opcode)) { 7584 uint32_t t; 7585 uint32_t imm32; 7586 bool add; 7587 7588 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7589 switch (encoding) { 7590 case eEncodingT1: 7591 // if Rt == '1111' then SEE "Unallocated memory hints"; 7592 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7593 t = Bits32(opcode, 15, 12); 7594 imm32 = Bits32(opcode, 11, 0); 7595 add = BitIsSet(opcode, 23); 7596 7597 // if t == 13 then UNPREDICTABLE; 7598 if (t == 13) 7599 return false; 7600 7601 break; 7602 7603 case eEncodingA1: { 7604 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7605 t = Bits32(opcode, 15, 12); 7606 uint32_t imm4H = Bits32(opcode, 11, 8); 7607 uint32_t imm4L = Bits32(opcode, 3, 0); 7608 imm32 = (imm4H << 4) | imm4L; 7609 add = BitIsSet(opcode, 23); 7610 7611 // if t == 15 then UNPREDICTABLE; 7612 if (t == 15) 7613 return false; 7614 7615 break; 7616 } 7617 default: 7618 return false; 7619 } 7620 7621 // base = Align(PC,4); 7622 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7623 if (!success) 7624 return false; 7625 7626 uint64_t base = AlignPC(pc_value); 7627 7628 addr_t address; 7629 // address = if add then (base + imm32) else (base - imm32); 7630 if (add) 7631 address = base + imm32; 7632 else 7633 address = base - imm32; 7634 7635 // data = MemU[address,2]; 7636 RegisterInfo base_reg; 7637 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7638 7639 EmulateInstruction::Context context; 7640 context.type = eContextRegisterLoad; 7641 context.SetRegisterPlusOffset(base_reg, imm32); 7642 7643 uint64_t data = MemURead(context, address, 2, 0, &success); 7644 if (!success) 7645 return false; 7646 7647 // if UnalignedSupport() || address<0> = '0' then 7648 if (UnalignedSupport() || BitIsClear(address, 0)) { 7649 // R[t] = SignExtend(data, 32); 7650 int64_t signed_data = llvm::SignExtend64<16>(data); 7651 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7652 (uint64_t)signed_data)) 7653 return false; 7654 } else // Can only apply before ARMv7 7655 { 7656 // R[t] = bits(32) UNKNOWN; 7657 WriteBits32Unknown(t); 7658 } 7659 } 7660 return true; 7661} 7662 7663// LDRSH (register) calculates an address from a base register value and an 7664// offset register value, loads a halfword 7665// from memory, sign-extends it to form a 32-bit word, and writes it to a 7666// register. The offset register value can be 7667// shifted left by 0, 1, 2, or 3 bits. 7668bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode, 7669 const ARMEncoding encoding) { 7670#if 0 7671 if ConditionPassed() then 7672 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7673 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7674 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7675 address = if index then offset_addr else R[n]; 7676 data = MemU[address,2]; 7677 if wback then R[n] = offset_addr; 7678 if UnalignedSupport() || address<0> = '0' then 7679 R[t] = SignExtend(data, 32); 7680 else // Can only apply before ARMv7 7681 R[t] = bits(32) UNKNOWN; 7682#endif 7683 7684 bool success = false; 7685 7686 if (ConditionPassed(opcode)) { 7687 uint32_t t; 7688 uint32_t n; 7689 uint32_t m; 7690 bool index; 7691 bool add; 7692 bool wback; 7693 ARM_ShifterType shift_t; 7694 uint32_t shift_n; 7695 7696 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7697 switch (encoding) { 7698 case eEncodingT1: 7699 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 7700 // in ThumbEE"; 7701 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7702 t = Bits32(opcode, 2, 0); 7703 n = Bits32(opcode, 5, 3); 7704 m = Bits32(opcode, 8, 6); 7705 7706 // index = TRUE; add = TRUE; wback = FALSE; 7707 index = true; 7708 add = true; 7709 wback = false; 7710 7711 // (shift_t, shift_n) = (SRType_LSL, 0); 7712 shift_t = SRType_LSL; 7713 shift_n = 0; 7714 7715 break; 7716 7717 case eEncodingT2: 7718 // if Rn == '1111' then SEE LDRSH (literal); 7719 // if Rt == '1111' then SEE "Unallocated memory hints"; 7720 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7721 t = Bits32(opcode, 15, 12); 7722 n = Bits32(opcode, 19, 16); 7723 m = Bits32(opcode, 3, 0); 7724 7725 // index = TRUE; add = TRUE; wback = FALSE; 7726 index = true; 7727 add = true; 7728 wback = false; 7729 7730 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7731 shift_t = SRType_LSL; 7732 shift_n = Bits32(opcode, 5, 4); 7733 7734 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7735 if ((t == 13) || BadReg(m)) 7736 return false; 7737 7738 break; 7739 7740 case eEncodingA1: 7741 // if P == '0' && W == '1' then SEE LDRSHT; 7742 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7743 t = Bits32(opcode, 15, 12); 7744 n = Bits32(opcode, 19, 16); 7745 m = Bits32(opcode, 3, 0); 7746 7747 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7748 // (W == '1'); 7749 index = BitIsSet(opcode, 24); 7750 add = BitIsSet(opcode, 23); 7751 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7752 7753 // (shift_t, shift_n) = (SRType_LSL, 0); 7754 shift_t = SRType_LSL; 7755 shift_n = 0; 7756 7757 // if t == 15 || m == 15 then UNPREDICTABLE; 7758 if ((t == 15) || (m == 15)) 7759 return false; 7760 7761 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7762 if (wback && ((n == 15) || (n == t))) 7763 return false; 7764 7765 break; 7766 7767 default: 7768 return false; 7769 } 7770 7771 uint64_t Rm = 7772 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7773 if (!success) 7774 return false; 7775 7776 uint64_t Rn = 7777 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7778 if (!success) 7779 return false; 7780 7781 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7782 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7783 if (!success) 7784 return false; 7785 7786 addr_t offset_addr; 7787 addr_t address; 7788 7789 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7790 if (add) 7791 offset_addr = Rn + offset; 7792 else 7793 offset_addr = Rn - offset; 7794 7795 // address = if index then offset_addr else R[n]; 7796 if (index) 7797 address = offset_addr; 7798 else 7799 address = Rn; 7800 7801 // data = MemU[address,2]; 7802 RegisterInfo base_reg; 7803 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7804 7805 RegisterInfo offset_reg; 7806 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7807 7808 EmulateInstruction::Context context; 7809 context.type = eContextRegisterLoad; 7810 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7811 7812 uint64_t data = MemURead(context, address, 2, 0, &success); 7813 if (!success) 7814 return false; 7815 7816 // if wback then R[n] = offset_addr; 7817 if (wback) { 7818 context.type = eContextAdjustBaseRegister; 7819 context.SetAddress(offset_addr); 7820 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7821 offset_addr)) 7822 return false; 7823 } 7824 7825 // if UnalignedSupport() || address<0> = '0' then 7826 if (UnalignedSupport() || BitIsClear(address, 0)) { 7827 // R[t] = SignExtend(data, 32); 7828 context.type = eContextRegisterLoad; 7829 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7830 7831 int64_t signed_data = llvm::SignExtend64<16>(data); 7832 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7833 (uint64_t)signed_data)) 7834 return false; 7835 } else // Can only apply before ARMv7 7836 { 7837 // R[t] = bits(32) UNKNOWN; 7838 WriteBits32Unknown(t); 7839 } 7840 } 7841 return true; 7842} 7843 7844// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and 7845// writes the result to the destination 7846// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before 7847// extracting the 8-bit value. 7848bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode, 7849 const ARMEncoding encoding) { 7850#if 0 7851 if ConditionPassed() then 7852 EncodingSpecificOperations(); 7853 rotated = ROR(R[m], rotation); 7854 R[d] = SignExtend(rotated<7:0>, 32); 7855#endif 7856 7857 bool success = false; 7858 7859 if (ConditionPassed(opcode)) { 7860 uint32_t d; 7861 uint32_t m; 7862 uint32_t rotation; 7863 7864 // EncodingSpecificOperations(); 7865 switch (encoding) { 7866 case eEncodingT1: 7867 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7868 d = Bits32(opcode, 2, 0); 7869 m = Bits32(opcode, 5, 3); 7870 rotation = 0; 7871 7872 break; 7873 7874 case eEncodingT2: 7875 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7876 d = Bits32(opcode, 11, 8); 7877 m = Bits32(opcode, 3, 0); 7878 rotation = Bits32(opcode, 5, 4) << 3; 7879 7880 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7881 if (BadReg(d) || BadReg(m)) 7882 return false; 7883 7884 break; 7885 7886 case eEncodingA1: 7887 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7888 d = Bits32(opcode, 15, 12); 7889 m = Bits32(opcode, 3, 0); 7890 rotation = Bits32(opcode, 11, 10) << 3; 7891 7892 // if d == 15 || m == 15 then UNPREDICTABLE; 7893 if ((d == 15) || (m == 15)) 7894 return false; 7895 7896 break; 7897 7898 default: 7899 return false; 7900 } 7901 7902 uint64_t Rm = 7903 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7904 if (!success) 7905 return false; 7906 7907 // rotated = ROR(R[m], rotation); 7908 uint64_t rotated = ROR(Rm, rotation, &success); 7909 if (!success) 7910 return false; 7911 7912 // R[d] = SignExtend(rotated<7:0>, 32); 7913 int64_t data = llvm::SignExtend64<8>(rotated); 7914 7915 RegisterInfo source_reg; 7916 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7917 7918 EmulateInstruction::Context context; 7919 context.type = eContextRegisterLoad; 7920 context.SetRegister(source_reg); 7921 7922 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 7923 (uint64_t)data)) 7924 return false; 7925 } 7926 return true; 7927} 7928 7929// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and 7930// writes the result to the destination 7931// register. You can specify a rotation by 0, 8, 16, or 24 bits before 7932// extracting the 16-bit value. 7933bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, 7934 const ARMEncoding encoding) { 7935#if 0 7936 if ConditionPassed() then 7937 EncodingSpecificOperations(); 7938 rotated = ROR(R[m], rotation); 7939 R[d] = SignExtend(rotated<15:0>, 32); 7940#endif 7941 7942 bool success = false; 7943 7944 if (ConditionPassed(opcode)) { 7945 uint32_t d; 7946 uint32_t m; 7947 uint32_t rotation; 7948 7949 // EncodingSpecificOperations(); 7950 switch (encoding) { 7951 case eEncodingT1: 7952 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7953 d = Bits32(opcode, 2, 0); 7954 m = Bits32(opcode, 5, 3); 7955 rotation = 0; 7956 7957 break; 7958 7959 case eEncodingT2: 7960 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7961 d = Bits32(opcode, 11, 8); 7962 m = Bits32(opcode, 3, 0); 7963 rotation = Bits32(opcode, 5, 4) << 3; 7964 7965 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7966 if (BadReg(d) || BadReg(m)) 7967 return false; 7968 7969 break; 7970 7971 case eEncodingA1: 7972 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7973 d = Bits32(opcode, 15, 12); 7974 m = Bits32(opcode, 3, 0); 7975 rotation = Bits32(opcode, 11, 10) << 3; 7976 7977 // if d == 15 || m == 15 then UNPREDICTABLE; 7978 if ((d == 15) || (m == 15)) 7979 return false; 7980 7981 break; 7982 7983 default: 7984 return false; 7985 } 7986 7987 uint64_t Rm = 7988 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7989 if (!success) 7990 return false; 7991 7992 // rotated = ROR(R[m], rotation); 7993 uint64_t rotated = ROR(Rm, rotation, &success); 7994 if (!success) 7995 return false; 7996 7997 // R[d] = SignExtend(rotated<15:0>, 32); 7998 RegisterInfo source_reg; 7999 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8000 8001 EmulateInstruction::Context context; 8002 context.type = eContextRegisterLoad; 8003 context.SetRegister(source_reg); 8004 8005 int64_t data = llvm::SignExtend64<16>(rotated); 8006 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8007 (uint64_t)data)) 8008 return false; 8009 } 8010 8011 return true; 8012} 8013 8014// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and 8015// writes the result to the destination 8016// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8017// extracting the 8-bit value. 8018bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode, 8019 const ARMEncoding encoding) { 8020#if 0 8021 if ConditionPassed() then 8022 EncodingSpecificOperations(); 8023 rotated = ROR(R[m], rotation); 8024 R[d] = ZeroExtend(rotated<7:0>, 32); 8025#endif 8026 8027 bool success = false; 8028 8029 if (ConditionPassed(opcode)) { 8030 uint32_t d; 8031 uint32_t m; 8032 uint32_t rotation; 8033 8034 // EncodingSpecificOperations(); 8035 switch (encoding) { 8036 case eEncodingT1: 8037 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8038 d = Bits32(opcode, 2, 0); 8039 m = Bits32(opcode, 5, 3); 8040 rotation = 0; 8041 8042 break; 8043 8044 case eEncodingT2: 8045 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8046 d = Bits32(opcode, 11, 8); 8047 m = Bits32(opcode, 3, 0); 8048 rotation = Bits32(opcode, 5, 4) << 3; 8049 8050 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8051 if (BadReg(d) || BadReg(m)) 8052 return false; 8053 8054 break; 8055 8056 case eEncodingA1: 8057 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8058 d = Bits32(opcode, 15, 12); 8059 m = Bits32(opcode, 3, 0); 8060 rotation = Bits32(opcode, 11, 10) << 3; 8061 8062 // if d == 15 || m == 15 then UNPREDICTABLE; 8063 if ((d == 15) || (m == 15)) 8064 return false; 8065 8066 break; 8067 8068 default: 8069 return false; 8070 } 8071 8072 uint64_t Rm = 8073 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8074 if (!success) 8075 return false; 8076 8077 // rotated = ROR(R[m], rotation); 8078 uint64_t rotated = ROR(Rm, rotation, &success); 8079 if (!success) 8080 return false; 8081 8082 // R[d] = ZeroExtend(rotated<7:0>, 32); 8083 RegisterInfo source_reg; 8084 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8085 8086 EmulateInstruction::Context context; 8087 context.type = eContextRegisterLoad; 8088 context.SetRegister(source_reg); 8089 8090 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8091 Bits32(rotated, 7, 0))) 8092 return false; 8093 } 8094 return true; 8095} 8096 8097// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and 8098// writes the result to the destination 8099// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8100// extracting the 16-bit value. 8101bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode, 8102 const ARMEncoding encoding) { 8103#if 0 8104 if ConditionPassed() then 8105 EncodingSpecificOperations(); 8106 rotated = ROR(R[m], rotation); 8107 R[d] = ZeroExtend(rotated<15:0>, 32); 8108#endif 8109 8110 bool success = false; 8111 8112 if (ConditionPassed(opcode)) { 8113 uint32_t d; 8114 uint32_t m; 8115 uint32_t rotation; 8116 8117 switch (encoding) { 8118 case eEncodingT1: 8119 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8120 d = Bits32(opcode, 2, 0); 8121 m = Bits32(opcode, 5, 3); 8122 rotation = 0; 8123 8124 break; 8125 8126 case eEncodingT2: 8127 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8128 d = Bits32(opcode, 11, 8); 8129 m = Bits32(opcode, 3, 0); 8130 rotation = Bits32(opcode, 5, 4) << 3; 8131 8132 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8133 if (BadReg(d) || BadReg(m)) 8134 return false; 8135 8136 break; 8137 8138 case eEncodingA1: 8139 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8140 d = Bits32(opcode, 15, 12); 8141 m = Bits32(opcode, 3, 0); 8142 rotation = Bits32(opcode, 11, 10) << 3; 8143 8144 // if d == 15 || m == 15 then UNPREDICTABLE; 8145 if ((d == 15) || (m == 15)) 8146 return false; 8147 8148 break; 8149 8150 default: 8151 return false; 8152 } 8153 8154 uint64_t Rm = 8155 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8156 if (!success) 8157 return false; 8158 8159 // rotated = ROR(R[m], rotation); 8160 uint64_t rotated = ROR(Rm, rotation, &success); 8161 if (!success) 8162 return false; 8163 8164 // R[d] = ZeroExtend(rotated<15:0>, 32); 8165 RegisterInfo source_reg; 8166 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8167 8168 EmulateInstruction::Context context; 8169 context.type = eContextRegisterLoad; 8170 context.SetRegister(source_reg); 8171 8172 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8173 Bits32(rotated, 15, 0))) 8174 return false; 8175 } 8176 return true; 8177} 8178 8179// RFE (Return From Exception) loads the PC and the CPSR from the word at the 8180// specified address and the following 8181// word respectively. 8182bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode, 8183 const ARMEncoding encoding) { 8184#if 0 8185 if ConditionPassed() then 8186 EncodingSpecificOperations(); 8187 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8188 UNPREDICTABLE; 8189 else 8190 address = if increment then R[n] else R[n]-8; 8191 if wordhigher then address = address+4; 8192 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8193 BranchWritePC(MemA[address,4]); 8194 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8195#endif 8196 8197 bool success = false; 8198 8199 if (ConditionPassed(opcode)) { 8200 uint32_t n; 8201 bool wback; 8202 bool increment; 8203 bool wordhigher; 8204 8205 // EncodingSpecificOperations(); 8206 switch (encoding) { 8207 case eEncodingT1: 8208 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = 8209 // FALSE; 8210 n = Bits32(opcode, 19, 16); 8211 wback = BitIsSet(opcode, 21); 8212 increment = false; 8213 wordhigher = false; 8214 8215 // if n == 15 then UNPREDICTABLE; 8216 if (n == 15) 8217 return false; 8218 8219 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8220 if (InITBlock() && !LastInITBlock()) 8221 return false; 8222 8223 break; 8224 8225 case eEncodingT2: 8226 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8227 n = Bits32(opcode, 19, 16); 8228 wback = BitIsSet(opcode, 21); 8229 increment = true; 8230 wordhigher = false; 8231 8232 // if n == 15 then UNPREDICTABLE; 8233 if (n == 15) 8234 return false; 8235 8236 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8237 if (InITBlock() && !LastInITBlock()) 8238 return false; 8239 8240 break; 8241 8242 case eEncodingA1: 8243 // n = UInt(Rn); 8244 n = Bits32(opcode, 19, 16); 8245 8246 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8247 wback = BitIsSet(opcode, 21); 8248 increment = BitIsSet(opcode, 23); 8249 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23)); 8250 8251 // if n == 15 then UNPREDICTABLE; 8252 if (n == 15) 8253 return false; 8254 8255 break; 8256 8257 default: 8258 return false; 8259 } 8260 8261 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE 8262 // then 8263 if (!CurrentModeIsPrivileged()) 8264 // UNPREDICTABLE; 8265 return false; 8266 else { 8267 uint64_t Rn = 8268 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8269 if (!success) 8270 return false; 8271 8272 addr_t address; 8273 // address = if increment then R[n] else R[n]-8; 8274 if (increment) 8275 address = Rn; 8276 else 8277 address = Rn - 8; 8278 8279 // if wordhigher then address = address+4; 8280 if (wordhigher) 8281 address = address + 4; 8282 8283 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8284 RegisterInfo base_reg; 8285 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8286 8287 EmulateInstruction::Context context; 8288 context.type = eContextReturnFromException; 8289 context.SetRegisterPlusOffset(base_reg, address - Rn); 8290 8291 uint64_t data = MemARead(context, address + 4, 4, 0, &success); 8292 if (!success) 8293 return false; 8294 8295 CPSRWriteByInstr(data, 15, true); 8296 8297 // BranchWritePC(MemA[address,4]); 8298 uint64_t data2 = MemARead(context, address, 4, 0, &success); 8299 if (!success) 8300 return false; 8301 8302 BranchWritePC(context, data2); 8303 8304 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8305 if (wback) { 8306 context.type = eContextAdjustBaseRegister; 8307 if (increment) { 8308 context.SetOffset(8); 8309 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8310 Rn + 8)) 8311 return false; 8312 } else { 8313 context.SetOffset(-8); 8314 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8315 Rn - 8)) 8316 return false; 8317 } 8318 } // if wback 8319 } 8320 } // if ConditionPassed() 8321 return true; 8322} 8323 8324// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a 8325// register value and an immediate value, 8326// and writes the result to the destination register. It can optionally update 8327// the condition flags based on 8328// the result. 8329bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode, 8330 const ARMEncoding encoding) { 8331#if 0 8332 // ARM pseudo code... 8333 if ConditionPassed() then 8334 EncodingSpecificOperations(); 8335 result = R[n] EOR imm32; 8336 if d == 15 then // Can only occur for ARM encoding 8337 ALUWritePC(result); // setflags is always FALSE here 8338 else 8339 R[d] = result; 8340 if setflags then 8341 APSR.N = result<31>; 8342 APSR.Z = IsZeroBit(result); 8343 APSR.C = carry; 8344 // APSR.V unchanged 8345#endif 8346 8347 bool success = false; 8348 8349 if (ConditionPassed(opcode)) { 8350 uint32_t Rd, Rn; 8351 uint32_t 8352 imm32; // the immediate value to be ORed to the value obtained from Rn 8353 bool setflags; 8354 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8355 switch (encoding) { 8356 case eEncodingT1: 8357 Rd = Bits32(opcode, 11, 8); 8358 Rn = Bits32(opcode, 19, 16); 8359 setflags = BitIsSet(opcode, 20); 8360 imm32 = ThumbExpandImm_C( 8361 opcode, APSR_C, 8362 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8363 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8364 if (Rd == 15 && setflags) 8365 return EmulateTEQImm(opcode, eEncodingT1); 8366 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8367 return false; 8368 break; 8369 case eEncodingA1: 8370 Rd = Bits32(opcode, 15, 12); 8371 Rn = Bits32(opcode, 19, 16); 8372 setflags = BitIsSet(opcode, 20); 8373 imm32 = 8374 ARMExpandImm_C(opcode, APSR_C, 8375 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8376 8377 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8378 // instructions; 8379 if (Rd == 15 && setflags) 8380 return EmulateSUBSPcLrEtc(opcode, encoding); 8381 break; 8382 default: 8383 return false; 8384 } 8385 8386 // Read the first operand. 8387 uint32_t val1 = ReadCoreReg(Rn, &success); 8388 if (!success) 8389 return false; 8390 8391 uint32_t result = val1 ^ imm32; 8392 8393 EmulateInstruction::Context context; 8394 context.type = EmulateInstruction::eContextImmediate; 8395 context.SetNoArgs(); 8396 8397 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8398 return false; 8399 } 8400 return true; 8401} 8402 8403// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register 8404// value and an 8405// optionally-shifted register value, and writes the result to the destination 8406// register. 8407// It can optionally update the condition flags based on the result. 8408bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode, 8409 const ARMEncoding encoding) { 8410#if 0 8411 // ARM pseudo code... 8412 if ConditionPassed() then 8413 EncodingSpecificOperations(); 8414 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8415 result = R[n] EOR shifted; 8416 if d == 15 then // Can only occur for ARM encoding 8417 ALUWritePC(result); // setflags is always FALSE here 8418 else 8419 R[d] = result; 8420 if setflags then 8421 APSR.N = result<31>; 8422 APSR.Z = IsZeroBit(result); 8423 APSR.C = carry; 8424 // APSR.V unchanged 8425#endif 8426 8427 bool success = false; 8428 8429 if (ConditionPassed(opcode)) { 8430 uint32_t Rd, Rn, Rm; 8431 ARM_ShifterType shift_t; 8432 uint32_t shift_n; // the shift applied to the value read from Rm 8433 bool setflags; 8434 uint32_t carry; 8435 switch (encoding) { 8436 case eEncodingT1: 8437 Rd = Rn = Bits32(opcode, 2, 0); 8438 Rm = Bits32(opcode, 5, 3); 8439 setflags = !InITBlock(); 8440 shift_t = SRType_LSL; 8441 shift_n = 0; 8442 break; 8443 case eEncodingT2: 8444 Rd = Bits32(opcode, 11, 8); 8445 Rn = Bits32(opcode, 19, 16); 8446 Rm = Bits32(opcode, 3, 0); 8447 setflags = BitIsSet(opcode, 20); 8448 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8449 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8450 if (Rd == 15 && setflags) 8451 return EmulateTEQReg(opcode, eEncodingT1); 8452 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8453 return false; 8454 break; 8455 case eEncodingA1: 8456 Rd = Bits32(opcode, 15, 12); 8457 Rn = Bits32(opcode, 19, 16); 8458 Rm = Bits32(opcode, 3, 0); 8459 setflags = BitIsSet(opcode, 20); 8460 shift_n = DecodeImmShiftARM(opcode, shift_t); 8461 8462 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8463 // instructions; 8464 if (Rd == 15 && setflags) 8465 return EmulateSUBSPcLrEtc(opcode, encoding); 8466 break; 8467 default: 8468 return false; 8469 } 8470 8471 // Read the first operand. 8472 uint32_t val1 = ReadCoreReg(Rn, &success); 8473 if (!success) 8474 return false; 8475 8476 // Read the second operand. 8477 uint32_t val2 = ReadCoreReg(Rm, &success); 8478 if (!success) 8479 return false; 8480 8481 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8482 if (!success) 8483 return false; 8484 uint32_t result = val1 ^ shifted; 8485 8486 EmulateInstruction::Context context; 8487 context.type = EmulateInstruction::eContextImmediate; 8488 context.SetNoArgs(); 8489 8490 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8491 return false; 8492 } 8493 return true; 8494} 8495 8496// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value 8497// and an immediate value, and 8498// writes the result to the destination register. It can optionally update the 8499// condition flags based 8500// on the result. 8501bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode, 8502 const ARMEncoding encoding) { 8503#if 0 8504 // ARM pseudo code... 8505 if ConditionPassed() then 8506 EncodingSpecificOperations(); 8507 result = R[n] OR imm32; 8508 if d == 15 then // Can only occur for ARM encoding 8509 ALUWritePC(result); // setflags is always FALSE here 8510 else 8511 R[d] = result; 8512 if setflags then 8513 APSR.N = result<31>; 8514 APSR.Z = IsZeroBit(result); 8515 APSR.C = carry; 8516 // APSR.V unchanged 8517#endif 8518 8519 bool success = false; 8520 8521 if (ConditionPassed(opcode)) { 8522 uint32_t Rd, Rn; 8523 uint32_t 8524 imm32; // the immediate value to be ORed to the value obtained from Rn 8525 bool setflags; 8526 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8527 switch (encoding) { 8528 case eEncodingT1: 8529 Rd = Bits32(opcode, 11, 8); 8530 Rn = Bits32(opcode, 19, 16); 8531 setflags = BitIsSet(opcode, 20); 8532 imm32 = ThumbExpandImm_C( 8533 opcode, APSR_C, 8534 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8535 // if Rn == '1111' then SEE MOV (immediate); 8536 if (Rn == 15) 8537 return EmulateMOVRdImm(opcode, eEncodingT2); 8538 if (BadReg(Rd) || Rn == 13) 8539 return false; 8540 break; 8541 case eEncodingA1: 8542 Rd = Bits32(opcode, 15, 12); 8543 Rn = Bits32(opcode, 19, 16); 8544 setflags = BitIsSet(opcode, 20); 8545 imm32 = 8546 ARMExpandImm_C(opcode, APSR_C, 8547 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8548 8549 if (Rd == 15 && setflags) 8550 return EmulateSUBSPcLrEtc(opcode, encoding); 8551 break; 8552 default: 8553 return false; 8554 } 8555 8556 // Read the first operand. 8557 uint32_t val1 = ReadCoreReg(Rn, &success); 8558 if (!success) 8559 return false; 8560 8561 uint32_t result = val1 | imm32; 8562 8563 EmulateInstruction::Context context; 8564 context.type = EmulateInstruction::eContextImmediate; 8565 context.SetNoArgs(); 8566 8567 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8568 return false; 8569 } 8570 return true; 8571} 8572 8573// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value 8574// and an optionally-shifted register 8575// value, and writes the result to the destination register. It can optionally 8576// update the condition flags based 8577// on the result. 8578bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode, 8579 const ARMEncoding encoding) { 8580#if 0 8581 // ARM pseudo code... 8582 if ConditionPassed() then 8583 EncodingSpecificOperations(); 8584 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8585 result = R[n] OR shifted; 8586 if d == 15 then // Can only occur for ARM encoding 8587 ALUWritePC(result); // setflags is always FALSE here 8588 else 8589 R[d] = result; 8590 if setflags then 8591 APSR.N = result<31>; 8592 APSR.Z = IsZeroBit(result); 8593 APSR.C = carry; 8594 // APSR.V unchanged 8595#endif 8596 8597 bool success = false; 8598 8599 if (ConditionPassed(opcode)) { 8600 uint32_t Rd, Rn, Rm; 8601 ARM_ShifterType shift_t; 8602 uint32_t shift_n; // the shift applied to the value read from Rm 8603 bool setflags; 8604 uint32_t carry; 8605 switch (encoding) { 8606 case eEncodingT1: 8607 Rd = Rn = Bits32(opcode, 2, 0); 8608 Rm = Bits32(opcode, 5, 3); 8609 setflags = !InITBlock(); 8610 shift_t = SRType_LSL; 8611 shift_n = 0; 8612 break; 8613 case eEncodingT2: 8614 Rd = Bits32(opcode, 11, 8); 8615 Rn = Bits32(opcode, 19, 16); 8616 Rm = Bits32(opcode, 3, 0); 8617 setflags = BitIsSet(opcode, 20); 8618 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8619 // if Rn == '1111' then SEE MOV (register); 8620 if (Rn == 15) 8621 return EmulateMOVRdRm(opcode, eEncodingT3); 8622 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8623 return false; 8624 break; 8625 case eEncodingA1: 8626 Rd = Bits32(opcode, 15, 12); 8627 Rn = Bits32(opcode, 19, 16); 8628 Rm = Bits32(opcode, 3, 0); 8629 setflags = BitIsSet(opcode, 20); 8630 shift_n = DecodeImmShiftARM(opcode, shift_t); 8631 8632 if (Rd == 15 && setflags) 8633 return EmulateSUBSPcLrEtc(opcode, encoding); 8634 break; 8635 default: 8636 return false; 8637 } 8638 8639 // Read the first operand. 8640 uint32_t val1 = ReadCoreReg(Rn, &success); 8641 if (!success) 8642 return false; 8643 8644 // Read the second operand. 8645 uint32_t val2 = ReadCoreReg(Rm, &success); 8646 if (!success) 8647 return false; 8648 8649 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8650 if (!success) 8651 return false; 8652 uint32_t result = val1 | shifted; 8653 8654 EmulateInstruction::Context context; 8655 context.type = EmulateInstruction::eContextImmediate; 8656 context.SetNoArgs(); 8657 8658 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8659 return false; 8660 } 8661 return true; 8662} 8663 8664// Reverse Subtract (immediate) subtracts a register value from an immediate 8665// value, and writes the result to 8666// the destination register. It can optionally update the condition flags based 8667// on the result. 8668bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, 8669 const ARMEncoding encoding) { 8670#if 0 8671 // ARM pseudo code... 8672 if ConditionPassed() then 8673 EncodingSpecificOperations(); 8674 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8675 if d == 15 then // Can only occur for ARM encoding 8676 ALUWritePC(result); // setflags is always FALSE here 8677 else 8678 R[d] = result; 8679 if setflags then 8680 APSR.N = result<31>; 8681 APSR.Z = IsZeroBit(result); 8682 APSR.C = carry; 8683 APSR.V = overflow; 8684#endif 8685 8686 bool success = false; 8687 8688 uint32_t Rd; // the destination register 8689 uint32_t Rn; // the first operand 8690 bool setflags; 8691 uint32_t 8692 imm32; // the immediate value to be added to the value obtained from Rn 8693 switch (encoding) { 8694 case eEncodingT1: 8695 Rd = Bits32(opcode, 2, 0); 8696 Rn = Bits32(opcode, 5, 3); 8697 setflags = !InITBlock(); 8698 imm32 = 0; 8699 break; 8700 case eEncodingT2: 8701 Rd = Bits32(opcode, 11, 8); 8702 Rn = Bits32(opcode, 19, 16); 8703 setflags = BitIsSet(opcode, 20); 8704 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8705 if (BadReg(Rd) || BadReg(Rn)) 8706 return false; 8707 break; 8708 case eEncodingA1: 8709 Rd = Bits32(opcode, 15, 12); 8710 Rn = Bits32(opcode, 19, 16); 8711 setflags = BitIsSet(opcode, 20); 8712 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8713 8714 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8715 // instructions; 8716 if (Rd == 15 && setflags) 8717 return EmulateSUBSPcLrEtc(opcode, encoding); 8718 break; 8719 default: 8720 return false; 8721 } 8722 // Read the register value from the operand register Rn. 8723 uint32_t reg_val = ReadCoreReg(Rn, &success); 8724 if (!success) 8725 return false; 8726 8727 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8728 8729 EmulateInstruction::Context context; 8730 context.type = EmulateInstruction::eContextImmediate; 8731 context.SetNoArgs(); 8732 8733 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 8734 res.carry_out, res.overflow)) 8735 return false; 8736 8737 return true; 8738} 8739 8740// Reverse Subtract (register) subtracts a register value from an 8741// optionally-shifted register value, and writes the 8742// result to the destination register. It can optionally update the condition 8743// flags based on the result. 8744bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, 8745 const ARMEncoding encoding) { 8746#if 0 8747 // ARM pseudo code... 8748 if ConditionPassed() then 8749 EncodingSpecificOperations(); 8750 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8751 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8752 if d == 15 then // Can only occur for ARM encoding 8753 ALUWritePC(result); // setflags is always FALSE here 8754 else 8755 R[d] = result; 8756 if setflags then 8757 APSR.N = result<31>; 8758 APSR.Z = IsZeroBit(result); 8759 APSR.C = carry; 8760 APSR.V = overflow; 8761#endif 8762 8763 bool success = false; 8764 8765 uint32_t Rd; // the destination register 8766 uint32_t Rn; // the first operand 8767 uint32_t Rm; // the second operand 8768 bool setflags; 8769 ARM_ShifterType shift_t; 8770 uint32_t shift_n; // the shift applied to the value read from Rm 8771 switch (encoding) { 8772 case eEncodingT1: 8773 Rd = Bits32(opcode, 11, 8); 8774 Rn = Bits32(opcode, 19, 16); 8775 Rm = Bits32(opcode, 3, 0); 8776 setflags = BitIsSet(opcode, 20); 8777 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8778 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8779 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8780 return false; 8781 break; 8782 case eEncodingA1: 8783 Rd = Bits32(opcode, 15, 12); 8784 Rn = Bits32(opcode, 19, 16); 8785 Rm = Bits32(opcode, 3, 0); 8786 setflags = BitIsSet(opcode, 20); 8787 shift_n = DecodeImmShiftARM(opcode, shift_t); 8788 8789 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8790 // instructions; 8791 if (Rd == 15 && setflags) 8792 return EmulateSUBSPcLrEtc(opcode, encoding); 8793 break; 8794 default: 8795 return false; 8796 } 8797 // Read the register value from register Rn. 8798 uint32_t val1 = ReadCoreReg(Rn, &success); 8799 if (!success) 8800 return false; 8801 8802 // Read the register value from register Rm. 8803 uint32_t val2 = ReadCoreReg(Rm, &success); 8804 if (!success) 8805 return false; 8806 8807 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8808 if (!success) 8809 return false; 8810 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8811 8812 EmulateInstruction::Context context; 8813 context.type = EmulateInstruction::eContextImmediate; 8814 context.SetNoArgs(); 8815 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 8816 res.carry_out, res.overflow)) 8817 return false; 8818 8819 return true; 8820} 8821 8822// Reverse Subtract with Carry (immediate) subtracts a register value and the 8823// value of NOT (Carry flag) from 8824// an immediate value, and writes the result to the destination register. It can 8825// optionally update the condition 8826// flags based on the result. 8827bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, 8828 const ARMEncoding encoding) { 8829#if 0 8830 // ARM pseudo code... 8831 if ConditionPassed() then 8832 EncodingSpecificOperations(); 8833 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8834 if d == 15 then 8835 ALUWritePC(result); // setflags is always FALSE here 8836 else 8837 R[d] = result; 8838 if setflags then 8839 APSR.N = result<31>; 8840 APSR.Z = IsZeroBit(result); 8841 APSR.C = carry; 8842 APSR.V = overflow; 8843#endif 8844 8845 bool success = false; 8846 8847 uint32_t Rd; // the destination register 8848 uint32_t Rn; // the first operand 8849 bool setflags; 8850 uint32_t 8851 imm32; // the immediate value to be added to the value obtained from Rn 8852 switch (encoding) { 8853 case eEncodingA1: 8854 Rd = Bits32(opcode, 15, 12); 8855 Rn = Bits32(opcode, 19, 16); 8856 setflags = BitIsSet(opcode, 20); 8857 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8858 8859 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8860 // instructions; 8861 if (Rd == 15 && setflags) 8862 return EmulateSUBSPcLrEtc(opcode, encoding); 8863 break; 8864 default: 8865 return false; 8866 } 8867 // Read the register value from the operand register Rn. 8868 uint32_t reg_val = ReadCoreReg(Rn, &success); 8869 if (!success) 8870 return false; 8871 8872 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8873 8874 EmulateInstruction::Context context; 8875 context.type = EmulateInstruction::eContextImmediate; 8876 context.SetNoArgs(); 8877 8878 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 8879 res.carry_out, res.overflow)) 8880 return false; 8881 8882 return true; 8883} 8884 8885// Reverse Subtract with Carry (register) subtracts a register value and the 8886// value of NOT (Carry flag) from an 8887// optionally-shifted register value, and writes the result to the destination 8888// register. It can optionally update the 8889// condition flags based on the result. 8890bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, 8891 const ARMEncoding encoding) { 8892#if 0 8893 // ARM pseudo code... 8894 if ConditionPassed() then 8895 EncodingSpecificOperations(); 8896 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8897 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8898 if d == 15 then 8899 ALUWritePC(result); // setflags is always FALSE here 8900 else 8901 R[d] = result; 8902 if setflags then 8903 APSR.N = result<31>; 8904 APSR.Z = IsZeroBit(result); 8905 APSR.C = carry; 8906 APSR.V = overflow; 8907#endif 8908 8909 bool success = false; 8910 8911 uint32_t Rd; // the destination register 8912 uint32_t Rn; // the first operand 8913 uint32_t Rm; // the second operand 8914 bool setflags; 8915 ARM_ShifterType shift_t; 8916 uint32_t shift_n; // the shift applied to the value read from Rm 8917 switch (encoding) { 8918 case eEncodingA1: 8919 Rd = Bits32(opcode, 15, 12); 8920 Rn = Bits32(opcode, 19, 16); 8921 Rm = Bits32(opcode, 3, 0); 8922 setflags = BitIsSet(opcode, 20); 8923 shift_n = DecodeImmShiftARM(opcode, shift_t); 8924 8925 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8926 // instructions; 8927 if (Rd == 15 && setflags) 8928 return EmulateSUBSPcLrEtc(opcode, encoding); 8929 break; 8930 default: 8931 return false; 8932 } 8933 // Read the register value from register Rn. 8934 uint32_t val1 = ReadCoreReg(Rn, &success); 8935 if (!success) 8936 return false; 8937 8938 // Read the register value from register Rm. 8939 uint32_t val2 = ReadCoreReg(Rm, &success); 8940 if (!success) 8941 return false; 8942 8943 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8944 if (!success) 8945 return false; 8946 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8947 8948 EmulateInstruction::Context context; 8949 context.type = EmulateInstruction::eContextImmediate; 8950 context.SetNoArgs(); 8951 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 8952 res.carry_out, res.overflow)) 8953 return false; 8954 8955 return true; 8956} 8957 8958// Subtract with Carry (immediate) subtracts an immediate value and the value of 8959// NOT (Carry flag) from a register value, and writes the result to the 8960// destination register. 8961// It can optionally update the condition flags based on the result. 8962bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, 8963 const ARMEncoding encoding) { 8964#if 0 8965 // ARM pseudo code... 8966 if ConditionPassed() then 8967 EncodingSpecificOperations(); 8968 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8969 if d == 15 then // Can only occur for ARM encoding 8970 ALUWritePC(result); // setflags is always FALSE here 8971 else 8972 R[d] = result; 8973 if setflags then 8974 APSR.N = result<31>; 8975 APSR.Z = IsZeroBit(result); 8976 APSR.C = carry; 8977 APSR.V = overflow; 8978#endif 8979 8980 bool success = false; 8981 8982 uint32_t Rd; // the destination register 8983 uint32_t Rn; // the first operand 8984 bool setflags; 8985 uint32_t 8986 imm32; // the immediate value to be added to the value obtained from Rn 8987 switch (encoding) { 8988 case eEncodingT1: 8989 Rd = Bits32(opcode, 11, 8); 8990 Rn = Bits32(opcode, 19, 16); 8991 setflags = BitIsSet(opcode, 20); 8992 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8993 if (BadReg(Rd) || BadReg(Rn)) 8994 return false; 8995 break; 8996 case eEncodingA1: 8997 Rd = Bits32(opcode, 15, 12); 8998 Rn = Bits32(opcode, 19, 16); 8999 setflags = BitIsSet(opcode, 20); 9000 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9001 9002 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9003 // instructions; 9004 if (Rd == 15 && setflags) 9005 return EmulateSUBSPcLrEtc(opcode, encoding); 9006 break; 9007 default: 9008 return false; 9009 } 9010 // Read the register value from the operand register Rn. 9011 uint32_t reg_val = ReadCoreReg(Rn, &success); 9012 if (!success) 9013 return false; 9014 9015 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9016 9017 EmulateInstruction::Context context; 9018 context.type = EmulateInstruction::eContextImmediate; 9019 context.SetNoArgs(); 9020 9021 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9022 res.carry_out, res.overflow)) 9023 return false; 9024 9025 return true; 9026} 9027 9028// Subtract with Carry (register) subtracts an optionally-shifted register value 9029// and the value of 9030// NOT (Carry flag) from a register value, and writes the result to the 9031// destination register. 9032// It can optionally update the condition flags based on the result. 9033bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, 9034 const ARMEncoding encoding) { 9035#if 0 9036 // ARM pseudo code... 9037 if ConditionPassed() then 9038 EncodingSpecificOperations(); 9039 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9040 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9041 if d == 15 then // Can only occur for ARM encoding 9042 ALUWritePC(result); // setflags is always FALSE here 9043 else 9044 R[d] = result; 9045 if setflags then 9046 APSR.N = result<31>; 9047 APSR.Z = IsZeroBit(result); 9048 APSR.C = carry; 9049 APSR.V = overflow; 9050#endif 9051 9052 bool success = false; 9053 9054 uint32_t Rd; // the destination register 9055 uint32_t Rn; // the first operand 9056 uint32_t Rm; // the second operand 9057 bool setflags; 9058 ARM_ShifterType shift_t; 9059 uint32_t shift_n; // the shift applied to the value read from Rm 9060 switch (encoding) { 9061 case eEncodingT1: 9062 Rd = Rn = Bits32(opcode, 2, 0); 9063 Rm = Bits32(opcode, 5, 3); 9064 setflags = !InITBlock(); 9065 shift_t = SRType_LSL; 9066 shift_n = 0; 9067 break; 9068 case eEncodingT2: 9069 Rd = Bits32(opcode, 11, 8); 9070 Rn = Bits32(opcode, 19, 16); 9071 Rm = Bits32(opcode, 3, 0); 9072 setflags = BitIsSet(opcode, 20); 9073 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9074 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9075 return false; 9076 break; 9077 case eEncodingA1: 9078 Rd = Bits32(opcode, 15, 12); 9079 Rn = Bits32(opcode, 19, 16); 9080 Rm = Bits32(opcode, 3, 0); 9081 setflags = BitIsSet(opcode, 20); 9082 shift_n = DecodeImmShiftARM(opcode, shift_t); 9083 9084 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9085 // instructions; 9086 if (Rd == 15 && setflags) 9087 return EmulateSUBSPcLrEtc(opcode, encoding); 9088 break; 9089 default: 9090 return false; 9091 } 9092 // Read the register value from register Rn. 9093 uint32_t val1 = ReadCoreReg(Rn, &success); 9094 if (!success) 9095 return false; 9096 9097 // Read the register value from register Rm. 9098 uint32_t val2 = ReadCoreReg(Rm, &success); 9099 if (!success) 9100 return false; 9101 9102 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9103 if (!success) 9104 return false; 9105 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9106 9107 EmulateInstruction::Context context; 9108 context.type = EmulateInstruction::eContextImmediate; 9109 context.SetNoArgs(); 9110 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9111 res.carry_out, res.overflow)) 9112 return false; 9113 9114 return true; 9115} 9116 9117// This instruction subtracts an immediate value from a register value, and 9118// writes the result 9119// to the destination register. It can optionally update the condition flags 9120// based on the result. 9121bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, 9122 const ARMEncoding encoding) { 9123#if 0 9124 // ARM pseudo code... 9125 if ConditionPassed() then 9126 EncodingSpecificOperations(); 9127 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9128 R[d] = result; 9129 if setflags then 9130 APSR.N = result<31>; 9131 APSR.Z = IsZeroBit(result); 9132 APSR.C = carry; 9133 APSR.V = overflow; 9134#endif 9135 9136 bool success = false; 9137 9138 uint32_t Rd; // the destination register 9139 uint32_t Rn; // the first operand 9140 bool setflags; 9141 uint32_t imm32; // the immediate value to be subtracted from the value 9142 // obtained from Rn 9143 switch (encoding) { 9144 case eEncodingT1: 9145 Rd = Bits32(opcode, 2, 0); 9146 Rn = Bits32(opcode, 5, 3); 9147 setflags = !InITBlock(); 9148 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9149 break; 9150 case eEncodingT2: 9151 Rd = Rn = Bits32(opcode, 10, 8); 9152 setflags = !InITBlock(); 9153 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9154 break; 9155 case eEncodingT3: 9156 Rd = Bits32(opcode, 11, 8); 9157 Rn = Bits32(opcode, 19, 16); 9158 setflags = BitIsSet(opcode, 20); 9159 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9160 9161 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9162 if (Rd == 15 && setflags) 9163 return EmulateCMPImm(opcode, eEncodingT2); 9164 9165 // if Rn == '1101' then SEE SUB (SP minus immediate); 9166 if (Rn == 13) 9167 return EmulateSUBSPImm(opcode, eEncodingT2); 9168 9169 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9170 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9171 return false; 9172 break; 9173 case eEncodingT4: 9174 Rd = Bits32(opcode, 11, 8); 9175 Rn = Bits32(opcode, 19, 16); 9176 setflags = BitIsSet(opcode, 20); 9177 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9178 9179 // if Rn == '1111' then SEE ADR; 9180 if (Rn == 15) 9181 return EmulateADR(opcode, eEncodingT2); 9182 9183 // if Rn == '1101' then SEE SUB (SP minus immediate); 9184 if (Rn == 13) 9185 return EmulateSUBSPImm(opcode, eEncodingT3); 9186 9187 if (BadReg(Rd)) 9188 return false; 9189 break; 9190 default: 9191 return false; 9192 } 9193 // Read the register value from the operand register Rn. 9194 uint32_t reg_val = ReadCoreReg(Rn, &success); 9195 if (!success) 9196 return false; 9197 9198 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9199 9200 EmulateInstruction::Context context; 9201 context.type = EmulateInstruction::eContextImmediate; 9202 context.SetNoArgs(); 9203 9204 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9205 res.carry_out, res.overflow)) 9206 return false; 9207 9208 return true; 9209} 9210 9211// This instruction subtracts an immediate value from a register value, and 9212// writes the result 9213// to the destination register. It can optionally update the condition flags 9214// based on the result. 9215bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode, 9216 const ARMEncoding encoding) { 9217#if 0 9218 // ARM pseudo code... 9219 if ConditionPassed() then 9220 EncodingSpecificOperations(); 9221 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9222 if d == 15 then 9223 ALUWritePC(result); // setflags is always FALSE here 9224 else 9225 R[d] = result; 9226 if setflags then 9227 APSR.N = result<31>; 9228 APSR.Z = IsZeroBit(result); 9229 APSR.C = carry; 9230 APSR.V = overflow; 9231#endif 9232 9233 bool success = false; 9234 9235 if (ConditionPassed(opcode)) { 9236 uint32_t Rd; // the destination register 9237 uint32_t Rn; // the first operand 9238 bool setflags; 9239 uint32_t imm32; // the immediate value to be subtracted from the value 9240 // obtained from Rn 9241 switch (encoding) { 9242 case eEncodingA1: 9243 Rd = Bits32(opcode, 15, 12); 9244 Rn = Bits32(opcode, 19, 16); 9245 setflags = BitIsSet(opcode, 20); 9246 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9247 9248 // if Rn == '1111' && S == '0' then SEE ADR; 9249 if (Rn == 15 && !setflags) 9250 return EmulateADR(opcode, eEncodingA2); 9251 9252 // if Rn == '1101' then SEE SUB (SP minus immediate); 9253 if (Rn == 13) 9254 return EmulateSUBSPImm(opcode, eEncodingA1); 9255 9256 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9257 // instructions; 9258 if (Rd == 15 && setflags) 9259 return EmulateSUBSPcLrEtc(opcode, encoding); 9260 break; 9261 default: 9262 return false; 9263 } 9264 // Read the register value from the operand register Rn. 9265 uint32_t reg_val = ReadCoreReg(Rn, &success); 9266 if (!success) 9267 return false; 9268 9269 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9270 9271 EmulateInstruction::Context context; 9272 if (Rd == 13) 9273 context.type = EmulateInstruction::eContextAdjustStackPointer; 9274 else 9275 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9276 9277 RegisterInfo dwarf_reg; 9278 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 9279 int64_t imm32_signed = imm32; 9280 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed); 9281 9282 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9283 res.carry_out, res.overflow)) 9284 return false; 9285 } 9286 return true; 9287} 9288 9289// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a 9290// register value and an 9291// immediate value. It updates the condition flags based on the result, and 9292// discards the result. 9293bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode, 9294 const ARMEncoding encoding) { 9295#if 0 9296 // ARM pseudo code... 9297 if ConditionPassed() then 9298 EncodingSpecificOperations(); 9299 result = R[n] EOR imm32; 9300 APSR.N = result<31>; 9301 APSR.Z = IsZeroBit(result); 9302 APSR.C = carry; 9303 // APSR.V unchanged 9304#endif 9305 9306 bool success = false; 9307 9308 if (ConditionPassed(opcode)) { 9309 uint32_t Rn; 9310 uint32_t 9311 imm32; // the immediate value to be ANDed to the value obtained from Rn 9312 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9313 switch (encoding) { 9314 case eEncodingT1: 9315 Rn = Bits32(opcode, 19, 16); 9316 imm32 = ThumbExpandImm_C( 9317 opcode, APSR_C, 9318 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9319 if (BadReg(Rn)) 9320 return false; 9321 break; 9322 case eEncodingA1: 9323 Rn = Bits32(opcode, 19, 16); 9324 imm32 = 9325 ARMExpandImm_C(opcode, APSR_C, 9326 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9327 break; 9328 default: 9329 return false; 9330 } 9331 9332 // Read the first operand. 9333 uint32_t val1 = ReadCoreReg(Rn, &success); 9334 if (!success) 9335 return false; 9336 9337 uint32_t result = val1 ^ imm32; 9338 9339 EmulateInstruction::Context context; 9340 context.type = EmulateInstruction::eContextImmediate; 9341 context.SetNoArgs(); 9342 9343 if (!WriteFlags(context, result, carry)) 9344 return false; 9345 } 9346 return true; 9347} 9348 9349// Test Equivalence (register) performs a bitwise exclusive OR operation on a 9350// register value and an 9351// optionally-shifted register value. It updates the condition flags based on 9352// the result, and discards 9353// the result. 9354bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode, 9355 const ARMEncoding encoding) { 9356#if 0 9357 // ARM pseudo code... 9358 if ConditionPassed() then 9359 EncodingSpecificOperations(); 9360 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9361 result = R[n] EOR shifted; 9362 APSR.N = result<31>; 9363 APSR.Z = IsZeroBit(result); 9364 APSR.C = carry; 9365 // APSR.V unchanged 9366#endif 9367 9368 bool success = false; 9369 9370 if (ConditionPassed(opcode)) { 9371 uint32_t Rn, Rm; 9372 ARM_ShifterType shift_t; 9373 uint32_t shift_n; // the shift applied to the value read from Rm 9374 uint32_t carry; 9375 switch (encoding) { 9376 case eEncodingT1: 9377 Rn = Bits32(opcode, 19, 16); 9378 Rm = Bits32(opcode, 3, 0); 9379 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9380 if (BadReg(Rn) || BadReg(Rm)) 9381 return false; 9382 break; 9383 case eEncodingA1: 9384 Rn = Bits32(opcode, 19, 16); 9385 Rm = Bits32(opcode, 3, 0); 9386 shift_n = DecodeImmShiftARM(opcode, shift_t); 9387 break; 9388 default: 9389 return false; 9390 } 9391 9392 // Read the first operand. 9393 uint32_t val1 = ReadCoreReg(Rn, &success); 9394 if (!success) 9395 return false; 9396 9397 // Read the second operand. 9398 uint32_t val2 = ReadCoreReg(Rm, &success); 9399 if (!success) 9400 return false; 9401 9402 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9403 if (!success) 9404 return false; 9405 uint32_t result = val1 ^ shifted; 9406 9407 EmulateInstruction::Context context; 9408 context.type = EmulateInstruction::eContextImmediate; 9409 context.SetNoArgs(); 9410 9411 if (!WriteFlags(context, result, carry)) 9412 return false; 9413 } 9414 return true; 9415} 9416 9417// Test (immediate) performs a bitwise AND operation on a register value and an 9418// immediate value. 9419// It updates the condition flags based on the result, and discards the result. 9420bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode, 9421 const ARMEncoding encoding) { 9422#if 0 9423 // ARM pseudo code... 9424 if ConditionPassed() then 9425 EncodingSpecificOperations(); 9426 result = R[n] AND imm32; 9427 APSR.N = result<31>; 9428 APSR.Z = IsZeroBit(result); 9429 APSR.C = carry; 9430 // APSR.V unchanged 9431#endif 9432 9433 bool success = false; 9434 9435 if (ConditionPassed(opcode)) { 9436 uint32_t Rn; 9437 uint32_t 9438 imm32; // the immediate value to be ANDed to the value obtained from Rn 9439 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9440 switch (encoding) { 9441 case eEncodingT1: 9442 Rn = Bits32(opcode, 19, 16); 9443 imm32 = ThumbExpandImm_C( 9444 opcode, APSR_C, 9445 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9446 if (BadReg(Rn)) 9447 return false; 9448 break; 9449 case eEncodingA1: 9450 Rn = Bits32(opcode, 19, 16); 9451 imm32 = 9452 ARMExpandImm_C(opcode, APSR_C, 9453 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9454 break; 9455 default: 9456 return false; 9457 } 9458 9459 // Read the first operand. 9460 uint32_t val1 = ReadCoreReg(Rn, &success); 9461 if (!success) 9462 return false; 9463 9464 uint32_t result = val1 & imm32; 9465 9466 EmulateInstruction::Context context; 9467 context.type = EmulateInstruction::eContextImmediate; 9468 context.SetNoArgs(); 9469 9470 if (!WriteFlags(context, result, carry)) 9471 return false; 9472 } 9473 return true; 9474} 9475 9476// Test (register) performs a bitwise AND operation on a register value and an 9477// optionally-shifted register value. 9478// It updates the condition flags based on the result, and discards the result. 9479bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode, 9480 const ARMEncoding encoding) { 9481#if 0 9482 // ARM pseudo code... 9483 if ConditionPassed() then 9484 EncodingSpecificOperations(); 9485 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9486 result = R[n] AND shifted; 9487 APSR.N = result<31>; 9488 APSR.Z = IsZeroBit(result); 9489 APSR.C = carry; 9490 // APSR.V unchanged 9491#endif 9492 9493 bool success = false; 9494 9495 if (ConditionPassed(opcode)) { 9496 uint32_t Rn, Rm; 9497 ARM_ShifterType shift_t; 9498 uint32_t shift_n; // the shift applied to the value read from Rm 9499 uint32_t carry; 9500 switch (encoding) { 9501 case eEncodingT1: 9502 Rn = Bits32(opcode, 2, 0); 9503 Rm = Bits32(opcode, 5, 3); 9504 shift_t = SRType_LSL; 9505 shift_n = 0; 9506 break; 9507 case eEncodingT2: 9508 Rn = Bits32(opcode, 19, 16); 9509 Rm = Bits32(opcode, 3, 0); 9510 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9511 if (BadReg(Rn) || BadReg(Rm)) 9512 return false; 9513 break; 9514 case eEncodingA1: 9515 Rn = Bits32(opcode, 19, 16); 9516 Rm = Bits32(opcode, 3, 0); 9517 shift_n = DecodeImmShiftARM(opcode, shift_t); 9518 break; 9519 default: 9520 return false; 9521 } 9522 9523 // Read the first operand. 9524 uint32_t val1 = ReadCoreReg(Rn, &success); 9525 if (!success) 9526 return false; 9527 9528 // Read the second operand. 9529 uint32_t val2 = ReadCoreReg(Rm, &success); 9530 if (!success) 9531 return false; 9532 9533 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9534 if (!success) 9535 return false; 9536 uint32_t result = val1 & shifted; 9537 9538 EmulateInstruction::Context context; 9539 context.type = EmulateInstruction::eContextImmediate; 9540 context.SetNoArgs(); 9541 9542 if (!WriteFlags(context, result, carry)) 9543 return false; 9544 } 9545 return true; 9546} 9547 9548// A8.6.216 SUB (SP minus register) 9549bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode, 9550 const ARMEncoding encoding) { 9551#if 0 9552 if ConditionPassed() then 9553 EncodingSpecificOperations(); 9554 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9555 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 9556 if d == 15 then // Can only occur for ARM encoding 9557 ALUWritePC(result); // setflags is always FALSE here 9558 else 9559 R[d] = result; 9560 if setflags then 9561 APSR.N = result<31>; 9562 APSR.Z = IsZeroBit(result); 9563 APSR.C = carry; 9564 APSR.V = overflow; 9565#endif 9566 9567 bool success = false; 9568 9569 if (ConditionPassed(opcode)) { 9570 uint32_t d; 9571 uint32_t m; 9572 bool setflags; 9573 ARM_ShifterType shift_t; 9574 uint32_t shift_n; 9575 9576 switch (encoding) { 9577 case eEncodingT1: 9578 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 9579 d = Bits32(opcode, 11, 8); 9580 m = Bits32(opcode, 3, 0); 9581 setflags = BitIsSet(opcode, 20); 9582 9583 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9584 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9585 9586 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then 9587 // UNPREDICTABLE; 9588 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9589 return false; 9590 9591 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9592 if ((d == 15) || BadReg(m)) 9593 return false; 9594 break; 9595 9596 case eEncodingA1: 9597 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 9598 d = Bits32(opcode, 15, 12); 9599 m = Bits32(opcode, 3, 0); 9600 setflags = BitIsSet(opcode, 20); 9601 9602 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9603 // instructions; 9604 if (d == 15 && setflags) 9605 EmulateSUBSPcLrEtc(opcode, encoding); 9606 9607 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9608 shift_n = DecodeImmShiftARM(opcode, shift_t); 9609 break; 9610 9611 default: 9612 return false; 9613 } 9614 9615 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9616 uint32_t Rm = ReadCoreReg(m, &success); 9617 if (!success) 9618 return false; 9619 9620 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 9621 if (!success) 9622 return false; 9623 9624 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 9625 uint32_t sp_val = ReadCoreReg(SP_REG, &success); 9626 if (!success) 9627 return false; 9628 9629 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1); 9630 9631 EmulateInstruction::Context context; 9632 context.type = eContextArithmetic; 9633 RegisterInfo sp_reg; 9634 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 9635 RegisterInfo dwarf_reg; 9636 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9637 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg); 9638 9639 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 9640 res.carry_out, res.overflow)) 9641 return false; 9642 } 9643 return true; 9644} 9645 9646// A8.6.7 ADD (register-shifted register) 9647bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode, 9648 const ARMEncoding encoding) { 9649#if 0 9650 if ConditionPassed() then 9651 EncodingSpecificOperations(); 9652 shift_n = UInt(R[s]<7:0>); 9653 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9654 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 9655 R[d] = result; 9656 if setflags then 9657 APSR.N = result<31>; 9658 APSR.Z = IsZeroBit(result); 9659 APSR.C = carry; 9660 APSR.V = overflow; 9661#endif 9662 9663 bool success = false; 9664 9665 if (ConditionPassed(opcode)) { 9666 uint32_t d; 9667 uint32_t n; 9668 uint32_t m; 9669 uint32_t s; 9670 bool setflags; 9671 ARM_ShifterType shift_t; 9672 9673 switch (encoding) { 9674 case eEncodingA1: 9675 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9676 d = Bits32(opcode, 15, 12); 9677 n = Bits32(opcode, 19, 16); 9678 m = Bits32(opcode, 3, 0); 9679 s = Bits32(opcode, 11, 8); 9680 9681 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 9682 setflags = BitIsSet(opcode, 20); 9683 shift_t = DecodeRegShift(Bits32(opcode, 6, 5)); 9684 9685 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9686 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9687 return false; 9688 break; 9689 9690 default: 9691 return false; 9692 } 9693 9694 // shift_n = UInt(R[s]<7:0>); 9695 uint32_t Rs = ReadCoreReg(s, &success); 9696 if (!success) 9697 return false; 9698 9699 uint32_t shift_n = Bits32(Rs, 7, 0); 9700 9701 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9702 uint32_t Rm = ReadCoreReg(m, &success); 9703 if (!success) 9704 return false; 9705 9706 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 9707 if (!success) 9708 return false; 9709 9710 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 9711 uint32_t Rn = ReadCoreReg(n, &success); 9712 if (!success) 9713 return false; 9714 9715 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0); 9716 9717 // R[d] = result; 9718 EmulateInstruction::Context context; 9719 context.type = eContextArithmetic; 9720 RegisterInfo reg_n; 9721 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9722 RegisterInfo reg_m; 9723 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9724 9725 context.SetRegisterRegisterOperands(reg_n, reg_m); 9726 9727 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 9728 res.result)) 9729 return false; 9730 9731 // if setflags then 9732 // APSR.N = result<31>; 9733 // APSR.Z = IsZeroBit(result); 9734 // APSR.C = carry; 9735 // APSR.V = overflow; 9736 if (setflags) 9737 return WriteFlags(context, res.result, res.carry_out, res.overflow); 9738 } 9739 return true; 9740} 9741 9742// A8.6.213 SUB (register) 9743bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode, 9744 const ARMEncoding encoding) { 9745#if 0 9746 if ConditionPassed() then 9747 EncodingSpecificOperations(); 9748 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9749 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 9750 if d == 15 then // Can only occur for ARM encoding 9751 ALUWritePC(result); // setflags is always FALSE here 9752 else 9753 R[d] = result; 9754 if setflags then 9755 APSR.N = result<31>; 9756 APSR.Z = IsZeroBit(result); 9757 APSR.C = carry; 9758 APSR.V = overflow; 9759#endif 9760 9761 bool success = false; 9762 9763 if (ConditionPassed(opcode)) { 9764 uint32_t d; 9765 uint32_t n; 9766 uint32_t m; 9767 bool setflags; 9768 ARM_ShifterType shift_t; 9769 uint32_t shift_n; 9770 9771 switch (encoding) { 9772 case eEncodingT1: 9773 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9774 d = Bits32(opcode, 2, 0); 9775 n = Bits32(opcode, 5, 3); 9776 m = Bits32(opcode, 8, 6); 9777 setflags = !InITBlock(); 9778 9779 // (shift_t, shift_n) = (SRType_LSL, 0); 9780 shift_t = SRType_LSL; 9781 shift_n = 0; 9782 9783 break; 9784 9785 case eEncodingT2: 9786 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 9787 d = Bits32(opcode, 11, 8); 9788 n = Bits32(opcode, 19, 16); 9789 m = Bits32(opcode, 3, 0); 9790 setflags = BitIsSet(opcode, 20); 9791 9792 // if Rd == "1111" && S == "1" then SEE CMP (register); 9793 if (d == 15 && setflags == 1) 9794 return EmulateCMPImm(opcode, eEncodingT3); 9795 9796 // if Rn == "1101" then SEE SUB (SP minus register); 9797 if (n == 13) 9798 return EmulateSUBSPReg(opcode, eEncodingT1); 9799 9800 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9801 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9802 9803 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then 9804 // UNPREDICTABLE; 9805 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) || 9806 BadReg(m)) 9807 return false; 9808 9809 break; 9810 9811 case eEncodingA1: 9812 // if Rn == '1101' then SEE SUB (SP minus register); 9813 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 9814 d = Bits32(opcode, 15, 12); 9815 n = Bits32(opcode, 19, 16); 9816 m = Bits32(opcode, 3, 0); 9817 setflags = BitIsSet(opcode, 20); 9818 9819 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9820 // instructions; 9821 if ((d == 15) && setflags) 9822 EmulateSUBSPcLrEtc(opcode, encoding); 9823 9824 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9825 shift_n = DecodeImmShiftARM(opcode, shift_t); 9826 9827 break; 9828 9829 default: 9830 return false; 9831 } 9832 9833 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9834 uint32_t Rm = ReadCoreReg(m, &success); 9835 if (!success) 9836 return false; 9837 9838 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 9839 if (!success) 9840 return false; 9841 9842 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 9843 uint32_t Rn = ReadCoreReg(n, &success); 9844 if (!success) 9845 return false; 9846 9847 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1); 9848 9849 // if d == 15 then // Can only occur for ARM encoding 9850 // ALUWritePC(result); // setflags is always FALSE here 9851 // else 9852 // R[d] = result; 9853 // if setflags then 9854 // APSR.N = result<31>; 9855 // APSR.Z = IsZeroBit(result); 9856 // APSR.C = carry; 9857 // APSR.V = overflow; 9858 9859 EmulateInstruction::Context context; 9860 context.type = eContextArithmetic; 9861 RegisterInfo reg_n; 9862 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9863 RegisterInfo reg_m; 9864 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9865 context.SetRegisterRegisterOperands(reg_n, reg_m); 9866 9867 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 9868 res.carry_out, res.overflow)) 9869 return false; 9870 } 9871 return true; 9872} 9873 9874// A8.6.202 STREX 9875// Store Register Exclusive calculates an address from a base register value and 9876// an immediate offset, and stores a 9877// word from a register to memory if the executing processor has exclusive 9878// access to the memory addressed. 9879bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode, 9880 const ARMEncoding encoding) { 9881#if 0 9882 if ConditionPassed() then 9883 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9884 address = R[n] + imm32; 9885 if ExclusiveMonitorsPass(address,4) then 9886 MemA[address,4] = R[t]; 9887 R[d] = 0; 9888 else 9889 R[d] = 1; 9890#endif 9891 9892 bool success = false; 9893 9894 if (ConditionPassed(opcode)) { 9895 uint32_t d; 9896 uint32_t t; 9897 uint32_t n; 9898 uint32_t imm32; 9899 const uint32_t addr_byte_size = GetAddressByteSize(); 9900 9901 switch (encoding) { 9902 case eEncodingT1: 9903 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 9904 // 32); 9905 d = Bits32(opcode, 11, 8); 9906 t = Bits32(opcode, 15, 12); 9907 n = Bits32(opcode, 19, 16); 9908 imm32 = Bits32(opcode, 7, 0) << 2; 9909 9910 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9911 if (BadReg(d) || BadReg(t) || (n == 15)) 9912 return false; 9913 9914 // if d == n || d == t then UNPREDICTABLE; 9915 if ((d == n) || (d == t)) 9916 return false; 9917 9918 break; 9919 9920 case eEncodingA1: 9921 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero 9922 // offset 9923 d = Bits32(opcode, 15, 12); 9924 t = Bits32(opcode, 3, 0); 9925 n = Bits32(opcode, 19, 16); 9926 imm32 = 0; 9927 9928 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9929 if ((d == 15) || (t == 15) || (n == 15)) 9930 return false; 9931 9932 // if d == n || d == t then UNPREDICTABLE; 9933 if ((d == n) || (d == t)) 9934 return false; 9935 9936 break; 9937 9938 default: 9939 return false; 9940 } 9941 9942 // address = R[n] + imm32; 9943 uint32_t Rn = ReadCoreReg(n, &success); 9944 if (!success) 9945 return false; 9946 9947 addr_t address = Rn + imm32; 9948 9949 RegisterInfo base_reg; 9950 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9951 RegisterInfo data_reg; 9952 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9953 EmulateInstruction::Context context; 9954 context.type = eContextRegisterStore; 9955 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32); 9956 9957 // if ExclusiveMonitorsPass(address,4) then 9958 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the 9959 // sake of emulation, we will say this 9960 // always return 9961 // true. 9962 if (true) { 9963 // MemA[address,4] = R[t]; 9964 uint32_t Rt = 9965 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9966 if (!success) 9967 return false; 9968 9969 if (!MemAWrite(context, address, Rt, addr_byte_size)) 9970 return false; 9971 9972 // R[d] = 0; 9973 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9974 return false; 9975 } 9976#if 0 // unreachable because if true 9977 else 9978 { 9979 // R[d] = 1; 9980 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9981 return false; 9982 } 9983#endif // unreachable because if true 9984 } 9985 return true; 9986} 9987 9988// A8.6.197 STRB (immediate, ARM) 9989bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode, 9990 const ARMEncoding encoding) { 9991#if 0 9992 if ConditionPassed() then 9993 EncodingSpecificOperations(); 9994 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9995 address = if index then offset_addr else R[n]; 9996 MemU[address,1] = R[t]<7:0>; 9997 if wback then R[n] = offset_addr; 9998#endif 9999 10000 bool success = false; 10001 10002 if (ConditionPassed(opcode)) { 10003 uint32_t t; 10004 uint32_t n; 10005 uint32_t imm32; 10006 bool index; 10007 bool add; 10008 bool wback; 10009 10010 switch (encoding) { 10011 case eEncodingA1: 10012 // if P == '0' && W == '1' then SEE STRBT; 10013 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10014 t = Bits32(opcode, 15, 12); 10015 n = Bits32(opcode, 19, 16); 10016 imm32 = Bits32(opcode, 11, 0); 10017 10018 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10019 index = BitIsSet(opcode, 24); 10020 add = BitIsSet(opcode, 23); 10021 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10022 10023 // if t == 15 then UNPREDICTABLE; 10024 if (t == 15) 10025 return false; 10026 10027 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10028 if (wback && ((n == 15) || (n == t))) 10029 return false; 10030 10031 break; 10032 10033 default: 10034 return false; 10035 } 10036 10037 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10038 uint32_t Rn = ReadCoreReg(n, &success); 10039 if (!success) 10040 return false; 10041 10042 addr_t offset_addr; 10043 if (add) 10044 offset_addr = Rn + imm32; 10045 else 10046 offset_addr = Rn - imm32; 10047 10048 // address = if index then offset_addr else R[n]; 10049 addr_t address; 10050 if (index) 10051 address = offset_addr; 10052 else 10053 address = Rn; 10054 10055 // MemU[address,1] = R[t]<7:0>; 10056 uint32_t Rt = ReadCoreReg(t, &success); 10057 if (!success) 10058 return false; 10059 10060 RegisterInfo base_reg; 10061 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10062 RegisterInfo data_reg; 10063 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10064 EmulateInstruction::Context context; 10065 context.type = eContextRegisterStore; 10066 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10067 10068 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1)) 10069 return false; 10070 10071 // if wback then R[n] = offset_addr; 10072 if (wback) { 10073 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10074 offset_addr)) 10075 return false; 10076 } 10077 } 10078 return true; 10079} 10080 10081// A8.6.194 STR (immediate, ARM) 10082bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode, 10083 const ARMEncoding encoding) { 10084#if 0 10085 if ConditionPassed() then 10086 EncodingSpecificOperations(); 10087 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10088 address = if index then offset_addr else R[n]; 10089 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10090 if wback then R[n] = offset_addr; 10091#endif 10092 10093 bool success = false; 10094 10095 if (ConditionPassed(opcode)) { 10096 uint32_t t; 10097 uint32_t n; 10098 uint32_t imm32; 10099 bool index; 10100 bool add; 10101 bool wback; 10102 10103 const uint32_t addr_byte_size = GetAddressByteSize(); 10104 10105 switch (encoding) { 10106 case eEncodingA1: 10107 // if P == '0' && W == '1' then SEE STRT; 10108 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == 10109 // '000000000100' then SEE PUSH; 10110 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10111 t = Bits32(opcode, 15, 12); 10112 n = Bits32(opcode, 19, 16); 10113 imm32 = Bits32(opcode, 11, 0); 10114 10115 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10116 index = BitIsSet(opcode, 24); 10117 add = BitIsSet(opcode, 23); 10118 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10119 10120 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10121 if (wback && ((n == 15) || (n == t))) 10122 return false; 10123 10124 break; 10125 10126 default: 10127 return false; 10128 } 10129 10130 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10131 uint32_t Rn = ReadCoreReg(n, &success); 10132 if (!success) 10133 return false; 10134 10135 addr_t offset_addr; 10136 if (add) 10137 offset_addr = Rn + imm32; 10138 else 10139 offset_addr = Rn - imm32; 10140 10141 // address = if index then offset_addr else R[n]; 10142 addr_t address; 10143 if (index) 10144 address = offset_addr; 10145 else 10146 address = Rn; 10147 10148 RegisterInfo base_reg; 10149 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10150 RegisterInfo data_reg; 10151 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10152 EmulateInstruction::Context context; 10153 context.type = eContextRegisterStore; 10154 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10155 10156 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10157 uint32_t Rt = ReadCoreReg(t, &success); 10158 if (!success) 10159 return false; 10160 10161 if (t == 15) { 10162 uint32_t pc_value = ReadCoreReg(PC_REG, &success); 10163 if (!success) 10164 return false; 10165 10166 if (!MemUWrite(context, address, pc_value, addr_byte_size)) 10167 return false; 10168 } else { 10169 if (!MemUWrite(context, address, Rt, addr_byte_size)) 10170 return false; 10171 } 10172 10173 // if wback then R[n] = offset_addr; 10174 if (wback) { 10175 context.type = eContextAdjustBaseRegister; 10176 context.SetImmediate(offset_addr); 10177 10178 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10179 offset_addr)) 10180 return false; 10181 } 10182 } 10183 return true; 10184} 10185 10186// A8.6.66 LDRD (immediate) 10187// Load Register Dual (immediate) calculates an address from a base register 10188// value and an immediate offset, loads two 10189// words from memory, and writes them to two registers. It can use offset, 10190// post-indexed, or pre-indexed addressing. 10191bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode, 10192 const ARMEncoding encoding) { 10193#if 0 10194 if ConditionPassed() then 10195 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10196 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10197 address = if index then offset_addr else R[n]; 10198 R[t] = MemA[address,4]; 10199 R[t2] = MemA[address+4,4]; 10200 if wback then R[n] = offset_addr; 10201#endif 10202 10203 bool success = false; 10204 10205 if (ConditionPassed(opcode)) { 10206 uint32_t t; 10207 uint32_t t2; 10208 uint32_t n; 10209 uint32_t imm32; 10210 bool index; 10211 bool add; 10212 bool wback; 10213 10214 switch (encoding) { 10215 case eEncodingT1: 10216 // if P == '0' && W == '0' then SEE 'Related encodings'; 10217 // if Rn == '1111' then SEE LDRD (literal); 10218 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10219 // ZeroExtend(imm8:'00', 32); 10220 t = Bits32(opcode, 15, 12); 10221 t2 = Bits32(opcode, 11, 8); 10222 n = Bits32(opcode, 19, 16); 10223 imm32 = Bits32(opcode, 7, 0) << 2; 10224 10225 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10226 index = BitIsSet(opcode, 24); 10227 add = BitIsSet(opcode, 23); 10228 wback = BitIsSet(opcode, 21); 10229 10230 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10231 if (wback && ((n == t) || (n == t2))) 10232 return false; 10233 10234 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10235 if (BadReg(t) || BadReg(t2) || (t == t2)) 10236 return false; 10237 10238 break; 10239 10240 case eEncodingA1: 10241 // if Rn == '1111' then SEE LDRD (literal); 10242 // if Rt<0> == '1' then UNPREDICTABLE; 10243 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10244 // 32); 10245 t = Bits32(opcode, 15, 12); 10246 if (BitIsSet(t, 0)) 10247 return false; 10248 t2 = t + 1; 10249 n = Bits32(opcode, 19, 16); 10250 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10251 10252 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10253 index = BitIsSet(opcode, 24); 10254 add = BitIsSet(opcode, 23); 10255 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10256 10257 // if P == '0' && W == '1' then UNPREDICTABLE; 10258 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10259 return false; 10260 10261 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10262 if (wback && ((n == t) || (n == t2))) 10263 return false; 10264 10265 // if t2 == 15 then UNPREDICTABLE; 10266 if (t2 == 15) 10267 return false; 10268 10269 break; 10270 10271 default: 10272 return false; 10273 } 10274 10275 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10276 uint32_t Rn = ReadCoreReg(n, &success); 10277 if (!success) 10278 return false; 10279 10280 addr_t offset_addr; 10281 if (add) 10282 offset_addr = Rn + imm32; 10283 else 10284 offset_addr = Rn - imm32; 10285 10286 // address = if index then offset_addr else R[n]; 10287 addr_t address; 10288 if (index) 10289 address = offset_addr; 10290 else 10291 address = Rn; 10292 10293 // R[t] = MemA[address,4]; 10294 RegisterInfo base_reg; 10295 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10296 10297 EmulateInstruction::Context context; 10298 if (n == 13) 10299 context.type = eContextPopRegisterOffStack; 10300 else 10301 context.type = eContextRegisterLoad; 10302 context.SetAddress(address); 10303 10304 const uint32_t addr_byte_size = GetAddressByteSize(); 10305 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10306 if (!success) 10307 return false; 10308 10309 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10310 return false; 10311 10312 // R[t2] = MemA[address+4,4]; 10313 context.SetAddress(address + 4); 10314 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10315 if (!success) 10316 return false; 10317 10318 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10319 data)) 10320 return false; 10321 10322 // if wback then R[n] = offset_addr; 10323 if (wback) { 10324 context.type = eContextAdjustBaseRegister; 10325 context.SetAddress(offset_addr); 10326 10327 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10328 offset_addr)) 10329 return false; 10330 } 10331 } 10332 return true; 10333} 10334 10335// A8.6.68 LDRD (register) 10336// Load Register Dual (register) calculates an address from a base register 10337// value and a register offset, loads two 10338// words from memory, and writes them to two registers. It can use offset, 10339// post-indexed or pre-indexed addressing. 10340bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode, 10341 const ARMEncoding encoding) { 10342#if 0 10343 if ConditionPassed() then 10344 EncodingSpecificOperations(); 10345 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10346 address = if index then offset_addr else R[n]; 10347 R[t] = MemA[address,4]; 10348 R[t2] = MemA[address+4,4]; 10349 if wback then R[n] = offset_addr; 10350#endif 10351 10352 bool success = false; 10353 10354 if (ConditionPassed(opcode)) { 10355 uint32_t t; 10356 uint32_t t2; 10357 uint32_t n; 10358 uint32_t m; 10359 bool index; 10360 bool add; 10361 bool wback; 10362 10363 switch (encoding) { 10364 case eEncodingA1: 10365 // if Rt<0> == '1' then UNPREDICTABLE; 10366 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10367 t = Bits32(opcode, 15, 12); 10368 if (BitIsSet(t, 0)) 10369 return false; 10370 t2 = t + 1; 10371 n = Bits32(opcode, 19, 16); 10372 m = Bits32(opcode, 3, 0); 10373 10374 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10375 index = BitIsSet(opcode, 24); 10376 add = BitIsSet(opcode, 23); 10377 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10378 10379 // if P == '0' && W == '1' then UNPREDICTABLE; 10380 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10381 return false; 10382 10383 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10384 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10385 return false; 10386 10387 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10388 if (wback && ((n == 15) || (n == t) || (n == t2))) 10389 return false; 10390 10391 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10392 if ((ArchVersion() < 6) && wback && (m == n)) 10393 return false; 10394 break; 10395 10396 default: 10397 return false; 10398 } 10399 10400 uint32_t Rn = ReadCoreReg(n, &success); 10401 if (!success) 10402 return false; 10403 RegisterInfo base_reg; 10404 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10405 10406 uint32_t Rm = ReadCoreReg(m, &success); 10407 if (!success) 10408 return false; 10409 RegisterInfo offset_reg; 10410 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10411 10412 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10413 addr_t offset_addr; 10414 if (add) 10415 offset_addr = Rn + Rm; 10416 else 10417 offset_addr = Rn - Rm; 10418 10419 // address = if index then offset_addr else R[n]; 10420 addr_t address; 10421 if (index) 10422 address = offset_addr; 10423 else 10424 address = Rn; 10425 10426 EmulateInstruction::Context context; 10427 if (n == 13) 10428 context.type = eContextPopRegisterOffStack; 10429 else 10430 context.type = eContextRegisterLoad; 10431 context.SetAddress(address); 10432 10433 // R[t] = MemA[address,4]; 10434 const uint32_t addr_byte_size = GetAddressByteSize(); 10435 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10436 if (!success) 10437 return false; 10438 10439 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10440 return false; 10441 10442 // R[t2] = MemA[address+4,4]; 10443 10444 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10445 if (!success) 10446 return false; 10447 10448 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10449 data)) 10450 return false; 10451 10452 // if wback then R[n] = offset_addr; 10453 if (wback) { 10454 context.type = eContextAdjustBaseRegister; 10455 context.SetAddress(offset_addr); 10456 10457 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10458 offset_addr)) 10459 return false; 10460 } 10461 } 10462 return true; 10463} 10464 10465// A8.6.200 STRD (immediate) 10466// Store Register Dual (immediate) calculates an address from a base register 10467// value and an immediate offset, and 10468// stores two words from two registers to memory. It can use offset, 10469// post-indexed, or pre-indexed addressing. 10470bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode, 10471 const ARMEncoding encoding) { 10472#if 0 10473 if ConditionPassed() then 10474 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10475 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10476 address = if index then offset_addr else R[n]; 10477 MemA[address,4] = R[t]; 10478 MemA[address+4,4] = R[t2]; 10479 if wback then R[n] = offset_addr; 10480#endif 10481 10482 bool success = false; 10483 10484 if (ConditionPassed(opcode)) { 10485 uint32_t t; 10486 uint32_t t2; 10487 uint32_t n; 10488 uint32_t imm32; 10489 bool index; 10490 bool add; 10491 bool wback; 10492 10493 switch (encoding) { 10494 case eEncodingT1: 10495 // if P == '0' && W == '0' then SEE 'Related encodings'; 10496 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10497 // ZeroExtend(imm8:'00', 32); 10498 t = Bits32(opcode, 15, 12); 10499 t2 = Bits32(opcode, 11, 8); 10500 n = Bits32(opcode, 19, 16); 10501 imm32 = Bits32(opcode, 7, 0) << 2; 10502 10503 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10504 index = BitIsSet(opcode, 24); 10505 add = BitIsSet(opcode, 23); 10506 wback = BitIsSet(opcode, 21); 10507 10508 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10509 if (wback && ((n == t) || (n == t2))) 10510 return false; 10511 10512 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10513 if ((n == 15) || BadReg(t) || BadReg(t2)) 10514 return false; 10515 10516 break; 10517 10518 case eEncodingA1: 10519 // if Rt<0> == '1' then UNPREDICTABLE; 10520 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10521 // 32); 10522 t = Bits32(opcode, 15, 12); 10523 if (BitIsSet(t, 0)) 10524 return false; 10525 10526 t2 = t + 1; 10527 n = Bits32(opcode, 19, 16); 10528 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10529 10530 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10531 index = BitIsSet(opcode, 24); 10532 add = BitIsSet(opcode, 23); 10533 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10534 10535 // if P == '0' && W == '1' then UNPREDICTABLE; 10536 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10537 return false; 10538 10539 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10540 if (wback && ((n == 15) || (n == t) || (n == t2))) 10541 return false; 10542 10543 // if t2 == 15 then UNPREDICTABLE; 10544 if (t2 == 15) 10545 return false; 10546 10547 break; 10548 10549 default: 10550 return false; 10551 } 10552 10553 RegisterInfo base_reg; 10554 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10555 10556 uint32_t Rn = ReadCoreReg(n, &success); 10557 if (!success) 10558 return false; 10559 10560 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10561 addr_t offset_addr; 10562 if (add) 10563 offset_addr = Rn + imm32; 10564 else 10565 offset_addr = Rn - imm32; 10566 10567 // address = if index then offset_addr else R[n]; 10568 addr_t address; 10569 if (index) 10570 address = offset_addr; 10571 else 10572 address = Rn; 10573 10574 // MemA[address,4] = R[t]; 10575 RegisterInfo data_reg; 10576 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10577 10578 uint32_t data = ReadCoreReg(t, &success); 10579 if (!success) 10580 return false; 10581 10582 EmulateInstruction::Context context; 10583 if (n == 13) 10584 context.type = eContextPushRegisterOnStack; 10585 else 10586 context.type = eContextRegisterStore; 10587 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10588 10589 const uint32_t addr_byte_size = GetAddressByteSize(); 10590 10591 if (!MemAWrite(context, address, data, addr_byte_size)) 10592 return false; 10593 10594 // MemA[address+4,4] = R[t2]; 10595 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10596 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 10597 (address + 4) - Rn); 10598 10599 data = ReadCoreReg(t2, &success); 10600 if (!success) 10601 return false; 10602 10603 if (!MemAWrite(context, address + 4, data, addr_byte_size)) 10604 return false; 10605 10606 // if wback then R[n] = offset_addr; 10607 if (wback) { 10608 if (n == 13) 10609 context.type = eContextAdjustStackPointer; 10610 else 10611 context.type = eContextAdjustBaseRegister; 10612 context.SetAddress(offset_addr); 10613 10614 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10615 offset_addr)) 10616 return false; 10617 } 10618 } 10619 return true; 10620} 10621 10622// A8.6.201 STRD (register) 10623bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode, 10624 const ARMEncoding encoding) { 10625#if 0 10626 if ConditionPassed() then 10627 EncodingSpecificOperations(); 10628 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10629 address = if index then offset_addr else R[n]; 10630 MemA[address,4] = R[t]; 10631 MemA[address+4,4] = R[t2]; 10632 if wback then R[n] = offset_addr; 10633#endif 10634 10635 bool success = false; 10636 10637 if (ConditionPassed(opcode)) { 10638 uint32_t t; 10639 uint32_t t2; 10640 uint32_t n; 10641 uint32_t m; 10642 bool index; 10643 bool add; 10644 bool wback; 10645 10646 switch (encoding) { 10647 case eEncodingA1: 10648 // if Rt<0> == '1' then UNPREDICTABLE; 10649 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10650 t = Bits32(opcode, 15, 12); 10651 if (BitIsSet(t, 0)) 10652 return false; 10653 10654 t2 = t + 1; 10655 n = Bits32(opcode, 19, 16); 10656 m = Bits32(opcode, 3, 0); 10657 10658 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10659 index = BitIsSet(opcode, 24); 10660 add = BitIsSet(opcode, 23); 10661 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10662 10663 // if P == '0' && W == '1' then UNPREDICTABLE; 10664 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10665 return false; 10666 10667 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10668 if ((t2 == 15) || (m == 15)) 10669 return false; 10670 10671 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10672 if (wback && ((n == 15) || (n == t) || (n == t2))) 10673 return false; 10674 10675 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10676 if ((ArchVersion() < 6) && wback && (m == n)) 10677 return false; 10678 10679 break; 10680 10681 default: 10682 return false; 10683 } 10684 10685 RegisterInfo base_reg; 10686 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10687 RegisterInfo offset_reg; 10688 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10689 RegisterInfo data_reg; 10690 10691 uint32_t Rn = ReadCoreReg(n, &success); 10692 if (!success) 10693 return false; 10694 10695 uint32_t Rm = ReadCoreReg(m, &success); 10696 if (!success) 10697 return false; 10698 10699 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10700 addr_t offset_addr; 10701 if (add) 10702 offset_addr = Rn + Rm; 10703 else 10704 offset_addr = Rn - Rm; 10705 10706 // address = if index then offset_addr else R[n]; 10707 addr_t address; 10708 if (index) 10709 address = offset_addr; 10710 else 10711 address = Rn; 10712 // MemA[address,4] = R[t]; 10713 uint32_t Rt = ReadCoreReg(t, &success); 10714 if (!success) 10715 return false; 10716 10717 EmulateInstruction::Context context; 10718 if (t == 13) 10719 context.type = eContextPushRegisterOnStack; 10720 else 10721 context.type = eContextRegisterStore; 10722 10723 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10724 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 10725 data_reg); 10726 10727 const uint32_t addr_byte_size = GetAddressByteSize(); 10728 10729 if (!MemAWrite(context, address, Rt, addr_byte_size)) 10730 return false; 10731 10732 // MemA[address+4,4] = R[t2]; 10733 uint32_t Rt2 = ReadCoreReg(t2, &success); 10734 if (!success) 10735 return false; 10736 10737 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10738 10739 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 10740 data_reg); 10741 10742 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size)) 10743 return false; 10744 10745 // if wback then R[n] = offset_addr; 10746 if (wback) { 10747 context.type = eContextAdjustBaseRegister; 10748 context.SetAddress(offset_addr); 10749 10750 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10751 offset_addr)) 10752 return false; 10753 } 10754 } 10755 return true; 10756} 10757 10758// A8.6.319 VLDM 10759// Vector Load Multiple loads multiple extension registers from consecutive 10760// memory locations using an address from 10761// an ARM core register. 10762bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode, 10763 const ARMEncoding encoding) { 10764#if 0 10765 if ConditionPassed() then 10766 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10767 address = if add then R[n] else R[n]-imm32; 10768 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10769 for r = 0 to regs-1 10770 if single_regs then 10771 S[d+r] = MemA[address,4]; address = address+4; 10772 else 10773 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10774 // Combine the word-aligned words in the correct order for current endianness. 10775 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10776#endif 10777 10778 bool success = false; 10779 10780 if (ConditionPassed(opcode)) { 10781 bool single_regs; 10782 bool add; 10783 bool wback; 10784 uint32_t d; 10785 uint32_t n; 10786 uint32_t imm32; 10787 uint32_t regs; 10788 10789 switch (encoding) { 10790 case eEncodingT1: 10791 case eEncodingA1: 10792 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10793 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 10794 // if P == '1' && W == '0' then SEE VLDR; 10795 // if P == U && W == '1' then UNDEFINED; 10796 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 10797 return false; 10798 10799 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 10800 // !), 101 (DB with !) 10801 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 10802 single_regs = false; 10803 add = BitIsSet(opcode, 23); 10804 wback = BitIsSet(opcode, 21); 10805 10806 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10807 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 10808 n = Bits32(opcode, 19, 16); 10809 imm32 = Bits32(opcode, 7, 0) << 2; 10810 10811 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 10812 regs = Bits32(opcode, 7, 0) / 2; 10813 10814 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 10815 // UNPREDICTABLE; 10816 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10817 return false; 10818 10819 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10820 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10821 return false; 10822 10823 break; 10824 10825 case eEncodingT2: 10826 case eEncodingA2: 10827 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10828 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 10829 // if P == '1' && W == '0' then SEE VLDR; 10830 // if P == U && W == '1' then UNDEFINED; 10831 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 10832 return false; 10833 10834 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 10835 // !), 101 (DB with !) 10836 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = 10837 // UInt(Vd:D); n = UInt(Rn); 10838 single_regs = true; 10839 add = BitIsSet(opcode, 23); 10840 wback = BitIsSet(opcode, 21); 10841 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 10842 n = Bits32(opcode, 19, 16); 10843 10844 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 10845 imm32 = Bits32(opcode, 7, 0) << 2; 10846 regs = Bits32(opcode, 7, 0); 10847 10848 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 10849 // UNPREDICTABLE; 10850 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10851 return false; 10852 10853 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10854 if ((regs == 0) || ((d + regs) > 32)) 10855 return false; 10856 break; 10857 10858 default: 10859 return false; 10860 } 10861 10862 RegisterInfo base_reg; 10863 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10864 10865 uint32_t Rn = ReadCoreReg(n, &success); 10866 if (!success) 10867 return false; 10868 10869 // address = if add then R[n] else R[n]-imm32; 10870 addr_t address; 10871 if (add) 10872 address = Rn; 10873 else 10874 address = Rn - imm32; 10875 10876 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10877 EmulateInstruction::Context context; 10878 10879 if (wback) { 10880 uint32_t value; 10881 if (add) 10882 value = Rn + imm32; 10883 else 10884 value = Rn - imm32; 10885 10886 context.type = eContextAdjustBaseRegister; 10887 context.SetImmediateSigned(value - Rn); 10888 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10889 value)) 10890 return false; 10891 } 10892 10893 const uint32_t addr_byte_size = GetAddressByteSize(); 10894 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10895 10896 context.type = eContextRegisterLoad; 10897 10898 // for r = 0 to regs-1 10899 for (uint32_t r = 0; r < regs; ++r) { 10900 if (single_regs) { 10901 // S[d+r] = MemA[address,4]; address = address+4; 10902 context.SetRegisterPlusOffset(base_reg, address - Rn); 10903 10904 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10905 if (!success) 10906 return false; 10907 10908 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 10909 start_reg + d + r, data)) 10910 return false; 10911 10912 address = address + 4; 10913 } else { 10914 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = 10915 // address+8; 10916 context.SetRegisterPlusOffset(base_reg, address - Rn); 10917 uint32_t word1 = 10918 MemARead(context, address, addr_byte_size, 0, &success); 10919 if (!success) 10920 return false; 10921 10922 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn); 10923 uint32_t word2 = 10924 MemARead(context, address + 4, addr_byte_size, 0, &success); 10925 if (!success) 10926 return false; 10927 10928 address = address + 8; 10929 // // Combine the word-aligned words in the correct order for current 10930 // endianness. 10931 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10932 uint64_t data; 10933 if (GetByteOrder() == eByteOrderBig) { 10934 data = word1; 10935 data = (data << 32) | word2; 10936 } else { 10937 data = word2; 10938 data = (data << 32) | word1; 10939 } 10940 10941 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 10942 start_reg + d + r, data)) 10943 return false; 10944 } 10945 } 10946 } 10947 return true; 10948} 10949 10950// A8.6.399 VSTM 10951// Vector Store Multiple stores multiple extension registers to consecutive 10952// memory locations using an address from an 10953// ARM core register. 10954bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode, 10955 const ARMEncoding encoding) { 10956#if 0 10957 if ConditionPassed() then 10958 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10959 address = if add then R[n] else R[n]-imm32; 10960 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10961 for r = 0 to regs-1 10962 if single_regs then 10963 MemA[address,4] = S[d+r]; address = address+4; 10964 else 10965 // Store as two word-aligned words in the correct order for current endianness. 10966 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10967 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10968 address = address+8; 10969#endif 10970 10971 bool success = false; 10972 10973 if (ConditionPassed(opcode)) { 10974 bool single_regs; 10975 bool add; 10976 bool wback; 10977 uint32_t d; 10978 uint32_t n; 10979 uint32_t imm32; 10980 uint32_t regs; 10981 10982 switch (encoding) { 10983 case eEncodingT1: 10984 case eEncodingA1: 10985 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10986 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 10987 // if P == '1' && W == '0' then SEE VSTR; 10988 // if P == U && W == '1' then UNDEFINED; 10989 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 10990 return false; 10991 10992 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 10993 // !), 101 (DB with !) 10994 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 10995 single_regs = false; 10996 add = BitIsSet(opcode, 23); 10997 wback = BitIsSet(opcode, 21); 10998 10999 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11000 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11001 n = Bits32(opcode, 19, 16); 11002 imm32 = Bits32(opcode, 7, 0) << 2; 11003 11004 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11005 regs = Bits32(opcode, 7, 0) / 2; 11006 11007 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11008 // UNPREDICTABLE; 11009 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11010 return false; 11011 11012 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11013 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11014 return false; 11015 11016 break; 11017 11018 case eEncodingT2: 11019 case eEncodingA2: 11020 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11021 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11022 // if P == '1' && W == '0' then SEE VSTR; 11023 // if P == U && W == '1' then UNDEFINED; 11024 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11025 return false; 11026 11027 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11028 // !), 101 (DB with !) 11029 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = 11030 // UInt(Vd:D); n = UInt(Rn); 11031 single_regs = true; 11032 add = BitIsSet(opcode, 23); 11033 wback = BitIsSet(opcode, 21); 11034 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11035 n = Bits32(opcode, 19, 16); 11036 11037 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11038 imm32 = Bits32(opcode, 7, 0) << 2; 11039 regs = Bits32(opcode, 7, 0); 11040 11041 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11042 // UNPREDICTABLE; 11043 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11044 return false; 11045 11046 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11047 if ((regs == 0) || ((d + regs) > 32)) 11048 return false; 11049 11050 break; 11051 11052 default: 11053 return false; 11054 } 11055 11056 RegisterInfo base_reg; 11057 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11058 11059 uint32_t Rn = ReadCoreReg(n, &success); 11060 if (!success) 11061 return false; 11062 11063 // address = if add then R[n] else R[n]-imm32; 11064 addr_t address; 11065 if (add) 11066 address = Rn; 11067 else 11068 address = Rn - imm32; 11069 11070 EmulateInstruction::Context context; 11071 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11072 if (wback) { 11073 uint32_t value; 11074 if (add) 11075 value = Rn + imm32; 11076 else 11077 value = Rn - imm32; 11078 11079 context.type = eContextAdjustBaseRegister; 11080 context.SetRegisterPlusOffset(base_reg, value - Rn); 11081 11082 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11083 value)) 11084 return false; 11085 } 11086 11087 const uint32_t addr_byte_size = GetAddressByteSize(); 11088 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11089 11090 context.type = eContextRegisterStore; 11091 // for r = 0 to regs-1 11092 for (uint32_t r = 0; r < regs; ++r) { 11093 11094 if (single_regs) { 11095 // MemA[address,4] = S[d+r]; address = address+4; 11096 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11097 start_reg + d + r, 0, &success); 11098 if (!success) 11099 return false; 11100 11101 RegisterInfo data_reg; 11102 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11103 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11104 address - Rn); 11105 if (!MemAWrite(context, address, data, addr_byte_size)) 11106 return false; 11107 11108 address = address + 4; 11109 } else { 11110 // // Store as two word-aligned words in the correct order for current 11111 // endianness. 11112 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else 11113 // D[d+r]<31:0>; 11114 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else 11115 // D[d+r]<63:32>; 11116 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11117 start_reg + d + r, 0, &success); 11118 if (!success) 11119 return false; 11120 11121 RegisterInfo data_reg; 11122 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11123 11124 if (GetByteOrder() == eByteOrderBig) { 11125 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11126 address - Rn); 11127 if (!MemAWrite(context, address, Bits64(data, 63, 32), 11128 addr_byte_size)) 11129 return false; 11130 11131 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11132 (address + 4) - Rn); 11133 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11134 addr_byte_size)) 11135 return false; 11136 } else { 11137 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11138 address - Rn); 11139 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11140 return false; 11141 11142 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11143 (address + 4) - Rn); 11144 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11145 addr_byte_size)) 11146 return false; 11147 } 11148 // address = address+8; 11149 address = address + 8; 11150 } 11151 } 11152 } 11153 return true; 11154} 11155 11156// A8.6.320 11157// This instruction loads a single extension register from memory, using an 11158// address from an ARM core register, with 11159// an optional offset. 11160bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode, 11161 ARMEncoding encoding) { 11162#if 0 11163 if ConditionPassed() then 11164 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11165 base = if n == 15 then Align(PC,4) else R[n]; 11166 address = if add then (base + imm32) else (base - imm32); 11167 if single_reg then 11168 S[d] = MemA[address,4]; 11169 else 11170 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11171 // Combine the word-aligned words in the correct order for current endianness. 11172 D[d] = if BigEndian() then word1:word2 else word2:word1; 11173#endif 11174 11175 bool success = false; 11176 11177 if (ConditionPassed(opcode)) { 11178 bool single_reg; 11179 bool add; 11180 uint32_t imm32; 11181 uint32_t d; 11182 uint32_t n; 11183 11184 switch (encoding) { 11185 case eEncodingT1: 11186 case eEncodingA1: 11187 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11188 // 32); 11189 single_reg = false; 11190 add = BitIsSet(opcode, 23); 11191 imm32 = Bits32(opcode, 7, 0) << 2; 11192 11193 // d = UInt(D:Vd); n = UInt(Rn); 11194 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11195 n = Bits32(opcode, 19, 16); 11196 11197 break; 11198 11199 case eEncodingT2: 11200 case eEncodingA2: 11201 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11202 single_reg = true; 11203 add = BitIsSet(opcode, 23); 11204 imm32 = Bits32(opcode, 7, 0) << 2; 11205 11206 // d = UInt(Vd:D); n = UInt(Rn); 11207 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11208 n = Bits32(opcode, 19, 16); 11209 11210 break; 11211 11212 default: 11213 return false; 11214 } 11215 RegisterInfo base_reg; 11216 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11217 11218 uint32_t Rn = ReadCoreReg(n, &success); 11219 if (!success) 11220 return false; 11221 11222 // base = if n == 15 then Align(PC,4) else R[n]; 11223 uint32_t base; 11224 if (n == 15) 11225 base = AlignPC(Rn); 11226 else 11227 base = Rn; 11228 11229 // address = if add then (base + imm32) else (base - imm32); 11230 addr_t address; 11231 if (add) 11232 address = base + imm32; 11233 else 11234 address = base - imm32; 11235 11236 const uint32_t addr_byte_size = GetAddressByteSize(); 11237 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11238 11239 EmulateInstruction::Context context; 11240 context.type = eContextRegisterLoad; 11241 context.SetRegisterPlusOffset(base_reg, address - base); 11242 11243 if (single_reg) { 11244 // S[d] = MemA[address,4]; 11245 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11246 if (!success) 11247 return false; 11248 11249 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11250 data)) 11251 return false; 11252 } else { 11253 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11254 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success); 11255 if (!success) 11256 return false; 11257 11258 context.SetRegisterPlusOffset(base_reg, (address + 4) - base); 11259 uint32_t word2 = 11260 MemARead(context, address + 4, addr_byte_size, 0, &success); 11261 if (!success) 11262 return false; 11263 // // Combine the word-aligned words in the correct order for current 11264 // endianness. 11265 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11266 uint64_t data64; 11267 if (GetByteOrder() == eByteOrderBig) { 11268 data64 = word1; 11269 data64 = (data64 << 32) | word2; 11270 } else { 11271 data64 = word2; 11272 data64 = (data64 << 32) | word1; 11273 } 11274 11275 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11276 data64)) 11277 return false; 11278 } 11279 } 11280 return true; 11281} 11282 11283// A8.6.400 VSTR 11284// This instruction stores a signle extension register to memory, using an 11285// address from an ARM core register, with an 11286// optional offset. 11287bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode, 11288 ARMEncoding encoding) { 11289#if 0 11290 if ConditionPassed() then 11291 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11292 address = if add then (R[n] + imm32) else (R[n] - imm32); 11293 if single_reg then 11294 MemA[address,4] = S[d]; 11295 else 11296 // Store as two word-aligned words in the correct order for current endianness. 11297 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11298 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11299#endif 11300 11301 bool success = false; 11302 11303 if (ConditionPassed(opcode)) { 11304 bool single_reg; 11305 bool add; 11306 uint32_t imm32; 11307 uint32_t d; 11308 uint32_t n; 11309 11310 switch (encoding) { 11311 case eEncodingT1: 11312 case eEncodingA1: 11313 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11314 // 32); 11315 single_reg = false; 11316 add = BitIsSet(opcode, 23); 11317 imm32 = Bits32(opcode, 7, 0) << 2; 11318 11319 // d = UInt(D:Vd); n = UInt(Rn); 11320 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11321 n = Bits32(opcode, 19, 16); 11322 11323 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11324 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11325 return false; 11326 11327 break; 11328 11329 case eEncodingT2: 11330 case eEncodingA2: 11331 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11332 single_reg = true; 11333 add = BitIsSet(opcode, 23); 11334 imm32 = Bits32(opcode, 7, 0) << 2; 11335 11336 // d = UInt(Vd:D); n = UInt(Rn); 11337 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11338 n = Bits32(opcode, 19, 16); 11339 11340 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11341 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11342 return false; 11343 11344 break; 11345 11346 default: 11347 return false; 11348 } 11349 11350 RegisterInfo base_reg; 11351 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11352 11353 uint32_t Rn = ReadCoreReg(n, &success); 11354 if (!success) 11355 return false; 11356 11357 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11358 addr_t address; 11359 if (add) 11360 address = Rn + imm32; 11361 else 11362 address = Rn - imm32; 11363 11364 const uint32_t addr_byte_size = GetAddressByteSize(); 11365 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11366 11367 RegisterInfo data_reg; 11368 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg); 11369 EmulateInstruction::Context context; 11370 context.type = eContextRegisterStore; 11371 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11372 11373 if (single_reg) { 11374 // MemA[address,4] = S[d]; 11375 uint32_t data = 11376 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11377 if (!success) 11378 return false; 11379 11380 if (!MemAWrite(context, address, data, addr_byte_size)) 11381 return false; 11382 } else { 11383 // // Store as two word-aligned words in the correct order for current 11384 // endianness. 11385 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11386 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11387 uint64_t data = 11388 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11389 if (!success) 11390 return false; 11391 11392 if (GetByteOrder() == eByteOrderBig) { 11393 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size)) 11394 return false; 11395 11396 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11397 (address + 4) - Rn); 11398 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11399 addr_byte_size)) 11400 return false; 11401 } else { 11402 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11403 return false; 11404 11405 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11406 (address + 4) - Rn); 11407 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11408 addr_byte_size)) 11409 return false; 11410 } 11411 } 11412 } 11413 return true; 11414} 11415 11416// A8.6.307 VLDI1 (multiple single elements) 11417// This instruction loads elements from memory into one, two, three or four 11418// registers, without de-interleaving. Every 11419// element of each register is loaded. 11420bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode, 11421 ARMEncoding encoding) { 11422#if 0 11423 if ConditionPassed() then 11424 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11425 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11426 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11427 for r = 0 to regs-1 11428 for e = 0 to elements-1 11429 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11430 address = address + ebytes; 11431#endif 11432 11433 bool success = false; 11434 11435 if (ConditionPassed(opcode)) { 11436 uint32_t regs; 11437 uint32_t alignment; 11438 uint32_t ebytes; 11439 uint32_t esize; 11440 uint32_t elements; 11441 uint32_t d; 11442 uint32_t n; 11443 uint32_t m; 11444 bool wback; 11445 bool register_index; 11446 11447 switch (encoding) { 11448 case eEncodingT1: 11449 case eEncodingA1: { 11450 // case type of 11451 // when '0111' 11452 // regs = 1; if align<1> == '1' then UNDEFINED; 11453 // when '1010' 11454 // regs = 2; if align == '11' then UNDEFINED; 11455 // when '0110' 11456 // regs = 3; if align<1> == '1' then UNDEFINED; 11457 // when '0010' 11458 // regs = 4; 11459 // otherwise 11460 // SEE 'Related encodings'; 11461 uint32_t type = Bits32(opcode, 11, 8); 11462 uint32_t align = Bits32(opcode, 5, 4); 11463 if (type == 7) // '0111' 11464 { 11465 regs = 1; 11466 if (BitIsSet(align, 1)) 11467 return false; 11468 } else if (type == 10) // '1010' 11469 { 11470 regs = 2; 11471 if (align == 3) 11472 return false; 11473 11474 } else if (type == 6) // '0110' 11475 { 11476 regs = 3; 11477 if (BitIsSet(align, 1)) 11478 return false; 11479 } else if (type == 2) // '0010' 11480 { 11481 regs = 4; 11482 } else 11483 return false; 11484 11485 // alignment = if align == '00' then 1 else 4 << UInt(align); 11486 if (align == 0) 11487 alignment = 1; 11488 else 11489 alignment = 4 << align; 11490 11491 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11492 ebytes = 1 << Bits32(opcode, 7, 6); 11493 esize = 8 * ebytes; 11494 elements = 8 / ebytes; 11495 11496 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11497 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11498 n = Bits32(opcode, 19, 15); 11499 m = Bits32(opcode, 3, 0); 11500 11501 // wback = (m != 15); register_index = (m != 15 && m != 13); 11502 wback = (m != 15); 11503 register_index = ((m != 15) && (m != 13)); 11504 11505 // if d+regs > 32 then UNPREDICTABLE; 11506 if ((d + regs) > 32) 11507 return false; 11508 } break; 11509 11510 default: 11511 return false; 11512 } 11513 11514 RegisterInfo base_reg; 11515 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11516 11517 uint32_t Rn = ReadCoreReg(n, &success); 11518 if (!success) 11519 return false; 11520 11521 // address = R[n]; if (address MOD alignment) != 0 then 11522 // GenerateAlignmentException(); 11523 addr_t address = Rn; 11524 if ((address % alignment) != 0) 11525 return false; 11526 11527 EmulateInstruction::Context context; 11528 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11529 if (wback) { 11530 uint32_t Rm = ReadCoreReg(m, &success); 11531 if (!success) 11532 return false; 11533 11534 uint32_t offset; 11535 if (register_index) 11536 offset = Rm; 11537 else 11538 offset = 8 * regs; 11539 11540 uint32_t value = Rn + offset; 11541 context.type = eContextAdjustBaseRegister; 11542 context.SetRegisterPlusOffset(base_reg, offset); 11543 11544 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11545 value)) 11546 return false; 11547 } 11548 11549 // for r = 0 to regs-1 11550 for (uint32_t r = 0; r < regs; ++r) { 11551 // for e = 0 to elements-1 11552 uint64_t assembled_data = 0; 11553 for (uint32_t e = 0; e < elements; ++e) { 11554 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11555 context.type = eContextRegisterLoad; 11556 context.SetRegisterPlusOffset(base_reg, address - Rn); 11557 uint64_t data = MemURead(context, address, ebytes, 0, &success); 11558 if (!success) 11559 return false; 11560 11561 assembled_data = 11562 (data << (e * esize)) | 11563 assembled_data; // New data goes to the left of existing data 11564 11565 // address = address + ebytes; 11566 address = address + ebytes; 11567 } 11568 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 11569 assembled_data)) 11570 return false; 11571 } 11572 } 11573 return true; 11574} 11575 11576// A8.6.308 VLD1 (single element to one lane) 11577// 11578bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode, 11579 const ARMEncoding encoding) { 11580#if 0 11581 if ConditionPassed() then 11582 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11583 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11584 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11585 Elem[D[d],index,esize] = MemU[address,ebytes]; 11586#endif 11587 11588 bool success = false; 11589 11590 if (ConditionPassed(opcode)) { 11591 uint32_t ebytes; 11592 uint32_t esize; 11593 uint32_t index; 11594 uint32_t alignment; 11595 uint32_t d; 11596 uint32_t n; 11597 uint32_t m; 11598 bool wback; 11599 bool register_index; 11600 11601 switch (encoding) { 11602 case eEncodingT1: 11603 case eEncodingA1: { 11604 uint32_t size = Bits32(opcode, 11, 10); 11605 uint32_t index_align = Bits32(opcode, 7, 4); 11606 // if size == '11' then SEE VLD1 (single element to all lanes); 11607 if (size == 3) 11608 return EmulateVLD1SingleAll(opcode, encoding); 11609 // case size of 11610 if (size == 0) // when '00' 11611 { 11612 // if index_align<0> != '0' then UNDEFINED; 11613 if (BitIsClear(index_align, 0)) 11614 return false; 11615 11616 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11617 ebytes = 1; 11618 esize = 8; 11619 index = Bits32(index_align, 3, 1); 11620 alignment = 1; 11621 } else if (size == 1) // when '01' 11622 { 11623 // if index_align<1> != '0' then UNDEFINED; 11624 if (BitIsClear(index_align, 1)) 11625 return false; 11626 11627 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11628 ebytes = 2; 11629 esize = 16; 11630 index = Bits32(index_align, 3, 2); 11631 11632 // alignment = if index_align<0> == '0' then 1 else 2; 11633 if (BitIsClear(index_align, 0)) 11634 alignment = 1; 11635 else 11636 alignment = 2; 11637 } else if (size == 2) // when '10' 11638 { 11639 // if index_align<2> != '0' then UNDEFINED; 11640 if (BitIsClear(index_align, 2)) 11641 return false; 11642 11643 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 11644 // UNDEFINED; 11645 if ((Bits32(index_align, 1, 0) != 0) && 11646 (Bits32(index_align, 1, 0) != 3)) 11647 return false; 11648 11649 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11650 ebytes = 4; 11651 esize = 32; 11652 index = Bit32(index_align, 3); 11653 11654 // alignment = if index_align<1:0> == '00' then 1 else 4; 11655 if (Bits32(index_align, 1, 0) == 0) 11656 alignment = 1; 11657 else 11658 alignment = 4; 11659 } else { 11660 return false; 11661 } 11662 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11663 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11664 n = Bits32(opcode, 19, 16); 11665 m = Bits32(opcode, 3, 0); 11666 11667 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 11668 // then UNPREDICTABLE; 11669 wback = (m != 15); 11670 register_index = ((m != 15) && (m != 13)); 11671 11672 if (n == 15) 11673 return false; 11674 11675 } break; 11676 11677 default: 11678 return false; 11679 } 11680 11681 RegisterInfo base_reg; 11682 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11683 11684 uint32_t Rn = ReadCoreReg(n, &success); 11685 if (!success) 11686 return false; 11687 11688 // address = R[n]; if (address MOD alignment) != 0 then 11689 // GenerateAlignmentException(); 11690 addr_t address = Rn; 11691 if ((address % alignment) != 0) 11692 return false; 11693 11694 EmulateInstruction::Context context; 11695 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11696 if (wback) { 11697 uint32_t Rm = ReadCoreReg(m, &success); 11698 if (!success) 11699 return false; 11700 11701 uint32_t offset; 11702 if (register_index) 11703 offset = Rm; 11704 else 11705 offset = ebytes; 11706 11707 uint32_t value = Rn + offset; 11708 11709 context.type = eContextAdjustBaseRegister; 11710 context.SetRegisterPlusOffset(base_reg, offset); 11711 11712 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11713 value)) 11714 return false; 11715 } 11716 11717 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11718 uint32_t element = MemURead(context, address, esize, 0, &success); 11719 if (!success) 11720 return false; 11721 11722 element = element << (index * esize); 11723 11724 uint64_t reg_data = 11725 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11726 if (!success) 11727 return false; 11728 11729 uint64_t all_ones = -1; 11730 uint64_t mask = all_ones 11731 << ((index + 1) * esize); // mask is all 1's to left of 11732 // where 'element' goes, & all 0's 11733 // at element & to the right of element. 11734 if (index > 0) 11735 mask = mask | Bits64(all_ones, (index * esize) - 1, 11736 0); // add 1's to the right of where 'element' goes. 11737 // now mask should be 0's where element goes & 1's 11738 // everywhere else. 11739 11740 uint64_t masked_reg = 11741 reg_data & mask; // Take original reg value & zero out 'element' bits 11742 reg_data = 11743 masked_reg & element; // Put 'element' into those bits in reg_data. 11744 11745 context.type = eContextRegisterLoad; 11746 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 11747 reg_data)) 11748 return false; 11749 } 11750 return true; 11751} 11752 11753// A8.6.391 VST1 (multiple single elements) 11754// Vector Store (multiple single elements) stores elements to memory from one, 11755// two, three, or four registers, without 11756// interleaving. Every element of each register is stored. 11757bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode, 11758 ARMEncoding encoding) { 11759#if 0 11760 if ConditionPassed() then 11761 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11762 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11763 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11764 for r = 0 to regs-1 11765 for e = 0 to elements-1 11766 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11767 address = address + ebytes; 11768#endif 11769 11770 bool success = false; 11771 11772 if (ConditionPassed(opcode)) { 11773 uint32_t regs; 11774 uint32_t alignment; 11775 uint32_t ebytes; 11776 uint32_t esize; 11777 uint32_t elements; 11778 uint32_t d; 11779 uint32_t n; 11780 uint32_t m; 11781 bool wback; 11782 bool register_index; 11783 11784 switch (encoding) { 11785 case eEncodingT1: 11786 case eEncodingA1: { 11787 uint32_t type = Bits32(opcode, 11, 8); 11788 uint32_t align = Bits32(opcode, 5, 4); 11789 11790 // case type of 11791 if (type == 7) // when '0111' 11792 { 11793 // regs = 1; if align<1> == '1' then UNDEFINED; 11794 regs = 1; 11795 if (BitIsSet(align, 1)) 11796 return false; 11797 } else if (type == 10) // when '1010' 11798 { 11799 // regs = 2; if align == '11' then UNDEFINED; 11800 regs = 2; 11801 if (align == 3) 11802 return false; 11803 } else if (type == 6) // when '0110' 11804 { 11805 // regs = 3; if align<1> == '1' then UNDEFINED; 11806 regs = 3; 11807 if (BitIsSet(align, 1)) 11808 return false; 11809 } else if (type == 2) // when '0010' 11810 // regs = 4; 11811 regs = 4; 11812 else // otherwise 11813 // SEE 'Related encodings'; 11814 return false; 11815 11816 // alignment = if align == '00' then 1 else 4 << UInt(align); 11817 if (align == 0) 11818 alignment = 1; 11819 else 11820 alignment = 4 << align; 11821 11822 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11823 ebytes = 1 << Bits32(opcode, 7, 6); 11824 esize = 8 * ebytes; 11825 elements = 8 / ebytes; 11826 11827 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11828 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11829 n = Bits32(opcode, 19, 16); 11830 m = Bits32(opcode, 3, 0); 11831 11832 // wback = (m != 15); register_index = (m != 15 && m != 13); 11833 wback = (m != 15); 11834 register_index = ((m != 15) && (m != 13)); 11835 11836 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11837 if ((d + regs) > 32) 11838 return false; 11839 11840 if (n == 15) 11841 return false; 11842 11843 } break; 11844 11845 default: 11846 return false; 11847 } 11848 11849 RegisterInfo base_reg; 11850 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11851 11852 uint32_t Rn = ReadCoreReg(n, &success); 11853 if (!success) 11854 return false; 11855 11856 // address = R[n]; if (address MOD alignment) != 0 then 11857 // GenerateAlignmentException(); 11858 addr_t address = Rn; 11859 if ((address % alignment) != 0) 11860 return false; 11861 11862 EmulateInstruction::Context context; 11863 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11864 if (wback) { 11865 uint32_t Rm = ReadCoreReg(m, &success); 11866 if (!success) 11867 return false; 11868 11869 uint32_t offset; 11870 if (register_index) 11871 offset = Rm; 11872 else 11873 offset = 8 * regs; 11874 11875 context.type = eContextAdjustBaseRegister; 11876 context.SetRegisterPlusOffset(base_reg, offset); 11877 11878 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11879 Rn + offset)) 11880 return false; 11881 } 11882 11883 RegisterInfo data_reg; 11884 context.type = eContextRegisterStore; 11885 // for r = 0 to regs-1 11886 for (uint32_t r = 0; r < regs; ++r) { 11887 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11888 uint64_t register_data = ReadRegisterUnsigned( 11889 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11890 if (!success) 11891 return false; 11892 11893 // for e = 0 to elements-1 11894 for (uint32_t e = 0; e < elements; ++e) { 11895 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11896 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize); 11897 11898 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11899 address - Rn); 11900 if (!MemUWrite(context, address, word, ebytes)) 11901 return false; 11902 11903 // address = address + ebytes; 11904 address = address + ebytes; 11905 } 11906 } 11907 } 11908 return true; 11909} 11910 11911// A8.6.392 VST1 (single element from one lane) 11912// This instruction stores one element to memory from one element of a register. 11913bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode, 11914 ARMEncoding encoding) { 11915#if 0 11916 if ConditionPassed() then 11917 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11918 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11919 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11920 MemU[address,ebytes] = Elem[D[d],index,esize]; 11921#endif 11922 11923 bool success = false; 11924 11925 if (ConditionPassed(opcode)) { 11926 uint32_t ebytes; 11927 uint32_t esize; 11928 uint32_t index; 11929 uint32_t alignment; 11930 uint32_t d; 11931 uint32_t n; 11932 uint32_t m; 11933 bool wback; 11934 bool register_index; 11935 11936 switch (encoding) { 11937 case eEncodingT1: 11938 case eEncodingA1: { 11939 uint32_t size = Bits32(opcode, 11, 10); 11940 uint32_t index_align = Bits32(opcode, 7, 4); 11941 11942 // if size == '11' then UNDEFINED; 11943 if (size == 3) 11944 return false; 11945 11946 // case size of 11947 if (size == 0) // when '00' 11948 { 11949 // if index_align<0> != '0' then UNDEFINED; 11950 if (BitIsClear(index_align, 0)) 11951 return false; 11952 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11953 ebytes = 1; 11954 esize = 8; 11955 index = Bits32(index_align, 3, 1); 11956 alignment = 1; 11957 } else if (size == 1) // when '01' 11958 { 11959 // if index_align<1> != '0' then UNDEFINED; 11960 if (BitIsClear(index_align, 1)) 11961 return false; 11962 11963 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11964 ebytes = 2; 11965 esize = 16; 11966 index = Bits32(index_align, 3, 2); 11967 11968 // alignment = if index_align<0> == '0' then 1 else 2; 11969 if (BitIsClear(index_align, 0)) 11970 alignment = 1; 11971 else 11972 alignment = 2; 11973 } else if (size == 2) // when '10' 11974 { 11975 // if index_align<2> != '0' then UNDEFINED; 11976 if (BitIsClear(index_align, 2)) 11977 return false; 11978 11979 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 11980 // UNDEFINED; 11981 if ((Bits32(index_align, 1, 0) != 0) && 11982 (Bits32(index_align, 1, 0) != 3)) 11983 return false; 11984 11985 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11986 ebytes = 4; 11987 esize = 32; 11988 index = Bit32(index_align, 3); 11989 11990 // alignment = if index_align<1:0> == '00' then 1 else 4; 11991 if (Bits32(index_align, 1, 0) == 0) 11992 alignment = 1; 11993 else 11994 alignment = 4; 11995 } else { 11996 return false; 11997 } 11998 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11999 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12000 n = Bits32(opcode, 19, 16); 12001 m = Bits32(opcode, 3, 0); 12002 12003 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12004 // then UNPREDICTABLE; 12005 wback = (m != 15); 12006 register_index = ((m != 15) && (m != 13)); 12007 12008 if (n == 15) 12009 return false; 12010 } break; 12011 12012 default: 12013 return false; 12014 } 12015 12016 RegisterInfo base_reg; 12017 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12018 12019 uint32_t Rn = ReadCoreReg(n, &success); 12020 if (!success) 12021 return false; 12022 12023 // address = R[n]; if (address MOD alignment) != 0 then 12024 // GenerateAlignmentException(); 12025 addr_t address = Rn; 12026 if ((address % alignment) != 0) 12027 return false; 12028 12029 EmulateInstruction::Context context; 12030 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12031 if (wback) { 12032 uint32_t Rm = ReadCoreReg(m, &success); 12033 if (!success) 12034 return false; 12035 12036 uint32_t offset; 12037 if (register_index) 12038 offset = Rm; 12039 else 12040 offset = ebytes; 12041 12042 context.type = eContextAdjustBaseRegister; 12043 context.SetRegisterPlusOffset(base_reg, offset); 12044 12045 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12046 Rn + offset)) 12047 return false; 12048 } 12049 12050 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12051 uint64_t register_data = 12052 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12053 if (!success) 12054 return false; 12055 12056 uint64_t word = 12057 Bits64(register_data, ((index + 1) * esize) - 1, index * esize); 12058 12059 RegisterInfo data_reg; 12060 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12061 context.type = eContextRegisterStore; 12062 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 12063 12064 if (!MemUWrite(context, address, word, ebytes)) 12065 return false; 12066 } 12067 return true; 12068} 12069 12070// A8.6.309 VLD1 (single element to all lanes) 12071// This instruction loads one element from memory into every element of one or 12072// two vectors. 12073bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode, 12074 const ARMEncoding encoding) { 12075#if 0 12076 if ConditionPassed() then 12077 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12078 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12079 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12080 replicated_element = Replicate(MemU[address,ebytes], elements); 12081 for r = 0 to regs-1 12082 D[d+r] = replicated_element; 12083#endif 12084 12085 bool success = false; 12086 12087 if (ConditionPassed(opcode)) { 12088 uint32_t ebytes; 12089 uint32_t elements; 12090 uint32_t regs; 12091 uint32_t alignment; 12092 uint32_t d; 12093 uint32_t n; 12094 uint32_t m; 12095 bool wback; 12096 bool register_index; 12097 12098 switch (encoding) { 12099 case eEncodingT1: 12100 case eEncodingA1: { 12101 // if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12102 uint32_t size = Bits32(opcode, 7, 6); 12103 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4))) 12104 return false; 12105 12106 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' 12107 // then 1 else 2; 12108 ebytes = 1 << size; 12109 elements = 8 / ebytes; 12110 if (BitIsClear(opcode, 5)) 12111 regs = 1; 12112 else 12113 regs = 2; 12114 12115 // alignment = if a == '0' then 1 else ebytes; 12116 if (BitIsClear(opcode, 4)) 12117 alignment = 1; 12118 else 12119 alignment = ebytes; 12120 12121 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12122 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12123 n = Bits32(opcode, 19, 16); 12124 m = Bits32(opcode, 3, 0); 12125 12126 // wback = (m != 15); register_index = (m != 15 && m != 13); 12127 wback = (m != 15); 12128 register_index = ((m != 15) && (m != 13)); 12129 12130 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12131 if ((d + regs) > 32) 12132 return false; 12133 12134 if (n == 15) 12135 return false; 12136 } break; 12137 12138 default: 12139 return false; 12140 } 12141 12142 RegisterInfo base_reg; 12143 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12144 12145 uint32_t Rn = ReadCoreReg(n, &success); 12146 if (!success) 12147 return false; 12148 12149 // address = R[n]; if (address MOD alignment) != 0 then 12150 // GenerateAlignmentException(); 12151 addr_t address = Rn; 12152 if ((address % alignment) != 0) 12153 return false; 12154 12155 EmulateInstruction::Context context; 12156 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12157 if (wback) { 12158 uint32_t Rm = ReadCoreReg(m, &success); 12159 if (!success) 12160 return false; 12161 12162 uint32_t offset; 12163 if (register_index) 12164 offset = Rm; 12165 else 12166 offset = ebytes; 12167 12168 context.type = eContextAdjustBaseRegister; 12169 context.SetRegisterPlusOffset(base_reg, offset); 12170 12171 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12172 Rn + offset)) 12173 return false; 12174 } 12175 12176 // replicated_element = Replicate(MemU[address,ebytes], elements); 12177 12178 context.type = eContextRegisterLoad; 12179 uint64_t word = MemURead(context, address, ebytes, 0, &success); 12180 if (!success) 12181 return false; 12182 12183 uint64_t replicated_element = 0; 12184 uint32_t esize = ebytes * 8; 12185 for (uint32_t e = 0; e < elements; ++e) 12186 replicated_element = 12187 (replicated_element << esize) | Bits64(word, esize - 1, 0); 12188 12189 // for r = 0 to regs-1 12190 for (uint32_t r = 0; r < regs; ++r) { 12191 // D[d+r] = replicated_element; 12192 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12193 replicated_element)) 12194 return false; 12195 } 12196 } 12197 return true; 12198} 12199 12200// B6.2.13 SUBS PC, LR and related instructions 12201// The SUBS PC, LR, #<const? instruction provides an exception return without 12202// the use of the stack. It subtracts the 12203// immediate constant from the LR, branches to the resulting address, and also 12204// copies the SPSR to the CPSR. 12205bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode, 12206 const ARMEncoding encoding) { 12207#if 0 12208 if ConditionPassed() then 12209 EncodingSpecificOperations(); 12210 if CurrentInstrSet() == InstrSet_ThumbEE then 12211 UNPREDICTABLE; 12212 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12213 case opcode of 12214 when '0000' result = R[n] AND operand2; // AND 12215 when '0001' result = R[n] EOR operand2; // EOR 12216 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12217 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12218 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12219 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12220 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12221 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12222 when '1100' result = R[n] OR operand2; // ORR 12223 when '1101' result = operand2; // MOV 12224 when '1110' result = R[n] AND NOT(operand2); // BIC 12225 when '1111' result = NOT(operand2); // MVN 12226 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12227 BranchWritePC(result); 12228#endif 12229 12230 bool success = false; 12231 12232 if (ConditionPassed(opcode)) { 12233 uint32_t n; 12234 uint32_t m; 12235 uint32_t imm32; 12236 bool register_form; 12237 ARM_ShifterType shift_t; 12238 uint32_t shift_n; 12239 uint32_t code; 12240 12241 switch (encoding) { 12242 case eEncodingT1: 12243 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12244 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = 12245 // '0010'; // = SUB 12246 n = 14; 12247 imm32 = Bits32(opcode, 7, 0); 12248 register_form = false; 12249 code = 2; 12250 12251 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12252 if (InITBlock() && !LastInITBlock()) 12253 return false; 12254 12255 break; 12256 12257 case eEncodingA1: 12258 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12259 n = Bits32(opcode, 19, 16); 12260 imm32 = ARMExpandImm(opcode); 12261 register_form = false; 12262 code = Bits32(opcode, 24, 21); 12263 12264 break; 12265 12266 case eEncodingA2: 12267 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12268 n = Bits32(opcode, 19, 16); 12269 m = Bits32(opcode, 3, 0); 12270 register_form = true; 12271 12272 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12273 shift_n = DecodeImmShiftARM(opcode, shift_t); 12274 12275 break; 12276 12277 default: 12278 return false; 12279 } 12280 12281 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) 12282 // else imm32; 12283 uint32_t operand2; 12284 if (register_form) { 12285 uint32_t Rm = ReadCoreReg(m, &success); 12286 if (!success) 12287 return false; 12288 12289 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success); 12290 if (!success) 12291 return false; 12292 } else { 12293 operand2 = imm32; 12294 } 12295 12296 uint32_t Rn = ReadCoreReg(n, &success); 12297 if (!success) 12298 return false; 12299 12300 AddWithCarryResult result; 12301 12302 // case opcode of 12303 switch (code) { 12304 case 0: // when '0000' 12305 // result = R[n] AND operand2; // AND 12306 result.result = Rn & operand2; 12307 break; 12308 12309 case 1: // when '0001' 12310 // result = R[n] EOR operand2; // EOR 12311 result.result = Rn ^ operand2; 12312 break; 12313 12314 case 2: // when '0010' 12315 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12316 result = AddWithCarry(Rn, ~(operand2), 1); 12317 break; 12318 12319 case 3: // when '0011' 12320 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12321 result = AddWithCarry(~(Rn), operand2, 1); 12322 break; 12323 12324 case 4: // when '0100' 12325 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12326 result = AddWithCarry(Rn, operand2, 0); 12327 break; 12328 12329 case 5: // when '0101' 12330 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12331 result = AddWithCarry(Rn, operand2, APSR_C); 12332 break; 12333 12334 case 6: // when '0110' 12335 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12336 result = AddWithCarry(Rn, ~(operand2), APSR_C); 12337 break; 12338 12339 case 7: // when '0111' 12340 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12341 result = AddWithCarry(~(Rn), operand2, APSR_C); 12342 break; 12343 12344 case 10: // when '1100' 12345 // result = R[n] OR operand2; // ORR 12346 result.result = Rn | operand2; 12347 break; 12348 12349 case 11: // when '1101' 12350 // result = operand2; // MOV 12351 result.result = operand2; 12352 break; 12353 12354 case 12: // when '1110' 12355 // result = R[n] AND NOT(operand2); // BIC 12356 result.result = Rn & ~(operand2); 12357 break; 12358 12359 case 15: // when '1111' 12360 // result = NOT(operand2); // MVN 12361 result.result = ~(operand2); 12362 break; 12363 12364 default: 12365 return false; 12366 } 12367 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12368 12369 // For now, in emulation mode, we don't have access to the SPSR, so we will 12370 // use the CPSR instead, and hope for 12371 // the best. 12372 uint32_t spsr = 12373 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12374 if (!success) 12375 return false; 12376 12377 CPSRWriteByInstr(spsr, 15, true); 12378 12379 // BranchWritePC(result); 12380 EmulateInstruction::Context context; 12381 context.type = eContextAdjustPC; 12382 context.SetImmediate(result.result); 12383 12384 BranchWritePC(context, result.result); 12385 } 12386 return true; 12387} 12388 12389EmulateInstructionARM::ARMOpcode * 12390EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode, 12391 uint32_t arm_isa) { 12392 static ARMOpcode g_arm_opcodes[] = { 12393 //---------------------------------------------------------------------- 12394 // Prologue instructions 12395 //---------------------------------------------------------------------- 12396 12397 // push register(s) 12398 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12399 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 12400 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12401 &EmulateInstructionARM::EmulatePUSH, "push <register>"}, 12402 12403 // set r7 to point to a stack offset 12404 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12405 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"}, 12406 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12407 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12408 // copy the stack pointer to ip 12409 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, 12410 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"}, 12411 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12412 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"}, 12413 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12414 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12415 12416 // adjust the stack pointer 12417 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12418 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12419 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12420 &EmulateInstructionARM::EmulateSUBSPReg, 12421 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 12422 12423 // push one register 12424 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12425 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12426 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"}, 12427 12428 // vector push consecutive extension register(s) 12429 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12430 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12431 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12432 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12433 12434 //---------------------------------------------------------------------- 12435 // Epilogue instructions 12436 //---------------------------------------------------------------------- 12437 12438 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12439 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12440 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12441 &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12442 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12443 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12444 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12445 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12446 12447 //---------------------------------------------------------------------- 12448 // Supervisor Call (previously Software Interrupt) 12449 //---------------------------------------------------------------------- 12450 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12451 &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12452 12453 //---------------------------------------------------------------------- 12454 // Branch instructions 12455 //---------------------------------------------------------------------- 12456 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and 12457 // "bl <label>". 12458 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, 12459 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12460 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12461 &EmulateInstructionARM::EmulateB, "b #imm24"}, 12462 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12463 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12464 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, 12465 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12466 // for example, "bx lr" 12467 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, 12468 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12469 // bxj 12470 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, 12471 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12472 12473 //---------------------------------------------------------------------- 12474 // Data-processing instructions 12475 //---------------------------------------------------------------------- 12476 // adc (immediate) 12477 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12478 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12479 // adc (register) 12480 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12481 &EmulateInstructionARM::EmulateADCReg, 12482 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12483 // add (immediate) 12484 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12485 &EmulateInstructionARM::EmulateADDImmARM, 12486 "add{s}<c> <Rd>, <Rn>, #const"}, 12487 // add (register) 12488 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12489 &EmulateInstructionARM::EmulateADDReg, 12490 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12491 // add (register-shifted register) 12492 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, 12493 &EmulateInstructionARM::EmulateADDRegShift, 12494 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12495 // adr 12496 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12497 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12498 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, 12499 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12500 // and (immediate) 12501 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12502 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12503 // and (register) 12504 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12505 &EmulateInstructionARM::EmulateANDReg, 12506 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12507 // bic (immediate) 12508 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12509 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12510 // bic (register) 12511 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12512 &EmulateInstructionARM::EmulateBICReg, 12513 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12514 // eor (immediate) 12515 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12516 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12517 // eor (register) 12518 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12519 &EmulateInstructionARM::EmulateEORReg, 12520 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12521 // orr (immediate) 12522 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12523 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12524 // orr (register) 12525 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12526 &EmulateInstructionARM::EmulateORRReg, 12527 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12528 // rsb (immediate) 12529 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12530 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12531 // rsb (register) 12532 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12533 &EmulateInstructionARM::EmulateRSBReg, 12534 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12535 // rsc (immediate) 12536 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12537 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12538 // rsc (register) 12539 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12540 &EmulateInstructionARM::EmulateRSCReg, 12541 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12542 // sbc (immediate) 12543 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12544 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12545 // sbc (register) 12546 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12547 &EmulateInstructionARM::EmulateSBCReg, 12548 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12549 // sub (immediate, ARM) 12550 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12551 &EmulateInstructionARM::EmulateSUBImmARM, 12552 "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12553 // sub (sp minus immediate) 12554 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12555 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12556 // sub (register) 12557 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12558 &EmulateInstructionARM::EmulateSUBReg, 12559 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12560 // teq (immediate) 12561 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12562 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12563 // teq (register) 12564 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12565 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12566 // tst (immediate) 12567 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12568 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12569 // tst (register) 12570 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12571 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12572 12573 // mov (immediate) 12574 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12575 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12576 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12577 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"}, 12578 // mov (register) 12579 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12580 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12581 // mvn (immediate) 12582 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12583 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12584 // mvn (register) 12585 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12586 &EmulateInstructionARM::EmulateMVNReg, 12587 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12588 // cmn (immediate) 12589 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12590 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12591 // cmn (register) 12592 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12593 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12594 // cmp (immediate) 12595 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12596 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12597 // cmp (register) 12598 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12599 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12600 // asr (immediate) 12601 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, 12602 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12603 // asr (register) 12604 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 12605 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12606 // lsl (immediate) 12607 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12608 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12609 // lsl (register) 12610 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, 12611 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12612 // lsr (immediate) 12613 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, 12614 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12615 // lsr (register) 12616 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 12617 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12618 // rrx is a special case encoding of ror (immediate) 12619 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 12620 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12621 // ror (immediate) 12622 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 12623 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12624 // ror (register) 12625 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, 12626 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12627 // mul 12628 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, 12629 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"}, 12630 12631 // subs pc, lr and related instructions 12632 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12633 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 12634 "<opc>S<c> PC,#<const> | <Rn>,#<const>"}, 12635 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, 12636 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 12637 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"}, 12638 12639 //---------------------------------------------------------------------- 12640 // Load instructions 12641 //---------------------------------------------------------------------- 12642 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12643 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 12644 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12645 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"}, 12646 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12647 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 12648 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12649 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"}, 12650 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12651 &EmulateInstructionARM::EmulateLDRImmediateARM, 12652 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"}, 12653 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12654 &EmulateInstructionARM::EmulateLDRRegister, 12655 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"}, 12656 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12657 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12658 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12659 &EmulateInstructionARM::EmulateLDRBRegister, 12660 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"}, 12661 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 12662 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 12663 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 12664 &EmulateInstructionARM::EmulateLDRHRegister, 12665 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 12666 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 12667 &EmulateInstructionARM::EmulateLDRSBImmediate, 12668 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"}, 12669 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 12670 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"}, 12671 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 12672 &EmulateInstructionARM::EmulateLDRSBRegister, 12673 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 12674 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 12675 &EmulateInstructionARM::EmulateLDRSHImmediate, 12676 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12677 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 12678 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 12679 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 12680 &EmulateInstructionARM::EmulateLDRSHRegister, 12681 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 12682 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 12683 &EmulateInstructionARM::EmulateLDRDImmediate, 12684 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12685 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 12686 &EmulateInstructionARM::EmulateLDRDRegister, 12687 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12688 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 12689 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12690 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 12691 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12692 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 12693 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12694 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 12695 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12696 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 12697 &EmulateInstructionARM::EmulateVLD1Multiple, 12698 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12699 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 12700 &EmulateInstructionARM::EmulateVLD1Single, 12701 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12702 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 12703 &EmulateInstructionARM::EmulateVLD1SingleAll, 12704 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12705 12706 //---------------------------------------------------------------------- 12707 // Store instructions 12708 //---------------------------------------------------------------------- 12709 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12710 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 12711 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12712 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"}, 12713 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12714 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 12715 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12716 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"}, 12717 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12718 &EmulateInstructionARM::EmulateSTRRegister, 12719 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"}, 12720 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 12721 &EmulateInstructionARM::EmulateSTRHRegister, 12722 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"}, 12723 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 12724 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12725 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12726 &EmulateInstructionARM::EmulateSTRBImmARM, 12727 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12728 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12729 &EmulateInstructionARM::EmulateSTRImmARM, 12730 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12731 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 12732 &EmulateInstructionARM::EmulateSTRDImm, 12733 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12734 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 12735 &EmulateInstructionARM::EmulateSTRDReg, 12736 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12737 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 12738 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12739 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 12740 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12741 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 12742 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12743 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 12744 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12745 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 12746 &EmulateInstructionARM::EmulateVST1Multiple, 12747 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12748 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 12749 &EmulateInstructionARM::EmulateVST1Single, 12750 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12751 12752 //---------------------------------------------------------------------- 12753 // Other instructions 12754 //---------------------------------------------------------------------- 12755 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 12756 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"}, 12757 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 12758 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"}, 12759 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 12760 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"}, 12761 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 12762 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"}, 12763 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 12764 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"} 12765 12766 }; 12767 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 12768 12769 for (size_t i = 0; i < k_num_arm_opcodes; ++i) { 12770 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12771 (g_arm_opcodes[i].variants & arm_isa) != 0) 12772 return &g_arm_opcodes[i]; 12773 } 12774 return NULL; 12775} 12776 12777EmulateInstructionARM::ARMOpcode * 12778EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode, 12779 uint32_t arm_isa) { 12780 12781 static ARMOpcode g_thumb_opcodes[] = { 12782 //---------------------------------------------------------------------- 12783 // Prologue instructions 12784 //---------------------------------------------------------------------- 12785 12786 // push register(s) 12787 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, 12788 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 12789 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12790 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"}, 12791 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 12792 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"}, 12793 12794 // set r7 to point to a stack offset 12795 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, 12796 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"}, 12797 // copy the stack pointer to r7 12798 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, 12799 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"}, 12800 // move from high register to low register (comes after "mov r7, sp" to 12801 // resolve ambiguity) 12802 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, 12803 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"}, 12804 12805 // PC-relative load into register (see also EmulateADDSPRm) 12806 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, 12807 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12808 12809 // adjust the stack pointer 12810 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, 12811 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12812 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, 12813 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12814 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12815 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12816 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 12817 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12818 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 12819 &EmulateInstructionARM::EmulateSUBSPReg, 12820 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 12821 12822 // vector push consecutive extension register(s) 12823 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 12824 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12825 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12826 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12827 12828 //---------------------------------------------------------------------- 12829 // Epilogue instructions 12830 //---------------------------------------------------------------------- 12831 12832 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 12833 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12834 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, 12835 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12836 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, 12837 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12838 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12839 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"}, 12840 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 12841 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"}, 12842 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 12843 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12844 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12845 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12846 12847 //---------------------------------------------------------------------- 12848 // Supervisor Call (previously Software Interrupt) 12849 //---------------------------------------------------------------------- 12850 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, 12851 &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12852 12853 //---------------------------------------------------------------------- 12854 // If Then makes up to four following instructions conditional. 12855 //---------------------------------------------------------------------- 12856 // The next 5 opcode _must_ come before the if then instruction 12857 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 12858 &EmulateInstructionARM::EmulateNop, "nop"}, 12859 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 12860 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12861 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 12862 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12863 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 12864 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12865 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 12866 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12867 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 12868 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12869 12870 //---------------------------------------------------------------------- 12871 // Branch instructions 12872 //---------------------------------------------------------------------- 12873 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12874 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, 12875 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12876 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, 12877 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12878 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 12879 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12880 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 12881 &EmulateInstructionARM::EmulateB, 12882 "b<c>.w #imm8 (outside or last in IT)"}, 12883 // J1 == J2 == 1 12884 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, 12885 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12886 // J1 == J2 == 1 12887 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, 12888 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12889 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, 12890 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12891 // for example, "bx lr" 12892 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, 12893 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12894 // bxj 12895 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, 12896 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12897 // compare and branch 12898 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 12899 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12900 // table branch byte 12901 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 12902 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12903 // table branch halfword 12904 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 12905 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12906 12907 //---------------------------------------------------------------------- 12908 // Data-processing instructions 12909 //---------------------------------------------------------------------- 12910 // adc (immediate) 12911 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 12912 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12913 // adc (register) 12914 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, 12915 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12916 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12917 &EmulateInstructionARM::EmulateADCReg, 12918 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12919 // add (register) 12920 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, 12921 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12922 // Make sure "add sp, <Rm>" comes before this instruction, so there's no 12923 // ambiguity decoding the two. 12924 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, 12925 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12926 // adr 12927 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, 12928 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12929 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12930 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12931 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 12932 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12933 // and (immediate) 12934 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 12935 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12936 // and (register) 12937 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, 12938 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12939 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12940 &EmulateInstructionARM::EmulateANDReg, 12941 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12942 // bic (immediate) 12943 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 12944 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12945 // bic (register) 12946 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, 12947 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12948 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12949 &EmulateInstructionARM::EmulateBICReg, 12950 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12951 // eor (immediate) 12952 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 12953 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12954 // eor (register) 12955 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, 12956 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12957 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12958 &EmulateInstructionARM::EmulateEORReg, 12959 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12960 // orr (immediate) 12961 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 12962 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12963 // orr (register) 12964 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, 12965 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12966 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12967 &EmulateInstructionARM::EmulateORRReg, 12968 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12969 // rsb (immediate) 12970 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, 12971 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12972 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12973 &EmulateInstructionARM::EmulateRSBImm, 12974 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12975 // rsb (register) 12976 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 12977 &EmulateInstructionARM::EmulateRSBReg, 12978 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12979 // sbc (immediate) 12980 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 12981 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12982 // sbc (register) 12983 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, 12984 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12985 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 12986 &EmulateInstructionARM::EmulateSBCReg, 12987 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12988 // add (immediate, Thumb) 12989 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 12990 &EmulateInstructionARM::EmulateADDImmThumb, 12991 "adds|add<c> <Rd>,<Rn>,#<imm3>"}, 12992 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 12993 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"}, 12994 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 12995 &EmulateInstructionARM::EmulateADDImmThumb, 12996 "add{s}<c>.w <Rd>,<Rn>,#<const>"}, 12997 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 12998 &EmulateInstructionARM::EmulateADDImmThumb, 12999 "addw<c> <Rd>,<Rn>,#<imm12>"}, 13000 // sub (immediate, Thumb) 13001 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13002 &EmulateInstructionARM::EmulateSUBImmThumb, 13003 "subs|sub<c> <Rd>, <Rn> #imm3"}, 13004 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, 13005 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 13006 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13007 &EmulateInstructionARM::EmulateSUBImmThumb, 13008 "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 13009 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13010 &EmulateInstructionARM::EmulateSUBImmThumb, 13011 "subw<c> <Rd>, <Rn>, #imm12"}, 13012 // sub (sp minus immediate) 13013 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13014 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 13015 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13016 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 13017 // sub (register) 13018 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13019 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 13020 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13021 &EmulateInstructionARM::EmulateSUBReg, 13022 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 13023 // teq (immediate) 13024 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13025 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 13026 // teq (register) 13027 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13028 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13029 // tst (immediate) 13030 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13031 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 13032 // tst (register) 13033 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, 13034 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 13035 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13036 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 13037 13038 // move from high register to high register 13039 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, 13040 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 13041 // move from low register to low register 13042 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13043 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 13044 // mov{s}<c>.w <Rd>, <Rm> 13045 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13046 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 13047 // move immediate 13048 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13049 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 13050 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13051 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 13052 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13053 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 13054 // mvn (immediate) 13055 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13056 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 13057 // mvn (register) 13058 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13059 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 13060 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13061 &EmulateInstructionARM::EmulateMVNReg, 13062 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 13063 // cmn (immediate) 13064 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13065 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13066 // cmn (register) 13067 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13068 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 13069 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13070 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13071 // cmp (immediate) 13072 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13073 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 13074 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13075 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 13076 // cmp (register) (Rn and Rm both from r0-r7) 13077 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, 13078 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13079 // cmp (register) (Rn and Rm not both from r0-r7) 13080 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, 13081 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13082 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, 13083 &EmulateInstructionARM::EmulateCMPReg, 13084 "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 13085 // asr (immediate) 13086 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13087 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 13088 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13089 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 13090 // asr (register) 13091 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, 13092 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 13093 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13094 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13095 // lsl (immediate) 13096 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13097 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 13098 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13099 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 13100 // lsl (register) 13101 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13102 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 13103 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13104 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13105 // lsr (immediate) 13106 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13107 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 13108 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13109 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 13110 // lsr (register) 13111 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13112 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 13113 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13114 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13115 // rrx is a special case encoding of ror (immediate) 13116 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13117 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 13118 // ror (immediate) 13119 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13120 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 13121 // ror (register) 13122 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13123 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 13124 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13125 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13126 // mul 13127 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13128 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"}, 13129 // mul 13130 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13131 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"}, 13132 13133 // subs pc, lr and related instructions 13134 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13135 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"}, 13136 13137 //---------------------------------------------------------------------- 13138 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE 13139 // LDM.. Instructions in this table; 13140 // otherwise the wrong instructions will be selected. 13141 //---------------------------------------------------------------------- 13142 13143 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13144 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"}, 13145 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13146 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"}, 13147 13148 //---------------------------------------------------------------------- 13149 // Load instructions 13150 //---------------------------------------------------------------------- 13151 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13152 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13153 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13154 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"}, 13155 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13156 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13157 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13158 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 13159 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13160 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 13161 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13162 &EmulateInstructionARM::EmulateLDRRtRnImm, 13163 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 13164 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13165 &EmulateInstructionARM::EmulateLDRRtRnImm, 13166 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 13167 // Thumb2 PC-relative load into register 13168 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13169 &EmulateInstructionARM::EmulateLDRRtPCRelative, 13170 "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 13171 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13172 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"}, 13173 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13174 &EmulateInstructionARM::EmulateLDRRegister, 13175 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"}, 13176 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13177 &EmulateInstructionARM::EmulateLDRBImmediate, 13178 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"}, 13179 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13180 &EmulateInstructionARM::EmulateLDRBImmediate, 13181 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13182 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13183 &EmulateInstructionARM::EmulateLDRBImmediate, 13184 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"}, 13185 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13186 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"}, 13187 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13188 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"}, 13189 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13190 &EmulateInstructionARM::EmulateLDRBRegister, 13191 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13192 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13193 &EmulateInstructionARM::EmulateLDRHImmediate, 13194 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"}, 13195 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13196 &EmulateInstructionARM::EmulateLDRHImmediate, 13197 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13198 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13199 &EmulateInstructionARM::EmulateLDRHImmediate, 13200 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"}, 13201 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13202 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13203 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13204 &EmulateInstructionARM::EmulateLDRHRegister, 13205 "ldrh<c> <Rt>, [<Rn>,<Rm>]"}, 13206 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13207 &EmulateInstructionARM::EmulateLDRHRegister, 13208 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13209 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13210 &EmulateInstructionARM::EmulateLDRSBImmediate, 13211 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"}, 13212 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13213 &EmulateInstructionARM::EmulateLDRSBImmediate, 13214 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13215 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13216 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"}, 13217 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13218 &EmulateInstructionARM::EmulateLDRSBRegister, 13219 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"}, 13220 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13221 &EmulateInstructionARM::EmulateLDRSBRegister, 13222 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13223 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13224 &EmulateInstructionARM::EmulateLDRSHImmediate, 13225 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"}, 13226 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13227 &EmulateInstructionARM::EmulateLDRSHImmediate, 13228 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13229 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13230 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13231 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13232 &EmulateInstructionARM::EmulateLDRSHRegister, 13233 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"}, 13234 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13235 &EmulateInstructionARM::EmulateLDRSHRegister, 13236 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13237 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13238 &EmulateInstructionARM::EmulateLDRDImmediate, 13239 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 13240 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13241 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13242 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13243 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13244 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13245 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13246 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13247 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 13248 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13249 &EmulateInstructionARM::EmulateVLD1Multiple, 13250 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13251 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13252 &EmulateInstructionARM::EmulateVLD1Single, 13253 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13254 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13255 &EmulateInstructionARM::EmulateVLD1SingleAll, 13256 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13257 13258 //---------------------------------------------------------------------- 13259 // Store instructions 13260 //---------------------------------------------------------------------- 13261 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13262 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13263 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13264 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"}, 13265 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13266 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13267 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13268 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"}, 13269 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13270 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"}, 13271 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13272 &EmulateInstructionARM::EmulateSTRThumb, 13273 "str<c>.w <Rt>, [<Rn>,#<imm12>]"}, 13274 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13275 &EmulateInstructionARM::EmulateSTRThumb, 13276 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"}, 13277 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13278 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"}, 13279 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13280 &EmulateInstructionARM::EmulateSTRRegister, 13281 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"}, 13282 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13283 &EmulateInstructionARM::EmulateSTRBThumb, 13284 "strb<c> <Rt>, [<Rn>, #<imm5>]"}, 13285 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13286 &EmulateInstructionARM::EmulateSTRBThumb, 13287 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"}, 13288 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13289 &EmulateInstructionARM::EmulateSTRBThumb, 13290 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"}, 13291 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13292 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"}, 13293 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13294 &EmulateInstructionARM::EmulateSTRHRegister, 13295 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13296 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13297 &EmulateInstructionARM::EmulateSTREX, 13298 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"}, 13299 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13300 &EmulateInstructionARM::EmulateSTRDImm, 13301 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 13302 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13303 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13304 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13305 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13306 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13307 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13308 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13309 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13310 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13311 &EmulateInstructionARM::EmulateVST1Multiple, 13312 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13313 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13314 &EmulateInstructionARM::EmulateVST1Single, 13315 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13316 13317 //---------------------------------------------------------------------- 13318 // Other instructions 13319 //---------------------------------------------------------------------- 13320 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13321 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"}, 13322 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, 13323 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13324 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13325 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"}, 13326 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13327 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13328 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13329 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"}, 13330 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13331 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13332 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13333 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"}, 13334 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13335 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13336 }; 13337 13338 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 13339 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) { 13340 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 13341 (g_thumb_opcodes[i].variants & arm_isa) != 0) 13342 return &g_thumb_opcodes[i]; 13343 } 13344 return NULL; 13345} 13346 13347bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { 13348 m_arch = arch; 13349 m_arm_isa = 0; 13350 const char *arch_cstr = arch.GetArchitectureName(); 13351 if (arch_cstr) { 13352 if (0 == ::strcasecmp(arch_cstr, "armv4t")) 13353 m_arm_isa = ARMv4T; 13354 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) 13355 m_arm_isa = ARMv5TEJ; 13356 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) 13357 m_arm_isa = ARMv5TE; 13358 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) 13359 m_arm_isa = ARMv5T; 13360 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) 13361 m_arm_isa = ARMv6K; 13362 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) 13363 m_arm_isa = ARMv6T2; 13364 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) 13365 m_arm_isa = ARMv7S; 13366 else if (0 == ::strcasecmp(arch_cstr, "arm")) 13367 m_arm_isa = ARMvAll; 13368 else if (0 == ::strcasecmp(arch_cstr, "thumb")) 13369 m_arm_isa = ARMvAll; 13370 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5)) 13371 m_arm_isa = ARMv4; 13372 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5)) 13373 m_arm_isa = ARMv6; 13374 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5)) 13375 m_arm_isa = ARMv7; 13376 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5)) 13377 m_arm_isa = ARMv8; 13378 } 13379 return m_arm_isa != 0; 13380} 13381 13382bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode, 13383 const Address &inst_addr, 13384 Target *target) { 13385 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 13386 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || 13387 m_arch.IsAlwaysThumbInstructions()) 13388 m_opcode_mode = eModeThumb; 13389 else { 13390 AddressClass addr_class = inst_addr.GetAddressClass(); 13391 13392 if ((addr_class == eAddressClassCode) || 13393 (addr_class == eAddressClassUnknown)) 13394 m_opcode_mode = eModeARM; 13395 else if (addr_class == eAddressClassCodeAlternateISA) 13396 m_opcode_mode = eModeThumb; 13397 else 13398 return false; 13399 } 13400 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions()) 13401 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13402 else 13403 m_opcode_cpsr = CPSR_MODE_USR; 13404 return true; 13405 } 13406 return false; 13407} 13408 13409bool EmulateInstructionARM::ReadInstruction() { 13410 bool success = false; 13411 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric, 13412 LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13413 if (success) { 13414 addr_t pc = 13415 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 13416 LLDB_INVALID_ADDRESS, &success); 13417 if (success) { 13418 Context read_inst_context; 13419 read_inst_context.type = eContextReadOpcode; 13420 read_inst_context.SetNoArgs(); 13421 13422 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) { 13423 m_opcode_mode = eModeThumb; 13424 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13425 13426 if (success) { 13427 if ((thumb_opcode & 0xe000) != 0xe000 || 13428 ((thumb_opcode & 0x1800u) == 0)) { 13429 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder()); 13430 } else { 13431 m_opcode.SetOpcode32( 13432 (thumb_opcode << 16) | 13433 MemARead(read_inst_context, pc + 2, 2, 0, &success), 13434 GetByteOrder()); 13435 } 13436 } 13437 } else { 13438 m_opcode_mode = eModeARM; 13439 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success), 13440 GetByteOrder()); 13441 } 13442 13443 if (!m_ignore_conditions) { 13444 // If we are not ignoreing the conditions then init the it session from 13445 // the current 13446 // value of cpsr. 13447 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | 13448 Bits32(m_opcode_cpsr, 26, 25); 13449 if (it != 0) 13450 m_it_session.InitIT(it); 13451 } 13452 } 13453 } 13454 if (!success) { 13455 m_opcode_mode = eModeInvalid; 13456 m_addr = LLDB_INVALID_ADDRESS; 13457 } 13458 return success; 13459} 13460 13461uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; } 13462 13463bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) { 13464 // If we are ignoring conditions, then always return true. 13465 // this allows us to iterate over disassembly code and still 13466 // emulate an instruction even if we don't have all the right 13467 // bits set in the CPSR register... 13468 if (m_ignore_conditions) 13469 return true; 13470 13471 const uint32_t cond = CurrentCond(opcode); 13472 if (cond == UINT32_MAX) 13473 return false; 13474 13475 bool result = false; 13476 switch (UnsignedBits(cond, 3, 1)) { 13477 case 0: 13478 if (m_opcode_cpsr == 0) 13479 result = true; 13480 else 13481 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13482 break; 13483 case 1: 13484 if (m_opcode_cpsr == 0) 13485 result = true; 13486 else 13487 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13488 break; 13489 case 2: 13490 if (m_opcode_cpsr == 0) 13491 result = true; 13492 else 13493 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13494 break; 13495 case 3: 13496 if (m_opcode_cpsr == 0) 13497 result = true; 13498 else 13499 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13500 break; 13501 case 4: 13502 if (m_opcode_cpsr == 0) 13503 result = true; 13504 else 13505 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && 13506 ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13507 break; 13508 case 5: 13509 if (m_opcode_cpsr == 0) 13510 result = true; 13511 else { 13512 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13513 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13514 result = n == v; 13515 } 13516 break; 13517 case 6: 13518 if (m_opcode_cpsr == 0) 13519 result = true; 13520 else { 13521 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13522 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13523 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13524 } 13525 break; 13526 case 7: 13527 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13528 // opcodes different meanings, but always means execution happens. 13529 return true; 13530 } 13531 13532 if (cond & 1) 13533 result = !result; 13534 return result; 13535} 13536 13537uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) { 13538 switch (m_opcode_mode) { 13539 case eModeInvalid: 13540 break; 13541 13542 case eModeARM: 13543 return UnsignedBits(opcode, 31, 28); 13544 13545 case eModeThumb: 13546 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13547 // 'cond' field of the encoding. 13548 { 13549 const uint32_t byte_size = m_opcode.GetByteSize(); 13550 if (byte_size == 2) { 13551 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 13552 return Bits32(opcode, 11, 8); 13553 } else if (byte_size == 4) { 13554 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 && 13555 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) { 13556 return Bits32(opcode, 25, 22); 13557 } 13558 } else 13559 // We have an invalid thumb instruction, let's bail out. 13560 break; 13561 13562 return m_it_session.GetCond(); 13563 } 13564 } 13565 return UINT32_MAX; // Return invalid value 13566} 13567 13568bool EmulateInstructionARM::InITBlock() { 13569 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13570} 13571 13572bool EmulateInstructionARM::LastInITBlock() { 13573 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13574} 13575 13576bool EmulateInstructionARM::BadMode(uint32_t mode) { 13577 13578 switch (mode) { 13579 case 16: 13580 return false; // '10000' 13581 case 17: 13582 return false; // '10001' 13583 case 18: 13584 return false; // '10010' 13585 case 19: 13586 return false; // '10011' 13587 case 22: 13588 return false; // '10110' 13589 case 23: 13590 return false; // '10111' 13591 case 27: 13592 return false; // '11011' 13593 case 31: 13594 return false; // '11111' 13595 default: 13596 return true; 13597 } 13598 return true; 13599} 13600 13601bool EmulateInstructionARM::CurrentModeIsPrivileged() { 13602 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0); 13603 13604 if (BadMode(mode)) 13605 return false; 13606 13607 if (mode == 16) 13608 return false; 13609 13610 return true; 13611} 13612 13613void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 13614 bool affect_execstate) { 13615 bool privileged = CurrentModeIsPrivileged(); 13616 13617 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20; 13618 13619 if (BitIsSet(bytemask, 3)) { 13620 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27); 13621 if (affect_execstate) 13622 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24); 13623 } 13624 13625 if (BitIsSet(bytemask, 2)) { 13626 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16); 13627 } 13628 13629 if (BitIsSet(bytemask, 1)) { 13630 if (affect_execstate) 13631 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10); 13632 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9); 13633 if (privileged) 13634 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8); 13635 } 13636 13637 if (BitIsSet(bytemask, 0)) { 13638 if (privileged) 13639 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6); 13640 if (affect_execstate) 13641 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5); 13642 if (privileged) 13643 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0); 13644 } 13645 13646 m_opcode_cpsr = tmp_cpsr; 13647} 13648 13649bool EmulateInstructionARM::BranchWritePC(const Context &context, 13650 uint32_t addr) { 13651 addr_t target; 13652 13653 // Check the current instruction set. 13654 if (CurrentInstrSet() == eModeARM) 13655 target = addr & 0xfffffffc; 13656 else 13657 target = addr & 0xfffffffe; 13658 13659 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 13660 LLDB_REGNUM_GENERIC_PC, target)) 13661 return false; 13662 13663 return true; 13664} 13665 13666// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by 13667// inspecting addr. 13668bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) { 13669 addr_t target; 13670 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13671 // we want to record it and issue a WriteRegister callback so the clients 13672 // can track the mode changes accordingly. 13673 bool cpsr_changed = false; 13674 13675 if (BitIsSet(addr, 0)) { 13676 if (CurrentInstrSet() != eModeThumb) { 13677 SelectInstrSet(eModeThumb); 13678 cpsr_changed = true; 13679 } 13680 target = addr & 0xfffffffe; 13681 context.SetISA(eModeThumb); 13682 } else if (BitIsClear(addr, 1)) { 13683 if (CurrentInstrSet() != eModeARM) { 13684 SelectInstrSet(eModeARM); 13685 cpsr_changed = true; 13686 } 13687 target = addr & 0xfffffffc; 13688 context.SetISA(eModeARM); 13689 } else 13690 return false; // address<1:0> == '10' => UNPREDICTABLE 13691 13692 if (cpsr_changed) { 13693 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 13694 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13695 return false; 13696 } 13697 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 13698 LLDB_REGNUM_GENERIC_PC, target)) 13699 return false; 13700 13701 return true; 13702} 13703 13704// Dispatches to either BXWritePC or BranchWritePC based on architecture 13705// versions. 13706bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) { 13707 if (ArchVersion() >= ARMv5T) 13708 return BXWritePC(context, addr); 13709 else 13710 return BranchWritePC((const Context)context, addr); 13711} 13712 13713// Dispatches to either BXWritePC or BranchWritePC based on architecture 13714// versions and current instruction set. 13715bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) { 13716 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13717 return BXWritePC(context, addr); 13718 else 13719 return BranchWritePC((const Context)context, addr); 13720} 13721 13722EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() { 13723 return m_opcode_mode; 13724} 13725 13726// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13727// ReadInstruction() is performed. This function has a side effect of updating 13728// the m_new_inst_cpsr member variable if necessary. 13729bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) { 13730 m_new_inst_cpsr = m_opcode_cpsr; 13731 switch (arm_or_thumb) { 13732 default: 13733 return false; 13734 case eModeARM: 13735 // Clear the T bit. 13736 m_new_inst_cpsr &= ~MASK_CPSR_T; 13737 break; 13738 case eModeThumb: 13739 // Set the T bit. 13740 m_new_inst_cpsr |= MASK_CPSR_T; 13741 break; 13742 } 13743 return true; 13744} 13745 13746// This function returns TRUE if the processor currently provides support for 13747// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13748// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13749bool EmulateInstructionARM::UnalignedSupport() { 13750 return (ArchVersion() >= ARMv7); 13751} 13752 13753// The main addition and subtraction instructions can produce status information 13754// about both unsigned carry and signed overflow conditions. This status 13755// information can be used to synthesize multi-word additions and subtractions. 13756EmulateInstructionARM::AddWithCarryResult 13757EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) { 13758 uint32_t result; 13759 uint8_t carry_out; 13760 uint8_t overflow; 13761 13762 uint64_t unsigned_sum = x + y + carry_in; 13763 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13764 13765 result = UnsignedBits(unsigned_sum, 31, 0); 13766 // carry_out = (result == unsigned_sum ? 0 : 1); 13767 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13768 13769 if (carry_in) 13770 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0; 13771 else 13772 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0; 13773 13774 AddWithCarryResult res = {result, carry_out, overflow}; 13775 return res; 13776} 13777 13778uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) { 13779 lldb::RegisterKind reg_kind; 13780 uint32_t reg_num; 13781 switch (num) { 13782 case SP_REG: 13783 reg_kind = eRegisterKindGeneric; 13784 reg_num = LLDB_REGNUM_GENERIC_SP; 13785 break; 13786 case LR_REG: 13787 reg_kind = eRegisterKindGeneric; 13788 reg_num = LLDB_REGNUM_GENERIC_RA; 13789 break; 13790 case PC_REG: 13791 reg_kind = eRegisterKindGeneric; 13792 reg_num = LLDB_REGNUM_GENERIC_PC; 13793 break; 13794 default: 13795 if (num < SP_REG) { 13796 reg_kind = eRegisterKindDWARF; 13797 reg_num = dwarf_r0 + num; 13798 } else { 13799 // assert(0 && "Invalid register number"); 13800 *success = false; 13801 return UINT32_MAX; 13802 } 13803 break; 13804 } 13805 13806 // Read our register. 13807 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success); 13808 13809 // When executing an ARM instruction , PC reads as the address of the current 13810 // instruction plus 8. 13811 // When executing a Thumb instruction , PC reads as the address of the current 13812 // instruction plus 4. 13813 if (num == 15) { 13814 if (CurrentInstrSet() == eModeARM) 13815 val += 8; 13816 else 13817 val += 4; 13818 } 13819 13820 return val; 13821} 13822 13823// Write the result to the ARM core register Rd, and optionally update the 13824// condition flags based on the result. 13825// 13826// This helper method tries to encapsulate the following pseudocode from the 13827// ARM Architecture Reference Manual: 13828// 13829// if d == 15 then // Can only occur for encoding A1 13830// ALUWritePC(result); // setflags is always FALSE here 13831// else 13832// R[d] = result; 13833// if setflags then 13834// APSR.N = result<31>; 13835// APSR.Z = IsZeroBit(result); 13836// APSR.C = carry; 13837// // APSR.V unchanged 13838// 13839// In the above case, the API client does not pass in the overflow arg, which 13840// defaults to ~0u. 13841bool EmulateInstructionARM::WriteCoreRegOptionalFlags( 13842 Context &context, const uint32_t result, const uint32_t Rd, bool setflags, 13843 const uint32_t carry, const uint32_t overflow) { 13844 if (Rd == 15) { 13845 if (!ALUWritePC(context, result)) 13846 return false; 13847 } else { 13848 lldb::RegisterKind reg_kind; 13849 uint32_t reg_num; 13850 switch (Rd) { 13851 case SP_REG: 13852 reg_kind = eRegisterKindGeneric; 13853 reg_num = LLDB_REGNUM_GENERIC_SP; 13854 break; 13855 case LR_REG: 13856 reg_kind = eRegisterKindGeneric; 13857 reg_num = LLDB_REGNUM_GENERIC_RA; 13858 break; 13859 default: 13860 reg_kind = eRegisterKindDWARF; 13861 reg_num = dwarf_r0 + Rd; 13862 } 13863 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result)) 13864 return false; 13865 if (setflags) 13866 return WriteFlags(context, result, carry, overflow); 13867 } 13868 return true; 13869} 13870 13871// This helper method tries to encapsulate the following pseudocode from the 13872// ARM Architecture Reference Manual: 13873// 13874// APSR.N = result<31>; 13875// APSR.Z = IsZeroBit(result); 13876// APSR.C = carry; 13877// APSR.V = overflow 13878// 13879// Default arguments can be specified for carry and overflow parameters, which 13880// means 13881// not to update the respective flags. 13882bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result, 13883 const uint32_t carry, 13884 const uint32_t overflow) { 13885 m_new_inst_cpsr = m_opcode_cpsr; 13886 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13887 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13888 if (carry != ~0u) 13889 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13890 if (overflow != ~0u) 13891 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13892 if (m_new_inst_cpsr != m_opcode_cpsr) { 13893 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 13894 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13895 return false; 13896 } 13897 return true; 13898} 13899 13900bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { 13901 ARMOpcode *opcode_data = NULL; 13902 13903 if (m_opcode_mode == eModeThumb) 13904 opcode_data = 13905 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 13906 else if (m_opcode_mode == eModeARM) 13907 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 13908 13909 const bool auto_advance_pc = 13910 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13911 m_ignore_conditions = 13912 evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13913 13914 bool success = false; 13915 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) { 13916 m_opcode_cpsr = 13917 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 13918 } 13919 13920 // Only return false if we are unable to read the CPSR if we care about 13921 // conditions 13922 if (success == false && m_ignore_conditions == false) 13923 return false; 13924 13925 uint32_t orig_pc_value = 0; 13926 if (auto_advance_pc) { 13927 orig_pc_value = 13928 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 13929 if (!success) 13930 return false; 13931 } 13932 13933 // Call the Emulate... function if we managed to decode the opcode. 13934 if (opcode_data) { 13935 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(), 13936 opcode_data->encoding); 13937 if (!success) 13938 return false; 13939 } 13940 13941 // Advance the ITSTATE bits to their values for the next instruction if we 13942 // haven't just executed 13943 // an IT instruction what initialized it. 13944 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() && 13945 (opcode_data == nullptr || 13946 opcode_data->callback != &EmulateInstructionARM::EmulateIT)) 13947 m_it_session.ITAdvance(); 13948 13949 if (auto_advance_pc) { 13950 uint32_t after_pc_value = 13951 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 13952 if (!success) 13953 return false; 13954 13955 if (auto_advance_pc && (after_pc_value == orig_pc_value)) { 13956 after_pc_value += m_opcode.GetByteSize(); 13957 13958 EmulateInstruction::Context context; 13959 context.type = eContextAdvancePC; 13960 context.SetNoArgs(); 13961 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc, 13962 after_pc_value)) 13963 return false; 13964 } 13965 } 13966 return true; 13967} 13968 13969EmulateInstruction::InstructionCondition 13970EmulateInstructionARM::GetInstructionCondition() { 13971 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32()); 13972 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) 13973 return EmulateInstruction::UnconditionalCondition; 13974 return cond; 13975} 13976 13977bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, 13978 OptionValueDictionary *test_data) { 13979 if (!test_data) { 13980 out_stream->Printf("TestEmulation: Missing test data.\n"); 13981 return false; 13982 } 13983 13984 static ConstString opcode_key("opcode"); 13985 static ConstString before_key("before_state"); 13986 static ConstString after_key("after_state"); 13987 13988 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key); 13989 13990 uint32_t test_opcode; 13991 if ((value_sp.get() == NULL) || 13992 (value_sp->GetType() != OptionValue::eTypeUInt64)) { 13993 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n"); 13994 return false; 13995 } 13996 test_opcode = value_sp->GetUInt64Value(); 13997 13998 if (arch.GetTriple().getArch() == llvm::Triple::thumb || 13999 arch.IsAlwaysThumbInstructions()) { 14000 m_opcode_mode = eModeThumb; 14001 if (test_opcode < 0x10000) 14002 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder()); 14003 else 14004 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14005 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) { 14006 m_opcode_mode = eModeARM; 14007 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14008 } else { 14009 out_stream->Printf("TestEmulation: Invalid arch.\n"); 14010 return false; 14011 } 14012 14013 EmulationStateARM before_state; 14014 EmulationStateARM after_state; 14015 14016 value_sp = test_data->GetValueForKey(before_key); 14017 if ((value_sp.get() == NULL) || 14018 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14019 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n"); 14020 return false; 14021 } 14022 14023 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary(); 14024 if (!before_state.LoadStateFromDictionary(state_dictionary)) { 14025 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n"); 14026 return false; 14027 } 14028 14029 value_sp = test_data->GetValueForKey(after_key); 14030 if ((value_sp.get() == NULL) || 14031 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14032 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n"); 14033 return false; 14034 } 14035 14036 state_dictionary = value_sp->GetAsDictionary(); 14037 if (!after_state.LoadStateFromDictionary(state_dictionary)) { 14038 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n"); 14039 return false; 14040 } 14041 14042 SetBaton((void *)&before_state); 14043 SetCallbacks(&EmulationStateARM::ReadPseudoMemory, 14044 &EmulationStateARM::WritePseudoMemory, 14045 &EmulationStateARM::ReadPseudoRegister, 14046 &EmulationStateARM::WritePseudoRegister); 14047 14048 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 14049 if (!success) { 14050 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n"); 14051 return false; 14052 } 14053 14054 success = before_state.CompareState(after_state); 14055 if (!success) 14056 out_stream->Printf( 14057 "TestEmulation: 'before' and 'after' states do not match.\n"); 14058 14059 return success; 14060} 14061// 14062// 14063// const char * 14064// EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 14065//{ 14066// if (reg_kind == eRegisterKindGeneric) 14067// { 14068// switch (reg_num) 14069// { 14070// case LLDB_REGNUM_GENERIC_PC: return "pc"; 14071// case LLDB_REGNUM_GENERIC_SP: return "sp"; 14072// case LLDB_REGNUM_GENERIC_FP: return "fp"; 14073// case LLDB_REGNUM_GENERIC_RA: return "lr"; 14074// case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 14075// default: return NULL; 14076// } 14077// } 14078// else if (reg_kind == eRegisterKindDWARF) 14079// { 14080// return GetARMDWARFRegisterName (reg_num); 14081// } 14082// return NULL; 14083//} 14084// 14085bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { 14086 unwind_plan.Clear(); 14087 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 14088 14089 UnwindPlan::RowSP row(new UnwindPlan::Row); 14090 14091 // Our previous Call Frame Address is the stack pointer 14092 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0); 14093 14094 unwind_plan.AppendRow(row); 14095 unwind_plan.SetSourceName("EmulateInstructionARM"); 14096 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 14097 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 14098 unwind_plan.SetReturnAddressRegister(dwarf_lr); 14099 return true; 14100} 14101