1//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include <stdlib.h> 11 12#include "EmulateInstructionARM.h" 13#include "EmulationStateARM.h" 14#include "lldb/Core/ArchSpec.h" 15#include "lldb/Core/Address.h" 16#include "lldb/Core/ConstString.h" 17#include "lldb/Core/PluginManager.h" 18#include "lldb/Core/Stream.h" 19#include "lldb/Interpreter/OptionValueArray.h" 20#include "lldb/Interpreter/OptionValueDictionary.h" 21#include "lldb/Symbol/UnwindPlan.h" 22 23#include "Plugins/Process/Utility/ARMDefines.h" 24#include "Plugins/Process/Utility/ARMUtils.h" 25#include "Utility/ARM_DWARF_Registers.h" 26 27#include "llvm/Support/MathExtras.h" // for SignExtend32 template function 28 // and countTrailingZeros function 29 30using namespace lldb; 31using namespace lldb_private; 32 33// Convenient macro definitions. 34#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 35#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 36 37#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 38 39//---------------------------------------------------------------------- 40// 41// ITSession implementation 42// 43//---------------------------------------------------------------------- 44 45// A8.6.50 46// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 47static uint32_t 48CountITSize (uint32_t ITMask) { 49 // First count the trailing zeros of the IT mask. 50 uint32_t TZ = llvm::countTrailingZeros(ITMask); 51 if (TZ > 3) 52 { 53#ifdef LLDB_CONFIGURATION_DEBUG 54 printf("Encoding error: IT Mask '0000'\n"); 55#endif 56 return 0; 57 } 58 return (4 - TZ); 59} 60 61// Init ITState. Note that at least one bit is always 1 in mask. 62bool ITSession::InitIT(uint32_t bits7_0) 63{ 64 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 65 if (ITCounter == 0) 66 return false; 67 68 // A8.6.50 IT 69 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 70 if (FirstCond == 0xF) 71 { 72#ifdef LLDB_CONFIGURATION_DEBUG 73 printf("Encoding error: IT FirstCond '1111'\n"); 74#endif 75 return false; 76 } 77 if (FirstCond == 0xE && ITCounter != 1) 78 { 79#ifdef LLDB_CONFIGURATION_DEBUG 80 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 81#endif 82 return false; 83 } 84 85 ITState = bits7_0; 86 return true; 87} 88 89// Update ITState if necessary. 90void ITSession::ITAdvance() 91{ 92 //assert(ITCounter); 93 --ITCounter; 94 if (ITCounter == 0) 95 ITState = 0; 96 else 97 { 98 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 99 SetBits32(ITState, 4, 0, NewITState4_0); 100 } 101} 102 103// Return true if we're inside an IT Block. 104bool ITSession::InITBlock() 105{ 106 return ITCounter != 0; 107} 108 109// Return true if we're the last instruction inside an IT Block. 110bool ITSession::LastInITBlock() 111{ 112 return ITCounter == 1; 113} 114 115// Get condition bits for the current thumb instruction. 116uint32_t ITSession::GetCond() 117{ 118 if (InITBlock()) 119 return Bits32(ITState, 7, 4); 120 else 121 return COND_AL; 122} 123 124// ARM constants used during decoding 125#define REG_RD 0 126#define LDM_REGLIST 1 127#define SP_REG 13 128#define LR_REG 14 129#define PC_REG 15 130#define PC_REGLIST_BIT 0x8000 131 132#define ARMv4 (1u << 0) 133#define ARMv4T (1u << 1) 134#define ARMv5T (1u << 2) 135#define ARMv5TE (1u << 3) 136#define ARMv5TEJ (1u << 4) 137#define ARMv6 (1u << 5) 138#define ARMv6K (1u << 6) 139#define ARMv6T2 (1u << 7) 140#define ARMv7 (1u << 8) 141#define ARMv7S (1u << 9) 142#define ARMv8 (1u << 10) 143#define ARMvAll (0xffffffffu) 144 145#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 146#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 147#define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 148#define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 149#define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 150#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8) 151#define ARMV7_ABOVE (ARMv7|ARMv7S|ARMv8) 152 153#define No_VFP 0 154#define VFPv1 (1u << 1) 155#define VFPv2 (1u << 2) 156#define VFPv3 (1u << 3) 157#define AdvancedSIMD (1u << 4) 158 159#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 160#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 161#define VFPv2v3 (VFPv2 | VFPv3) 162 163//---------------------------------------------------------------------- 164// 165// EmulateInstructionARM implementation 166// 167//---------------------------------------------------------------------- 168 169void 170EmulateInstructionARM::Initialize () 171{ 172 PluginManager::RegisterPlugin (GetPluginNameStatic (), 173 GetPluginDescriptionStatic (), 174 CreateInstance); 175} 176 177void 178EmulateInstructionARM::Terminate () 179{ 180 PluginManager::UnregisterPlugin (CreateInstance); 181} 182 183ConstString 184EmulateInstructionARM::GetPluginNameStatic () 185{ 186 static ConstString g_name("arm"); 187 return g_name; 188} 189 190const char * 191EmulateInstructionARM::GetPluginDescriptionStatic () 192{ 193 return "Emulate instructions for the ARM architecture."; 194} 195 196EmulateInstruction * 197EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) 198{ 199 if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type)) 200 { 201 if (arch.GetTriple().getArch() == llvm::Triple::arm) 202 { 203 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 204 205 if (emulate_insn_ap.get()) 206 return emulate_insn_ap.release(); 207 } 208 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 209 { 210 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 211 212 if (emulate_insn_ap.get()) 213 return emulate_insn_ap.release(); 214 } 215 } 216 217 return NULL; 218} 219 220bool 221EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch) 222{ 223 if (arch.GetTriple().getArch () == llvm::Triple::arm) 224 return true; 225 else if (arch.GetTriple().getArch () == llvm::Triple::thumb) 226 return true; 227 228 return false; 229} 230 231// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 232bool 233EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 234{ 235 EmulateInstruction::Context context; 236 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 237 context.SetNoArgs (); 238 239 uint32_t random_data = rand (); 240 const uint32_t addr_byte_size = GetAddressByteSize(); 241 242 if (!MemAWrite (context, address, random_data, addr_byte_size)) 243 return false; 244 245 return true; 246} 247 248// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 249bool 250EmulateInstructionARM::WriteBits32Unknown (int n) 251{ 252 EmulateInstruction::Context context; 253 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 254 context.SetNoArgs (); 255 256 bool success; 257 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 258 259 if (!success) 260 return false; 261 262 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 263 return false; 264 265 return true; 266} 267 268bool 269EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo ®_info) 270{ 271 if (reg_kind == eRegisterKindGeneric) 272 { 273 switch (reg_num) 274 { 275 case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break; 276 case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break; 277 case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break; 278 case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break; 279 case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break; 280 default: return false; 281 } 282 } 283 284 if (reg_kind == eRegisterKindDWARF) 285 return GetARMDWARFRegisterInfo(reg_num, reg_info); 286 return false; 287} 288 289uint32_t 290EmulateInstructionARM::GetFramePointerRegisterNumber () const 291{ 292 if (m_opcode_mode == eModeThumb) 293 { 294 switch (m_arch.GetTriple().getOS()) 295 { 296 case llvm::Triple::Darwin: 297 case llvm::Triple::MacOSX: 298 case llvm::Triple::IOS: 299 return 7; 300 default: 301 break; 302 } 303 } 304 return 11; 305} 306 307uint32_t 308EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 309{ 310 if (m_opcode_mode == eModeThumb) 311 { 312 switch (m_arch.GetTriple().getOS()) 313 { 314 case llvm::Triple::Darwin: 315 case llvm::Triple::MacOSX: 316 case llvm::Triple::IOS: 317 return dwarf_r7; 318 default: 319 break; 320 } 321 } 322 return dwarf_r11; 323} 324 325// Push Multiple Registers stores multiple registers to the stack, storing to 326// consecutive memory locations ending just below the address in SP, and updates 327// SP to point to the start of the stored data. 328bool 329EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 330{ 331#if 0 332 // ARM pseudo code... 333 if (ConditionPassed()) 334 { 335 EncodingSpecificOperations(); 336 NullCheckIfThumbEE(13); 337 address = SP - 4*BitCount(registers); 338 339 for (i = 0 to 14) 340 { 341 if (registers<i> == '1') 342 { 343 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 344 MemA[address,4] = bits(32) UNKNOWN; 345 else 346 MemA[address,4] = R[i]; 347 address = address + 4; 348 } 349 } 350 351 if (registers<15> == '1') // Only possible for encoding A1 or A2 352 MemA[address,4] = PCStoreValue(); 353 354 SP = SP - 4*BitCount(registers); 355 } 356#endif 357 358 bool conditional = false; 359 bool success = false; 360 if (ConditionPassed(opcode, &conditional)) 361 { 362 const uint32_t addr_byte_size = GetAddressByteSize(); 363 const addr_t sp = ReadCoreReg (SP_REG, &success); 364 if (!success) 365 return false; 366 uint32_t registers = 0; 367 uint32_t Rt; // the source register 368 switch (encoding) { 369 case eEncodingT1: 370 registers = Bits32(opcode, 7, 0); 371 // The M bit represents LR. 372 if (Bit32(opcode, 8)) 373 registers |= (1u << 14); 374 // if BitCount(registers) < 1 then UNPREDICTABLE; 375 if (BitCount(registers) < 1) 376 return false; 377 break; 378 case eEncodingT2: 379 // Ignore bits 15 & 13. 380 registers = Bits32(opcode, 15, 0) & ~0xa000; 381 // if BitCount(registers) < 2 then UNPREDICTABLE; 382 if (BitCount(registers) < 2) 383 return false; 384 break; 385 case eEncodingT3: 386 Rt = Bits32(opcode, 15, 12); 387 // if BadReg(t) then UNPREDICTABLE; 388 if (BadReg(Rt)) 389 return false; 390 registers = (1u << Rt); 391 break; 392 case eEncodingA1: 393 registers = Bits32(opcode, 15, 0); 394 // Instead of return false, let's handle the following case as well, 395 // which amounts to pushing one reg onto the full descending stacks. 396 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 397 break; 398 case eEncodingA2: 399 Rt = Bits32(opcode, 15, 12); 400 // if t == 13 then UNPREDICTABLE; 401 if (Rt == dwarf_sp) 402 return false; 403 registers = (1u << Rt); 404 break; 405 default: 406 return false; 407 } 408 addr_t sp_offset = addr_byte_size * BitCount (registers); 409 addr_t addr = sp - sp_offset; 410 uint32_t i; 411 412 EmulateInstruction::Context context; 413 if (conditional) 414 context.type = EmulateInstruction::eContextRegisterStore; 415 else 416 context.type = EmulateInstruction::eContextPushRegisterOnStack; 417 RegisterInfo reg_info; 418 RegisterInfo sp_reg; 419 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 420 for (i=0; i<15; ++i) 421 { 422 if (BitIsSet (registers, i)) 423 { 424 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 425 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 426 uint32_t reg_value = ReadCoreReg(i, &success); 427 if (!success) 428 return false; 429 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 430 return false; 431 addr += addr_byte_size; 432 } 433 } 434 435 if (BitIsSet (registers, 15)) 436 { 437 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 438 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 439 const uint32_t pc = ReadCoreReg(PC_REG, &success); 440 if (!success) 441 return false; 442 if (!MemAWrite (context, addr, pc, addr_byte_size)) 443 return false; 444 } 445 446 context.type = EmulateInstruction::eContextAdjustStackPointer; 447 context.SetImmediateSigned (-sp_offset); 448 449 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 450 return false; 451 } 452 return true; 453} 454 455// Pop Multiple Registers loads multiple registers from the stack, loading from 456// consecutive memory locations staring at the address in SP, and updates 457// SP to point just above the loaded data. 458bool 459EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 460{ 461#if 0 462 // ARM pseudo code... 463 if (ConditionPassed()) 464 { 465 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 466 address = SP; 467 for i = 0 to 14 468 if registers<i> == '1' then 469 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 470 if registers<15> == '1' then 471 if UnalignedAllowed then 472 LoadWritePC(MemU[address,4]); 473 else 474 LoadWritePC(MemA[address,4]); 475 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 476 if registers<13> == '1' then SP = bits(32) UNKNOWN; 477 } 478#endif 479 480 bool success = false; 481 482 bool conditional = false; 483 if (ConditionPassed(opcode, &conditional)) 484 { 485 const uint32_t addr_byte_size = GetAddressByteSize(); 486 const addr_t sp = ReadCoreReg (SP_REG, &success); 487 if (!success) 488 return false; 489 uint32_t registers = 0; 490 uint32_t Rt; // the destination register 491 switch (encoding) { 492 case eEncodingT1: 493 registers = Bits32(opcode, 7, 0); 494 // The P bit represents PC. 495 if (Bit32(opcode, 8)) 496 registers |= (1u << 15); 497 // if BitCount(registers) < 1 then UNPREDICTABLE; 498 if (BitCount(registers) < 1) 499 return false; 500 break; 501 case eEncodingT2: 502 // Ignore bit 13. 503 registers = Bits32(opcode, 15, 0) & ~0x2000; 504 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 505 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 506 return false; 507 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 508 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 509 return false; 510 break; 511 case eEncodingT3: 512 Rt = Bits32(opcode, 15, 12); 513 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 514 if (Rt == 13) 515 return false; 516 if (Rt == 15 && InITBlock() && !LastInITBlock()) 517 return false; 518 registers = (1u << Rt); 519 break; 520 case eEncodingA1: 521 registers = Bits32(opcode, 15, 0); 522 // Instead of return false, let's handle the following case as well, 523 // which amounts to popping one reg from the full descending stacks. 524 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 525 526 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 527 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 528 return false; 529 break; 530 case eEncodingA2: 531 Rt = Bits32(opcode, 15, 12); 532 // if t == 13 then UNPREDICTABLE; 533 if (Rt == dwarf_sp) 534 return false; 535 registers = (1u << Rt); 536 break; 537 default: 538 return false; 539 } 540 addr_t sp_offset = addr_byte_size * BitCount (registers); 541 addr_t addr = sp; 542 uint32_t i, data; 543 544 EmulateInstruction::Context context; 545 if (conditional) 546 context.type = EmulateInstruction::eContextRegisterLoad; 547 else 548 context.type = EmulateInstruction::eContextPopRegisterOffStack; 549 550 RegisterInfo sp_reg; 551 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 552 553 for (i=0; i<15; ++i) 554 { 555 if (BitIsSet (registers, i)) 556 { 557 context.SetRegisterPlusOffset (sp_reg, addr - sp); 558 data = MemARead(context, addr, 4, 0, &success); 559 if (!success) 560 return false; 561 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 562 return false; 563 addr += addr_byte_size; 564 } 565 } 566 567 if (BitIsSet (registers, 15)) 568 { 569 context.SetRegisterPlusOffset (sp_reg, addr - sp); 570 data = MemARead(context, addr, 4, 0, &success); 571 if (!success) 572 return false; 573 // In ARMv5T and above, this is an interworking branch. 574 if (!LoadWritePC(context, data)) 575 return false; 576 //addr += addr_byte_size; 577 } 578 579 context.type = EmulateInstruction::eContextAdjustStackPointer; 580 context.SetImmediateSigned (sp_offset); 581 582 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 583 return false; 584 } 585 return true; 586} 587 588// Set r7 or ip to point to saved value residing within the stack. 589// ADD (SP plus immediate) 590bool 591EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 592{ 593#if 0 594 // ARM pseudo code... 595 if (ConditionPassed()) 596 { 597 EncodingSpecificOperations(); 598 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 599 if d == 15 then 600 ALUWritePC(result); // setflags is always FALSE here 601 else 602 R[d] = result; 603 if setflags then 604 APSR.N = result<31>; 605 APSR.Z = IsZeroBit(result); 606 APSR.C = carry; 607 APSR.V = overflow; 608 } 609#endif 610 611 bool success = false; 612 613 if (ConditionPassed(opcode)) 614 { 615 const addr_t sp = ReadCoreReg (SP_REG, &success); 616 if (!success) 617 return false; 618 uint32_t Rd; // the destination register 619 uint32_t imm32; 620 switch (encoding) { 621 case eEncodingT1: 622 Rd = 7; 623 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 624 break; 625 case eEncodingA1: 626 Rd = Bits32(opcode, 15, 12); 627 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 628 break; 629 default: 630 return false; 631 } 632 addr_t sp_offset = imm32; 633 addr_t addr = sp + sp_offset; // a pointer to the stack area 634 635 EmulateInstruction::Context context; 636 context.type = eContextSetFramePointer; 637 RegisterInfo sp_reg; 638 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 639 context.SetRegisterPlusOffset (sp_reg, sp_offset); 640 641 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 642 return false; 643 } 644 return true; 645} 646 647// Set r7 or ip to the current stack pointer. 648// MOV (register) 649bool 650EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 651{ 652#if 0 653 // ARM pseudo code... 654 if (ConditionPassed()) 655 { 656 EncodingSpecificOperations(); 657 result = R[m]; 658 if d == 15 then 659 ALUWritePC(result); // setflags is always FALSE here 660 else 661 R[d] = result; 662 if setflags then 663 APSR.N = result<31>; 664 APSR.Z = IsZeroBit(result); 665 // APSR.C unchanged 666 // APSR.V unchanged 667 } 668#endif 669 670 bool success = false; 671 672 if (ConditionPassed(opcode)) 673 { 674 const addr_t sp = ReadCoreReg (SP_REG, &success); 675 if (!success) 676 return false; 677 uint32_t Rd; // the destination register 678 switch (encoding) { 679 case eEncodingT1: 680 Rd = 7; 681 break; 682 case eEncodingA1: 683 Rd = 12; 684 break; 685 default: 686 return false; 687 } 688 689 EmulateInstruction::Context context; 690 if (Rd == GetFramePointerRegisterNumber()) 691 context.type = EmulateInstruction::eContextSetFramePointer; 692 else 693 context.type = EmulateInstruction::eContextRegisterPlusOffset; 694 RegisterInfo sp_reg; 695 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 696 context.SetRegisterPlusOffset (sp_reg, 0); 697 698 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 699 return false; 700 } 701 return true; 702} 703 704// Move from high register (r8-r15) to low register (r0-r7). 705// MOV (register) 706bool 707EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 708{ 709 return EmulateMOVRdRm (opcode, encoding); 710} 711 712// Move from register to register. 713// MOV (register) 714bool 715EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 716{ 717#if 0 718 // ARM pseudo code... 719 if (ConditionPassed()) 720 { 721 EncodingSpecificOperations(); 722 result = R[m]; 723 if d == 15 then 724 ALUWritePC(result); // setflags is always FALSE here 725 else 726 R[d] = result; 727 if setflags then 728 APSR.N = result<31>; 729 APSR.Z = IsZeroBit(result); 730 // APSR.C unchanged 731 // APSR.V unchanged 732 } 733#endif 734 735 bool success = false; 736 737 if (ConditionPassed(opcode)) 738 { 739 uint32_t Rm; // the source register 740 uint32_t Rd; // the destination register 741 bool setflags; 742 switch (encoding) { 743 case eEncodingT1: 744 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 745 Rm = Bits32(opcode, 6, 3); 746 setflags = false; 747 if (Rd == 15 && InITBlock() && !LastInITBlock()) 748 return false; 749 break; 750 case eEncodingT2: 751 Rd = Bits32(opcode, 2, 0); 752 Rm = Bits32(opcode, 5, 3); 753 setflags = true; 754 if (InITBlock()) 755 return false; 756 break; 757 case eEncodingT3: 758 Rd = Bits32(opcode, 11, 8); 759 Rm = Bits32(opcode, 3, 0); 760 setflags = BitIsSet(opcode, 20); 761 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 762 if (setflags && (BadReg(Rd) || BadReg(Rm))) 763 return false; 764 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 765 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 766 return false; 767 break; 768 case eEncodingA1: 769 Rd = Bits32(opcode, 15, 12); 770 Rm = Bits32(opcode, 3, 0); 771 setflags = BitIsSet(opcode, 20); 772 773 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 774 if (Rd == 15 && setflags) 775 return EmulateSUBSPcLrEtc (opcode, encoding); 776 break; 777 default: 778 return false; 779 } 780 uint32_t result = ReadCoreReg(Rm, &success); 781 if (!success) 782 return false; 783 784 // The context specifies that Rm is to be moved into Rd. 785 EmulateInstruction::Context context; 786 context.type = EmulateInstruction::eContextRegisterLoad; 787 RegisterInfo dwarf_reg; 788 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 789 context.SetRegister (dwarf_reg); 790 791 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 792 return false; 793 } 794 return true; 795} 796 797// Move (immediate) writes an immediate value to the destination register. It 798// can optionally update the condition flags based on the value. 799// MOV (immediate) 800bool 801EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 802{ 803#if 0 804 // ARM pseudo code... 805 if (ConditionPassed()) 806 { 807 EncodingSpecificOperations(); 808 result = imm32; 809 if d == 15 then // Can only occur for ARM encoding 810 ALUWritePC(result); // setflags is always FALSE here 811 else 812 R[d] = result; 813 if setflags then 814 APSR.N = result<31>; 815 APSR.Z = IsZeroBit(result); 816 APSR.C = carry; 817 // APSR.V unchanged 818 } 819#endif 820 821 if (ConditionPassed(opcode)) 822 { 823 uint32_t Rd; // the destination register 824 uint32_t imm32; // the immediate value to be written to Rd 825 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 826 // for setflags == false, this value is a don't care 827 // initialized to 0 to silence the static analyzer 828 bool setflags; 829 switch (encoding) { 830 case eEncodingT1: 831 Rd = Bits32(opcode, 10, 8); 832 setflags = !InITBlock(); 833 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 834 carry = APSR_C; 835 836 break; 837 838 case eEncodingT2: 839 Rd = Bits32(opcode, 11, 8); 840 setflags = BitIsSet(opcode, 20); 841 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 842 if (BadReg(Rd)) 843 return false; 844 845 break; 846 847 case eEncodingT3: 848 { 849 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 850 Rd = Bits32 (opcode, 11, 8); 851 setflags = false; 852 uint32_t imm4 = Bits32 (opcode, 19, 16); 853 uint32_t imm3 = Bits32 (opcode, 14, 12); 854 uint32_t i = Bit32 (opcode, 26); 855 uint32_t imm8 = Bits32 (opcode, 7, 0); 856 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 857 858 // if BadReg(d) then UNPREDICTABLE; 859 if (BadReg (Rd)) 860 return false; 861 } 862 break; 863 864 case eEncodingA1: 865 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 866 Rd = Bits32 (opcode, 15, 12); 867 setflags = BitIsSet (opcode, 20); 868 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 869 870 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 871 if ((Rd == 15) && setflags) 872 return EmulateSUBSPcLrEtc (opcode, encoding); 873 874 break; 875 876 case eEncodingA2: 877 { 878 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 879 Rd = Bits32 (opcode, 15, 12); 880 setflags = false; 881 uint32_t imm4 = Bits32 (opcode, 19, 16); 882 uint32_t imm12 = Bits32 (opcode, 11, 0); 883 imm32 = (imm4 << 12) | imm12; 884 885 // if d == 15 then UNPREDICTABLE; 886 if (Rd == 15) 887 return false; 888 } 889 break; 890 891 default: 892 return false; 893 } 894 uint32_t result = imm32; 895 896 // The context specifies that an immediate is to be moved into Rd. 897 EmulateInstruction::Context context; 898 context.type = EmulateInstruction::eContextImmediate; 899 context.SetNoArgs (); 900 901 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 902 return false; 903 } 904 return true; 905} 906 907// MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 908// register. These 32 bits do not depend on whether the source register values are considered to be signed values or 909// unsigned values. 910// 911// Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 912// limited to only a few forms of the instruction. 913bool 914EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 915{ 916#if 0 917 if ConditionPassed() then 918 EncodingSpecificOperations(); 919 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 920 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 921 result = operand1 * operand2; 922 R[d] = result<31:0>; 923 if setflags then 924 APSR.N = result<31>; 925 APSR.Z = IsZeroBit(result); 926 if ArchVersion() == 4 then 927 APSR.C = bit UNKNOWN; 928 // else APSR.C unchanged 929 // APSR.V always unchanged 930#endif 931 932 if (ConditionPassed(opcode)) 933 { 934 uint32_t d; 935 uint32_t n; 936 uint32_t m; 937 bool setflags; 938 939 // EncodingSpecificOperations(); 940 switch (encoding) 941 { 942 case eEncodingT1: 943 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 944 d = Bits32 (opcode, 2, 0); 945 n = Bits32 (opcode, 5, 3); 946 m = Bits32 (opcode, 2, 0); 947 setflags = !InITBlock(); 948 949 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 950 if ((ArchVersion() < ARMv6) && (d == n)) 951 return false; 952 953 break; 954 955 case eEncodingT2: 956 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 957 d = Bits32 (opcode, 11, 8); 958 n = Bits32 (opcode, 19, 16); 959 m = Bits32 (opcode, 3, 0); 960 setflags = false; 961 962 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 963 if (BadReg (d) || BadReg (n) || BadReg (m)) 964 return false; 965 966 break; 967 968 case eEncodingA1: 969 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 970 d = Bits32 (opcode, 19, 16); 971 n = Bits32 (opcode, 3, 0); 972 m = Bits32 (opcode, 11, 8); 973 setflags = BitIsSet (opcode, 20); 974 975 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 976 if ((d == 15) || (n == 15) || (m == 15)) 977 return false; 978 979 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 980 if ((ArchVersion() < ARMv6) && (d == n)) 981 return false; 982 983 break; 984 985 default: 986 return false; 987 } 988 989 bool success = false; 990 991 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 992 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 993 if (!success) 994 return false; 995 996 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 997 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 998 if (!success) 999 return false; 1000 1001 // result = operand1 * operand2; 1002 uint64_t result = operand1 * operand2; 1003 1004 // R[d] = result<31:0>; 1005 RegisterInfo op1_reg; 1006 RegisterInfo op2_reg; 1007 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1008 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1009 1010 EmulateInstruction::Context context; 1011 context.type = eContextArithmetic; 1012 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 1013 1014 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 1015 return false; 1016 1017 // if setflags then 1018 if (setflags) 1019 { 1020 // APSR.N = result<31>; 1021 // APSR.Z = IsZeroBit(result); 1022 m_new_inst_cpsr = m_opcode_cpsr; 1023 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 1024 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1025 if (m_new_inst_cpsr != m_opcode_cpsr) 1026 { 1027 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1028 return false; 1029 } 1030 1031 // if ArchVersion() == 4 then 1032 // APSR.C = bit UNKNOWN; 1033 } 1034 } 1035 return true; 1036} 1037 1038// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1039// It can optionally update the condition flags based on the value. 1040bool 1041EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1042{ 1043#if 0 1044 // ARM pseudo code... 1045 if (ConditionPassed()) 1046 { 1047 EncodingSpecificOperations(); 1048 result = NOT(imm32); 1049 if d == 15 then // Can only occur for ARM encoding 1050 ALUWritePC(result); // setflags is always FALSE here 1051 else 1052 R[d] = result; 1053 if setflags then 1054 APSR.N = result<31>; 1055 APSR.Z = IsZeroBit(result); 1056 APSR.C = carry; 1057 // APSR.V unchanged 1058 } 1059#endif 1060 1061 if (ConditionPassed(opcode)) 1062 { 1063 uint32_t Rd; // the destination register 1064 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1065 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1066 bool setflags; 1067 switch (encoding) { 1068 case eEncodingT1: 1069 Rd = Bits32(opcode, 11, 8); 1070 setflags = BitIsSet(opcode, 20); 1071 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1072 break; 1073 case eEncodingA1: 1074 Rd = Bits32(opcode, 15, 12); 1075 setflags = BitIsSet(opcode, 20); 1076 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1077 1078 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1079 if (Rd == 15 && setflags) 1080 return EmulateSUBSPcLrEtc (opcode, encoding); 1081 break; 1082 default: 1083 return false; 1084 } 1085 uint32_t result = ~imm32; 1086 1087 // The context specifies that an immediate is to be moved into Rd. 1088 EmulateInstruction::Context context; 1089 context.type = EmulateInstruction::eContextImmediate; 1090 context.SetNoArgs (); 1091 1092 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1093 return false; 1094 } 1095 return true; 1096} 1097 1098// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1099// It can optionally update the condition flags based on the result. 1100bool 1101EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1102{ 1103#if 0 1104 // ARM pseudo code... 1105 if (ConditionPassed()) 1106 { 1107 EncodingSpecificOperations(); 1108 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1109 result = NOT(shifted); 1110 if d == 15 then // Can only occur for ARM encoding 1111 ALUWritePC(result); // setflags is always FALSE here 1112 else 1113 R[d] = result; 1114 if setflags then 1115 APSR.N = result<31>; 1116 APSR.Z = IsZeroBit(result); 1117 APSR.C = carry; 1118 // APSR.V unchanged 1119 } 1120#endif 1121 1122 if (ConditionPassed(opcode)) 1123 { 1124 uint32_t Rm; // the source register 1125 uint32_t Rd; // the destination register 1126 ARM_ShifterType shift_t; 1127 uint32_t shift_n; // the shift applied to the value read from Rm 1128 bool setflags; 1129 uint32_t carry; // the carry bit after the shift operation 1130 switch (encoding) { 1131 case eEncodingT1: 1132 Rd = Bits32(opcode, 2, 0); 1133 Rm = Bits32(opcode, 5, 3); 1134 setflags = !InITBlock(); 1135 shift_t = SRType_LSL; 1136 shift_n = 0; 1137 if (InITBlock()) 1138 return false; 1139 break; 1140 case eEncodingT2: 1141 Rd = Bits32(opcode, 11, 8); 1142 Rm = Bits32(opcode, 3, 0); 1143 setflags = BitIsSet(opcode, 20); 1144 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1145 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1146 if (BadReg(Rd) || BadReg(Rm)) 1147 return false; 1148 break; 1149 case eEncodingA1: 1150 Rd = Bits32(opcode, 15, 12); 1151 Rm = Bits32(opcode, 3, 0); 1152 setflags = BitIsSet(opcode, 20); 1153 shift_n = DecodeImmShiftARM(opcode, shift_t); 1154 break; 1155 default: 1156 return false; 1157 } 1158 bool success = false; 1159 uint32_t value = ReadCoreReg(Rm, &success); 1160 if (!success) 1161 return false; 1162 1163 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1164 if (!success) 1165 return false; 1166 uint32_t result = ~shifted; 1167 1168 // The context specifies that an immediate is to be moved into Rd. 1169 EmulateInstruction::Context context; 1170 context.type = EmulateInstruction::eContextImmediate; 1171 context.SetNoArgs (); 1172 1173 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1174 return false; 1175 } 1176 return true; 1177} 1178 1179// PC relative immediate load into register, possibly followed by ADD (SP plus register). 1180// LDR (literal) 1181bool 1182EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1183{ 1184#if 0 1185 // ARM pseudo code... 1186 if (ConditionPassed()) 1187 { 1188 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1189 base = Align(PC,4); 1190 address = if add then (base + imm32) else (base - imm32); 1191 data = MemU[address,4]; 1192 if t == 15 then 1193 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1194 elsif UnalignedSupport() || address<1:0> = '00' then 1195 R[t] = data; 1196 else // Can only apply before ARMv7 1197 if CurrentInstrSet() == InstrSet_ARM then 1198 R[t] = ROR(data, 8*UInt(address<1:0>)); 1199 else 1200 R[t] = bits(32) UNKNOWN; 1201 } 1202#endif 1203 1204 if (ConditionPassed(opcode)) 1205 { 1206 bool success = false; 1207 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1208 if (!success) 1209 return false; 1210 1211 // PC relative immediate load context 1212 EmulateInstruction::Context context; 1213 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1214 RegisterInfo pc_reg; 1215 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1216 context.SetRegisterPlusOffset (pc_reg, 0); 1217 1218 uint32_t Rt; // the destination register 1219 uint32_t imm32; // immediate offset from the PC 1220 bool add; // +imm32 or -imm32? 1221 addr_t base; // the base address 1222 addr_t address; // the PC relative address 1223 uint32_t data; // the literal data value from the PC relative load 1224 switch (encoding) { 1225 case eEncodingT1: 1226 Rt = Bits32(opcode, 10, 8); 1227 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1228 add = true; 1229 break; 1230 case eEncodingT2: 1231 Rt = Bits32(opcode, 15, 12); 1232 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1233 add = BitIsSet(opcode, 23); 1234 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1235 return false; 1236 break; 1237 default: 1238 return false; 1239 } 1240 1241 base = Align(pc, 4); 1242 if (add) 1243 address = base + imm32; 1244 else 1245 address = base - imm32; 1246 1247 context.SetRegisterPlusOffset(pc_reg, address - base); 1248 data = MemURead(context, address, 4, 0, &success); 1249 if (!success) 1250 return false; 1251 1252 if (Rt == 15) 1253 { 1254 if (Bits32(address, 1, 0) == 0) 1255 { 1256 // In ARMv5T and above, this is an interworking branch. 1257 if (!LoadWritePC(context, data)) 1258 return false; 1259 } 1260 else 1261 return false; 1262 } 1263 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1264 { 1265 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1266 return false; 1267 } 1268 else // We don't handle ARM for now. 1269 return false; 1270 1271 } 1272 return true; 1273} 1274 1275// An add operation to adjust the SP. 1276// ADD (SP plus immediate) 1277bool 1278EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1279{ 1280#if 0 1281 // ARM pseudo code... 1282 if (ConditionPassed()) 1283 { 1284 EncodingSpecificOperations(); 1285 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1286 if d == 15 then // Can only occur for ARM encoding 1287 ALUWritePC(result); // setflags is always FALSE here 1288 else 1289 R[d] = result; 1290 if setflags then 1291 APSR.N = result<31>; 1292 APSR.Z = IsZeroBit(result); 1293 APSR.C = carry; 1294 APSR.V = overflow; 1295 } 1296#endif 1297 1298 bool success = false; 1299 1300 if (ConditionPassed(opcode)) 1301 { 1302 const addr_t sp = ReadCoreReg (SP_REG, &success); 1303 if (!success) 1304 return false; 1305 uint32_t imm32; // the immediate operand 1306 uint32_t d; 1307 //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1 1308 switch (encoding) 1309 { 1310 case eEncodingT1: 1311 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1312 d = Bits32 (opcode, 10, 8); 1313 imm32 = (Bits32 (opcode, 7, 0) << 2); 1314 1315 break; 1316 1317 case eEncodingT2: 1318 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1319 d = 13; 1320 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1321 1322 break; 1323 1324 default: 1325 return false; 1326 } 1327 addr_t sp_offset = imm32; 1328 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1329 1330 EmulateInstruction::Context context; 1331 context.type = EmulateInstruction::eContextAdjustStackPointer; 1332 RegisterInfo sp_reg; 1333 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1334 context.SetRegisterPlusOffset (sp_reg, sp_offset); 1335 1336 if (d == 15) 1337 { 1338 if (!ALUWritePC (context, addr)) 1339 return false; 1340 } 1341 else 1342 { 1343 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr)) 1344 return false; 1345 1346 // Add this back if/when support eEncodingT3 eEncodingA1 1347 //if (setflags) 1348 //{ 1349 // APSR.N = result<31>; 1350 // APSR.Z = IsZeroBit(result); 1351 // APSR.C = carry; 1352 // APSR.V = overflow; 1353 //} 1354 } 1355 } 1356 return true; 1357} 1358 1359// An add operation to adjust the SP. 1360// ADD (SP plus register) 1361bool 1362EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1363{ 1364#if 0 1365 // ARM pseudo code... 1366 if (ConditionPassed()) 1367 { 1368 EncodingSpecificOperations(); 1369 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1370 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1371 if d == 15 then 1372 ALUWritePC(result); // setflags is always FALSE here 1373 else 1374 R[d] = result; 1375 if setflags then 1376 APSR.N = result<31>; 1377 APSR.Z = IsZeroBit(result); 1378 APSR.C = carry; 1379 APSR.V = overflow; 1380 } 1381#endif 1382 1383 bool success = false; 1384 1385 if (ConditionPassed(opcode)) 1386 { 1387 const addr_t sp = ReadCoreReg (SP_REG, &success); 1388 if (!success) 1389 return false; 1390 uint32_t Rm; // the second operand 1391 switch (encoding) { 1392 case eEncodingT2: 1393 Rm = Bits32(opcode, 6, 3); 1394 break; 1395 default: 1396 return false; 1397 } 1398 int32_t reg_value = ReadCoreReg(Rm, &success); 1399 if (!success) 1400 return false; 1401 1402 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1403 1404 EmulateInstruction::Context context; 1405 context.type = eContextArithmetic; 1406 RegisterInfo sp_reg; 1407 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1408 1409 RegisterInfo other_reg; 1410 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1411 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1412 1413 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1414 return false; 1415 } 1416 return true; 1417} 1418 1419// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1420// at a PC-relative address, and changes instruction set from ARM to Thumb, or 1421// from Thumb to ARM. 1422// BLX (immediate) 1423bool 1424EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1425{ 1426#if 0 1427 // ARM pseudo code... 1428 if (ConditionPassed()) 1429 { 1430 EncodingSpecificOperations(); 1431 if CurrentInstrSet() == InstrSet_ARM then 1432 LR = PC - 4; 1433 else 1434 LR = PC<31:1> : '1'; 1435 if targetInstrSet == InstrSet_ARM then 1436 targetAddress = Align(PC,4) + imm32; 1437 else 1438 targetAddress = PC + imm32; 1439 SelectInstrSet(targetInstrSet); 1440 BranchWritePC(targetAddress); 1441 } 1442#endif 1443 1444 bool success = true; 1445 1446 if (ConditionPassed(opcode)) 1447 { 1448 EmulateInstruction::Context context; 1449 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1450 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1451 if (!success) 1452 return false; 1453 addr_t lr; // next instruction address 1454 addr_t target; // target address 1455 int32_t imm32; // PC-relative offset 1456 switch (encoding) { 1457 case eEncodingT1: 1458 { 1459 lr = pc | 1u; // return address 1460 uint32_t S = Bit32(opcode, 26); 1461 uint32_t imm10 = Bits32(opcode, 25, 16); 1462 uint32_t J1 = Bit32(opcode, 13); 1463 uint32_t J2 = Bit32(opcode, 11); 1464 uint32_t imm11 = Bits32(opcode, 10, 0); 1465 uint32_t I1 = !(J1 ^ S); 1466 uint32_t I2 = !(J2 ^ S); 1467 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1468 imm32 = llvm::SignExtend32<25>(imm25); 1469 target = pc + imm32; 1470 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1471 if (InITBlock() && !LastInITBlock()) 1472 return false; 1473 break; 1474 } 1475 case eEncodingT2: 1476 { 1477 lr = pc | 1u; // return address 1478 uint32_t S = Bit32(opcode, 26); 1479 uint32_t imm10H = Bits32(opcode, 25, 16); 1480 uint32_t J1 = Bit32(opcode, 13); 1481 uint32_t J2 = Bit32(opcode, 11); 1482 uint32_t imm10L = Bits32(opcode, 10, 1); 1483 uint32_t I1 = !(J1 ^ S); 1484 uint32_t I2 = !(J2 ^ S); 1485 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1486 imm32 = llvm::SignExtend32<25>(imm25); 1487 target = Align(pc, 4) + imm32; 1488 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1489 if (InITBlock() && !LastInITBlock()) 1490 return false; 1491 break; 1492 } 1493 case eEncodingA1: 1494 lr = pc - 4; // return address 1495 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1496 target = Align(pc, 4) + imm32; 1497 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1498 break; 1499 case eEncodingA2: 1500 lr = pc - 4; // return address 1501 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1502 target = pc + imm32; 1503 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1504 break; 1505 default: 1506 return false; 1507 } 1508 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1509 return false; 1510 if (!BranchWritePC(context, target)) 1511 return false; 1512 } 1513 return true; 1514} 1515 1516// Branch with Link and Exchange (register) calls a subroutine at an address and 1517// instruction set specified by a register. 1518// BLX (register) 1519bool 1520EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1521{ 1522#if 0 1523 // ARM pseudo code... 1524 if (ConditionPassed()) 1525 { 1526 EncodingSpecificOperations(); 1527 target = R[m]; 1528 if CurrentInstrSet() == InstrSet_ARM then 1529 next_instr_addr = PC - 4; 1530 LR = next_instr_addr; 1531 else 1532 next_instr_addr = PC - 2; 1533 LR = next_instr_addr<31:1> : '1'; 1534 BXWritePC(target); 1535 } 1536#endif 1537 1538 bool success = false; 1539 1540 if (ConditionPassed(opcode)) 1541 { 1542 EmulateInstruction::Context context; 1543 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1544 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1545 addr_t lr; // next instruction address 1546 if (!success) 1547 return false; 1548 uint32_t Rm; // the register with the target address 1549 switch (encoding) { 1550 case eEncodingT1: 1551 lr = (pc - 2) | 1u; // return address 1552 Rm = Bits32(opcode, 6, 3); 1553 // if m == 15 then UNPREDICTABLE; 1554 if (Rm == 15) 1555 return false; 1556 if (InITBlock() && !LastInITBlock()) 1557 return false; 1558 break; 1559 case eEncodingA1: 1560 lr = pc - 4; // return address 1561 Rm = Bits32(opcode, 3, 0); 1562 // if m == 15 then UNPREDICTABLE; 1563 if (Rm == 15) 1564 return false; 1565 break; 1566 default: 1567 return false; 1568 } 1569 addr_t target = ReadCoreReg (Rm, &success); 1570 if (!success) 1571 return false; 1572 RegisterInfo dwarf_reg; 1573 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1574 context.SetRegister (dwarf_reg); 1575 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1576 return false; 1577 if (!BXWritePC(context, target)) 1578 return false; 1579 } 1580 return true; 1581} 1582 1583// Branch and Exchange causes a branch to an address and instruction set specified by a register. 1584bool 1585EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1586{ 1587#if 0 1588 // ARM pseudo code... 1589 if (ConditionPassed()) 1590 { 1591 EncodingSpecificOperations(); 1592 BXWritePC(R[m]); 1593 } 1594#endif 1595 1596 if (ConditionPassed(opcode)) 1597 { 1598 EmulateInstruction::Context context; 1599 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1600 uint32_t Rm; // the register with the target address 1601 switch (encoding) { 1602 case eEncodingT1: 1603 Rm = Bits32(opcode, 6, 3); 1604 if (InITBlock() && !LastInITBlock()) 1605 return false; 1606 break; 1607 case eEncodingA1: 1608 Rm = Bits32(opcode, 3, 0); 1609 break; 1610 default: 1611 return false; 1612 } 1613 bool success = false; 1614 addr_t target = ReadCoreReg (Rm, &success); 1615 if (!success) 1616 return false; 1617 1618 RegisterInfo dwarf_reg; 1619 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1620 context.SetRegister (dwarf_reg); 1621 if (!BXWritePC(context, target)) 1622 return false; 1623 } 1624 return true; 1625} 1626 1627// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1628// address and instruction set specified by a register as though it were a BX instruction. 1629// 1630// TODO: Emulate Jazelle architecture? 1631// We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1632bool 1633EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1634{ 1635#if 0 1636 // ARM pseudo code... 1637 if (ConditionPassed()) 1638 { 1639 EncodingSpecificOperations(); 1640 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1641 BXWritePC(R[m]); 1642 else 1643 if JazelleAcceptsExecution() then 1644 SwitchToJazelleExecution(); 1645 else 1646 SUBARCHITECTURE_DEFINED handler call; 1647 } 1648#endif 1649 1650 if (ConditionPassed(opcode)) 1651 { 1652 EmulateInstruction::Context context; 1653 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1654 uint32_t Rm; // the register with the target address 1655 switch (encoding) { 1656 case eEncodingT1: 1657 Rm = Bits32(opcode, 19, 16); 1658 if (BadReg(Rm)) 1659 return false; 1660 if (InITBlock() && !LastInITBlock()) 1661 return false; 1662 break; 1663 case eEncodingA1: 1664 Rm = Bits32(opcode, 3, 0); 1665 if (Rm == 15) 1666 return false; 1667 break; 1668 default: 1669 return false; 1670 } 1671 bool success = false; 1672 addr_t target = ReadCoreReg (Rm, &success); 1673 if (!success) 1674 return false; 1675 1676 RegisterInfo dwarf_reg; 1677 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1678 context.SetRegister (dwarf_reg); 1679 if (!BXWritePC(context, target)) 1680 return false; 1681 } 1682 return true; 1683} 1684 1685// Set r7 to point to some ip offset. 1686// SUB (immediate) 1687bool 1688EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1689{ 1690#if 0 1691 // ARM pseudo code... 1692 if (ConditionPassed()) 1693 { 1694 EncodingSpecificOperations(); 1695 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1696 if d == 15 then // Can only occur for ARM encoding 1697 ALUWritePC(result); // setflags is always FALSE here 1698 else 1699 R[d] = result; 1700 if setflags then 1701 APSR.N = result<31>; 1702 APSR.Z = IsZeroBit(result); 1703 APSR.C = carry; 1704 APSR.V = overflow; 1705 } 1706#endif 1707 1708 if (ConditionPassed(opcode)) 1709 { 1710 bool success = false; 1711 const addr_t ip = ReadCoreReg (12, &success); 1712 if (!success) 1713 return false; 1714 uint32_t imm32; 1715 switch (encoding) { 1716 case eEncodingA1: 1717 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1718 break; 1719 default: 1720 return false; 1721 } 1722 addr_t ip_offset = imm32; 1723 addr_t addr = ip - ip_offset; // the adjusted ip value 1724 1725 EmulateInstruction::Context context; 1726 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1727 RegisterInfo dwarf_reg; 1728 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1729 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1730 1731 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1732 return false; 1733 } 1734 return true; 1735} 1736 1737// Set ip to point to some stack offset. 1738// SUB (SP minus immediate) 1739bool 1740EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1741{ 1742#if 0 1743 // ARM pseudo code... 1744 if (ConditionPassed()) 1745 { 1746 EncodingSpecificOperations(); 1747 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1748 if d == 15 then // Can only occur for ARM encoding 1749 ALUWritePC(result); // setflags is always FALSE here 1750 else 1751 R[d] = result; 1752 if setflags then 1753 APSR.N = result<31>; 1754 APSR.Z = IsZeroBit(result); 1755 APSR.C = carry; 1756 APSR.V = overflow; 1757 } 1758#endif 1759 1760 if (ConditionPassed(opcode)) 1761 { 1762 bool success = false; 1763 const addr_t sp = ReadCoreReg (SP_REG, &success); 1764 if (!success) 1765 return false; 1766 uint32_t imm32; 1767 switch (encoding) { 1768 case eEncodingA1: 1769 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1770 break; 1771 default: 1772 return false; 1773 } 1774 addr_t sp_offset = imm32; 1775 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1776 1777 EmulateInstruction::Context context; 1778 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1779 RegisterInfo dwarf_reg; 1780 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1781 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1782 1783 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1784 return false; 1785 } 1786 return true; 1787} 1788 1789// This instruction subtracts an immediate value from the SP value, and writes 1790// the result to the destination register. 1791// 1792// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1793bool 1794EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1795{ 1796#if 0 1797 // ARM pseudo code... 1798 if (ConditionPassed()) 1799 { 1800 EncodingSpecificOperations(); 1801 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1802 if d == 15 then // Can only occur for ARM encoding 1803 ALUWritePC(result); // setflags is always FALSE here 1804 else 1805 R[d] = result; 1806 if setflags then 1807 APSR.N = result<31>; 1808 APSR.Z = IsZeroBit(result); 1809 APSR.C = carry; 1810 APSR.V = overflow; 1811 } 1812#endif 1813 1814 bool success = false; 1815 if (ConditionPassed(opcode)) 1816 { 1817 const addr_t sp = ReadCoreReg (SP_REG, &success); 1818 if (!success) 1819 return false; 1820 1821 uint32_t Rd; 1822 bool setflags; 1823 uint32_t imm32; 1824 switch (encoding) { 1825 case eEncodingT1: 1826 Rd = 13; 1827 setflags = false; 1828 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1829 break; 1830 case eEncodingT2: 1831 Rd = Bits32(opcode, 11, 8); 1832 setflags = BitIsSet(opcode, 20); 1833 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1834 if (Rd == 15 && setflags) 1835 return EmulateCMPImm(opcode, eEncodingT2); 1836 if (Rd == 15 && !setflags) 1837 return false; 1838 break; 1839 case eEncodingT3: 1840 Rd = Bits32(opcode, 11, 8); 1841 setflags = false; 1842 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1843 if (Rd == 15) 1844 return false; 1845 break; 1846 case eEncodingA1: 1847 Rd = Bits32(opcode, 15, 12); 1848 setflags = BitIsSet(opcode, 20); 1849 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1850 1851 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1852 if (Rd == 15 && setflags) 1853 return EmulateSUBSPcLrEtc (opcode, encoding); 1854 break; 1855 default: 1856 return false; 1857 } 1858 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1859 1860 EmulateInstruction::Context context; 1861 if (Rd == 13) 1862 { 1863 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1864 // value gets passed down to context.SetImmediateSigned. 1865 context.type = EmulateInstruction::eContextAdjustStackPointer; 1866 context.SetImmediateSigned (-imm64); // the stack pointer offset 1867 } 1868 else 1869 { 1870 context.type = EmulateInstruction::eContextImmediate; 1871 context.SetNoArgs (); 1872 } 1873 1874 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1875 return false; 1876 } 1877 return true; 1878} 1879 1880// A store operation to the stack that also updates the SP. 1881bool 1882EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1883{ 1884#if 0 1885 // ARM pseudo code... 1886 if (ConditionPassed()) 1887 { 1888 EncodingSpecificOperations(); 1889 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1890 address = if index then offset_addr else R[n]; 1891 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1892 if wback then R[n] = offset_addr; 1893 } 1894#endif 1895 1896 bool conditional = false; 1897 bool success = false; 1898 if (ConditionPassed(opcode, &conditional)) 1899 { 1900 const uint32_t addr_byte_size = GetAddressByteSize(); 1901 const addr_t sp = ReadCoreReg (SP_REG, &success); 1902 if (!success) 1903 return false; 1904 uint32_t Rt; // the source register 1905 uint32_t imm12; 1906 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1907 1908 bool index; 1909 bool add; 1910 bool wback; 1911 switch (encoding) { 1912 case eEncodingA1: 1913 Rt = Bits32(opcode, 15, 12); 1914 imm12 = Bits32(opcode, 11, 0); 1915 Rn = Bits32 (opcode, 19, 16); 1916 1917 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1918 return false; 1919 1920 index = BitIsSet (opcode, 24); 1921 add = BitIsSet (opcode, 23); 1922 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1923 1924 if (wback && ((Rn == 15) || (Rn == Rt))) 1925 return false; 1926 break; 1927 default: 1928 return false; 1929 } 1930 addr_t offset_addr; 1931 if (add) 1932 offset_addr = sp + imm12; 1933 else 1934 offset_addr = sp - imm12; 1935 1936 addr_t addr; 1937 if (index) 1938 addr = offset_addr; 1939 else 1940 addr = sp; 1941 1942 EmulateInstruction::Context context; 1943 if (conditional) 1944 context.type = EmulateInstruction::eContextRegisterStore; 1945 else 1946 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1947 RegisterInfo sp_reg; 1948 RegisterInfo dwarf_reg; 1949 1950 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1951 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 1952 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 1953 if (Rt != 15) 1954 { 1955 uint32_t reg_value = ReadCoreReg(Rt, &success); 1956 if (!success) 1957 return false; 1958 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1959 return false; 1960 } 1961 else 1962 { 1963 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1964 if (!success) 1965 return false; 1966 if (!MemUWrite (context, addr, pc, addr_byte_size)) 1967 return false; 1968 } 1969 1970 1971 if (wback) 1972 { 1973 context.type = EmulateInstruction::eContextAdjustStackPointer; 1974 context.SetImmediateSigned (addr - sp); 1975 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 1976 return false; 1977 } 1978 } 1979 return true; 1980} 1981 1982// Vector Push stores multiple extension registers to the stack. 1983// It also updates SP to point to the start of the stored data. 1984bool 1985EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 1986{ 1987#if 0 1988 // ARM pseudo code... 1989 if (ConditionPassed()) 1990 { 1991 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1992 address = SP - imm32; 1993 SP = SP - imm32; 1994 if single_regs then 1995 for r = 0 to regs-1 1996 MemA[address,4] = S[d+r]; address = address+4; 1997 else 1998 for r = 0 to regs-1 1999 // Store as two word-aligned words in the correct order for current endianness. 2000 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2001 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2002 address = address+8; 2003 } 2004#endif 2005 2006 bool success = false; 2007 bool conditional = false; 2008 if (ConditionPassed(opcode, &conditional)) 2009 { 2010 const uint32_t addr_byte_size = GetAddressByteSize(); 2011 const addr_t sp = ReadCoreReg (SP_REG, &success); 2012 if (!success) 2013 return false; 2014 bool single_regs; 2015 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2016 uint32_t imm32; // stack offset 2017 uint32_t regs; // number of registers 2018 switch (encoding) { 2019 case eEncodingT1: 2020 case eEncodingA1: 2021 single_regs = false; 2022 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2023 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2024 // If UInt(imm8) is odd, see "FSTMX". 2025 regs = Bits32(opcode, 7, 0) / 2; 2026 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2027 if (regs == 0 || regs > 16 || (d + regs) > 32) 2028 return false; 2029 break; 2030 case eEncodingT2: 2031 case eEncodingA2: 2032 single_regs = true; 2033 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2034 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2035 regs = Bits32(opcode, 7, 0); 2036 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2037 if (regs == 0 || regs > 16 || (d + regs) > 32) 2038 return false; 2039 break; 2040 default: 2041 return false; 2042 } 2043 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2044 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2045 addr_t sp_offset = imm32; 2046 addr_t addr = sp - sp_offset; 2047 uint32_t i; 2048 2049 EmulateInstruction::Context context; 2050 if (conditional) 2051 context.type = EmulateInstruction::eContextRegisterStore; 2052 else 2053 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2054 RegisterInfo dwarf_reg; 2055 RegisterInfo sp_reg; 2056 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2057 for (i=0; i<regs; ++i) 2058 { 2059 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2060 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2061 // uint64_t to accommodate 64-bit registers. 2062 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2063 if (!success) 2064 return false; 2065 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2066 return false; 2067 addr += reg_byte_size; 2068 } 2069 2070 context.type = EmulateInstruction::eContextAdjustStackPointer; 2071 context.SetImmediateSigned (-sp_offset); 2072 2073 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2074 return false; 2075 } 2076 return true; 2077} 2078 2079// Vector Pop loads multiple extension registers from the stack. 2080// It also updates SP to point just above the loaded data. 2081bool 2082EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2083{ 2084#if 0 2085 // ARM pseudo code... 2086 if (ConditionPassed()) 2087 { 2088 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2089 address = SP; 2090 SP = SP + imm32; 2091 if single_regs then 2092 for r = 0 to regs-1 2093 S[d+r] = MemA[address,4]; address = address+4; 2094 else 2095 for r = 0 to regs-1 2096 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2097 // Combine the word-aligned words in the correct order for current endianness. 2098 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2099 } 2100#endif 2101 2102 bool success = false; 2103 bool conditional = false; 2104 if (ConditionPassed(opcode, &conditional)) 2105 { 2106 const uint32_t addr_byte_size = GetAddressByteSize(); 2107 const addr_t sp = ReadCoreReg (SP_REG, &success); 2108 if (!success) 2109 return false; 2110 bool single_regs; 2111 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2112 uint32_t imm32; // stack offset 2113 uint32_t regs; // number of registers 2114 switch (encoding) { 2115 case eEncodingT1: 2116 case eEncodingA1: 2117 single_regs = false; 2118 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2119 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2120 // If UInt(imm8) is odd, see "FLDMX". 2121 regs = Bits32(opcode, 7, 0) / 2; 2122 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2123 if (regs == 0 || regs > 16 || (d + regs) > 32) 2124 return false; 2125 break; 2126 case eEncodingT2: 2127 case eEncodingA2: 2128 single_regs = true; 2129 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2130 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2131 regs = Bits32(opcode, 7, 0); 2132 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2133 if (regs == 0 || regs > 16 || (d + regs) > 32) 2134 return false; 2135 break; 2136 default: 2137 return false; 2138 } 2139 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2140 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2141 addr_t sp_offset = imm32; 2142 addr_t addr = sp; 2143 uint32_t i; 2144 uint64_t data; // uint64_t to accomodate 64-bit registers. 2145 2146 EmulateInstruction::Context context; 2147 if (conditional) 2148 context.type = EmulateInstruction::eContextRegisterLoad; 2149 else 2150 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2151 RegisterInfo dwarf_reg; 2152 RegisterInfo sp_reg; 2153 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2154 for (i=0; i<regs; ++i) 2155 { 2156 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2157 context.SetRegisterPlusOffset (sp_reg, addr - sp); 2158 data = MemARead(context, addr, reg_byte_size, 0, &success); 2159 if (!success) 2160 return false; 2161 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2162 return false; 2163 addr += reg_byte_size; 2164 } 2165 2166 context.type = EmulateInstruction::eContextAdjustStackPointer; 2167 context.SetImmediateSigned (sp_offset); 2168 2169 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2170 return false; 2171 } 2172 return true; 2173} 2174 2175// SVC (previously SWI) 2176bool 2177EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2178{ 2179#if 0 2180 // ARM pseudo code... 2181 if (ConditionPassed()) 2182 { 2183 EncodingSpecificOperations(); 2184 CallSupervisor(); 2185 } 2186#endif 2187 2188 bool success = false; 2189 2190 if (ConditionPassed(opcode)) 2191 { 2192 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2193 addr_t lr; // next instruction address 2194 if (!success) 2195 return false; 2196 uint32_t imm32; // the immediate constant 2197 uint32_t mode; // ARM or Thumb mode 2198 switch (encoding) { 2199 case eEncodingT1: 2200 lr = (pc + 2) | 1u; // return address 2201 imm32 = Bits32(opcode, 7, 0); 2202 mode = eModeThumb; 2203 break; 2204 case eEncodingA1: 2205 lr = pc + 4; // return address 2206 imm32 = Bits32(opcode, 23, 0); 2207 mode = eModeARM; 2208 break; 2209 default: 2210 return false; 2211 } 2212 2213 EmulateInstruction::Context context; 2214 context.type = EmulateInstruction::eContextSupervisorCall; 2215 context.SetISAAndImmediate (mode, imm32); 2216 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2217 return false; 2218 } 2219 return true; 2220} 2221 2222// If Then makes up to four following instructions (the IT block) conditional. 2223bool 2224EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2225{ 2226#if 0 2227 // ARM pseudo code... 2228 EncodingSpecificOperations(); 2229 ITSTATE.IT<7:0> = firstcond:mask; 2230#endif 2231 2232 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2233 return true; 2234} 2235 2236bool 2237EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2238{ 2239 // NOP, nothing to do... 2240 return true; 2241} 2242 2243// Branch causes a branch to a target address. 2244bool 2245EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2246{ 2247#if 0 2248 // ARM pseudo code... 2249 if (ConditionPassed()) 2250 { 2251 EncodingSpecificOperations(); 2252 BranchWritePC(PC + imm32); 2253 } 2254#endif 2255 2256 bool success = false; 2257 2258 if (ConditionPassed(opcode)) 2259 { 2260 EmulateInstruction::Context context; 2261 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2262 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2263 if (!success) 2264 return false; 2265 addr_t target; // target address 2266 int32_t imm32; // PC-relative offset 2267 switch (encoding) { 2268 case eEncodingT1: 2269 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2270 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2271 target = pc + imm32; 2272 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2273 break; 2274 case eEncodingT2: 2275 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2276 target = pc + imm32; 2277 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2278 break; 2279 case eEncodingT3: 2280 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2281 { 2282 uint32_t S = Bit32(opcode, 26); 2283 uint32_t imm6 = Bits32(opcode, 21, 16); 2284 uint32_t J1 = Bit32(opcode, 13); 2285 uint32_t J2 = Bit32(opcode, 11); 2286 uint32_t imm11 = Bits32(opcode, 10, 0); 2287 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2288 imm32 = llvm::SignExtend32<21>(imm21); 2289 target = pc + imm32; 2290 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2291 break; 2292 } 2293 case eEncodingT4: 2294 { 2295 uint32_t S = Bit32(opcode, 26); 2296 uint32_t imm10 = Bits32(opcode, 25, 16); 2297 uint32_t J1 = Bit32(opcode, 13); 2298 uint32_t J2 = Bit32(opcode, 11); 2299 uint32_t imm11 = Bits32(opcode, 10, 0); 2300 uint32_t I1 = !(J1 ^ S); 2301 uint32_t I2 = !(J2 ^ S); 2302 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2303 imm32 = llvm::SignExtend32<25>(imm25); 2304 target = pc + imm32; 2305 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2306 break; 2307 } 2308 case eEncodingA1: 2309 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2310 target = pc + imm32; 2311 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2312 break; 2313 default: 2314 return false; 2315 } 2316 if (!BranchWritePC(context, target)) 2317 return false; 2318 } 2319 return true; 2320} 2321 2322// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2323// zero and conditionally branch forward a constant value. They do not affect the condition flags. 2324// CBNZ, CBZ 2325bool 2326EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2327{ 2328#if 0 2329 // ARM pseudo code... 2330 EncodingSpecificOperations(); 2331 if nonzero ^ IsZero(R[n]) then 2332 BranchWritePC(PC + imm32); 2333#endif 2334 2335 bool success = false; 2336 2337 // Read the register value from the operand register Rn. 2338 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2339 if (!success) 2340 return false; 2341 2342 EmulateInstruction::Context context; 2343 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2344 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2345 if (!success) 2346 return false; 2347 2348 addr_t target; // target address 2349 uint32_t imm32; // PC-relative offset to branch forward 2350 bool nonzero; 2351 switch (encoding) { 2352 case eEncodingT1: 2353 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2354 nonzero = BitIsSet(opcode, 11); 2355 target = pc + imm32; 2356 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2357 break; 2358 default: 2359 return false; 2360 } 2361 if (nonzero ^ (reg_val == 0)) 2362 if (!BranchWritePC(context, target)) 2363 return false; 2364 2365 return true; 2366} 2367 2368// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2369// A base register provides a pointer to the table, and a second register supplies an index into the table. 2370// The branch length is twice the value of the byte returned from the table. 2371// 2372// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2373// A base register provides a pointer to the table, and a second register supplies an index into the table. 2374// The branch length is twice the value of the halfword returned from the table. 2375// TBB, TBH 2376bool 2377EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2378{ 2379#if 0 2380 // ARM pseudo code... 2381 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2382 if is_tbh then 2383 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2384 else 2385 halfwords = UInt(MemU[R[n]+R[m], 1]); 2386 BranchWritePC(PC + 2*halfwords); 2387#endif 2388 2389 bool success = false; 2390 2391 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2392 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2393 bool is_tbh; // true if table branch halfword 2394 switch (encoding) { 2395 case eEncodingT1: 2396 Rn = Bits32(opcode, 19, 16); 2397 Rm = Bits32(opcode, 3, 0); 2398 is_tbh = BitIsSet(opcode, 4); 2399 if (Rn == 13 || BadReg(Rm)) 2400 return false; 2401 if (InITBlock() && !LastInITBlock()) 2402 return false; 2403 break; 2404 default: 2405 return false; 2406 } 2407 2408 // Read the address of the table from the operand register Rn. 2409 // The PC can be used, in which case the table immediately follows this instruction. 2410 uint32_t base = ReadCoreReg(Rm, &success); 2411 if (!success) 2412 return false; 2413 2414 // the table index 2415 uint32_t index = ReadCoreReg(Rm, &success); 2416 if (!success) 2417 return false; 2418 2419 // the offsetted table address 2420 addr_t addr = base + (is_tbh ? index*2 : index); 2421 2422 // PC-relative offset to branch forward 2423 EmulateInstruction::Context context; 2424 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2425 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2426 if (!success) 2427 return false; 2428 2429 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2430 if (!success) 2431 return false; 2432 2433 // target address 2434 addr_t target = pc + offset; 2435 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2436 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2437 2438 if (!BranchWritePC(context, target)) 2439 return false; 2440 2441 return true; 2442} 2443 2444// This instruction adds an immediate value to a register value, and writes the result to the destination register. 2445// It can optionally update the condition flags based on the result. 2446bool 2447EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2448{ 2449#if 0 2450 if ConditionPassed() then 2451 EncodingSpecificOperations(); 2452 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2453 R[d] = result; 2454 if setflags then 2455 APSR.N = result<31>; 2456 APSR.Z = IsZeroBit(result); 2457 APSR.C = carry; 2458 APSR.V = overflow; 2459#endif 2460 2461 bool success = false; 2462 2463 if (ConditionPassed(opcode)) 2464 { 2465 uint32_t d; 2466 uint32_t n; 2467 bool setflags; 2468 uint32_t imm32; 2469 uint32_t carry_out; 2470 2471 //EncodingSpecificOperations(); 2472 switch (encoding) 2473 { 2474 case eEncodingT1: 2475 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2476 d = Bits32 (opcode, 2, 0); 2477 n = Bits32 (opcode, 5, 3); 2478 setflags = !InITBlock(); 2479 imm32 = Bits32 (opcode, 8,6); 2480 2481 break; 2482 2483 case eEncodingT2: 2484 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2485 d = Bits32 (opcode, 10, 8); 2486 n = Bits32 (opcode, 10, 8); 2487 setflags = !InITBlock(); 2488 imm32 = Bits32 (opcode, 7, 0); 2489 2490 break; 2491 2492 case eEncodingT3: 2493 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2494 // if Rn == '1101' then SEE ADD (SP plus immediate); 2495 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2496 d = Bits32 (opcode, 11, 8); 2497 n = Bits32 (opcode, 19, 16); 2498 setflags = BitIsSet (opcode, 20); 2499 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2500 2501 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2502 if (BadReg (d) || (n == 15)) 2503 return false; 2504 2505 break; 2506 2507 case eEncodingT4: 2508 { 2509 // if Rn == '1111' then SEE ADR; 2510 // if Rn == '1101' then SEE ADD (SP plus immediate); 2511 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2512 d = Bits32 (opcode, 11, 8); 2513 n = Bits32 (opcode, 19, 16); 2514 setflags = false; 2515 uint32_t i = Bit32 (opcode, 26); 2516 uint32_t imm3 = Bits32 (opcode, 14, 12); 2517 uint32_t imm8 = Bits32 (opcode, 7, 0); 2518 imm32 = (i << 11) | (imm3 << 8) | imm8; 2519 2520 // if BadReg(d) then UNPREDICTABLE; 2521 if (BadReg (d)) 2522 return false; 2523 2524 break; 2525 } 2526 default: 2527 return false; 2528 } 2529 2530 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2531 if (!success) 2532 return false; 2533 2534 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2535 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2536 2537 RegisterInfo reg_n; 2538 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2539 2540 EmulateInstruction::Context context; 2541 context.type = eContextArithmetic; 2542 context.SetRegisterPlusOffset (reg_n, imm32); 2543 2544 //R[d] = result; 2545 //if setflags then 2546 //APSR.N = result<31>; 2547 //APSR.Z = IsZeroBit(result); 2548 //APSR.C = carry; 2549 //APSR.V = overflow; 2550 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2551 return false; 2552 2553 } 2554 return true; 2555} 2556 2557// This instruction adds an immediate value to a register value, and writes the result to the destination 2558// register. It can optionally update the condition flags based on the result. 2559bool 2560EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2561{ 2562#if 0 2563 // ARM pseudo code... 2564 if ConditionPassed() then 2565 EncodingSpecificOperations(); 2566 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2567 if d == 15 then 2568 ALUWritePC(result); // setflags is always FALSE here 2569 else 2570 R[d] = result; 2571 if setflags then 2572 APSR.N = result<31>; 2573 APSR.Z = IsZeroBit(result); 2574 APSR.C = carry; 2575 APSR.V = overflow; 2576#endif 2577 2578 bool success = false; 2579 2580 if (ConditionPassed(opcode)) 2581 { 2582 uint32_t Rd, Rn; 2583 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2584 bool setflags; 2585 switch (encoding) 2586 { 2587 case eEncodingA1: 2588 Rd = Bits32(opcode, 15, 12); 2589 Rn = Bits32(opcode, 19, 16); 2590 setflags = BitIsSet(opcode, 20); 2591 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2592 break; 2593 default: 2594 return false; 2595 } 2596 2597 // Read the first operand. 2598 uint32_t val1 = ReadCoreReg(Rn, &success); 2599 if (!success) 2600 return false; 2601 2602 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2603 2604 EmulateInstruction::Context context; 2605 context.type = eContextArithmetic; 2606 RegisterInfo dwarf_reg; 2607 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2608 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2609 2610 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2611 return false; 2612 } 2613 return true; 2614} 2615 2616// This instruction adds a register value and an optionally-shifted register value, and writes the result 2617// to the destination register. It can optionally update the condition flags based on the result. 2618bool 2619EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2620{ 2621#if 0 2622 // ARM pseudo code... 2623 if ConditionPassed() then 2624 EncodingSpecificOperations(); 2625 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2626 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2627 if d == 15 then 2628 ALUWritePC(result); // setflags is always FALSE here 2629 else 2630 R[d] = result; 2631 if setflags then 2632 APSR.N = result<31>; 2633 APSR.Z = IsZeroBit(result); 2634 APSR.C = carry; 2635 APSR.V = overflow; 2636#endif 2637 2638 bool success = false; 2639 2640 if (ConditionPassed(opcode)) 2641 { 2642 uint32_t Rd, Rn, Rm; 2643 ARM_ShifterType shift_t; 2644 uint32_t shift_n; // the shift applied to the value read from Rm 2645 bool setflags; 2646 switch (encoding) 2647 { 2648 case eEncodingT1: 2649 Rd = Bits32(opcode, 2, 0); 2650 Rn = Bits32(opcode, 5, 3); 2651 Rm = Bits32(opcode, 8, 6); 2652 setflags = !InITBlock(); 2653 shift_t = SRType_LSL; 2654 shift_n = 0; 2655 break; 2656 case eEncodingT2: 2657 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2658 Rm = Bits32(opcode, 6, 3); 2659 setflags = false; 2660 shift_t = SRType_LSL; 2661 shift_n = 0; 2662 if (Rn == 15 && Rm == 15) 2663 return false; 2664 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2665 return false; 2666 break; 2667 case eEncodingA1: 2668 Rd = Bits32(opcode, 15, 12); 2669 Rn = Bits32(opcode, 19, 16); 2670 Rm = Bits32(opcode, 3, 0); 2671 setflags = BitIsSet(opcode, 20); 2672 shift_n = DecodeImmShiftARM(opcode, shift_t); 2673 break; 2674 default: 2675 return false; 2676 } 2677 2678 // Read the first operand. 2679 uint32_t val1 = ReadCoreReg(Rn, &success); 2680 if (!success) 2681 return false; 2682 2683 // Read the second operand. 2684 uint32_t val2 = ReadCoreReg(Rm, &success); 2685 if (!success) 2686 return false; 2687 2688 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2689 if (!success) 2690 return false; 2691 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2692 2693 EmulateInstruction::Context context; 2694 context.type = eContextArithmetic; 2695 RegisterInfo op1_reg; 2696 RegisterInfo op2_reg; 2697 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2698 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2699 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2700 2701 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2702 return false; 2703 } 2704 return true; 2705} 2706 2707// Compare Negative (immediate) adds a register value and an immediate value. 2708// It updates the condition flags based on the result, and discards the result. 2709bool 2710EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2711{ 2712#if 0 2713 // ARM pseudo code... 2714 if ConditionPassed() then 2715 EncodingSpecificOperations(); 2716 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2717 APSR.N = result<31>; 2718 APSR.Z = IsZeroBit(result); 2719 APSR.C = carry; 2720 APSR.V = overflow; 2721#endif 2722 2723 bool success = false; 2724 2725 uint32_t Rn; // the first operand 2726 uint32_t imm32; // the immediate value to be compared with 2727 switch (encoding) { 2728 case eEncodingT1: 2729 Rn = Bits32(opcode, 19, 16); 2730 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2731 if (Rn == 15) 2732 return false; 2733 break; 2734 case eEncodingA1: 2735 Rn = Bits32(opcode, 19, 16); 2736 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2737 break; 2738 default: 2739 return false; 2740 } 2741 // Read the register value from the operand register Rn. 2742 uint32_t reg_val = ReadCoreReg(Rn, &success); 2743 if (!success) 2744 return false; 2745 2746 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2747 2748 EmulateInstruction::Context context; 2749 context.type = EmulateInstruction::eContextImmediate; 2750 context.SetNoArgs (); 2751 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2752 return false; 2753 2754 return true; 2755} 2756 2757// Compare Negative (register) adds a register value and an optionally-shifted register value. 2758// It updates the condition flags based on the result, and discards the result. 2759bool 2760EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2761{ 2762#if 0 2763 // ARM pseudo code... 2764 if ConditionPassed() then 2765 EncodingSpecificOperations(); 2766 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2767 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2768 APSR.N = result<31>; 2769 APSR.Z = IsZeroBit(result); 2770 APSR.C = carry; 2771 APSR.V = overflow; 2772#endif 2773 2774 bool success = false; 2775 2776 uint32_t Rn; // the first operand 2777 uint32_t Rm; // the second operand 2778 ARM_ShifterType shift_t; 2779 uint32_t shift_n; // the shift applied to the value read from Rm 2780 switch (encoding) { 2781 case eEncodingT1: 2782 Rn = Bits32(opcode, 2, 0); 2783 Rm = Bits32(opcode, 5, 3); 2784 shift_t = SRType_LSL; 2785 shift_n = 0; 2786 break; 2787 case eEncodingT2: 2788 Rn = Bits32(opcode, 19, 16); 2789 Rm = Bits32(opcode, 3, 0); 2790 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2791 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2792 if (Rn == 15 || BadReg(Rm)) 2793 return false; 2794 break; 2795 case eEncodingA1: 2796 Rn = Bits32(opcode, 19, 16); 2797 Rm = Bits32(opcode, 3, 0); 2798 shift_n = DecodeImmShiftARM(opcode, shift_t); 2799 break; 2800 default: 2801 return false; 2802 } 2803 // Read the register value from register Rn. 2804 uint32_t val1 = ReadCoreReg(Rn, &success); 2805 if (!success) 2806 return false; 2807 2808 // Read the register value from register Rm. 2809 uint32_t val2 = ReadCoreReg(Rm, &success); 2810 if (!success) 2811 return false; 2812 2813 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2814 if (!success) 2815 return false; 2816 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2817 2818 EmulateInstruction::Context context; 2819 context.type = EmulateInstruction::eContextImmediate; 2820 context.SetNoArgs(); 2821 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2822 return false; 2823 2824 return true; 2825} 2826 2827// Compare (immediate) subtracts an immediate value from a register value. 2828// It updates the condition flags based on the result, and discards the result. 2829bool 2830EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2831{ 2832#if 0 2833 // ARM pseudo code... 2834 if ConditionPassed() then 2835 EncodingSpecificOperations(); 2836 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2837 APSR.N = result<31>; 2838 APSR.Z = IsZeroBit(result); 2839 APSR.C = carry; 2840 APSR.V = overflow; 2841#endif 2842 2843 bool success = false; 2844 2845 uint32_t Rn; // the first operand 2846 uint32_t imm32; // the immediate value to be compared with 2847 switch (encoding) { 2848 case eEncodingT1: 2849 Rn = Bits32(opcode, 10, 8); 2850 imm32 = Bits32(opcode, 7, 0); 2851 break; 2852 case eEncodingT2: 2853 Rn = Bits32(opcode, 19, 16); 2854 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2855 if (Rn == 15) 2856 return false; 2857 break; 2858 case eEncodingA1: 2859 Rn = Bits32(opcode, 19, 16); 2860 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2861 break; 2862 default: 2863 return false; 2864 } 2865 // Read the register value from the operand register Rn. 2866 uint32_t reg_val = ReadCoreReg(Rn, &success); 2867 if (!success) 2868 return false; 2869 2870 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2871 2872 EmulateInstruction::Context context; 2873 context.type = EmulateInstruction::eContextImmediate; 2874 context.SetNoArgs (); 2875 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2876 return false; 2877 2878 return true; 2879} 2880 2881// Compare (register) subtracts an optionally-shifted register value from a register value. 2882// It updates the condition flags based on the result, and discards the result. 2883bool 2884EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2885{ 2886#if 0 2887 // ARM pseudo code... 2888 if ConditionPassed() then 2889 EncodingSpecificOperations(); 2890 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2891 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2892 APSR.N = result<31>; 2893 APSR.Z = IsZeroBit(result); 2894 APSR.C = carry; 2895 APSR.V = overflow; 2896#endif 2897 2898 bool success = false; 2899 2900 uint32_t Rn; // the first operand 2901 uint32_t Rm; // the second operand 2902 ARM_ShifterType shift_t; 2903 uint32_t shift_n; // the shift applied to the value read from Rm 2904 switch (encoding) { 2905 case eEncodingT1: 2906 Rn = Bits32(opcode, 2, 0); 2907 Rm = Bits32(opcode, 5, 3); 2908 shift_t = SRType_LSL; 2909 shift_n = 0; 2910 break; 2911 case eEncodingT2: 2912 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2913 Rm = Bits32(opcode, 6, 3); 2914 shift_t = SRType_LSL; 2915 shift_n = 0; 2916 if (Rn < 8 && Rm < 8) 2917 return false; 2918 if (Rn == 15 || Rm == 15) 2919 return false; 2920 break; 2921 case eEncodingA1: 2922 Rn = Bits32(opcode, 19, 16); 2923 Rm = Bits32(opcode, 3, 0); 2924 shift_n = DecodeImmShiftARM(opcode, shift_t); 2925 break; 2926 default: 2927 return false; 2928 } 2929 // Read the register value from register Rn. 2930 uint32_t val1 = ReadCoreReg(Rn, &success); 2931 if (!success) 2932 return false; 2933 2934 // Read the register value from register Rm. 2935 uint32_t val2 = ReadCoreReg(Rm, &success); 2936 if (!success) 2937 return false; 2938 2939 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2940 if (!success) 2941 return false; 2942 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 2943 2944 EmulateInstruction::Context context; 2945 context.type = EmulateInstruction::eContextImmediate; 2946 context.SetNoArgs(); 2947 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2948 return false; 2949 2950 return true; 2951} 2952 2953// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2954// shifting in copies of its sign bit, and writes the result to the destination register. It can 2955// optionally update the condition flags based on the result. 2956bool 2957EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 2958{ 2959#if 0 2960 // ARM pseudo code... 2961 if ConditionPassed() then 2962 EncodingSpecificOperations(); 2963 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2964 if d == 15 then // Can only occur for ARM encoding 2965 ALUWritePC(result); // setflags is always FALSE here 2966 else 2967 R[d] = result; 2968 if setflags then 2969 APSR.N = result<31>; 2970 APSR.Z = IsZeroBit(result); 2971 APSR.C = carry; 2972 // APSR.V unchanged 2973#endif 2974 2975 return EmulateShiftImm (opcode, encoding, SRType_ASR); 2976} 2977 2978// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 2979// shifting in copies of its sign bit, and writes the result to the destination register. 2980// The variable number of bits is read from the bottom byte of a register. It can optionally update 2981// the condition flags based on the result. 2982bool 2983EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 2984{ 2985#if 0 2986 // ARM pseudo code... 2987 if ConditionPassed() then 2988 EncodingSpecificOperations(); 2989 shift_n = UInt(R[m]<7:0>); 2990 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2991 R[d] = result; 2992 if setflags then 2993 APSR.N = result<31>; 2994 APSR.Z = IsZeroBit(result); 2995 APSR.C = carry; 2996 // APSR.V unchanged 2997#endif 2998 2999 return EmulateShiftReg (opcode, encoding, SRType_ASR); 3000} 3001 3002// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 3003// shifting in zeros, and writes the result to the destination register. It can optionally 3004// update the condition flags based on the result. 3005bool 3006EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 3007{ 3008#if 0 3009 // ARM pseudo code... 3010 if ConditionPassed() then 3011 EncodingSpecificOperations(); 3012 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3013 if d == 15 then // Can only occur for ARM encoding 3014 ALUWritePC(result); // setflags is always FALSE here 3015 else 3016 R[d] = result; 3017 if setflags then 3018 APSR.N = result<31>; 3019 APSR.Z = IsZeroBit(result); 3020 APSR.C = carry; 3021 // APSR.V unchanged 3022#endif 3023 3024 return EmulateShiftImm (opcode, encoding, SRType_LSL); 3025} 3026 3027// Logical Shift Left (register) shifts a register value left by a variable number of bits, 3028// shifting in zeros, and writes the result to the destination register. The variable number 3029// of bits is read from the bottom byte of a register. It can optionally update the condition 3030// flags based on the result. 3031bool 3032EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 3033{ 3034#if 0 3035 // ARM pseudo code... 3036 if ConditionPassed() then 3037 EncodingSpecificOperations(); 3038 shift_n = UInt(R[m]<7:0>); 3039 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3040 R[d] = result; 3041 if setflags then 3042 APSR.N = result<31>; 3043 APSR.Z = IsZeroBit(result); 3044 APSR.C = carry; 3045 // APSR.V unchanged 3046#endif 3047 3048 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3049} 3050 3051// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3052// shifting in zeros, and writes the result to the destination register. It can optionally 3053// update the condition flags based on the result. 3054bool 3055EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3056{ 3057#if 0 3058 // ARM pseudo code... 3059 if ConditionPassed() then 3060 EncodingSpecificOperations(); 3061 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3062 if d == 15 then // Can only occur for ARM encoding 3063 ALUWritePC(result); // setflags is always FALSE here 3064 else 3065 R[d] = result; 3066 if setflags then 3067 APSR.N = result<31>; 3068 APSR.Z = IsZeroBit(result); 3069 APSR.C = carry; 3070 // APSR.V unchanged 3071#endif 3072 3073 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3074} 3075 3076// Logical Shift Right (register) shifts a register value right by a variable number of bits, 3077// shifting in zeros, and writes the result to the destination register. The variable number 3078// of bits is read from the bottom byte of a register. It can optionally update the condition 3079// flags based on the result. 3080bool 3081EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3082{ 3083#if 0 3084 // ARM pseudo code... 3085 if ConditionPassed() then 3086 EncodingSpecificOperations(); 3087 shift_n = UInt(R[m]<7:0>); 3088 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3089 R[d] = result; 3090 if setflags then 3091 APSR.N = result<31>; 3092 APSR.Z = IsZeroBit(result); 3093 APSR.C = carry; 3094 // APSR.V unchanged 3095#endif 3096 3097 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3098} 3099 3100// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3101// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3102// It can optionally update the condition flags based on the result. 3103bool 3104EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3105{ 3106#if 0 3107 // ARM pseudo code... 3108 if ConditionPassed() then 3109 EncodingSpecificOperations(); 3110 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3111 if d == 15 then // Can only occur for ARM encoding 3112 ALUWritePC(result); // setflags is always FALSE here 3113 else 3114 R[d] = result; 3115 if setflags then 3116 APSR.N = result<31>; 3117 APSR.Z = IsZeroBit(result); 3118 APSR.C = carry; 3119 // APSR.V unchanged 3120#endif 3121 3122 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3123} 3124 3125// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3126// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3127// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3128// flags based on the result. 3129bool 3130EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3131{ 3132#if 0 3133 // ARM pseudo code... 3134 if ConditionPassed() then 3135 EncodingSpecificOperations(); 3136 shift_n = UInt(R[m]<7:0>); 3137 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3138 R[d] = result; 3139 if setflags then 3140 APSR.N = result<31>; 3141 APSR.Z = IsZeroBit(result); 3142 APSR.C = carry; 3143 // APSR.V unchanged 3144#endif 3145 3146 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3147} 3148 3149// Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3150// with the carry flag shifted into bit [31]. 3151// 3152// RRX can optionally update the condition flags based on the result. 3153// In that case, bit [0] is shifted into the carry flag. 3154bool 3155EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3156{ 3157#if 0 3158 // ARM pseudo code... 3159 if ConditionPassed() then 3160 EncodingSpecificOperations(); 3161 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3162 if d == 15 then // Can only occur for ARM encoding 3163 ALUWritePC(result); // setflags is always FALSE here 3164 else 3165 R[d] = result; 3166 if setflags then 3167 APSR.N = result<31>; 3168 APSR.Z = IsZeroBit(result); 3169 APSR.C = carry; 3170 // APSR.V unchanged 3171#endif 3172 3173 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3174} 3175 3176bool 3177EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3178{ 3179// assert(shift_type == SRType_ASR 3180// || shift_type == SRType_LSL 3181// || shift_type == SRType_LSR 3182// || shift_type == SRType_ROR 3183// || shift_type == SRType_RRX); 3184 3185 bool success = false; 3186 3187 if (ConditionPassed(opcode)) 3188 { 3189 uint32_t Rd; // the destination register 3190 uint32_t Rm; // the first operand register 3191 uint32_t imm5; // encoding for the shift amount 3192 uint32_t carry; // the carry bit after the shift operation 3193 bool setflags; 3194 3195 // Special case handling! 3196 // A8.6.139 ROR (immediate) -- Encoding T1 3197 ARMEncoding use_encoding = encoding; 3198 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3199 { 3200 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3201 // have the same decoding of bit fields as the other Thumb2 shift operations. 3202 use_encoding = eEncodingT2; 3203 } 3204 3205 switch (use_encoding) { 3206 case eEncodingT1: 3207 // Due to the above special case handling! 3208 if (shift_type == SRType_ROR) 3209 return false; 3210 3211 Rd = Bits32(opcode, 2, 0); 3212 Rm = Bits32(opcode, 5, 3); 3213 setflags = !InITBlock(); 3214 imm5 = Bits32(opcode, 10, 6); 3215 break; 3216 case eEncodingT2: 3217 // A8.6.141 RRX 3218 // There's no imm form of RRX instructions. 3219 if (shift_type == SRType_RRX) 3220 return false; 3221 3222 Rd = Bits32(opcode, 11, 8); 3223 Rm = Bits32(opcode, 3, 0); 3224 setflags = BitIsSet(opcode, 20); 3225 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3226 if (BadReg(Rd) || BadReg(Rm)) 3227 return false; 3228 break; 3229 case eEncodingA1: 3230 Rd = Bits32(opcode, 15, 12); 3231 Rm = Bits32(opcode, 3, 0); 3232 setflags = BitIsSet(opcode, 20); 3233 imm5 = Bits32(opcode, 11, 7); 3234 break; 3235 default: 3236 return false; 3237 } 3238 3239 // A8.6.139 ROR (immediate) 3240 if (shift_type == SRType_ROR && imm5 == 0) 3241 shift_type = SRType_RRX; 3242 3243 // Get the first operand. 3244 uint32_t value = ReadCoreReg (Rm, &success); 3245 if (!success) 3246 return false; 3247 3248 // Decode the shift amount if not RRX. 3249 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3250 3251 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3252 if (!success) 3253 return false; 3254 3255 // The context specifies that an immediate is to be moved into Rd. 3256 EmulateInstruction::Context context; 3257 context.type = EmulateInstruction::eContextImmediate; 3258 context.SetNoArgs (); 3259 3260 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3261 return false; 3262 } 3263 return true; 3264} 3265 3266bool 3267EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3268{ 3269 // assert(shift_type == SRType_ASR 3270 // || shift_type == SRType_LSL 3271 // || shift_type == SRType_LSR 3272 // || shift_type == SRType_ROR); 3273 3274 bool success = false; 3275 3276 if (ConditionPassed(opcode)) 3277 { 3278 uint32_t Rd; // the destination register 3279 uint32_t Rn; // the first operand register 3280 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3281 uint32_t carry; // the carry bit after the shift operation 3282 bool setflags; 3283 switch (encoding) { 3284 case eEncodingT1: 3285 Rd = Bits32(opcode, 2, 0); 3286 Rn = Rd; 3287 Rm = Bits32(opcode, 5, 3); 3288 setflags = !InITBlock(); 3289 break; 3290 case eEncodingT2: 3291 Rd = Bits32(opcode, 11, 8); 3292 Rn = Bits32(opcode, 19, 16); 3293 Rm = Bits32(opcode, 3, 0); 3294 setflags = BitIsSet(opcode, 20); 3295 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3296 return false; 3297 break; 3298 case eEncodingA1: 3299 Rd = Bits32(opcode, 15, 12); 3300 Rn = Bits32(opcode, 3, 0); 3301 Rm = Bits32(opcode, 11, 8); 3302 setflags = BitIsSet(opcode, 20); 3303 if (Rd == 15 || Rn == 15 || Rm == 15) 3304 return false; 3305 break; 3306 default: 3307 return false; 3308 } 3309 3310 // Get the first operand. 3311 uint32_t value = ReadCoreReg (Rn, &success); 3312 if (!success) 3313 return false; 3314 // Get the Rm register content. 3315 uint32_t val = ReadCoreReg (Rm, &success); 3316 if (!success) 3317 return false; 3318 3319 // Get the shift amount. 3320 uint32_t amt = Bits32(val, 7, 0); 3321 3322 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3323 if (!success) 3324 return false; 3325 3326 // The context specifies that an immediate is to be moved into Rd. 3327 EmulateInstruction::Context context; 3328 context.type = EmulateInstruction::eContextImmediate; 3329 context.SetNoArgs (); 3330 3331 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3332 return false; 3333 } 3334 return true; 3335} 3336 3337// LDM loads multiple registers from consecutive memory locations, using an 3338// address from a base register. Optionally the address just above the highest of those locations 3339// can be written back to the base register. 3340bool 3341EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3342{ 3343#if 0 3344 // ARM pseudo code... 3345 if ConditionPassed() 3346 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3347 address = R[n]; 3348 3349 for i = 0 to 14 3350 if registers<i> == '1' then 3351 R[i] = MemA[address, 4]; address = address + 4; 3352 if registers<15> == '1' then 3353 LoadWritePC (MemA[address, 4]); 3354 3355 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3356 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3357 3358#endif 3359 3360 bool success = false; 3361 bool conditional = false; 3362 if (ConditionPassed(opcode, &conditional)) 3363 { 3364 uint32_t n; 3365 uint32_t registers = 0; 3366 bool wback; 3367 const uint32_t addr_byte_size = GetAddressByteSize(); 3368 switch (encoding) 3369 { 3370 case eEncodingT1: 3371 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3372 n = Bits32 (opcode, 10, 8); 3373 registers = Bits32 (opcode, 7, 0); 3374 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3375 wback = BitIsClear (registers, n); 3376 // if BitCount(registers) < 1 then UNPREDICTABLE; 3377 if (BitCount(registers) < 1) 3378 return false; 3379 break; 3380 case eEncodingT2: 3381 // if W == '1' && Rn == '1101' then SEE POP; 3382 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3383 n = Bits32 (opcode, 19, 16); 3384 registers = Bits32 (opcode, 15, 0); 3385 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3386 wback = BitIsSet (opcode, 21); 3387 3388 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3389 if ((n == 15) 3390 || (BitCount (registers) < 2) 3391 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3392 return false; 3393 3394 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3395 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3396 return false; 3397 3398 // if wback && registers<n> == '1' then UNPREDICTABLE; 3399 if (wback 3400 && BitIsSet (registers, n)) 3401 return false; 3402 break; 3403 3404 case eEncodingA1: 3405 n = Bits32 (opcode, 19, 16); 3406 registers = Bits32 (opcode, 15, 0); 3407 wback = BitIsSet (opcode, 21); 3408 if ((n == 15) 3409 || (BitCount (registers) < 1)) 3410 return false; 3411 break; 3412 default: 3413 return false; 3414 } 3415 3416 int32_t offset = 0; 3417 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3418 if (!success) 3419 return false; 3420 3421 EmulateInstruction::Context context; 3422 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3423 RegisterInfo dwarf_reg; 3424 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3425 context.SetRegisterPlusOffset (dwarf_reg, offset); 3426 3427 for (int i = 0; i < 14; ++i) 3428 { 3429 if (BitIsSet (registers, i)) 3430 { 3431 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3432 context.SetRegisterPlusOffset (dwarf_reg, offset); 3433 if (wback && (n == 13)) // Pop Instruction 3434 { 3435 if (conditional) 3436 context.type = EmulateInstruction::eContextRegisterLoad; 3437 else 3438 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3439 } 3440 3441 // R[i] = MemA [address, 4]; address = address + 4; 3442 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3443 if (!success) 3444 return false; 3445 3446 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3447 return false; 3448 3449 offset += addr_byte_size; 3450 } 3451 } 3452 3453 if (BitIsSet (registers, 15)) 3454 { 3455 //LoadWritePC (MemA [address, 4]); 3456 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3457 context.SetRegisterPlusOffset (dwarf_reg, offset); 3458 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3459 if (!success) 3460 return false; 3461 // In ARMv5T and above, this is an interworking branch. 3462 if (!LoadWritePC(context, data)) 3463 return false; 3464 } 3465 3466 if (wback && BitIsClear (registers, n)) 3467 { 3468 // R[n] = R[n] + 4 * BitCount (registers) 3469 int32_t offset = addr_byte_size * BitCount (registers); 3470 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3471 context.SetRegisterPlusOffset (dwarf_reg, offset); 3472 3473 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3474 return false; 3475 } 3476 if (wback && BitIsSet (registers, n)) 3477 // R[n] bits(32) UNKNOWN; 3478 return WriteBits32Unknown (n); 3479 } 3480 return true; 3481} 3482 3483// LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3484// The consecutive memory locations end at this address and the address just below the lowest of those locations 3485// can optionally be written back to the base register. 3486bool 3487EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3488{ 3489#if 0 3490 // ARM pseudo code... 3491 if ConditionPassed() then 3492 EncodingSpecificOperations(); 3493 address = R[n] - 4*BitCount(registers) + 4; 3494 3495 for i = 0 to 14 3496 if registers<i> == '1' then 3497 R[i] = MemA[address,4]; address = address + 4; 3498 3499 if registers<15> == '1' then 3500 LoadWritePC(MemA[address,4]); 3501 3502 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3503 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3504#endif 3505 3506 bool success = false; 3507 3508 if (ConditionPassed(opcode)) 3509 { 3510 uint32_t n; 3511 uint32_t registers = 0; 3512 bool wback; 3513 const uint32_t addr_byte_size = GetAddressByteSize(); 3514 3515 // EncodingSpecificOperations(); 3516 switch (encoding) 3517 { 3518 case eEncodingA1: 3519 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3520 n = Bits32 (opcode, 19, 16); 3521 registers = Bits32 (opcode, 15, 0); 3522 wback = BitIsSet (opcode, 21); 3523 3524 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3525 if ((n == 15) || (BitCount (registers) < 1)) 3526 return false; 3527 3528 break; 3529 3530 default: 3531 return false; 3532 } 3533 // address = R[n] - 4*BitCount(registers) + 4; 3534 3535 int32_t offset = 0; 3536 addr_t Rn = ReadCoreReg (n, &success); 3537 3538 if (!success) 3539 return false; 3540 3541 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3542 3543 EmulateInstruction::Context context; 3544 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3545 RegisterInfo dwarf_reg; 3546 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3547 context.SetRegisterPlusOffset (dwarf_reg, offset); 3548 3549 // for i = 0 to 14 3550 for (int i = 0; i < 14; ++i) 3551 { 3552 // if registers<i> == '1' then 3553 if (BitIsSet (registers, i)) 3554 { 3555 // R[i] = MemA[address,4]; address = address + 4; 3556 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3557 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3558 if (!success) 3559 return false; 3560 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3561 return false; 3562 offset += addr_byte_size; 3563 } 3564 } 3565 3566 // if registers<15> == '1' then 3567 // LoadWritePC(MemA[address,4]); 3568 if (BitIsSet (registers, 15)) 3569 { 3570 context.SetRegisterPlusOffset (dwarf_reg, offset); 3571 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3572 if (!success) 3573 return false; 3574 // In ARMv5T and above, this is an interworking branch. 3575 if (!LoadWritePC(context, data)) 3576 return false; 3577 } 3578 3579 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3580 if (wback && BitIsClear (registers, n)) 3581 { 3582 if (!success) 3583 return false; 3584 3585 offset = (addr_byte_size * BitCount (registers)) * -1; 3586 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3587 context.SetImmediateSigned (offset); 3588 addr_t addr = Rn + offset; 3589 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3590 return false; 3591 } 3592 3593 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3594 if (wback && BitIsSet (registers, n)) 3595 return WriteBits32Unknown (n); 3596 } 3597 return true; 3598} 3599 3600// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3601// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3602// be optionally written back to the base register. 3603bool 3604EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3605{ 3606#if 0 3607 // ARM pseudo code... 3608 if ConditionPassed() then 3609 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3610 address = R[n] - 4*BitCount(registers); 3611 3612 for i = 0 to 14 3613 if registers<i> == '1' then 3614 R[i] = MemA[address,4]; address = address + 4; 3615 if registers<15> == '1' then 3616 LoadWritePC(MemA[address,4]); 3617 3618 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3619 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3620#endif 3621 3622 bool success = false; 3623 3624 if (ConditionPassed(opcode)) 3625 { 3626 uint32_t n; 3627 uint32_t registers = 0; 3628 bool wback; 3629 const uint32_t addr_byte_size = GetAddressByteSize(); 3630 switch (encoding) 3631 { 3632 case eEncodingT1: 3633 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3634 n = Bits32 (opcode, 19, 16); 3635 registers = Bits32 (opcode, 15, 0); 3636 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3637 wback = BitIsSet (opcode, 21); 3638 3639 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3640 if ((n == 15) 3641 || (BitCount (registers) < 2) 3642 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3643 return false; 3644 3645 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3646 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3647 return false; 3648 3649 // if wback && registers<n> == '1' then UNPREDICTABLE; 3650 if (wback && BitIsSet (registers, n)) 3651 return false; 3652 3653 break; 3654 3655 case eEncodingA1: 3656 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3657 n = Bits32 (opcode, 19, 16); 3658 registers = Bits32 (opcode, 15, 0); 3659 wback = BitIsSet (opcode, 21); 3660 3661 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3662 if ((n == 15) || (BitCount (registers) < 1)) 3663 return false; 3664 3665 break; 3666 3667 default: 3668 return false; 3669 } 3670 3671 // address = R[n] - 4*BitCount(registers); 3672 3673 int32_t offset = 0; 3674 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3675 3676 if (!success) 3677 return false; 3678 3679 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3680 EmulateInstruction::Context context; 3681 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3682 RegisterInfo dwarf_reg; 3683 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3684 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3685 3686 for (int i = 0; i < 14; ++i) 3687 { 3688 if (BitIsSet (registers, i)) 3689 { 3690 // R[i] = MemA[address,4]; address = address + 4; 3691 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3692 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3693 if (!success) 3694 return false; 3695 3696 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3697 return false; 3698 3699 offset += addr_byte_size; 3700 } 3701 } 3702 3703 // if registers<15> == '1' then 3704 // LoadWritePC(MemA[address,4]); 3705 if (BitIsSet (registers, 15)) 3706 { 3707 context.SetRegisterPlusOffset (dwarf_reg, offset); 3708 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3709 if (!success) 3710 return false; 3711 // In ARMv5T and above, this is an interworking branch. 3712 if (!LoadWritePC(context, data)) 3713 return false; 3714 } 3715 3716 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3717 if (wback && BitIsClear (registers, n)) 3718 { 3719 if (!success) 3720 return false; 3721 3722 offset = (addr_byte_size * BitCount (registers)) * -1; 3723 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3724 context.SetImmediateSigned (offset); 3725 addr_t addr = Rn + offset; 3726 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3727 return false; 3728 } 3729 3730 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3731 if (wback && BitIsSet (registers, n)) 3732 return WriteBits32Unknown (n); 3733 } 3734 return true; 3735} 3736 3737// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3738// consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3739// optinoally be written back to the base register. 3740bool 3741EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3742{ 3743#if 0 3744 if ConditionPassed() then 3745 EncodingSpecificOperations(); 3746 address = R[n] + 4; 3747 3748 for i = 0 to 14 3749 if registers<i> == '1' then 3750 R[i] = MemA[address,4]; address = address + 4; 3751 if registers<15> == '1' then 3752 LoadWritePC(MemA[address,4]); 3753 3754 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3755 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3756#endif 3757 3758 bool success = false; 3759 3760 if (ConditionPassed(opcode)) 3761 { 3762 uint32_t n; 3763 uint32_t registers = 0; 3764 bool wback; 3765 const uint32_t addr_byte_size = GetAddressByteSize(); 3766 switch (encoding) 3767 { 3768 case eEncodingA1: 3769 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3770 n = Bits32 (opcode, 19, 16); 3771 registers = Bits32 (opcode, 15, 0); 3772 wback = BitIsSet (opcode, 21); 3773 3774 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3775 if ((n == 15) || (BitCount (registers) < 1)) 3776 return false; 3777 3778 break; 3779 default: 3780 return false; 3781 } 3782 // address = R[n] + 4; 3783 3784 int32_t offset = 0; 3785 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3786 3787 if (!success) 3788 return false; 3789 3790 addr_t address = Rn + addr_byte_size; 3791 3792 EmulateInstruction::Context context; 3793 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3794 RegisterInfo dwarf_reg; 3795 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3796 context.SetRegisterPlusOffset (dwarf_reg, offset); 3797 3798 for (int i = 0; i < 14; ++i) 3799 { 3800 if (BitIsSet (registers, i)) 3801 { 3802 // R[i] = MemA[address,4]; address = address + 4; 3803 3804 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3805 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3806 if (!success) 3807 return false; 3808 3809 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3810 return false; 3811 3812 offset += addr_byte_size; 3813 } 3814 } 3815 3816 // if registers<15> == '1' then 3817 // LoadWritePC(MemA[address,4]); 3818 if (BitIsSet (registers, 15)) 3819 { 3820 context.SetRegisterPlusOffset (dwarf_reg, offset); 3821 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3822 if (!success) 3823 return false; 3824 // In ARMv5T and above, this is an interworking branch. 3825 if (!LoadWritePC(context, data)) 3826 return false; 3827 } 3828 3829 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3830 if (wback && BitIsClear (registers, n)) 3831 { 3832 if (!success) 3833 return false; 3834 3835 offset = addr_byte_size * BitCount (registers); 3836 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3837 context.SetImmediateSigned (offset); 3838 addr_t addr = Rn + offset; 3839 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3840 return false; 3841 } 3842 3843 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3844 if (wback && BitIsSet (registers, n)) 3845 return WriteBits32Unknown (n); 3846 } 3847 return true; 3848} 3849 3850// Load Register (immediate) calculates an address from a base register value and 3851// an immediate offset, loads a word from memory, and writes to a register. 3852// LDR (immediate, Thumb) 3853bool 3854EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3855{ 3856#if 0 3857 // ARM pseudo code... 3858 if (ConditionPassed()) 3859 { 3860 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3861 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3862 address = if index then offset_addr else R[n]; 3863 data = MemU[address,4]; 3864 if wback then R[n] = offset_addr; 3865 if t == 15 then 3866 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3867 elsif UnalignedSupport() || address<1:0> = '00' then 3868 R[t] = data; 3869 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3870 } 3871#endif 3872 3873 bool success = false; 3874 3875 if (ConditionPassed(opcode)) 3876 { 3877 uint32_t Rt; // the destination register 3878 uint32_t Rn; // the base register 3879 uint32_t imm32; // the immediate offset used to form the address 3880 addr_t offset_addr; // the offset address 3881 addr_t address; // the calculated address 3882 uint32_t data; // the literal data value from memory load 3883 bool add, index, wback; 3884 switch (encoding) { 3885 case eEncodingT1: 3886 Rt = Bits32(opcode, 2, 0); 3887 Rn = Bits32(opcode, 5, 3); 3888 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3889 // index = TRUE; add = TRUE; wback = FALSE 3890 add = true; 3891 index = true; 3892 wback = false; 3893 3894 break; 3895 3896 case eEncodingT2: 3897 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3898 Rt = Bits32 (opcode, 10, 8); 3899 Rn = 13; 3900 imm32 = Bits32 (opcode, 7, 0) << 2; 3901 3902 // index = TRUE; add = TRUE; wback = FALSE; 3903 index = true; 3904 add = true; 3905 wback = false; 3906 3907 break; 3908 3909 case eEncodingT3: 3910 // if Rn == '1111' then SEE LDR (literal); 3911 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3912 Rt = Bits32 (opcode, 15, 12); 3913 Rn = Bits32 (opcode, 19, 16); 3914 imm32 = Bits32 (opcode, 11, 0); 3915 3916 // index = TRUE; add = TRUE; wback = FALSE; 3917 index = true; 3918 add = true; 3919 wback = false; 3920 3921 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3922 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3923 return false; 3924 3925 break; 3926 3927 case eEncodingT4: 3928 // if Rn == '1111' then SEE LDR (literal); 3929 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3930 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3931 // if P == '0' && W == '0' then UNDEFINED; 3932 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3933 return false; 3934 3935 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3936 Rt = Bits32 (opcode, 15, 12); 3937 Rn = Bits32 (opcode, 19, 16); 3938 imm32 = Bits32 (opcode, 7, 0); 3939 3940 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3941 index = BitIsSet (opcode, 10); 3942 add = BitIsSet (opcode, 9); 3943 wback = BitIsSet (opcode, 8); 3944 3945 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3946 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3947 return false; 3948 3949 break; 3950 3951 default: 3952 return false; 3953 } 3954 uint32_t base = ReadCoreReg (Rn, &success); 3955 if (!success) 3956 return false; 3957 if (add) 3958 offset_addr = base + imm32; 3959 else 3960 offset_addr = base - imm32; 3961 3962 address = (index ? offset_addr : base); 3963 3964 RegisterInfo base_reg; 3965 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 3966 if (wback) 3967 { 3968 EmulateInstruction::Context ctx; 3969 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 3970 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3971 3972 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3973 return false; 3974 } 3975 3976 // Prepare to write to the Rt register. 3977 EmulateInstruction::Context context; 3978 context.type = EmulateInstruction::eContextRegisterLoad; 3979 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3980 3981 // Read memory from the address. 3982 data = MemURead(context, address, 4, 0, &success); 3983 if (!success) 3984 return false; 3985 3986 if (Rt == 15) 3987 { 3988 if (Bits32(address, 1, 0) == 0) 3989 { 3990 if (!LoadWritePC(context, data)) 3991 return false; 3992 } 3993 else 3994 return false; 3995 } 3996 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3997 { 3998 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3999 return false; 4000 } 4001 else 4002 WriteBits32Unknown (Rt); 4003 } 4004 return true; 4005} 4006 4007// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 4008// from a base register. The consecutive memory locations start at this address, and teh address just above the last 4009// of those locations can optionally be written back to the base register. 4010bool 4011EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 4012{ 4013#if 0 4014 if ConditionPassed() then 4015 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4016 address = R[n]; 4017 4018 for i = 0 to 14 4019 if registers<i> == '1' then 4020 if i == n && wback && i != LowestSetBit(registers) then 4021 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4022 else 4023 MemA[address,4] = R[i]; 4024 address = address + 4; 4025 4026 if registers<15> == '1' then // Only possible for encoding A1 4027 MemA[address,4] = PCStoreValue(); 4028 if wback then R[n] = R[n] + 4*BitCount(registers); 4029#endif 4030 4031 bool success = false; 4032 4033 if (ConditionPassed(opcode)) 4034 { 4035 uint32_t n; 4036 uint32_t registers = 0; 4037 bool wback; 4038 const uint32_t addr_byte_size = GetAddressByteSize(); 4039 4040 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4041 switch (encoding) 4042 { 4043 case eEncodingT1: 4044 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4045 n = Bits32 (opcode, 10, 8); 4046 registers = Bits32 (opcode, 7, 0); 4047 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4048 wback = true; 4049 4050 // if BitCount(registers) < 1 then UNPREDICTABLE; 4051 if (BitCount (registers) < 1) 4052 return false; 4053 4054 break; 4055 4056 case eEncodingT2: 4057 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4058 n = Bits32 (opcode, 19, 16); 4059 registers = Bits32 (opcode, 15, 0); 4060 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4061 wback = BitIsSet (opcode, 21); 4062 4063 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4064 if ((n == 15) || (BitCount (registers) < 2)) 4065 return false; 4066 4067 // if wback && registers<n> == '1' then UNPREDICTABLE; 4068 if (wback && BitIsSet (registers, n)) 4069 return false; 4070 4071 break; 4072 4073 case eEncodingA1: 4074 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4075 n = Bits32 (opcode, 19, 16); 4076 registers = Bits32 (opcode, 15, 0); 4077 wback = BitIsSet (opcode, 21); 4078 4079 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4080 if ((n == 15) || (BitCount (registers) < 1)) 4081 return false; 4082 4083 break; 4084 4085 default: 4086 return false; 4087 } 4088 4089 // address = R[n]; 4090 int32_t offset = 0; 4091 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4092 if (!success) 4093 return false; 4094 4095 EmulateInstruction::Context context; 4096 context.type = EmulateInstruction::eContextRegisterStore; 4097 RegisterInfo base_reg; 4098 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4099 4100 // for i = 0 to 14 4101 uint32_t lowest_set_bit = 14; 4102 for (uint32_t i = 0; i < 14; ++i) 4103 { 4104 // if registers<i> == '1' then 4105 if (BitIsSet (registers, i)) 4106 { 4107 if (i < lowest_set_bit) 4108 lowest_set_bit = i; 4109 // if i == n && wback && i != LowestSetBit(registers) then 4110 if ((i == n) && wback && (i != lowest_set_bit)) 4111 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4112 WriteBits32UnknownToMemory (address + offset); 4113 else 4114 { 4115 // MemA[address,4] = R[i]; 4116 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4117 if (!success) 4118 return false; 4119 4120 RegisterInfo data_reg; 4121 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4122 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4123 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4124 return false; 4125 } 4126 4127 // address = address + 4; 4128 offset += addr_byte_size; 4129 } 4130 } 4131 4132 // if registers<15> == '1' then // Only possible for encoding A1 4133 // MemA[address,4] = PCStoreValue(); 4134 if (BitIsSet (registers, 15)) 4135 { 4136 RegisterInfo pc_reg; 4137 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4138 context.SetRegisterPlusOffset (pc_reg, 8); 4139 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4140 if (!success) 4141 return false; 4142 4143 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4144 return false; 4145 } 4146 4147 // if wback then R[n] = R[n] + 4*BitCount(registers); 4148 if (wback) 4149 { 4150 offset = addr_byte_size * BitCount (registers); 4151 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4152 context.SetImmediateSigned (offset); 4153 addr_t data = address + offset; 4154 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4155 return false; 4156 } 4157 } 4158 return true; 4159} 4160 4161// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4162// from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4163// of those locations can optionally be written back to the base register. 4164bool 4165EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4166{ 4167#if 0 4168 if ConditionPassed() then 4169 EncodingSpecificOperations(); 4170 address = R[n] - 4*BitCount(registers) + 4; 4171 4172 for i = 0 to 14 4173 if registers<i> == '1' then 4174 if i == n && wback && i != LowestSetBit(registers) then 4175 MemA[address,4] = bits(32) UNKNOWN; 4176 else 4177 MemA[address,4] = R[i]; 4178 address = address + 4; 4179 4180 if registers<15> == '1' then 4181 MemA[address,4] = PCStoreValue(); 4182 4183 if wback then R[n] = R[n] - 4*BitCount(registers); 4184#endif 4185 4186 bool success = false; 4187 4188 if (ConditionPassed(opcode)) 4189 { 4190 uint32_t n; 4191 uint32_t registers = 0; 4192 bool wback; 4193 const uint32_t addr_byte_size = GetAddressByteSize(); 4194 4195 // EncodingSpecificOperations(); 4196 switch (encoding) 4197 { 4198 case eEncodingA1: 4199 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4200 n = Bits32 (opcode, 19, 16); 4201 registers = Bits32 (opcode, 15, 0); 4202 wback = BitIsSet (opcode, 21); 4203 4204 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4205 if ((n == 15) || (BitCount (registers) < 1)) 4206 return false; 4207 break; 4208 default: 4209 return false; 4210 } 4211 4212 // address = R[n] - 4*BitCount(registers) + 4; 4213 int32_t offset = 0; 4214 addr_t Rn = ReadCoreReg (n, &success); 4215 if (!success) 4216 return false; 4217 4218 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4219 4220 EmulateInstruction::Context context; 4221 context.type = EmulateInstruction::eContextRegisterStore; 4222 RegisterInfo base_reg; 4223 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4224 4225 // for i = 0 to 14 4226 uint32_t lowest_bit_set = 14; 4227 for (uint32_t i = 0; i < 14; ++i) 4228 { 4229 // if registers<i> == '1' then 4230 if (BitIsSet (registers, i)) 4231 { 4232 if (i < lowest_bit_set) 4233 lowest_bit_set = i; 4234 //if i == n && wback && i != LowestSetBit(registers) then 4235 if ((i == n) && wback && (i != lowest_bit_set)) 4236 // MemA[address,4] = bits(32) UNKNOWN; 4237 WriteBits32UnknownToMemory (address + offset); 4238 else 4239 { 4240 // MemA[address,4] = R[i]; 4241 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4242 if (!success) 4243 return false; 4244 4245 RegisterInfo data_reg; 4246 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4247 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4248 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4249 return false; 4250 } 4251 4252 // address = address + 4; 4253 offset += addr_byte_size; 4254 } 4255 } 4256 4257 // if registers<15> == '1' then 4258 // MemA[address,4] = PCStoreValue(); 4259 if (BitIsSet (registers, 15)) 4260 { 4261 RegisterInfo pc_reg; 4262 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4263 context.SetRegisterPlusOffset (pc_reg, 8); 4264 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4265 if (!success) 4266 return false; 4267 4268 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4269 return false; 4270 } 4271 4272 // if wback then R[n] = R[n] - 4*BitCount(registers); 4273 if (wback) 4274 { 4275 offset = (addr_byte_size * BitCount (registers)) * -1; 4276 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4277 context.SetImmediateSigned (offset); 4278 addr_t data = Rn + offset; 4279 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4280 return false; 4281 } 4282 } 4283 return true; 4284} 4285 4286// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4287// from a base register. The consecutive memory locations end just below this address, and the address of the first of 4288// those locations can optionally be written back to the base register. 4289bool 4290EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4291{ 4292#if 0 4293 if ConditionPassed() then 4294 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4295 address = R[n] - 4*BitCount(registers); 4296 4297 for i = 0 to 14 4298 if registers<i> == '1' then 4299 if i == n && wback && i != LowestSetBit(registers) then 4300 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4301 else 4302 MemA[address,4] = R[i]; 4303 address = address + 4; 4304 4305 if registers<15> == '1' then // Only possible for encoding A1 4306 MemA[address,4] = PCStoreValue(); 4307 4308 if wback then R[n] = R[n] - 4*BitCount(registers); 4309#endif 4310 4311 4312 bool success = false; 4313 4314 if (ConditionPassed(opcode)) 4315 { 4316 uint32_t n; 4317 uint32_t registers = 0; 4318 bool wback; 4319 const uint32_t addr_byte_size = GetAddressByteSize(); 4320 4321 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4322 switch (encoding) 4323 { 4324 case eEncodingT1: 4325 // if W == '1' && Rn == '1101' then SEE PUSH; 4326 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4327 { 4328 // See PUSH 4329 } 4330 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4331 n = Bits32 (opcode, 19, 16); 4332 registers = Bits32 (opcode, 15, 0); 4333 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4334 wback = BitIsSet (opcode, 21); 4335 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4336 if ((n == 15) || BitCount (registers) < 2) 4337 return false; 4338 // if wback && registers<n> == '1' then UNPREDICTABLE; 4339 if (wback && BitIsSet (registers, n)) 4340 return false; 4341 break; 4342 4343 case eEncodingA1: 4344 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH; 4345 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4346 { 4347 // See Push 4348 } 4349 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4350 n = Bits32 (opcode, 19, 16); 4351 registers = Bits32 (opcode, 15, 0); 4352 wback = BitIsSet (opcode, 21); 4353 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4354 if ((n == 15) || BitCount (registers) < 1) 4355 return false; 4356 break; 4357 4358 default: 4359 return false; 4360 } 4361 4362 // address = R[n] - 4*BitCount(registers); 4363 4364 int32_t offset = 0; 4365 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4366 if (!success) 4367 return false; 4368 4369 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4370 4371 EmulateInstruction::Context context; 4372 context.type = EmulateInstruction::eContextRegisterStore; 4373 RegisterInfo base_reg; 4374 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4375 4376 // for i = 0 to 14 4377 uint32_t lowest_set_bit = 14; 4378 for (uint32_t i = 0; i < 14; ++i) 4379 { 4380 // if registers<i> == '1' then 4381 if (BitIsSet (registers, i)) 4382 { 4383 if (i < lowest_set_bit) 4384 lowest_set_bit = i; 4385 // if i == n && wback && i != LowestSetBit(registers) then 4386 if ((i == n) && wback && (i != lowest_set_bit)) 4387 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4388 WriteBits32UnknownToMemory (address + offset); 4389 else 4390 { 4391 // MemA[address,4] = R[i]; 4392 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4393 if (!success) 4394 return false; 4395 4396 RegisterInfo data_reg; 4397 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4398 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4399 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4400 return false; 4401 } 4402 4403 // address = address + 4; 4404 offset += addr_byte_size; 4405 } 4406 } 4407 4408 // if registers<15> == '1' then // Only possible for encoding A1 4409 // MemA[address,4] = PCStoreValue(); 4410 if (BitIsSet (registers, 15)) 4411 { 4412 RegisterInfo pc_reg; 4413 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4414 context.SetRegisterPlusOffset (pc_reg, 8); 4415 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4416 if (!success) 4417 return false; 4418 4419 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4420 return false; 4421 } 4422 4423 // if wback then R[n] = R[n] - 4*BitCount(registers); 4424 if (wback) 4425 { 4426 offset = (addr_byte_size * BitCount (registers)) * -1; 4427 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4428 context.SetImmediateSigned (offset); 4429 addr_t data = Rn + offset; 4430 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4431 return false; 4432 } 4433 } 4434 return true; 4435} 4436 4437// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4438// from a base register. The consecutive memory locations start just above this address, and the address of the last 4439// of those locations can optionally be written back to the base register. 4440bool 4441EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4442{ 4443#if 0 4444 if ConditionPassed() then 4445 EncodingSpecificOperations(); 4446 address = R[n] + 4; 4447 4448 for i = 0 to 14 4449 if registers<i> == '1' then 4450 if i == n && wback && i != LowestSetBit(registers) then 4451 MemA[address,4] = bits(32) UNKNOWN; 4452 else 4453 MemA[address,4] = R[i]; 4454 address = address + 4; 4455 4456 if registers<15> == '1' then 4457 MemA[address,4] = PCStoreValue(); 4458 4459 if wback then R[n] = R[n] + 4*BitCount(registers); 4460#endif 4461 4462 bool success = false; 4463 4464 if (ConditionPassed(opcode)) 4465 { 4466 uint32_t n; 4467 uint32_t registers = 0; 4468 bool wback; 4469 const uint32_t addr_byte_size = GetAddressByteSize(); 4470 4471 // EncodingSpecificOperations(); 4472 switch (encoding) 4473 { 4474 case eEncodingA1: 4475 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4476 n = Bits32 (opcode, 19, 16); 4477 registers = Bits32 (opcode, 15, 0); 4478 wback = BitIsSet (opcode, 21); 4479 4480 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4481 if ((n == 15) && (BitCount (registers) < 1)) 4482 return false; 4483 break; 4484 default: 4485 return false; 4486 } 4487 // address = R[n] + 4; 4488 4489 int32_t offset = 0; 4490 addr_t Rn = ReadCoreReg (n, &success); 4491 if (!success) 4492 return false; 4493 4494 addr_t address = Rn + addr_byte_size; 4495 4496 EmulateInstruction::Context context; 4497 context.type = EmulateInstruction::eContextRegisterStore; 4498 RegisterInfo base_reg; 4499 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4500 4501 uint32_t lowest_set_bit = 14; 4502 // for i = 0 to 14 4503 for (uint32_t i = 0; i < 14; ++i) 4504 { 4505 // if registers<i> == '1' then 4506 if (BitIsSet (registers, i)) 4507 { 4508 if (i < lowest_set_bit) 4509 lowest_set_bit = i; 4510 // if i == n && wback && i != LowestSetBit(registers) then 4511 if ((i == n) && wback && (i != lowest_set_bit)) 4512 // MemA[address,4] = bits(32) UNKNOWN; 4513 WriteBits32UnknownToMemory (address + offset); 4514 // else 4515 else 4516 { 4517 // MemA[address,4] = R[i]; 4518 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4519 if (!success) 4520 return false; 4521 4522 RegisterInfo data_reg; 4523 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4524 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4525 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4526 return false; 4527 } 4528 4529 // address = address + 4; 4530 offset += addr_byte_size; 4531 } 4532 } 4533 4534 // if registers<15> == '1' then 4535 // MemA[address,4] = PCStoreValue(); 4536 if (BitIsSet (registers, 15)) 4537 { 4538 RegisterInfo pc_reg; 4539 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4540 context.SetRegisterPlusOffset (pc_reg, 8); 4541 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4542 if (!success) 4543 return false; 4544 4545 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4546 return false; 4547 } 4548 4549 // if wback then R[n] = R[n] + 4*BitCount(registers); 4550 if (wback) 4551 { 4552 offset = addr_byte_size * BitCount (registers); 4553 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4554 context.SetImmediateSigned (offset); 4555 addr_t data = Rn + offset; 4556 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4557 return false; 4558 } 4559 } 4560 return true; 4561} 4562 4563// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 4564// from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4565bool 4566EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4567{ 4568#if 0 4569 if ConditionPassed() then 4570 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4571 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4572 address = if index then offset_addr else R[n]; 4573 if UnalignedSupport() || address<1:0> == '00' then 4574 MemU[address,4] = R[t]; 4575 else // Can only occur before ARMv7 4576 MemU[address,4] = bits(32) UNKNOWN; 4577 if wback then R[n] = offset_addr; 4578#endif 4579 4580 bool success = false; 4581 4582 if (ConditionPassed(opcode)) 4583 { 4584 const uint32_t addr_byte_size = GetAddressByteSize(); 4585 4586 uint32_t t; 4587 uint32_t n; 4588 uint32_t imm32; 4589 bool index; 4590 bool add; 4591 bool wback; 4592 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4593 switch (encoding) 4594 { 4595 case eEncodingT1: 4596 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4597 t = Bits32 (opcode, 2, 0); 4598 n = Bits32 (opcode, 5, 3); 4599 imm32 = Bits32 (opcode, 10, 6) << 2; 4600 4601 // index = TRUE; add = TRUE; wback = FALSE; 4602 index = true; 4603 add = false; 4604 wback = false; 4605 break; 4606 4607 case eEncodingT2: 4608 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4609 t = Bits32 (opcode, 10, 8); 4610 n = 13; 4611 imm32 = Bits32 (opcode, 7, 0) << 2; 4612 4613 // index = TRUE; add = TRUE; wback = FALSE; 4614 index = true; 4615 add = true; 4616 wback = false; 4617 break; 4618 4619 case eEncodingT3: 4620 // if Rn == '1111' then UNDEFINED; 4621 if (Bits32 (opcode, 19, 16) == 15) 4622 return false; 4623 4624 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4625 t = Bits32 (opcode, 15, 12); 4626 n = Bits32 (opcode, 19, 16); 4627 imm32 = Bits32 (opcode, 11, 0); 4628 4629 // index = TRUE; add = TRUE; wback = FALSE; 4630 index = true; 4631 add = true; 4632 wback = false; 4633 4634 // if t == 15 then UNPREDICTABLE; 4635 if (t == 15) 4636 return false; 4637 break; 4638 4639 case eEncodingT4: 4640 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4641 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4642 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4643 if ((Bits32 (opcode, 19, 16) == 15) 4644 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4645 return false; 4646 4647 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4648 t = Bits32 (opcode, 15, 12); 4649 n = Bits32 (opcode, 19, 16); 4650 imm32 = Bits32 (opcode, 7, 0); 4651 4652 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4653 index = BitIsSet (opcode, 10); 4654 add = BitIsSet (opcode, 9); 4655 wback = BitIsSet (opcode, 8); 4656 4657 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4658 if ((t == 15) || (wback && (n == t))) 4659 return false; 4660 break; 4661 4662 default: 4663 return false; 4664 } 4665 4666 addr_t offset_addr; 4667 addr_t address; 4668 4669 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4670 uint32_t base_address = ReadCoreReg (n, &success); 4671 if (!success) 4672 return false; 4673 4674 if (add) 4675 offset_addr = base_address + imm32; 4676 else 4677 offset_addr = base_address - imm32; 4678 4679 // address = if index then offset_addr else R[n]; 4680 if (index) 4681 address = offset_addr; 4682 else 4683 address = base_address; 4684 4685 EmulateInstruction::Context context; 4686 context.type = eContextRegisterStore; 4687 RegisterInfo base_reg; 4688 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4689 4690 // if UnalignedSupport() || address<1:0> == '00' then 4691 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4692 { 4693 // MemU[address,4] = R[t]; 4694 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4695 if (!success) 4696 return false; 4697 4698 RegisterInfo data_reg; 4699 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4700 int32_t offset = address - base_address; 4701 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4702 if (!MemUWrite (context, address, data, addr_byte_size)) 4703 return false; 4704 } 4705 else 4706 { 4707 // MemU[address,4] = bits(32) UNKNOWN; 4708 WriteBits32UnknownToMemory (address); 4709 } 4710 4711 // if wback then R[n] = offset_addr; 4712 if (wback) 4713 { 4714 context.type = eContextRegisterLoad; 4715 context.SetAddress (offset_addr); 4716 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4717 return false; 4718 } 4719 } 4720 return true; 4721} 4722 4723// STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4724// word from a register to memory. The offset register value can optionally be shifted. 4725bool 4726EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4727{ 4728#if 0 4729 if ConditionPassed() then 4730 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4731 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4732 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4733 address = if index then offset_addr else R[n]; 4734 if t == 15 then // Only possible for encoding A1 4735 data = PCStoreValue(); 4736 else 4737 data = R[t]; 4738 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4739 MemU[address,4] = data; 4740 else // Can only occur before ARMv7 4741 MemU[address,4] = bits(32) UNKNOWN; 4742 if wback then R[n] = offset_addr; 4743#endif 4744 4745 bool success = false; 4746 4747 if (ConditionPassed(opcode)) 4748 { 4749 const uint32_t addr_byte_size = GetAddressByteSize(); 4750 4751 uint32_t t; 4752 uint32_t n; 4753 uint32_t m; 4754 ARM_ShifterType shift_t; 4755 uint32_t shift_n; 4756 bool index; 4757 bool add; 4758 bool wback; 4759 4760 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4761 switch (encoding) 4762 { 4763 case eEncodingT1: 4764 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4765 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4766 t = Bits32 (opcode, 2, 0); 4767 n = Bits32 (opcode, 5, 3); 4768 m = Bits32 (opcode, 8, 6); 4769 4770 // index = TRUE; add = TRUE; wback = FALSE; 4771 index = true; 4772 add = true; 4773 wback = false; 4774 4775 // (shift_t, shift_n) = (SRType_LSL, 0); 4776 shift_t = SRType_LSL; 4777 shift_n = 0; 4778 break; 4779 4780 case eEncodingT2: 4781 // if Rn == '1111' then UNDEFINED; 4782 if (Bits32 (opcode, 19, 16) == 15) 4783 return false; 4784 4785 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4786 t = Bits32 (opcode, 15, 12); 4787 n = Bits32 (opcode, 19, 16); 4788 m = Bits32 (opcode, 3, 0); 4789 4790 // index = TRUE; add = TRUE; wback = FALSE; 4791 index = true; 4792 add = true; 4793 wback = false; 4794 4795 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4796 shift_t = SRType_LSL; 4797 shift_n = Bits32 (opcode, 5, 4); 4798 4799 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4800 if ((t == 15) || (BadReg (m))) 4801 return false; 4802 break; 4803 4804 case eEncodingA1: 4805 { 4806 // if P == '0' && W == '1' then SEE STRT; 4807 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4808 t = Bits32 (opcode, 15, 12); 4809 n = Bits32 (opcode, 19, 16); 4810 m = Bits32 (opcode, 3, 0); 4811 4812 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4813 index = BitIsSet (opcode, 24); 4814 add = BitIsSet (opcode, 23); 4815 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4816 4817 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4818 uint32_t typ = Bits32 (opcode, 6, 5); 4819 uint32_t imm5 = Bits32 (opcode, 11, 7); 4820 shift_n = DecodeImmShift(typ, imm5, shift_t); 4821 4822 // if m == 15 then UNPREDICTABLE; 4823 if (m == 15) 4824 return false; 4825 4826 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4827 if (wback && ((n == 15) || (n == t))) 4828 return false; 4829 4830 break; 4831 } 4832 default: 4833 return false; 4834 } 4835 4836 addr_t offset_addr; 4837 addr_t address; 4838 int32_t offset = 0; 4839 4840 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4841 if (!success) 4842 return false; 4843 4844 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4845 if (!success) 4846 return false; 4847 4848 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4849 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4850 if (!success) 4851 return false; 4852 4853 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4854 if (add) 4855 offset_addr = base_address + offset; 4856 else 4857 offset_addr = base_address - offset; 4858 4859 // address = if index then offset_addr else R[n]; 4860 if (index) 4861 address = offset_addr; 4862 else 4863 address = base_address; 4864 4865 uint32_t data; 4866 // if t == 15 then // Only possible for encoding A1 4867 if (t == 15) 4868 // data = PCStoreValue(); 4869 data = ReadCoreReg (PC_REG, &success); 4870 else 4871 // data = R[t]; 4872 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4873 4874 if (!success) 4875 return false; 4876 4877 EmulateInstruction::Context context; 4878 context.type = eContextRegisterStore; 4879 4880 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4881 if (UnalignedSupport () 4882 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4883 || CurrentInstrSet() == eModeARM) 4884 { 4885 // MemU[address,4] = data; 4886 4887 RegisterInfo base_reg; 4888 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4889 4890 RegisterInfo data_reg; 4891 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4892 4893 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4894 if (!MemUWrite (context, address, data, addr_byte_size)) 4895 return false; 4896 4897 } 4898 else 4899 // MemU[address,4] = bits(32) UNKNOWN; 4900 WriteBits32UnknownToMemory (address); 4901 4902 // if wback then R[n] = offset_addr; 4903 if (wback) 4904 { 4905 context.type = eContextRegisterLoad; 4906 context.SetAddress (offset_addr); 4907 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4908 return false; 4909 } 4910 4911 } 4912 return true; 4913} 4914 4915bool 4916EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 4917{ 4918#if 0 4919 if ConditionPassed() then 4920 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4921 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4922 address = if index then offset_addr else R[n]; 4923 MemU[address,1] = R[t]<7:0>; 4924 if wback then R[n] = offset_addr; 4925#endif 4926 4927 4928 bool success = false; 4929 4930 if (ConditionPassed(opcode)) 4931 { 4932 uint32_t t; 4933 uint32_t n; 4934 uint32_t imm32; 4935 bool index; 4936 bool add; 4937 bool wback; 4938 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4939 switch (encoding) 4940 { 4941 case eEncodingT1: 4942 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4943 t = Bits32 (opcode, 2, 0); 4944 n = Bits32 (opcode, 5, 3); 4945 imm32 = Bits32 (opcode, 10, 6); 4946 4947 // index = TRUE; add = TRUE; wback = FALSE; 4948 index = true; 4949 add = true; 4950 wback = false; 4951 break; 4952 4953 case eEncodingT2: 4954 // if Rn == '1111' then UNDEFINED; 4955 if (Bits32 (opcode, 19, 16) == 15) 4956 return false; 4957 4958 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4959 t = Bits32 (opcode, 15, 12); 4960 n = Bits32 (opcode, 19, 16); 4961 imm32 = Bits32 (opcode, 11, 0); 4962 4963 // index = TRUE; add = TRUE; wback = FALSE; 4964 index = true; 4965 add = true; 4966 wback = false; 4967 4968 // if BadReg(t) then UNPREDICTABLE; 4969 if (BadReg (t)) 4970 return false; 4971 break; 4972 4973 case eEncodingT3: 4974 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 4975 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4976 if (Bits32 (opcode, 19, 16) == 15) 4977 return false; 4978 4979 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4980 t = Bits32 (opcode, 15, 12); 4981 n = Bits32 (opcode, 19, 16); 4982 imm32 = Bits32 (opcode, 7, 0); 4983 4984 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4985 index = BitIsSet (opcode, 10); 4986 add = BitIsSet (opcode, 9); 4987 wback = BitIsSet (opcode, 8); 4988 4989 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 4990 if ((BadReg (t)) || (wback && (n == t))) 4991 return false; 4992 break; 4993 4994 default: 4995 return false; 4996 } 4997 4998 addr_t offset_addr; 4999 addr_t address; 5000 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5001 if (!success) 5002 return false; 5003 5004 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5005 if (add) 5006 offset_addr = base_address + imm32; 5007 else 5008 offset_addr = base_address - imm32; 5009 5010 // address = if index then offset_addr else R[n]; 5011 if (index) 5012 address = offset_addr; 5013 else 5014 address = base_address; 5015 5016 // MemU[address,1] = R[t]<7:0> 5017 RegisterInfo base_reg; 5018 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5019 5020 RegisterInfo data_reg; 5021 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5022 5023 EmulateInstruction::Context context; 5024 context.type = eContextRegisterStore; 5025 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5026 5027 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5028 if (!success) 5029 return false; 5030 5031 data = Bits32 (data, 7, 0); 5032 5033 if (!MemUWrite (context, address, data, 1)) 5034 return false; 5035 5036 // if wback then R[n] = offset_addr; 5037 if (wback) 5038 { 5039 context.type = eContextRegisterLoad; 5040 context.SetAddress (offset_addr); 5041 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5042 return false; 5043 } 5044 5045 } 5046 5047 return true; 5048} 5049 5050// STRH (register) calculates an address from a base register value and an offset register value, and stores a 5051// halfword from a register to memory. The offset register alue can be shifted left by 0, 1, 2, or 3 bits. 5052bool 5053EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5054{ 5055#if 0 5056 if ConditionPassed() then 5057 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5058 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5059 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5060 address = if index then offset_addr else R[n]; 5061 if UnalignedSupport() || address<0> == '0' then 5062 MemU[address,2] = R[t]<15:0>; 5063 else // Can only occur before ARMv7 5064 MemU[address,2] = bits(16) UNKNOWN; 5065 if wback then R[n] = offset_addr; 5066#endif 5067 5068 bool success = false; 5069 5070 if (ConditionPassed(opcode)) 5071 { 5072 uint32_t t; 5073 uint32_t n; 5074 uint32_t m; 5075 bool index; 5076 bool add; 5077 bool wback; 5078 ARM_ShifterType shift_t; 5079 uint32_t shift_n; 5080 5081 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5082 switch (encoding) 5083 { 5084 case eEncodingT1: 5085 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5086 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5087 t = Bits32 (opcode, 2, 0); 5088 n = Bits32 (opcode, 5, 3); 5089 m = Bits32 (opcode, 8, 6); 5090 5091 // index = TRUE; add = TRUE; wback = FALSE; 5092 index = true; 5093 add = true; 5094 wback = false; 5095 5096 // (shift_t, shift_n) = (SRType_LSL, 0); 5097 shift_t = SRType_LSL; 5098 shift_n = 0; 5099 5100 break; 5101 5102 case eEncodingT2: 5103 // if Rn == '1111' then UNDEFINED; 5104 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5105 t = Bits32 (opcode, 15, 12); 5106 n = Bits32 (opcode, 19, 16); 5107 m = Bits32 (opcode, 3, 0); 5108 if (n == 15) 5109 return false; 5110 5111 // index = TRUE; add = TRUE; wback = FALSE; 5112 index = true; 5113 add = true; 5114 wback = false; 5115 5116 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5117 shift_t = SRType_LSL; 5118 shift_n = Bits32 (opcode, 5, 4); 5119 5120 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5121 if (BadReg (t) || BadReg (m)) 5122 return false; 5123 5124 break; 5125 5126 case eEncodingA1: 5127 // if P == '0' && W == '1' then SEE STRHT; 5128 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5129 t = Bits32 (opcode, 15, 12); 5130 n = Bits32 (opcode, 19, 16); 5131 m = Bits32 (opcode, 3, 0); 5132 5133 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5134 index = BitIsSet (opcode, 24); 5135 add = BitIsSet (opcode, 23); 5136 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5137 5138 // (shift_t, shift_n) = (SRType_LSL, 0); 5139 shift_t = SRType_LSL; 5140 shift_n = 0; 5141 5142 // if t == 15 || m == 15 then UNPREDICTABLE; 5143 if ((t == 15) || (m == 15)) 5144 return false; 5145 5146 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5147 if (wback && ((n == 15) || (n == t))) 5148 return false; 5149 5150 break; 5151 5152 default: 5153 return false; 5154 } 5155 5156 uint32_t Rm = ReadCoreReg (m, &success); 5157 if (!success) 5158 return false; 5159 5160 uint32_t Rn = ReadCoreReg (n, &success); 5161 if (!success) 5162 return false; 5163 5164 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5165 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5166 if (!success) 5167 return false; 5168 5169 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5170 addr_t offset_addr; 5171 if (add) 5172 offset_addr = Rn + offset; 5173 else 5174 offset_addr = Rn - offset; 5175 5176 // address = if index then offset_addr else R[n]; 5177 addr_t address; 5178 if (index) 5179 address = offset_addr; 5180 else 5181 address = Rn; 5182 5183 EmulateInstruction::Context context; 5184 context.type = eContextRegisterStore; 5185 RegisterInfo base_reg; 5186 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5187 RegisterInfo offset_reg; 5188 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5189 5190 // if UnalignedSupport() || address<0> == '0' then 5191 if (UnalignedSupport() || BitIsClear (address, 0)) 5192 { 5193 // MemU[address,2] = R[t]<15:0>; 5194 uint32_t Rt = ReadCoreReg (t, &success); 5195 if (!success) 5196 return false; 5197 5198 EmulateInstruction::Context context; 5199 context.type = eContextRegisterStore; 5200 RegisterInfo base_reg; 5201 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5202 RegisterInfo offset_reg; 5203 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5204 RegisterInfo data_reg; 5205 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5206 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5207 5208 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5209 return false; 5210 } 5211 else // Can only occur before ARMv7 5212 { 5213 // MemU[address,2] = bits(16) UNKNOWN; 5214 } 5215 5216 // if wback then R[n] = offset_addr; 5217 if (wback) 5218 { 5219 context.type = eContextAdjustBaseRegister; 5220 context.SetAddress (offset_addr); 5221 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5222 return false; 5223 } 5224 } 5225 5226 return true; 5227} 5228 5229// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5230// and writes the result to the destination register. It can optionally update the condition flags 5231// based on the result. 5232bool 5233EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5234{ 5235#if 0 5236 // ARM pseudo code... 5237 if ConditionPassed() then 5238 EncodingSpecificOperations(); 5239 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5240 if d == 15 then // Can only occur for ARM encoding 5241 ALUWritePC(result); // setflags is always FALSE here 5242 else 5243 R[d] = result; 5244 if setflags then 5245 APSR.N = result<31>; 5246 APSR.Z = IsZeroBit(result); 5247 APSR.C = carry; 5248 APSR.V = overflow; 5249#endif 5250 5251 bool success = false; 5252 5253 if (ConditionPassed(opcode)) 5254 { 5255 uint32_t Rd, Rn; 5256 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5257 bool setflags; 5258 switch (encoding) 5259 { 5260 case eEncodingT1: 5261 Rd = Bits32(opcode, 11, 8); 5262 Rn = Bits32(opcode, 19, 16); 5263 setflags = BitIsSet(opcode, 20); 5264 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5265 if (BadReg(Rd) || BadReg(Rn)) 5266 return false; 5267 break; 5268 case eEncodingA1: 5269 Rd = Bits32(opcode, 15, 12); 5270 Rn = Bits32(opcode, 19, 16); 5271 setflags = BitIsSet(opcode, 20); 5272 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5273 5274 if (Rd == 15 && setflags) 5275 return EmulateSUBSPcLrEtc (opcode, encoding); 5276 break; 5277 default: 5278 return false; 5279 } 5280 5281 // Read the first operand. 5282 int32_t val1 = ReadCoreReg(Rn, &success); 5283 if (!success) 5284 return false; 5285 5286 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5287 5288 EmulateInstruction::Context context; 5289 context.type = EmulateInstruction::eContextImmediate; 5290 context.SetNoArgs (); 5291 5292 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5293 return false; 5294 } 5295 return true; 5296} 5297 5298// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5299// register value, and writes the result to the destination register. It can optionally update the 5300// condition flags based on the result. 5301bool 5302EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5303{ 5304#if 0 5305 // ARM pseudo code... 5306 if ConditionPassed() then 5307 EncodingSpecificOperations(); 5308 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5309 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5310 if d == 15 then // Can only occur for ARM encoding 5311 ALUWritePC(result); // setflags is always FALSE here 5312 else 5313 R[d] = result; 5314 if setflags then 5315 APSR.N = result<31>; 5316 APSR.Z = IsZeroBit(result); 5317 APSR.C = carry; 5318 APSR.V = overflow; 5319#endif 5320 5321 bool success = false; 5322 5323 if (ConditionPassed(opcode)) 5324 { 5325 uint32_t Rd, Rn, Rm; 5326 ARM_ShifterType shift_t; 5327 uint32_t shift_n; // the shift applied to the value read from Rm 5328 bool setflags; 5329 switch (encoding) 5330 { 5331 case eEncodingT1: 5332 Rd = Rn = Bits32(opcode, 2, 0); 5333 Rm = Bits32(opcode, 5, 3); 5334 setflags = !InITBlock(); 5335 shift_t = SRType_LSL; 5336 shift_n = 0; 5337 break; 5338 case eEncodingT2: 5339 Rd = Bits32(opcode, 11, 8); 5340 Rn = Bits32(opcode, 19, 16); 5341 Rm = Bits32(opcode, 3, 0); 5342 setflags = BitIsSet(opcode, 20); 5343 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5344 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5345 return false; 5346 break; 5347 case eEncodingA1: 5348 Rd = Bits32(opcode, 15, 12); 5349 Rn = Bits32(opcode, 19, 16); 5350 Rm = Bits32(opcode, 3, 0); 5351 setflags = BitIsSet(opcode, 20); 5352 shift_n = DecodeImmShiftARM(opcode, shift_t); 5353 5354 if (Rd == 15 && setflags) 5355 return EmulateSUBSPcLrEtc (opcode, encoding); 5356 break; 5357 default: 5358 return false; 5359 } 5360 5361 // Read the first operand. 5362 int32_t val1 = ReadCoreReg(Rn, &success); 5363 if (!success) 5364 return false; 5365 5366 // Read the second operand. 5367 int32_t val2 = ReadCoreReg(Rm, &success); 5368 if (!success) 5369 return false; 5370 5371 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5372 if (!success) 5373 return false; 5374 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5375 5376 EmulateInstruction::Context context; 5377 context.type = EmulateInstruction::eContextImmediate; 5378 context.SetNoArgs (); 5379 5380 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5381 return false; 5382 } 5383 return true; 5384} 5385 5386// This instruction adds an immediate value to the PC value to form a PC-relative address, 5387// and writes the result to the destination register. 5388bool 5389EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5390{ 5391#if 0 5392 // ARM pseudo code... 5393 if ConditionPassed() then 5394 EncodingSpecificOperations(); 5395 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5396 if d == 15 then // Can only occur for ARM encodings 5397 ALUWritePC(result); 5398 else 5399 R[d] = result; 5400#endif 5401 5402 bool success = false; 5403 5404 if (ConditionPassed(opcode)) 5405 { 5406 uint32_t Rd; 5407 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5408 bool add; 5409 switch (encoding) 5410 { 5411 case eEncodingT1: 5412 Rd = Bits32(opcode, 10, 8); 5413 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5414 add = true; 5415 break; 5416 case eEncodingT2: 5417 case eEncodingT3: 5418 Rd = Bits32(opcode, 11, 8); 5419 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5420 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5421 if (BadReg(Rd)) 5422 return false; 5423 break; 5424 case eEncodingA1: 5425 case eEncodingA2: 5426 Rd = Bits32(opcode, 15, 12); 5427 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5428 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5429 break; 5430 default: 5431 return false; 5432 } 5433 5434 // Read the PC value. 5435 uint32_t pc = ReadCoreReg(PC_REG, &success); 5436 if (!success) 5437 return false; 5438 5439 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5440 5441 EmulateInstruction::Context context; 5442 context.type = EmulateInstruction::eContextImmediate; 5443 context.SetNoArgs (); 5444 5445 if (!WriteCoreReg(context, result, Rd)) 5446 return false; 5447 } 5448 return true; 5449} 5450 5451// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5452// to the destination register. It can optionally update the condition flags based on the result. 5453bool 5454EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5455{ 5456#if 0 5457 // ARM pseudo code... 5458 if ConditionPassed() then 5459 EncodingSpecificOperations(); 5460 result = R[n] AND imm32; 5461 if d == 15 then // Can only occur for ARM encoding 5462 ALUWritePC(result); // setflags is always FALSE here 5463 else 5464 R[d] = result; 5465 if setflags then 5466 APSR.N = result<31>; 5467 APSR.Z = IsZeroBit(result); 5468 APSR.C = carry; 5469 // APSR.V unchanged 5470#endif 5471 5472 bool success = false; 5473 5474 if (ConditionPassed(opcode)) 5475 { 5476 uint32_t Rd, Rn; 5477 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5478 bool setflags; 5479 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5480 switch (encoding) 5481 { 5482 case eEncodingT1: 5483 Rd = Bits32(opcode, 11, 8); 5484 Rn = Bits32(opcode, 19, 16); 5485 setflags = BitIsSet(opcode, 20); 5486 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5487 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5488 if (Rd == 15 && setflags) 5489 return EmulateTSTImm(opcode, eEncodingT1); 5490 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5491 return false; 5492 break; 5493 case eEncodingA1: 5494 Rd = Bits32(opcode, 15, 12); 5495 Rn = Bits32(opcode, 19, 16); 5496 setflags = BitIsSet(opcode, 20); 5497 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5498 5499 if (Rd == 15 && setflags) 5500 return EmulateSUBSPcLrEtc (opcode, encoding); 5501 break; 5502 default: 5503 return false; 5504 } 5505 5506 // Read the first operand. 5507 uint32_t val1 = ReadCoreReg(Rn, &success); 5508 if (!success) 5509 return false; 5510 5511 uint32_t result = val1 & imm32; 5512 5513 EmulateInstruction::Context context; 5514 context.type = EmulateInstruction::eContextImmediate; 5515 context.SetNoArgs (); 5516 5517 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5518 return false; 5519 } 5520 return true; 5521} 5522 5523// This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5524// and writes the result to the destination register. It can optionally update the condition flags 5525// based on the result. 5526bool 5527EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5528{ 5529#if 0 5530 // ARM pseudo code... 5531 if ConditionPassed() then 5532 EncodingSpecificOperations(); 5533 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5534 result = R[n] AND shifted; 5535 if d == 15 then // Can only occur for ARM encoding 5536 ALUWritePC(result); // setflags is always FALSE here 5537 else 5538 R[d] = result; 5539 if setflags then 5540 APSR.N = result<31>; 5541 APSR.Z = IsZeroBit(result); 5542 APSR.C = carry; 5543 // APSR.V unchanged 5544#endif 5545 5546 bool success = false; 5547 5548 if (ConditionPassed(opcode)) 5549 { 5550 uint32_t Rd, Rn, Rm; 5551 ARM_ShifterType shift_t; 5552 uint32_t shift_n; // the shift applied to the value read from Rm 5553 bool setflags; 5554 uint32_t carry; 5555 switch (encoding) 5556 { 5557 case eEncodingT1: 5558 Rd = Rn = Bits32(opcode, 2, 0); 5559 Rm = Bits32(opcode, 5, 3); 5560 setflags = !InITBlock(); 5561 shift_t = SRType_LSL; 5562 shift_n = 0; 5563 break; 5564 case eEncodingT2: 5565 Rd = Bits32(opcode, 11, 8); 5566 Rn = Bits32(opcode, 19, 16); 5567 Rm = Bits32(opcode, 3, 0); 5568 setflags = BitIsSet(opcode, 20); 5569 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5570 // if Rd == '1111' && S == '1' then SEE TST (register); 5571 if (Rd == 15 && setflags) 5572 return EmulateTSTReg(opcode, eEncodingT2); 5573 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5574 return false; 5575 break; 5576 case eEncodingA1: 5577 Rd = Bits32(opcode, 15, 12); 5578 Rn = Bits32(opcode, 19, 16); 5579 Rm = Bits32(opcode, 3, 0); 5580 setflags = BitIsSet(opcode, 20); 5581 shift_n = DecodeImmShiftARM(opcode, shift_t); 5582 5583 if (Rd == 15 && setflags) 5584 return EmulateSUBSPcLrEtc (opcode, encoding); 5585 break; 5586 default: 5587 return false; 5588 } 5589 5590 // Read the first operand. 5591 uint32_t val1 = ReadCoreReg(Rn, &success); 5592 if (!success) 5593 return false; 5594 5595 // Read the second operand. 5596 uint32_t val2 = ReadCoreReg(Rm, &success); 5597 if (!success) 5598 return false; 5599 5600 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5601 if (!success) 5602 return false; 5603 uint32_t result = val1 & shifted; 5604 5605 EmulateInstruction::Context context; 5606 context.type = EmulateInstruction::eContextImmediate; 5607 context.SetNoArgs (); 5608 5609 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5610 return false; 5611 } 5612 return true; 5613} 5614 5615// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5616// immediate value, and writes the result to the destination register. It can optionally update the 5617// condition flags based on the result. 5618bool 5619EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5620{ 5621#if 0 5622 // ARM pseudo code... 5623 if ConditionPassed() then 5624 EncodingSpecificOperations(); 5625 result = R[n] AND NOT(imm32); 5626 if d == 15 then // Can only occur for ARM encoding 5627 ALUWritePC(result); // setflags is always FALSE here 5628 else 5629 R[d] = result; 5630 if setflags then 5631 APSR.N = result<31>; 5632 APSR.Z = IsZeroBit(result); 5633 APSR.C = carry; 5634 // APSR.V unchanged 5635#endif 5636 5637 bool success = false; 5638 5639 if (ConditionPassed(opcode)) 5640 { 5641 uint32_t Rd, Rn; 5642 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5643 bool setflags; 5644 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5645 switch (encoding) 5646 { 5647 case eEncodingT1: 5648 Rd = Bits32(opcode, 11, 8); 5649 Rn = Bits32(opcode, 19, 16); 5650 setflags = BitIsSet(opcode, 20); 5651 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5652 if (BadReg(Rd) || BadReg(Rn)) 5653 return false; 5654 break; 5655 case eEncodingA1: 5656 Rd = Bits32(opcode, 15, 12); 5657 Rn = Bits32(opcode, 19, 16); 5658 setflags = BitIsSet(opcode, 20); 5659 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5660 5661 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5662 if (Rd == 15 && setflags) 5663 return EmulateSUBSPcLrEtc (opcode, encoding); 5664 break; 5665 default: 5666 return false; 5667 } 5668 5669 // Read the first operand. 5670 uint32_t val1 = ReadCoreReg(Rn, &success); 5671 if (!success) 5672 return false; 5673 5674 uint32_t result = val1 & ~imm32; 5675 5676 EmulateInstruction::Context context; 5677 context.type = EmulateInstruction::eContextImmediate; 5678 context.SetNoArgs (); 5679 5680 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5681 return false; 5682 } 5683 return true; 5684} 5685 5686// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5687// optionally-shifted register value, and writes the result to the destination register. 5688// It can optionally update the condition flags based on the result. 5689bool 5690EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5691{ 5692#if 0 5693 // ARM pseudo code... 5694 if ConditionPassed() then 5695 EncodingSpecificOperations(); 5696 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5697 result = R[n] AND NOT(shifted); 5698 if d == 15 then // Can only occur for ARM encoding 5699 ALUWritePC(result); // setflags is always FALSE here 5700 else 5701 R[d] = result; 5702 if setflags then 5703 APSR.N = result<31>; 5704 APSR.Z = IsZeroBit(result); 5705 APSR.C = carry; 5706 // APSR.V unchanged 5707#endif 5708 5709 bool success = false; 5710 5711 if (ConditionPassed(opcode)) 5712 { 5713 uint32_t Rd, Rn, Rm; 5714 ARM_ShifterType shift_t; 5715 uint32_t shift_n; // the shift applied to the value read from Rm 5716 bool setflags; 5717 uint32_t carry; 5718 switch (encoding) 5719 { 5720 case eEncodingT1: 5721 Rd = Rn = Bits32(opcode, 2, 0); 5722 Rm = Bits32(opcode, 5, 3); 5723 setflags = !InITBlock(); 5724 shift_t = SRType_LSL; 5725 shift_n = 0; 5726 break; 5727 case eEncodingT2: 5728 Rd = Bits32(opcode, 11, 8); 5729 Rn = Bits32(opcode, 19, 16); 5730 Rm = Bits32(opcode, 3, 0); 5731 setflags = BitIsSet(opcode, 20); 5732 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5733 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5734 return false; 5735 break; 5736 case eEncodingA1: 5737 Rd = Bits32(opcode, 15, 12); 5738 Rn = Bits32(opcode, 19, 16); 5739 Rm = Bits32(opcode, 3, 0); 5740 setflags = BitIsSet(opcode, 20); 5741 shift_n = DecodeImmShiftARM(opcode, shift_t); 5742 5743 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5744 if (Rd == 15 && setflags) 5745 return EmulateSUBSPcLrEtc (opcode, encoding); 5746 break; 5747 default: 5748 return false; 5749 } 5750 5751 // Read the first operand. 5752 uint32_t val1 = ReadCoreReg(Rn, &success); 5753 if (!success) 5754 return false; 5755 5756 // Read the second operand. 5757 uint32_t val2 = ReadCoreReg(Rm, &success); 5758 if (!success) 5759 return false; 5760 5761 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5762 if (!success) 5763 return false; 5764 uint32_t result = val1 & ~shifted; 5765 5766 EmulateInstruction::Context context; 5767 context.type = EmulateInstruction::eContextImmediate; 5768 context.SetNoArgs (); 5769 5770 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5771 return false; 5772 } 5773 return true; 5774} 5775 5776// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5777// from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5778bool 5779EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5780{ 5781#if 0 5782 if ConditionPassed() then 5783 EncodingSpecificOperations(); 5784 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5785 address = if index then offset_addr else R[n]; 5786 data = MemU[address,4]; 5787 if wback then R[n] = offset_addr; 5788 if t == 15 then 5789 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5790 elsif UnalignedSupport() || address<1:0> = '00' then 5791 R[t] = data; 5792 else // Can only apply before ARMv7 5793 R[t] = ROR(data, 8*UInt(address<1:0>)); 5794#endif 5795 5796 bool success = false; 5797 5798 if (ConditionPassed(opcode)) 5799 { 5800 const uint32_t addr_byte_size = GetAddressByteSize(); 5801 5802 uint32_t t; 5803 uint32_t n; 5804 uint32_t imm32; 5805 bool index; 5806 bool add; 5807 bool wback; 5808 5809 switch (encoding) 5810 { 5811 case eEncodingA1: 5812 // if Rn == '1111' then SEE LDR (literal); 5813 // if P == '0' && W == '1' then SEE LDRT; 5814 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5815 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5816 t = Bits32 (opcode, 15, 12); 5817 n = Bits32 (opcode, 19, 16); 5818 imm32 = Bits32 (opcode, 11, 0); 5819 5820 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5821 index = BitIsSet (opcode, 24); 5822 add = BitIsSet (opcode, 23); 5823 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5824 5825 // if wback && n == t then UNPREDICTABLE; 5826 if (wback && (n == t)) 5827 return false; 5828 5829 break; 5830 5831 default: 5832 return false; 5833 } 5834 5835 addr_t address; 5836 addr_t offset_addr; 5837 addr_t base_address = ReadCoreReg (n, &success); 5838 if (!success) 5839 return false; 5840 5841 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5842 if (add) 5843 offset_addr = base_address + imm32; 5844 else 5845 offset_addr = base_address - imm32; 5846 5847 // address = if index then offset_addr else R[n]; 5848 if (index) 5849 address = offset_addr; 5850 else 5851 address = base_address; 5852 5853 // data = MemU[address,4]; 5854 5855 RegisterInfo base_reg; 5856 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5857 5858 EmulateInstruction::Context context; 5859 context.type = eContextRegisterLoad; 5860 context.SetRegisterPlusOffset (base_reg, address - base_address); 5861 5862 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5863 if (!success) 5864 return false; 5865 5866 // if wback then R[n] = offset_addr; 5867 if (wback) 5868 { 5869 context.type = eContextAdjustBaseRegister; 5870 context.SetAddress (offset_addr); 5871 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5872 return false; 5873 } 5874 5875 // if t == 15 then 5876 if (t == 15) 5877 { 5878 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5879 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5880 { 5881 // LoadWritePC (data); 5882 context.type = eContextRegisterLoad; 5883 context.SetRegisterPlusOffset (base_reg, address - base_address); 5884 LoadWritePC (context, data); 5885 } 5886 else 5887 return false; 5888 } 5889 // elsif UnalignedSupport() || address<1:0> = '00' then 5890 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5891 { 5892 // R[t] = data; 5893 context.type = eContextRegisterLoad; 5894 context.SetRegisterPlusOffset (base_reg, address - base_address); 5895 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5896 return false; 5897 } 5898 // else // Can only apply before ARMv7 5899 else 5900 { 5901 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5902 data = ROR (data, Bits32 (address, 1, 0), &success); 5903 if (!success) 5904 return false; 5905 context.type = eContextRegisterLoad; 5906 context.SetImmediate (data); 5907 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5908 return false; 5909 } 5910 5911 } 5912 return true; 5913} 5914 5915// LDR (register) calculates an address from a base register value and an offset register value, loads a word 5916// from memory, and writes it to a resgister. The offset register value can optionally be shifted. 5917bool 5918EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5919{ 5920#if 0 5921 if ConditionPassed() then 5922 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5923 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5924 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5925 address = if index then offset_addr else R[n]; 5926 data = MemU[address,4]; 5927 if wback then R[n] = offset_addr; 5928 if t == 15 then 5929 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5930 elsif UnalignedSupport() || address<1:0> = '00' then 5931 R[t] = data; 5932 else // Can only apply before ARMv7 5933 if CurrentInstrSet() == InstrSet_ARM then 5934 R[t] = ROR(data, 8*UInt(address<1:0>)); 5935 else 5936 R[t] = bits(32) UNKNOWN; 5937#endif 5938 5939 bool success = false; 5940 5941 if (ConditionPassed(opcode)) 5942 { 5943 const uint32_t addr_byte_size = GetAddressByteSize(); 5944 5945 uint32_t t; 5946 uint32_t n; 5947 uint32_t m; 5948 bool index; 5949 bool add; 5950 bool wback; 5951 ARM_ShifterType shift_t; 5952 uint32_t shift_n; 5953 5954 switch (encoding) 5955 { 5956 case eEncodingT1: 5957 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5958 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5959 t = Bits32 (opcode, 2, 0); 5960 n = Bits32 (opcode, 5, 3); 5961 m = Bits32 (opcode, 8, 6); 5962 5963 // index = TRUE; add = TRUE; wback = FALSE; 5964 index = true; 5965 add = true; 5966 wback = false; 5967 5968 // (shift_t, shift_n) = (SRType_LSL, 0); 5969 shift_t = SRType_LSL; 5970 shift_n = 0; 5971 5972 break; 5973 5974 case eEncodingT2: 5975 // if Rn == '1111' then SEE LDR (literal); 5976 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5977 t = Bits32 (opcode, 15, 12); 5978 n = Bits32 (opcode, 19, 16); 5979 m = Bits32 (opcode, 3, 0); 5980 5981 // index = TRUE; add = TRUE; wback = FALSE; 5982 index = true; 5983 add = true; 5984 wback = false; 5985 5986 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5987 shift_t = SRType_LSL; 5988 shift_n = Bits32 (opcode, 5, 4); 5989 5990 // if BadReg(m) then UNPREDICTABLE; 5991 if (BadReg (m)) 5992 return false; 5993 5994 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5995 if ((t == 15) && InITBlock() && !LastInITBlock()) 5996 return false; 5997 5998 break; 5999 6000 case eEncodingA1: 6001 { 6002 // if P == '0' && W == '1' then SEE LDRT; 6003 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6004 t = Bits32 (opcode, 15, 12); 6005 n = Bits32 (opcode, 19, 16); 6006 m = Bits32 (opcode, 3, 0); 6007 6008 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6009 index = BitIsSet (opcode, 24); 6010 add = BitIsSet (opcode, 23); 6011 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6012 6013 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6014 uint32_t type = Bits32 (opcode, 6, 5); 6015 uint32_t imm5 = Bits32 (opcode, 11, 7); 6016 shift_n = DecodeImmShift (type, imm5, shift_t); 6017 6018 // if m == 15 then UNPREDICTABLE; 6019 if (m == 15) 6020 return false; 6021 6022 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6023 if (wback && ((n == 15) || (n == t))) 6024 return false; 6025 } 6026 break; 6027 6028 6029 default: 6030 return false; 6031 } 6032 6033 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6034 if (!success) 6035 return false; 6036 6037 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6038 if (!success) 6039 return false; 6040 6041 addr_t offset_addr; 6042 addr_t address; 6043 6044 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6045 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6046 if (!success) 6047 return false; 6048 6049 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6050 if (add) 6051 offset_addr = Rn + offset; 6052 else 6053 offset_addr = Rn - offset; 6054 6055 // address = if index then offset_addr else R[n]; 6056 if (index) 6057 address = offset_addr; 6058 else 6059 address = Rn; 6060 6061 // data = MemU[address,4]; 6062 RegisterInfo base_reg; 6063 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6064 6065 EmulateInstruction::Context context; 6066 context.type = eContextRegisterLoad; 6067 context.SetRegisterPlusOffset (base_reg, address - Rn); 6068 6069 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6070 if (!success) 6071 return false; 6072 6073 // if wback then R[n] = offset_addr; 6074 if (wback) 6075 { 6076 context.type = eContextAdjustBaseRegister; 6077 context.SetAddress (offset_addr); 6078 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6079 return false; 6080 } 6081 6082 // if t == 15 then 6083 if (t == 15) 6084 { 6085 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6086 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6087 { 6088 context.type = eContextRegisterLoad; 6089 context.SetRegisterPlusOffset (base_reg, address - Rn); 6090 LoadWritePC (context, data); 6091 } 6092 else 6093 return false; 6094 } 6095 // elsif UnalignedSupport() || address<1:0> = '00' then 6096 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6097 { 6098 // R[t] = data; 6099 context.type = eContextRegisterLoad; 6100 context.SetRegisterPlusOffset (base_reg, address - Rn); 6101 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6102 return false; 6103 } 6104 else // Can only apply before ARMv7 6105 { 6106 // if CurrentInstrSet() == InstrSet_ARM then 6107 if (CurrentInstrSet () == eModeARM) 6108 { 6109 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6110 data = ROR (data, Bits32 (address, 1, 0), &success); 6111 if (!success) 6112 return false; 6113 context.type = eContextRegisterLoad; 6114 context.SetImmediate (data); 6115 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6116 return false; 6117 } 6118 else 6119 { 6120 // R[t] = bits(32) UNKNOWN; 6121 WriteBits32Unknown (t); 6122 } 6123 } 6124 } 6125 return true; 6126} 6127 6128// LDRB (immediate, Thumb) 6129bool 6130EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6131{ 6132#if 0 6133 if ConditionPassed() then 6134 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6135 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6136 address = if index then offset_addr else R[n]; 6137 R[t] = ZeroExtend(MemU[address,1], 32); 6138 if wback then R[n] = offset_addr; 6139#endif 6140 6141 bool success = false; 6142 6143 if (ConditionPassed(opcode)) 6144 { 6145 uint32_t t; 6146 uint32_t n; 6147 uint32_t imm32; 6148 bool index; 6149 bool add; 6150 bool wback; 6151 6152 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6153 switch (encoding) 6154 { 6155 case eEncodingT1: 6156 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6157 t = Bits32 (opcode, 2, 0); 6158 n = Bits32 (opcode, 5, 3); 6159 imm32 = Bits32 (opcode, 10, 6); 6160 6161 // index = TRUE; add = TRUE; wback = FALSE; 6162 index = true; 6163 add = true; 6164 wback= false; 6165 6166 break; 6167 6168 case eEncodingT2: 6169 // if Rt == '1111' then SEE PLD; 6170 // if Rn == '1111' then SEE LDRB (literal); 6171 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6172 t = Bits32 (opcode, 15, 12); 6173 n = Bits32 (opcode, 19, 16); 6174 imm32 = Bits32 (opcode, 11, 0); 6175 6176 // index = TRUE; add = TRUE; wback = FALSE; 6177 index = true; 6178 add = true; 6179 wback = false; 6180 6181 // if t == 13 then UNPREDICTABLE; 6182 if (t == 13) 6183 return false; 6184 6185 break; 6186 6187 case eEncodingT3: 6188 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6189 // if Rn == '1111' then SEE LDRB (literal); 6190 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6191 // if P == '0' && W == '0' then UNDEFINED; 6192 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6193 return false; 6194 6195 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6196 t = Bits32 (opcode, 15, 12); 6197 n = Bits32 (opcode, 19, 16); 6198 imm32 = Bits32 (opcode, 7, 0); 6199 6200 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6201 index = BitIsSet (opcode, 10); 6202 add = BitIsSet (opcode, 9); 6203 wback = BitIsSet (opcode, 8); 6204 6205 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6206 if (BadReg (t) || (wback && (n == t))) 6207 return false; 6208 6209 break; 6210 6211 default: 6212 return false; 6213 } 6214 6215 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6216 if (!success) 6217 return false; 6218 6219 addr_t address; 6220 addr_t offset_addr; 6221 6222 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6223 if (add) 6224 offset_addr = Rn + imm32; 6225 else 6226 offset_addr = Rn - imm32; 6227 6228 // address = if index then offset_addr else R[n]; 6229 if (index) 6230 address = offset_addr; 6231 else 6232 address = Rn; 6233 6234 // R[t] = ZeroExtend(MemU[address,1], 32); 6235 RegisterInfo base_reg; 6236 RegisterInfo data_reg; 6237 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6238 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6239 6240 EmulateInstruction::Context context; 6241 context.type = eContextRegisterLoad; 6242 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6243 6244 uint64_t data = MemURead (context, address, 1, 0, &success); 6245 if (!success) 6246 return false; 6247 6248 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6249 return false; 6250 6251 // if wback then R[n] = offset_addr; 6252 if (wback) 6253 { 6254 context.type = eContextAdjustBaseRegister; 6255 context.SetAddress (offset_addr); 6256 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6257 return false; 6258 } 6259 } 6260 return true; 6261} 6262 6263// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6264// zero-extends it to form a 32-bit word and writes it to a register. 6265bool 6266EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6267{ 6268#if 0 6269 if ConditionPassed() then 6270 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6271 base = Align(PC,4); 6272 address = if add then (base + imm32) else (base - imm32); 6273 R[t] = ZeroExtend(MemU[address,1], 32); 6274#endif 6275 6276 bool success = false; 6277 6278 if (ConditionPassed(opcode)) 6279 { 6280 uint32_t t; 6281 uint32_t imm32; 6282 bool add; 6283 switch (encoding) 6284 { 6285 case eEncodingT1: 6286 // if Rt == '1111' then SEE PLD; 6287 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6288 t = Bits32 (opcode, 15, 12); 6289 imm32 = Bits32 (opcode, 11, 0); 6290 add = BitIsSet (opcode, 23); 6291 6292 // if t == 13 then UNPREDICTABLE; 6293 if (t == 13) 6294 return false; 6295 6296 break; 6297 6298 case eEncodingA1: 6299 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6300 t = Bits32 (opcode, 15, 12); 6301 imm32 = Bits32 (opcode, 11, 0); 6302 add = BitIsSet (opcode, 23); 6303 6304 // if t == 15 then UNPREDICTABLE; 6305 if (t == 15) 6306 return false; 6307 break; 6308 6309 default: 6310 return false; 6311 } 6312 6313 // base = Align(PC,4); 6314 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6315 if (!success) 6316 return false; 6317 6318 uint32_t base = AlignPC (pc_val); 6319 6320 addr_t address; 6321 // address = if add then (base + imm32) else (base - imm32); 6322 if (add) 6323 address = base + imm32; 6324 else 6325 address = base - imm32; 6326 6327 // R[t] = ZeroExtend(MemU[address,1], 32); 6328 EmulateInstruction::Context context; 6329 context.type = eContextRelativeBranchImmediate; 6330 context.SetImmediate (address - base); 6331 6332 uint64_t data = MemURead (context, address, 1, 0, &success); 6333 if (!success) 6334 return false; 6335 6336 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6337 return false; 6338 } 6339 return true; 6340} 6341 6342// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6343// memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6344// optionally be shifted. 6345bool 6346EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6347{ 6348#if 0 6349 if ConditionPassed() then 6350 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6351 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6352 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6353 address = if index then offset_addr else R[n]; 6354 R[t] = ZeroExtend(MemU[address,1],32); 6355 if wback then R[n] = offset_addr; 6356#endif 6357 6358 bool success = false; 6359 6360 if (ConditionPassed(opcode)) 6361 { 6362 uint32_t t; 6363 uint32_t n; 6364 uint32_t m; 6365 bool index; 6366 bool add; 6367 bool wback; 6368 ARM_ShifterType shift_t; 6369 uint32_t shift_n; 6370 6371 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6372 switch (encoding) 6373 { 6374 case eEncodingT1: 6375 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6376 t = Bits32 (opcode, 2, 0); 6377 n = Bits32 (opcode, 5, 3); 6378 m = Bits32 (opcode, 8, 6); 6379 6380 // index = TRUE; add = TRUE; wback = FALSE; 6381 index = true; 6382 add = true; 6383 wback = false; 6384 6385 // (shift_t, shift_n) = (SRType_LSL, 0); 6386 shift_t = SRType_LSL; 6387 shift_n = 0; 6388 break; 6389 6390 case eEncodingT2: 6391 // if Rt == '1111' then SEE PLD; 6392 // if Rn == '1111' then SEE LDRB (literal); 6393 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6394 t = Bits32 (opcode, 15, 12); 6395 n = Bits32 (opcode, 19, 16); 6396 m = Bits32 (opcode, 3, 0); 6397 6398 // index = TRUE; add = TRUE; wback = FALSE; 6399 index = true; 6400 add = true; 6401 wback = false; 6402 6403 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6404 shift_t = SRType_LSL; 6405 shift_n = Bits32 (opcode, 5, 4); 6406 6407 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6408 if ((t == 13) || BadReg (m)) 6409 return false; 6410 break; 6411 6412 case eEncodingA1: 6413 { 6414 // if P == '0' && W == '1' then SEE LDRBT; 6415 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6416 t = Bits32 (opcode, 15, 12); 6417 n = Bits32 (opcode, 19, 16); 6418 m = Bits32 (opcode, 3, 0); 6419 6420 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6421 index = BitIsSet (opcode, 24); 6422 add = BitIsSet (opcode, 23); 6423 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6424 6425 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6426 uint32_t type = Bits32 (opcode, 6, 5); 6427 uint32_t imm5 = Bits32 (opcode, 11, 7); 6428 shift_n = DecodeImmShift (type, imm5, shift_t); 6429 6430 // if t == 15 || m == 15 then UNPREDICTABLE; 6431 if ((t == 15) || (m == 15)) 6432 return false; 6433 6434 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6435 if (wback && ((n == 15) || (n == t))) 6436 return false; 6437 } 6438 break; 6439 6440 default: 6441 return false; 6442 } 6443 6444 addr_t offset_addr; 6445 addr_t address; 6446 6447 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6448 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6449 if (!success) 6450 return false; 6451 6452 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6453 if (!success) 6454 return false; 6455 6456 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6457 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6458 if (!success) 6459 return false; 6460 6461 if (add) 6462 offset_addr = Rn + offset; 6463 else 6464 offset_addr = Rn - offset; 6465 6466 // address = if index then offset_addr else R[n]; 6467 if (index) 6468 address = offset_addr; 6469 else 6470 address = Rn; 6471 6472 // R[t] = ZeroExtend(MemU[address,1],32); 6473 RegisterInfo base_reg; 6474 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6475 6476 EmulateInstruction::Context context; 6477 context.type = eContextRegisterLoad; 6478 context.SetRegisterPlusOffset (base_reg, address - Rn); 6479 6480 uint64_t data = MemURead (context, address, 1, 0, &success); 6481 if (!success) 6482 return false; 6483 6484 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6485 return false; 6486 6487 // if wback then R[n] = offset_addr; 6488 if (wback) 6489 { 6490 context.type = eContextAdjustBaseRegister; 6491 context.SetAddress (offset_addr); 6492 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6493 return false; 6494 } 6495 } 6496 return true; 6497} 6498 6499// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6500// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6501// post-indexed, or pre-indexed addressing. 6502bool 6503EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6504{ 6505#if 0 6506 if ConditionPassed() then 6507 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6508 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6509 address = if index then offset_addr else R[n]; 6510 data = MemU[address,2]; 6511 if wback then R[n] = offset_addr; 6512 if UnalignedSupport() || address<0> = '0' then 6513 R[t] = ZeroExtend(data, 32); 6514 else // Can only apply before ARMv7 6515 R[t] = bits(32) UNKNOWN; 6516#endif 6517 6518 6519 bool success = false; 6520 6521 if (ConditionPassed(opcode)) 6522 { 6523 uint32_t t; 6524 uint32_t n; 6525 uint32_t imm32; 6526 bool index; 6527 bool add; 6528 bool wback; 6529 6530 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6531 switch (encoding) 6532 { 6533 case eEncodingT1: 6534 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6535 t = Bits32 (opcode, 2, 0); 6536 n = Bits32 (opcode, 5, 3); 6537 imm32 = Bits32 (opcode, 10, 6) << 1; 6538 6539 // index = TRUE; add = TRUE; wback = FALSE; 6540 index = true; 6541 add = true; 6542 wback = false; 6543 6544 break; 6545 6546 case eEncodingT2: 6547 // if Rt == '1111' then SEE "Unallocated memory hints"; 6548 // if Rn == '1111' then SEE LDRH (literal); 6549 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6550 t = Bits32 (opcode, 15, 12); 6551 n = Bits32 (opcode, 19, 16); 6552 imm32 = Bits32 (opcode, 11, 0); 6553 6554 // index = TRUE; add = TRUE; wback = FALSE; 6555 index = true; 6556 add = true; 6557 wback = false; 6558 6559 // if t == 13 then UNPREDICTABLE; 6560 if (t == 13) 6561 return false; 6562 break; 6563 6564 case eEncodingT3: 6565 // if Rn == '1111' then SEE LDRH (literal); 6566 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6567 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6568 // if P == '0' && W == '0' then UNDEFINED; 6569 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6570 return false; 6571 6572 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6573 t = Bits32 (opcode, 15, 12); 6574 n = Bits32 (opcode, 19, 16); 6575 imm32 = Bits32 (opcode, 7, 0); 6576 6577 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6578 index = BitIsSet (opcode, 10); 6579 add = BitIsSet (opcode, 9); 6580 wback = BitIsSet (opcode, 8); 6581 6582 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6583 if (BadReg (t) || (wback && (n == t))) 6584 return false; 6585 break; 6586 6587 default: 6588 return false; 6589 } 6590 6591 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6592 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6593 if (!success) 6594 return false; 6595 6596 addr_t offset_addr; 6597 addr_t address; 6598 6599 if (add) 6600 offset_addr = Rn + imm32; 6601 else 6602 offset_addr = Rn - imm32; 6603 6604 // address = if index then offset_addr else R[n]; 6605 if (index) 6606 address = offset_addr; 6607 else 6608 address = Rn; 6609 6610 // data = MemU[address,2]; 6611 RegisterInfo base_reg; 6612 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6613 6614 EmulateInstruction::Context context; 6615 context.type = eContextRegisterLoad; 6616 context.SetRegisterPlusOffset (base_reg, address - Rn); 6617 6618 uint64_t data = MemURead (context, address, 2, 0, &success); 6619 if (!success) 6620 return false; 6621 6622 // if wback then R[n] = offset_addr; 6623 if (wback) 6624 { 6625 context.type = eContextAdjustBaseRegister; 6626 context.SetAddress (offset_addr); 6627 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6628 return false; 6629 } 6630 6631 // if UnalignedSupport() || address<0> = '0' then 6632 if (UnalignedSupport () || BitIsClear (address, 0)) 6633 { 6634 // R[t] = ZeroExtend(data, 32); 6635 context.type = eContextRegisterLoad; 6636 context.SetRegisterPlusOffset (base_reg, address - Rn); 6637 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6638 return false; 6639 } 6640 else // Can only apply before ARMv7 6641 { 6642 // R[t] = bits(32) UNKNOWN; 6643 WriteBits32Unknown (t); 6644 } 6645 } 6646 return true; 6647} 6648 6649// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6650// zero-extends it to form a 32-bit word, and writes it to a register. 6651bool 6652EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6653{ 6654#if 0 6655 if ConditionPassed() then 6656 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6657 base = Align(PC,4); 6658 address = if add then (base + imm32) else (base - imm32); 6659 data = MemU[address,2]; 6660 if UnalignedSupport() || address<0> = '0' then 6661 R[t] = ZeroExtend(data, 32); 6662 else // Can only apply before ARMv7 6663 R[t] = bits(32) UNKNOWN; 6664#endif 6665 6666 bool success = false; 6667 6668 if (ConditionPassed(opcode)) 6669 { 6670 uint32_t t; 6671 uint32_t imm32; 6672 bool add; 6673 6674 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6675 switch (encoding) 6676 { 6677 case eEncodingT1: 6678 // if Rt == '1111' then SEE "Unallocated memory hints"; 6679 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6680 t = Bits32 (opcode, 15, 12); 6681 imm32 = Bits32 (opcode, 11, 0); 6682 add = BitIsSet (opcode, 23); 6683 6684 // if t == 13 then UNPREDICTABLE; 6685 if (t == 13) 6686 return false; 6687 6688 break; 6689 6690 case eEncodingA1: 6691 { 6692 uint32_t imm4H = Bits32 (opcode, 11, 8); 6693 uint32_t imm4L = Bits32 (opcode, 3, 0); 6694 6695 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6696 t = Bits32 (opcode, 15, 12); 6697 imm32 = (imm4H << 4) | imm4L; 6698 add = BitIsSet (opcode, 23); 6699 6700 // if t == 15 then UNPREDICTABLE; 6701 if (t == 15) 6702 return false; 6703 break; 6704 } 6705 6706 default: 6707 return false; 6708 } 6709 6710 // base = Align(PC,4); 6711 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6712 if (!success) 6713 return false; 6714 6715 addr_t base = AlignPC (pc_value); 6716 addr_t address; 6717 6718 // address = if add then (base + imm32) else (base - imm32); 6719 if (add) 6720 address = base + imm32; 6721 else 6722 address = base - imm32; 6723 6724 // data = MemU[address,2]; 6725 RegisterInfo base_reg; 6726 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6727 6728 EmulateInstruction::Context context; 6729 context.type = eContextRegisterLoad; 6730 context.SetRegisterPlusOffset (base_reg, address - base); 6731 6732 uint64_t data = MemURead (context, address, 2, 0, &success); 6733 if (!success) 6734 return false; 6735 6736 6737 // if UnalignedSupport() || address<0> = '0' then 6738 if (UnalignedSupport () || BitIsClear (address, 0)) 6739 { 6740 // R[t] = ZeroExtend(data, 32); 6741 context.type = eContextRegisterLoad; 6742 context.SetRegisterPlusOffset (base_reg, address - base); 6743 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6744 return false; 6745 6746 } 6747 else // Can only apply before ARMv7 6748 { 6749 // R[t] = bits(32) UNKNOWN; 6750 WriteBits32Unknown (t); 6751 } 6752 } 6753 return true; 6754} 6755 6756// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6757// from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6758// be shifted left by 0, 1, 2, or 3 bits. 6759bool 6760EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6761{ 6762#if 0 6763 if ConditionPassed() then 6764 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6765 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6766 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6767 address = if index then offset_addr else R[n]; 6768 data = MemU[address,2]; 6769 if wback then R[n] = offset_addr; 6770 if UnalignedSupport() || address<0> = '0' then 6771 R[t] = ZeroExtend(data, 32); 6772 else // Can only apply before ARMv7 6773 R[t] = bits(32) UNKNOWN; 6774#endif 6775 6776 bool success = false; 6777 6778 if (ConditionPassed(opcode)) 6779 { 6780 uint32_t t; 6781 uint32_t n; 6782 uint32_t m; 6783 bool index; 6784 bool add; 6785 bool wback; 6786 ARM_ShifterType shift_t; 6787 uint32_t shift_n; 6788 6789 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6790 switch (encoding) 6791 { 6792 case eEncodingT1: 6793 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6794 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6795 t = Bits32 (opcode, 2, 0); 6796 n = Bits32 (opcode, 5, 3); 6797 m = Bits32 (opcode, 8, 6); 6798 6799 // index = TRUE; add = TRUE; wback = FALSE; 6800 index = true; 6801 add = true; 6802 wback = false; 6803 6804 // (shift_t, shift_n) = (SRType_LSL, 0); 6805 shift_t = SRType_LSL; 6806 shift_n = 0; 6807 6808 break; 6809 6810 case eEncodingT2: 6811 // if Rn == '1111' then SEE LDRH (literal); 6812 // if Rt == '1111' then SEE "Unallocated memory hints"; 6813 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6814 t = Bits32 (opcode, 15, 12); 6815 n = Bits32 (opcode, 19, 16); 6816 m = Bits32 (opcode, 3, 0); 6817 6818 // index = TRUE; add = TRUE; wback = FALSE; 6819 index = true; 6820 add = true; 6821 wback = false; 6822 6823 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6824 shift_t = SRType_LSL; 6825 shift_n = Bits32 (opcode, 5, 4); 6826 6827 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6828 if ((t == 13) || BadReg (m)) 6829 return false; 6830 break; 6831 6832 case eEncodingA1: 6833 // if P == '0' && W == '1' then SEE LDRHT; 6834 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6835 t = Bits32 (opcode, 15, 12); 6836 n = Bits32 (opcode, 19, 16); 6837 m = Bits32 (opcode, 3, 0); 6838 6839 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6840 index = BitIsSet (opcode, 24); 6841 add = BitIsSet (opcode, 23); 6842 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6843 6844 // (shift_t, shift_n) = (SRType_LSL, 0); 6845 shift_t = SRType_LSL; 6846 shift_n = 0; 6847 6848 // if t == 15 || m == 15 then UNPREDICTABLE; 6849 if ((t == 15) || (m == 15)) 6850 return false; 6851 6852 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6853 if (wback && ((n == 15) || (n == t))) 6854 return false; 6855 6856 break; 6857 6858 default: 6859 return false; 6860 } 6861 6862 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6863 6864 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6865 if (!success) 6866 return false; 6867 6868 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6869 if (!success) 6870 return false; 6871 6872 addr_t offset_addr; 6873 addr_t address; 6874 6875 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6876 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6877 if (!success) 6878 return false; 6879 6880 if (add) 6881 offset_addr = Rn + offset; 6882 else 6883 offset_addr = Rn - offset; 6884 6885 // address = if index then offset_addr else R[n]; 6886 if (index) 6887 address = offset_addr; 6888 else 6889 address = Rn; 6890 6891 // data = MemU[address,2]; 6892 RegisterInfo base_reg; 6893 RegisterInfo offset_reg; 6894 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6895 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 6896 6897 EmulateInstruction::Context context; 6898 context.type = eContextRegisterLoad; 6899 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6900 uint64_t data = MemURead (context, address, 2, 0, &success); 6901 if (!success) 6902 return false; 6903 6904 // if wback then R[n] = offset_addr; 6905 if (wback) 6906 { 6907 context.type = eContextAdjustBaseRegister; 6908 context.SetAddress (offset_addr); 6909 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6910 return false; 6911 } 6912 6913 // if UnalignedSupport() || address<0> = '0' then 6914 if (UnalignedSupport() || BitIsClear (address, 0)) 6915 { 6916 // R[t] = ZeroExtend(data, 32); 6917 context.type = eContextRegisterLoad; 6918 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6919 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6920 return false; 6921 } 6922 else // Can only apply before ARMv7 6923 { 6924 // R[t] = bits(32) UNKNOWN; 6925 WriteBits32Unknown (t); 6926 } 6927 } 6928 return true; 6929} 6930 6931// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6932// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6933// or pre-indexed addressing. 6934bool 6935EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6936{ 6937#if 0 6938 if ConditionPassed() then 6939 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6940 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6941 address = if index then offset_addr else R[n]; 6942 R[t] = SignExtend(MemU[address,1], 32); 6943 if wback then R[n] = offset_addr; 6944#endif 6945 6946 bool success = false; 6947 6948 if (ConditionPassed(opcode)) 6949 { 6950 uint32_t t; 6951 uint32_t n; 6952 uint32_t imm32; 6953 bool index; 6954 bool add; 6955 bool wback; 6956 6957 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6958 switch (encoding) 6959 { 6960 case eEncodingT1: 6961 // if Rt == '1111' then SEE PLI; 6962 // if Rn == '1111' then SEE LDRSB (literal); 6963 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6964 t = Bits32 (opcode, 15, 12); 6965 n = Bits32 (opcode, 19, 16); 6966 imm32 = Bits32 (opcode, 11, 0); 6967 6968 // index = TRUE; add = TRUE; wback = FALSE; 6969 index = true; 6970 add = true; 6971 wback = false; 6972 6973 // if t == 13 then UNPREDICTABLE; 6974 if (t == 13) 6975 return false; 6976 6977 break; 6978 6979 case eEncodingT2: 6980 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 6981 // if Rn == '1111' then SEE LDRSB (literal); 6982 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 6983 // if P == '0' && W == '0' then UNDEFINED; 6984 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6985 return false; 6986 6987 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6988 t = Bits32 (opcode, 15, 12); 6989 n = Bits32 (opcode, 19, 16); 6990 imm32 = Bits32 (opcode, 7, 0); 6991 6992 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6993 index = BitIsSet (opcode, 10); 6994 add = BitIsSet (opcode, 9); 6995 wback = BitIsSet (opcode, 8); 6996 6997 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6998 if (((t == 13) || ((t == 15) 6999 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 7000 || (wback && (n == t))) 7001 return false; 7002 7003 break; 7004 7005 case eEncodingA1: 7006 { 7007 // if Rn == '1111' then SEE LDRSB (literal); 7008 // if P == '0' && W == '1' then SEE LDRSBT; 7009 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7010 t = Bits32 (opcode, 15, 12); 7011 n = Bits32 (opcode, 19, 16); 7012 7013 uint32_t imm4H = Bits32 (opcode, 11, 8); 7014 uint32_t imm4L = Bits32 (opcode, 3, 0); 7015 imm32 = (imm4H << 4) | imm4L; 7016 7017 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7018 index = BitIsSet (opcode, 24); 7019 add = BitIsSet (opcode, 23); 7020 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7021 7022 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7023 if ((t == 15) || (wback && (n == t))) 7024 return false; 7025 7026 break; 7027 } 7028 7029 default: 7030 return false; 7031 } 7032 7033 uint64_t Rn = ReadCoreReg (n, &success); 7034 if (!success) 7035 return false; 7036 7037 addr_t offset_addr; 7038 addr_t address; 7039 7040 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7041 if (add) 7042 offset_addr = Rn + imm32; 7043 else 7044 offset_addr = Rn - imm32; 7045 7046 // address = if index then offset_addr else R[n]; 7047 if (index) 7048 address = offset_addr; 7049 else 7050 address = Rn; 7051 7052 // R[t] = SignExtend(MemU[address,1], 32); 7053 RegisterInfo base_reg; 7054 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7055 7056 EmulateInstruction::Context context; 7057 context.type = eContextRegisterLoad; 7058 context.SetRegisterPlusOffset (base_reg, address - Rn); 7059 7060 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7061 if (!success) 7062 return false; 7063 7064 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7065 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7066 return false; 7067 7068 // if wback then R[n] = offset_addr; 7069 if (wback) 7070 { 7071 context.type = eContextAdjustBaseRegister; 7072 context.SetAddress (offset_addr); 7073 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7074 return false; 7075 } 7076 } 7077 7078 return true; 7079} 7080 7081// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7082// sign-extends it to form a 32-bit word, and writes tit to a register. 7083bool 7084EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7085{ 7086#if 0 7087 if ConditionPassed() then 7088 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7089 base = Align(PC,4); 7090 address = if add then (base + imm32) else (base - imm32); 7091 R[t] = SignExtend(MemU[address,1], 32); 7092#endif 7093 7094 bool success = false; 7095 7096 if (ConditionPassed(opcode)) 7097 { 7098 uint32_t t; 7099 uint32_t imm32; 7100 bool add; 7101 7102 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7103 switch (encoding) 7104 { 7105 case eEncodingT1: 7106 // if Rt == '1111' then SEE PLI; 7107 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7108 t = Bits32 (opcode, 15, 12); 7109 imm32 = Bits32 (opcode, 11, 0); 7110 add = BitIsSet (opcode, 23); 7111 7112 // if t == 13 then UNPREDICTABLE; 7113 if (t == 13) 7114 return false; 7115 7116 break; 7117 7118 case eEncodingA1: 7119 { 7120 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7121 t = Bits32 (opcode, 15, 12); 7122 uint32_t imm4H = Bits32 (opcode, 11, 8); 7123 uint32_t imm4L = Bits32 (opcode, 3, 0); 7124 imm32 = (imm4H << 4) | imm4L; 7125 add = BitIsSet (opcode, 23); 7126 7127 // if t == 15 then UNPREDICTABLE; 7128 if (t == 15) 7129 return false; 7130 7131 break; 7132 } 7133 7134 default: 7135 return false; 7136 } 7137 7138 // base = Align(PC,4); 7139 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7140 if (!success) 7141 return false; 7142 uint64_t base = AlignPC (pc_value); 7143 7144 // address = if add then (base + imm32) else (base - imm32); 7145 addr_t address; 7146 if (add) 7147 address = base + imm32; 7148 else 7149 address = base - imm32; 7150 7151 // R[t] = SignExtend(MemU[address,1], 32); 7152 RegisterInfo base_reg; 7153 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7154 7155 EmulateInstruction::Context context; 7156 context.type = eContextRegisterLoad; 7157 context.SetRegisterPlusOffset (base_reg, address - base); 7158 7159 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7160 if (!success) 7161 return false; 7162 7163 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7164 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7165 return false; 7166 } 7167 return true; 7168} 7169 7170// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7171// memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7172// shifted left by 0, 1, 2, or 3 bits. 7173bool 7174EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7175{ 7176#if 0 7177 if ConditionPassed() then 7178 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7179 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7180 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7181 address = if index then offset_addr else R[n]; 7182 R[t] = SignExtend(MemU[address,1], 32); 7183 if wback then R[n] = offset_addr; 7184#endif 7185 7186 bool success = false; 7187 7188 if (ConditionPassed(opcode)) 7189 { 7190 uint32_t t; 7191 uint32_t n; 7192 uint32_t m; 7193 bool index; 7194 bool add; 7195 bool wback; 7196 ARM_ShifterType shift_t; 7197 uint32_t shift_n; 7198 7199 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7200 switch (encoding) 7201 { 7202 case eEncodingT1: 7203 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7204 t = Bits32 (opcode, 2, 0); 7205 n = Bits32 (opcode, 5, 3); 7206 m = Bits32 (opcode, 8, 6); 7207 7208 // index = TRUE; add = TRUE; wback = FALSE; 7209 index = true; 7210 add = true; 7211 wback = false; 7212 7213 // (shift_t, shift_n) = (SRType_LSL, 0); 7214 shift_t = SRType_LSL; 7215 shift_n = 0; 7216 7217 break; 7218 7219 case eEncodingT2: 7220 // if Rt == '1111' then SEE PLI; 7221 // if Rn == '1111' then SEE LDRSB (literal); 7222 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7223 t = Bits32 (opcode, 15, 12); 7224 n = Bits32 (opcode, 19, 16); 7225 m = Bits32 (opcode, 3, 0); 7226 7227 // index = TRUE; add = TRUE; wback = FALSE; 7228 index = true; 7229 add = true; 7230 wback = false; 7231 7232 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7233 shift_t = SRType_LSL; 7234 shift_n = Bits32 (opcode, 5, 4); 7235 7236 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7237 if ((t == 13) || BadReg (m)) 7238 return false; 7239 break; 7240 7241 case eEncodingA1: 7242 // if P == '0' && W == '1' then SEE LDRSBT; 7243 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7244 t = Bits32 (opcode, 15, 12); 7245 n = Bits32 (opcode, 19, 16); 7246 m = Bits32 (opcode, 3, 0); 7247 7248 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7249 index = BitIsSet (opcode, 24); 7250 add = BitIsSet (opcode, 23); 7251 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7252 7253 // (shift_t, shift_n) = (SRType_LSL, 0); 7254 shift_t = SRType_LSL; 7255 shift_n = 0; 7256 7257 // if t == 15 || m == 15 then UNPREDICTABLE; 7258 if ((t == 15) || (m == 15)) 7259 return false; 7260 7261 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7262 if (wback && ((n == 15) || (n == t))) 7263 return false; 7264 break; 7265 7266 default: 7267 return false; 7268 } 7269 7270 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7271 if (!success) 7272 return false; 7273 7274 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7275 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7276 if (!success) 7277 return false; 7278 7279 addr_t offset_addr; 7280 addr_t address; 7281 7282 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7283 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7284 if (!success) 7285 return false; 7286 7287 if (add) 7288 offset_addr = Rn + offset; 7289 else 7290 offset_addr = Rn - offset; 7291 7292 // address = if index then offset_addr else R[n]; 7293 if (index) 7294 address = offset_addr; 7295 else 7296 address = Rn; 7297 7298 // R[t] = SignExtend(MemU[address,1], 32); 7299 RegisterInfo base_reg; 7300 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7301 RegisterInfo offset_reg; 7302 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7303 7304 EmulateInstruction::Context context; 7305 context.type = eContextRegisterLoad; 7306 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7307 7308 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7309 if (!success) 7310 return false; 7311 7312 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7313 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7314 return false; 7315 7316 // if wback then R[n] = offset_addr; 7317 if (wback) 7318 { 7319 context.type = eContextAdjustBaseRegister; 7320 context.SetAddress (offset_addr); 7321 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7322 return false; 7323 } 7324 } 7325 return true; 7326} 7327 7328// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7329// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7330// pre-indexed addressing. 7331bool 7332EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7333{ 7334#if 0 7335 if ConditionPassed() then 7336 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7337 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7338 address = if index then offset_addr else R[n]; 7339 data = MemU[address,2]; 7340 if wback then R[n] = offset_addr; 7341 if UnalignedSupport() || address<0> = '0' then 7342 R[t] = SignExtend(data, 32); 7343 else // Can only apply before ARMv7 7344 R[t] = bits(32) UNKNOWN; 7345#endif 7346 7347 bool success = false; 7348 7349 if (ConditionPassed(opcode)) 7350 { 7351 uint32_t t; 7352 uint32_t n; 7353 uint32_t imm32; 7354 bool index; 7355 bool add; 7356 bool wback; 7357 7358 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7359 switch (encoding) 7360 { 7361 case eEncodingT1: 7362 // if Rn == '1111' then SEE LDRSH (literal); 7363 // if Rt == '1111' then SEE "Unallocated memory hints"; 7364 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7365 t = Bits32 (opcode, 15, 12); 7366 n = Bits32 (opcode, 19, 16); 7367 imm32 = Bits32 (opcode, 11, 0); 7368 7369 // index = TRUE; add = TRUE; wback = FALSE; 7370 index = true; 7371 add = true; 7372 wback = false; 7373 7374 // if t == 13 then UNPREDICTABLE; 7375 if (t == 13) 7376 return false; 7377 7378 break; 7379 7380 case eEncodingT2: 7381 // if Rn == '1111' then SEE LDRSH (literal); 7382 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7383 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7384 // if P == '0' && W == '0' then UNDEFINED; 7385 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7386 return false; 7387 7388 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7389 t = Bits32 (opcode, 15, 12); 7390 n = Bits32 (opcode, 19, 16); 7391 imm32 = Bits32 (opcode, 7, 0); 7392 7393 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7394 index = BitIsSet (opcode, 10); 7395 add = BitIsSet (opcode, 9); 7396 wback = BitIsSet (opcode, 8); 7397 7398 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7399 if (BadReg (t) || (wback && (n == t))) 7400 return false; 7401 7402 break; 7403 7404 case eEncodingA1: 7405 { 7406 // if Rn == '1111' then SEE LDRSH (literal); 7407 // if P == '0' && W == '1' then SEE LDRSHT; 7408 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7409 t = Bits32 (opcode, 15, 12); 7410 n = Bits32 (opcode, 19, 16); 7411 uint32_t imm4H = Bits32 (opcode, 11,8); 7412 uint32_t imm4L = Bits32 (opcode, 3, 0); 7413 imm32 = (imm4H << 4) | imm4L; 7414 7415 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7416 index = BitIsSet (opcode, 24); 7417 add = BitIsSet (opcode, 23); 7418 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7419 7420 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7421 if ((t == 15) || (wback && (n == t))) 7422 return false; 7423 7424 break; 7425 } 7426 7427 default: 7428 return false; 7429 } 7430 7431 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7432 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7433 if (!success) 7434 return false; 7435 7436 addr_t offset_addr; 7437 if (add) 7438 offset_addr = Rn + imm32; 7439 else 7440 offset_addr = Rn - imm32; 7441 7442 // address = if index then offset_addr else R[n]; 7443 addr_t address; 7444 if (index) 7445 address = offset_addr; 7446 else 7447 address = Rn; 7448 7449 // data = MemU[address,2]; 7450 RegisterInfo base_reg; 7451 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7452 7453 EmulateInstruction::Context context; 7454 context.type = eContextRegisterLoad; 7455 context.SetRegisterPlusOffset (base_reg, address - Rn); 7456 7457 uint64_t data = MemURead (context, address, 2, 0, &success); 7458 if (!success) 7459 return false; 7460 7461 // if wback then R[n] = offset_addr; 7462 if (wback) 7463 { 7464 context.type = eContextAdjustBaseRegister; 7465 context.SetAddress (offset_addr); 7466 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7467 return false; 7468 } 7469 7470 // if UnalignedSupport() || address<0> = '0' then 7471 if (UnalignedSupport() || BitIsClear (address, 0)) 7472 { 7473 // R[t] = SignExtend(data, 32); 7474 int64_t signed_data = llvm::SignExtend64<16>(data); 7475 context.type = eContextRegisterLoad; 7476 context.SetRegisterPlusOffset (base_reg, address - Rn); 7477 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7478 return false; 7479 } 7480 else // Can only apply before ARMv7 7481 { 7482 // R[t] = bits(32) UNKNOWN; 7483 WriteBits32Unknown (t); 7484 } 7485 } 7486 return true; 7487} 7488 7489// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7490// sign-extends it to from a 32-bit word, and writes it to a register. 7491bool 7492EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7493{ 7494#if 0 7495 if ConditionPassed() then 7496 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7497 base = Align(PC,4); 7498 address = if add then (base + imm32) else (base - imm32); 7499 data = MemU[address,2]; 7500 if UnalignedSupport() || address<0> = '0' then 7501 R[t] = SignExtend(data, 32); 7502 else // Can only apply before ARMv7 7503 R[t] = bits(32) UNKNOWN; 7504#endif 7505 7506 bool success = false; 7507 7508 if (ConditionPassed(opcode)) 7509 { 7510 uint32_t t; 7511 uint32_t imm32; 7512 bool add; 7513 7514 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7515 switch (encoding) 7516 { 7517 case eEncodingT1: 7518 // if Rt == '1111' then SEE "Unallocated memory hints"; 7519 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7520 t = Bits32 (opcode, 15, 12); 7521 imm32 = Bits32 (opcode, 11, 0); 7522 add = BitIsSet (opcode, 23); 7523 7524 // if t == 13 then UNPREDICTABLE; 7525 if (t == 13) 7526 return false; 7527 7528 break; 7529 7530 case eEncodingA1: 7531 { 7532 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7533 t = Bits32 (opcode, 15, 12); 7534 uint32_t imm4H = Bits32 (opcode, 11, 8); 7535 uint32_t imm4L = Bits32 (opcode, 3, 0); 7536 imm32 = (imm4H << 4) | imm4L; 7537 add = BitIsSet (opcode, 23); 7538 7539 // if t == 15 then UNPREDICTABLE; 7540 if (t == 15) 7541 return false; 7542 7543 break; 7544 } 7545 default: 7546 return false; 7547 } 7548 7549 // base = Align(PC,4); 7550 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7551 if (!success) 7552 return false; 7553 7554 uint64_t base = AlignPC (pc_value); 7555 7556 addr_t address; 7557 // address = if add then (base + imm32) else (base - imm32); 7558 if (add) 7559 address = base + imm32; 7560 else 7561 address = base - imm32; 7562 7563 // data = MemU[address,2]; 7564 RegisterInfo base_reg; 7565 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7566 7567 EmulateInstruction::Context context; 7568 context.type = eContextRegisterLoad; 7569 context.SetRegisterPlusOffset (base_reg, imm32); 7570 7571 uint64_t data = MemURead (context, address, 2, 0, &success); 7572 if (!success) 7573 return false; 7574 7575 // if UnalignedSupport() || address<0> = '0' then 7576 if (UnalignedSupport() || BitIsClear (address, 0)) 7577 { 7578 // R[t] = SignExtend(data, 32); 7579 int64_t signed_data = llvm::SignExtend64<16>(data); 7580 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7581 return false; 7582 } 7583 else // Can only apply before ARMv7 7584 { 7585 // R[t] = bits(32) UNKNOWN; 7586 WriteBits32Unknown (t); 7587 } 7588 } 7589 return true; 7590} 7591 7592// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7593// from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7594// shifted left by 0, 1, 2, or 3 bits. 7595bool 7596EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7597{ 7598#if 0 7599 if ConditionPassed() then 7600 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7601 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7602 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7603 address = if index then offset_addr else R[n]; 7604 data = MemU[address,2]; 7605 if wback then R[n] = offset_addr; 7606 if UnalignedSupport() || address<0> = '0' then 7607 R[t] = SignExtend(data, 32); 7608 else // Can only apply before ARMv7 7609 R[t] = bits(32) UNKNOWN; 7610#endif 7611 7612 bool success = false; 7613 7614 if (ConditionPassed(opcode)) 7615 { 7616 uint32_t t; 7617 uint32_t n; 7618 uint32_t m; 7619 bool index; 7620 bool add; 7621 bool wback; 7622 ARM_ShifterType shift_t; 7623 uint32_t shift_n; 7624 7625 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7626 switch (encoding) 7627 { 7628 case eEncodingT1: 7629 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7630 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7631 t = Bits32 (opcode, 2, 0); 7632 n = Bits32 (opcode, 5, 3); 7633 m = Bits32 (opcode, 8, 6); 7634 7635 // index = TRUE; add = TRUE; wback = FALSE; 7636 index = true; 7637 add = true; 7638 wback = false; 7639 7640 // (shift_t, shift_n) = (SRType_LSL, 0); 7641 shift_t = SRType_LSL; 7642 shift_n = 0; 7643 7644 break; 7645 7646 case eEncodingT2: 7647 // if Rn == '1111' then SEE LDRSH (literal); 7648 // if Rt == '1111' then SEE "Unallocated memory hints"; 7649 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7650 t = Bits32 (opcode, 15, 12); 7651 n = Bits32 (opcode, 19, 16); 7652 m = Bits32 (opcode, 3, 0); 7653 7654 // index = TRUE; add = TRUE; wback = FALSE; 7655 index = true; 7656 add = true; 7657 wback = false; 7658 7659 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7660 shift_t = SRType_LSL; 7661 shift_n = Bits32 (opcode, 5, 4); 7662 7663 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7664 if ((t == 13) || BadReg (m)) 7665 return false; 7666 7667 break; 7668 7669 case eEncodingA1: 7670 // if P == '0' && W == '1' then SEE LDRSHT; 7671 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7672 t = Bits32 (opcode, 15, 12); 7673 n = Bits32 (opcode, 19, 16); 7674 m = Bits32 (opcode, 3, 0); 7675 7676 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7677 index = BitIsSet (opcode, 24); 7678 add = BitIsSet (opcode, 23); 7679 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7680 7681 // (shift_t, shift_n) = (SRType_LSL, 0); 7682 shift_t = SRType_LSL; 7683 shift_n = 0; 7684 7685 // if t == 15 || m == 15 then UNPREDICTABLE; 7686 if ((t == 15) || (m == 15)) 7687 return false; 7688 7689 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7690 if (wback && ((n == 15) || (n == t))) 7691 return false; 7692 7693 break; 7694 7695 default: 7696 return false; 7697 } 7698 7699 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7700 if (!success) 7701 return false; 7702 7703 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7704 if (!success) 7705 return false; 7706 7707 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7708 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7709 if (!success) 7710 return false; 7711 7712 addr_t offset_addr; 7713 addr_t address; 7714 7715 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7716 if (add) 7717 offset_addr = Rn + offset; 7718 else 7719 offset_addr = Rn - offset; 7720 7721 // address = if index then offset_addr else R[n]; 7722 if (index) 7723 address = offset_addr; 7724 else 7725 address = Rn; 7726 7727 // data = MemU[address,2]; 7728 RegisterInfo base_reg; 7729 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7730 7731 RegisterInfo offset_reg; 7732 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7733 7734 EmulateInstruction::Context context; 7735 context.type = eContextRegisterLoad; 7736 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7737 7738 uint64_t data = MemURead (context, address, 2, 0, &success); 7739 if (!success) 7740 return false; 7741 7742 // if wback then R[n] = offset_addr; 7743 if (wback) 7744 { 7745 context.type = eContextAdjustBaseRegister; 7746 context.SetAddress (offset_addr); 7747 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7748 return false; 7749 } 7750 7751 // if UnalignedSupport() || address<0> = '0' then 7752 if (UnalignedSupport() || BitIsClear (address, 0)) 7753 { 7754 // R[t] = SignExtend(data, 32); 7755 context.type = eContextRegisterLoad; 7756 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7757 7758 int64_t signed_data = llvm::SignExtend64<16>(data); 7759 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7760 return false; 7761 } 7762 else // Can only apply before ARMv7 7763 { 7764 // R[t] = bits(32) UNKNOWN; 7765 WriteBits32Unknown (t); 7766 } 7767 } 7768 return true; 7769} 7770 7771// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7772// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7773bool 7774EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7775{ 7776#if 0 7777 if ConditionPassed() then 7778 EncodingSpecificOperations(); 7779 rotated = ROR(R[m], rotation); 7780 R[d] = SignExtend(rotated<7:0>, 32); 7781#endif 7782 7783 bool success = false; 7784 7785 if (ConditionPassed(opcode)) 7786 { 7787 uint32_t d; 7788 uint32_t m; 7789 uint32_t rotation; 7790 7791 // EncodingSpecificOperations(); 7792 switch (encoding) 7793 { 7794 case eEncodingT1: 7795 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7796 d = Bits32 (opcode, 2, 0); 7797 m = Bits32 (opcode, 5, 3); 7798 rotation = 0; 7799 7800 break; 7801 7802 case eEncodingT2: 7803 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7804 d = Bits32 (opcode, 11, 8); 7805 m = Bits32 (opcode, 3, 0); 7806 rotation = Bits32 (opcode, 5, 4) << 3; 7807 7808 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7809 if (BadReg (d) || BadReg (m)) 7810 return false; 7811 7812 break; 7813 7814 case eEncodingA1: 7815 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7816 d = Bits32 (opcode, 15, 12); 7817 m = Bits32 (opcode, 3, 0); 7818 rotation = Bits32 (opcode, 11, 10) << 3; 7819 7820 // if d == 15 || m == 15 then UNPREDICTABLE; 7821 if ((d == 15) || (m == 15)) 7822 return false; 7823 7824 break; 7825 7826 default: 7827 return false; 7828 } 7829 7830 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7831 if (!success) 7832 return false; 7833 7834 // rotated = ROR(R[m], rotation); 7835 uint64_t rotated = ROR (Rm, rotation, &success); 7836 if (!success) 7837 return false; 7838 7839 // R[d] = SignExtend(rotated<7:0>, 32); 7840 int64_t data = llvm::SignExtend64<8>(rotated); 7841 7842 RegisterInfo source_reg; 7843 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7844 7845 EmulateInstruction::Context context; 7846 context.type = eContextRegisterLoad; 7847 context.SetRegister (source_reg); 7848 7849 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7850 return false; 7851 } 7852 return true; 7853} 7854 7855// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7856// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7857bool 7858EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7859{ 7860#if 0 7861 if ConditionPassed() then 7862 EncodingSpecificOperations(); 7863 rotated = ROR(R[m], rotation); 7864 R[d] = SignExtend(rotated<15:0>, 32); 7865#endif 7866 7867 bool success = false; 7868 7869 if (ConditionPassed(opcode)) 7870 { 7871 uint32_t d; 7872 uint32_t m; 7873 uint32_t rotation; 7874 7875 // EncodingSpecificOperations(); 7876 switch (encoding) 7877 { 7878 case eEncodingT1: 7879 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7880 d = Bits32 (opcode, 2, 0); 7881 m = Bits32 (opcode, 5, 3); 7882 rotation = 0; 7883 7884 break; 7885 7886 case eEncodingT2: 7887 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7888 d = Bits32 (opcode, 11, 8); 7889 m = Bits32 (opcode, 3, 0); 7890 rotation = Bits32 (opcode, 5, 4) << 3; 7891 7892 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7893 if (BadReg (d) || BadReg (m)) 7894 return false; 7895 7896 break; 7897 7898 case eEncodingA1: 7899 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7900 d = Bits32 (opcode, 15, 12); 7901 m = Bits32 (opcode, 3, 0); 7902 rotation = Bits32 (opcode, 11, 10) << 3; 7903 7904 // if d == 15 || m == 15 then UNPREDICTABLE; 7905 if ((d == 15) || (m == 15)) 7906 return false; 7907 7908 break; 7909 7910 default: 7911 return false; 7912 } 7913 7914 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7915 if (!success) 7916 return false; 7917 7918 // rotated = ROR(R[m], rotation); 7919 uint64_t rotated = ROR (Rm, rotation, &success); 7920 if (!success) 7921 return false; 7922 7923 // R[d] = SignExtend(rotated<15:0>, 32); 7924 RegisterInfo source_reg; 7925 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7926 7927 EmulateInstruction::Context context; 7928 context.type = eContextRegisterLoad; 7929 context.SetRegister (source_reg); 7930 7931 int64_t data = llvm::SignExtend64<16> (rotated); 7932 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7933 return false; 7934 } 7935 7936 return true; 7937} 7938 7939// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 7940// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7941bool 7942EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 7943{ 7944#if 0 7945 if ConditionPassed() then 7946 EncodingSpecificOperations(); 7947 rotated = ROR(R[m], rotation); 7948 R[d] = ZeroExtend(rotated<7:0>, 32); 7949#endif 7950 7951 bool success = false; 7952 7953 if (ConditionPassed(opcode)) 7954 { 7955 uint32_t d; 7956 uint32_t m; 7957 uint32_t rotation; 7958 7959 // EncodingSpecificOperations(); 7960 switch (encoding) 7961 { 7962 case eEncodingT1: 7963 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7964 d = Bits32 (opcode, 2, 0); 7965 m = Bits32 (opcode, 5, 3); 7966 rotation = 0; 7967 7968 break; 7969 7970 case eEncodingT2: 7971 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7972 d = Bits32 (opcode, 11, 8); 7973 m = Bits32 (opcode, 3, 0); 7974 rotation = Bits32 (opcode, 5, 4) << 3; 7975 7976 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7977 if (BadReg (d) || BadReg (m)) 7978 return false; 7979 7980 break; 7981 7982 case eEncodingA1: 7983 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7984 d = Bits32 (opcode, 15, 12); 7985 m = Bits32 (opcode, 3, 0); 7986 rotation = Bits32 (opcode, 11, 10) << 3; 7987 7988 // if d == 15 || m == 15 then UNPREDICTABLE; 7989 if ((d == 15) || (m == 15)) 7990 return false; 7991 7992 break; 7993 7994 default: 7995 return false; 7996 } 7997 7998 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7999 if (!success) 8000 return false; 8001 8002 // rotated = ROR(R[m], rotation); 8003 uint64_t rotated = ROR (Rm, rotation, &success); 8004 if (!success) 8005 return false; 8006 8007 // R[d] = ZeroExtend(rotated<7:0>, 32); 8008 RegisterInfo source_reg; 8009 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8010 8011 EmulateInstruction::Context context; 8012 context.type = eContextRegisterLoad; 8013 context.SetRegister (source_reg); 8014 8015 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 8016 return false; 8017 } 8018 return true; 8019} 8020 8021// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 8022// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 8023bool 8024EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 8025{ 8026#if 0 8027 if ConditionPassed() then 8028 EncodingSpecificOperations(); 8029 rotated = ROR(R[m], rotation); 8030 R[d] = ZeroExtend(rotated<15:0>, 32); 8031#endif 8032 8033 bool success = false; 8034 8035 if (ConditionPassed(opcode)) 8036 { 8037 uint32_t d; 8038 uint32_t m; 8039 uint32_t rotation; 8040 8041 switch (encoding) 8042 { 8043 case eEncodingT1: 8044 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8045 d = Bits32 (opcode, 2, 0); 8046 m = Bits32 (opcode, 5, 3); 8047 rotation = 0; 8048 8049 break; 8050 8051 case eEncodingT2: 8052 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8053 d = Bits32 (opcode, 11, 8); 8054 m = Bits32 (opcode, 3, 0); 8055 rotation = Bits32 (opcode, 5, 4) << 3; 8056 8057 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8058 if (BadReg (d) || BadReg (m)) 8059 return false; 8060 8061 break; 8062 8063 case eEncodingA1: 8064 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8065 d = Bits32 (opcode, 15, 12); 8066 m = Bits32 (opcode, 3, 0); 8067 rotation = Bits32 (opcode, 11, 10) << 3; 8068 8069 // if d == 15 || m == 15 then UNPREDICTABLE; 8070 if ((d == 15) || (m == 15)) 8071 return false; 8072 8073 break; 8074 8075 default: 8076 return false; 8077 } 8078 8079 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8080 if (!success) 8081 return false; 8082 8083 // rotated = ROR(R[m], rotation); 8084 uint64_t rotated = ROR (Rm, rotation, &success); 8085 if (!success) 8086 return false; 8087 8088 // R[d] = ZeroExtend(rotated<15:0>, 32); 8089 RegisterInfo source_reg; 8090 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8091 8092 EmulateInstruction::Context context; 8093 context.type = eContextRegisterLoad; 8094 context.SetRegister (source_reg); 8095 8096 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8097 return false; 8098 } 8099 return true; 8100} 8101 8102// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8103// word respectively. 8104bool 8105EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8106{ 8107#if 0 8108 if ConditionPassed() then 8109 EncodingSpecificOperations(); 8110 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8111 UNPREDICTABLE; 8112 else 8113 address = if increment then R[n] else R[n]-8; 8114 if wordhigher then address = address+4; 8115 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8116 BranchWritePC(MemA[address,4]); 8117 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8118#endif 8119 8120 bool success = false; 8121 8122 if (ConditionPassed(opcode)) 8123 { 8124 uint32_t n; 8125 bool wback; 8126 bool increment; 8127 bool wordhigher; 8128 8129 // EncodingSpecificOperations(); 8130 switch (encoding) 8131 { 8132 case eEncodingT1: 8133 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8134 n = Bits32 (opcode, 19, 16); 8135 wback = BitIsSet (opcode, 21); 8136 increment = false; 8137 wordhigher = false; 8138 8139 // if n == 15 then UNPREDICTABLE; 8140 if (n == 15) 8141 return false; 8142 8143 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8144 if (InITBlock() && !LastInITBlock()) 8145 return false; 8146 8147 break; 8148 8149 case eEncodingT2: 8150 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8151 n = Bits32 (opcode, 19, 16); 8152 wback = BitIsSet (opcode, 21); 8153 increment = true; 8154 wordhigher = false; 8155 8156 // if n == 15 then UNPREDICTABLE; 8157 if (n == 15) 8158 return false; 8159 8160 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8161 if (InITBlock() && !LastInITBlock()) 8162 return false; 8163 8164 break; 8165 8166 case eEncodingA1: 8167 // n = UInt(Rn); 8168 n = Bits32 (opcode, 19, 16); 8169 8170 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8171 wback = BitIsSet (opcode, 21); 8172 increment = BitIsSet (opcode, 23); 8173 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8174 8175 // if n == 15 then UNPREDICTABLE; 8176 if (n == 15) 8177 return false; 8178 8179 break; 8180 8181 default: 8182 return false; 8183 } 8184 8185 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8186 if (!CurrentModeIsPrivileged ()) 8187 // UNPREDICTABLE; 8188 return false; 8189 else 8190 { 8191 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8192 if (!success) 8193 return false; 8194 8195 addr_t address; 8196 // address = if increment then R[n] else R[n]-8; 8197 if (increment) 8198 address = Rn; 8199 else 8200 address = Rn - 8; 8201 8202 // if wordhigher then address = address+4; 8203 if (wordhigher) 8204 address = address + 4; 8205 8206 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8207 RegisterInfo base_reg; 8208 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8209 8210 EmulateInstruction::Context context; 8211 context.type = eContextReturnFromException; 8212 context.SetRegisterPlusOffset (base_reg, address - Rn); 8213 8214 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8215 if (!success) 8216 return false; 8217 8218 CPSRWriteByInstr (data, 15, true); 8219 8220 // BranchWritePC(MemA[address,4]); 8221 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8222 if (!success) 8223 return false; 8224 8225 BranchWritePC (context, data2); 8226 8227 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8228 if (wback) 8229 { 8230 context.type = eContextAdjustBaseRegister; 8231 if (increment) 8232 { 8233 context.SetOffset (8); 8234 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8235 return false; 8236 } 8237 else 8238 { 8239 context.SetOffset (-8); 8240 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8241 return false; 8242 } 8243 } // if wback 8244 } 8245 } // if ConditionPassed() 8246 return true; 8247} 8248 8249// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8250// and writes the result to the destination register. It can optionally update the condition flags based on 8251// the result. 8252bool 8253EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8254{ 8255#if 0 8256 // ARM pseudo code... 8257 if ConditionPassed() then 8258 EncodingSpecificOperations(); 8259 result = R[n] EOR imm32; 8260 if d == 15 then // Can only occur for ARM encoding 8261 ALUWritePC(result); // setflags is always FALSE here 8262 else 8263 R[d] = result; 8264 if setflags then 8265 APSR.N = result<31>; 8266 APSR.Z = IsZeroBit(result); 8267 APSR.C = carry; 8268 // APSR.V unchanged 8269#endif 8270 8271 bool success = false; 8272 8273 if (ConditionPassed(opcode)) 8274 { 8275 uint32_t Rd, Rn; 8276 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8277 bool setflags; 8278 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8279 switch (encoding) 8280 { 8281 case eEncodingT1: 8282 Rd = Bits32(opcode, 11, 8); 8283 Rn = Bits32(opcode, 19, 16); 8284 setflags = BitIsSet(opcode, 20); 8285 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8286 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8287 if (Rd == 15 && setflags) 8288 return EmulateTEQImm (opcode, eEncodingT1); 8289 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8290 return false; 8291 break; 8292 case eEncodingA1: 8293 Rd = Bits32(opcode, 15, 12); 8294 Rn = Bits32(opcode, 19, 16); 8295 setflags = BitIsSet(opcode, 20); 8296 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8297 8298 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8299 if (Rd == 15 && setflags) 8300 return EmulateSUBSPcLrEtc (opcode, encoding); 8301 break; 8302 default: 8303 return false; 8304 } 8305 8306 // Read the first operand. 8307 uint32_t val1 = ReadCoreReg(Rn, &success); 8308 if (!success) 8309 return false; 8310 8311 uint32_t result = val1 ^ imm32; 8312 8313 EmulateInstruction::Context context; 8314 context.type = EmulateInstruction::eContextImmediate; 8315 context.SetNoArgs (); 8316 8317 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8318 return false; 8319 } 8320 return true; 8321} 8322 8323// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8324// optionally-shifted register value, and writes the result to the destination register. 8325// It can optionally update the condition flags based on the result. 8326bool 8327EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8328{ 8329#if 0 8330 // ARM pseudo code... 8331 if ConditionPassed() then 8332 EncodingSpecificOperations(); 8333 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8334 result = R[n] EOR shifted; 8335 if d == 15 then // Can only occur for ARM encoding 8336 ALUWritePC(result); // setflags is always FALSE here 8337 else 8338 R[d] = result; 8339 if setflags then 8340 APSR.N = result<31>; 8341 APSR.Z = IsZeroBit(result); 8342 APSR.C = carry; 8343 // APSR.V unchanged 8344#endif 8345 8346 bool success = false; 8347 8348 if (ConditionPassed(opcode)) 8349 { 8350 uint32_t Rd, Rn, Rm; 8351 ARM_ShifterType shift_t; 8352 uint32_t shift_n; // the shift applied to the value read from Rm 8353 bool setflags; 8354 uint32_t carry; 8355 switch (encoding) 8356 { 8357 case eEncodingT1: 8358 Rd = Rn = Bits32(opcode, 2, 0); 8359 Rm = Bits32(opcode, 5, 3); 8360 setflags = !InITBlock(); 8361 shift_t = SRType_LSL; 8362 shift_n = 0; 8363 break; 8364 case eEncodingT2: 8365 Rd = Bits32(opcode, 11, 8); 8366 Rn = Bits32(opcode, 19, 16); 8367 Rm = Bits32(opcode, 3, 0); 8368 setflags = BitIsSet(opcode, 20); 8369 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8370 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8371 if (Rd == 15 && setflags) 8372 return EmulateTEQReg (opcode, eEncodingT1); 8373 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8374 return false; 8375 break; 8376 case eEncodingA1: 8377 Rd = Bits32(opcode, 15, 12); 8378 Rn = Bits32(opcode, 19, 16); 8379 Rm = Bits32(opcode, 3, 0); 8380 setflags = BitIsSet(opcode, 20); 8381 shift_n = DecodeImmShiftARM(opcode, shift_t); 8382 8383 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8384 if (Rd == 15 && setflags) 8385 return EmulateSUBSPcLrEtc (opcode, encoding); 8386 break; 8387 default: 8388 return false; 8389 } 8390 8391 // Read the first operand. 8392 uint32_t val1 = ReadCoreReg(Rn, &success); 8393 if (!success) 8394 return false; 8395 8396 // Read the second operand. 8397 uint32_t val2 = ReadCoreReg(Rm, &success); 8398 if (!success) 8399 return false; 8400 8401 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8402 if (!success) 8403 return false; 8404 uint32_t result = val1 ^ shifted; 8405 8406 EmulateInstruction::Context context; 8407 context.type = EmulateInstruction::eContextImmediate; 8408 context.SetNoArgs (); 8409 8410 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8411 return false; 8412 } 8413 return true; 8414} 8415 8416// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8417// writes the result to the destination register. It can optionally update the condition flags based 8418// on the result. 8419bool 8420EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8421{ 8422#if 0 8423 // ARM pseudo code... 8424 if ConditionPassed() then 8425 EncodingSpecificOperations(); 8426 result = R[n] OR imm32; 8427 if d == 15 then // Can only occur for ARM encoding 8428 ALUWritePC(result); // setflags is always FALSE here 8429 else 8430 R[d] = result; 8431 if setflags then 8432 APSR.N = result<31>; 8433 APSR.Z = IsZeroBit(result); 8434 APSR.C = carry; 8435 // APSR.V unchanged 8436#endif 8437 8438 bool success = false; 8439 8440 if (ConditionPassed(opcode)) 8441 { 8442 uint32_t Rd, Rn; 8443 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8444 bool setflags; 8445 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8446 switch (encoding) 8447 { 8448 case eEncodingT1: 8449 Rd = Bits32(opcode, 11, 8); 8450 Rn = Bits32(opcode, 19, 16); 8451 setflags = BitIsSet(opcode, 20); 8452 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8453 // if Rn == '1111' then SEE MOV (immediate); 8454 if (Rn == 15) 8455 return EmulateMOVRdImm (opcode, eEncodingT2); 8456 if (BadReg(Rd) || Rn == 13) 8457 return false; 8458 break; 8459 case eEncodingA1: 8460 Rd = Bits32(opcode, 15, 12); 8461 Rn = Bits32(opcode, 19, 16); 8462 setflags = BitIsSet(opcode, 20); 8463 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8464 8465 if (Rd == 15 && setflags) 8466 return EmulateSUBSPcLrEtc (opcode, encoding); 8467 break; 8468 default: 8469 return false; 8470 } 8471 8472 // Read the first operand. 8473 uint32_t val1 = ReadCoreReg(Rn, &success); 8474 if (!success) 8475 return false; 8476 8477 uint32_t result = val1 | imm32; 8478 8479 EmulateInstruction::Context context; 8480 context.type = EmulateInstruction::eContextImmediate; 8481 context.SetNoArgs (); 8482 8483 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8484 return false; 8485 } 8486 return true; 8487} 8488 8489// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8490// value, and writes the result to the destination register. It can optionally update the condition flags based 8491// on the result. 8492bool 8493EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8494{ 8495#if 0 8496 // ARM pseudo code... 8497 if ConditionPassed() then 8498 EncodingSpecificOperations(); 8499 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8500 result = R[n] OR shifted; 8501 if d == 15 then // Can only occur for ARM encoding 8502 ALUWritePC(result); // setflags is always FALSE here 8503 else 8504 R[d] = result; 8505 if setflags then 8506 APSR.N = result<31>; 8507 APSR.Z = IsZeroBit(result); 8508 APSR.C = carry; 8509 // APSR.V unchanged 8510#endif 8511 8512 bool success = false; 8513 8514 if (ConditionPassed(opcode)) 8515 { 8516 uint32_t Rd, Rn, Rm; 8517 ARM_ShifterType shift_t; 8518 uint32_t shift_n; // the shift applied to the value read from Rm 8519 bool setflags; 8520 uint32_t carry; 8521 switch (encoding) 8522 { 8523 case eEncodingT1: 8524 Rd = Rn = Bits32(opcode, 2, 0); 8525 Rm = Bits32(opcode, 5, 3); 8526 setflags = !InITBlock(); 8527 shift_t = SRType_LSL; 8528 shift_n = 0; 8529 break; 8530 case eEncodingT2: 8531 Rd = Bits32(opcode, 11, 8); 8532 Rn = Bits32(opcode, 19, 16); 8533 Rm = Bits32(opcode, 3, 0); 8534 setflags = BitIsSet(opcode, 20); 8535 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8536 // if Rn == '1111' then SEE MOV (register); 8537 if (Rn == 15) 8538 return EmulateMOVRdRm (opcode, eEncodingT3); 8539 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8540 return false; 8541 break; 8542 case eEncodingA1: 8543 Rd = Bits32(opcode, 15, 12); 8544 Rn = Bits32(opcode, 19, 16); 8545 Rm = Bits32(opcode, 3, 0); 8546 setflags = BitIsSet(opcode, 20); 8547 shift_n = DecodeImmShiftARM(opcode, shift_t); 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 // Read the second operand. 8562 uint32_t val2 = ReadCoreReg(Rm, &success); 8563 if (!success) 8564 return false; 8565 8566 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8567 if (!success) 8568 return false; 8569 uint32_t result = val1 | shifted; 8570 8571 EmulateInstruction::Context context; 8572 context.type = EmulateInstruction::eContextImmediate; 8573 context.SetNoArgs (); 8574 8575 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8576 return false; 8577 } 8578 return true; 8579} 8580 8581// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8582// the destination register. It can optionally update the condition flags based on the result. 8583bool 8584EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8585{ 8586#if 0 8587 // ARM pseudo code... 8588 if ConditionPassed() then 8589 EncodingSpecificOperations(); 8590 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8591 if d == 15 then // Can only occur for ARM encoding 8592 ALUWritePC(result); // setflags is always FALSE here 8593 else 8594 R[d] = result; 8595 if setflags then 8596 APSR.N = result<31>; 8597 APSR.Z = IsZeroBit(result); 8598 APSR.C = carry; 8599 APSR.V = overflow; 8600#endif 8601 8602 bool success = false; 8603 8604 uint32_t Rd; // the destination register 8605 uint32_t Rn; // the first operand 8606 bool setflags; 8607 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8608 switch (encoding) { 8609 case eEncodingT1: 8610 Rd = Bits32(opcode, 2, 0); 8611 Rn = Bits32(opcode, 5, 3); 8612 setflags = !InITBlock(); 8613 imm32 = 0; 8614 break; 8615 case eEncodingT2: 8616 Rd = Bits32(opcode, 11, 8); 8617 Rn = Bits32(opcode, 19, 16); 8618 setflags = BitIsSet(opcode, 20); 8619 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8620 if (BadReg(Rd) || BadReg(Rn)) 8621 return false; 8622 break; 8623 case eEncodingA1: 8624 Rd = Bits32(opcode, 15, 12); 8625 Rn = Bits32(opcode, 19, 16); 8626 setflags = BitIsSet(opcode, 20); 8627 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8628 8629 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8630 if (Rd == 15 && setflags) 8631 return EmulateSUBSPcLrEtc (opcode, encoding); 8632 break; 8633 default: 8634 return false; 8635 } 8636 // Read the register value from the operand register Rn. 8637 uint32_t reg_val = ReadCoreReg(Rn, &success); 8638 if (!success) 8639 return false; 8640 8641 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8642 8643 EmulateInstruction::Context context; 8644 context.type = EmulateInstruction::eContextImmediate; 8645 context.SetNoArgs (); 8646 8647 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8648 return false; 8649 8650 return true; 8651} 8652 8653// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8654// result to the destination register. It can optionally update the condition flags based on the result. 8655bool 8656EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8657{ 8658#if 0 8659 // ARM pseudo code... 8660 if ConditionPassed() then 8661 EncodingSpecificOperations(); 8662 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8663 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8664 if d == 15 then // Can only occur for ARM encoding 8665 ALUWritePC(result); // setflags is always FALSE here 8666 else 8667 R[d] = result; 8668 if setflags then 8669 APSR.N = result<31>; 8670 APSR.Z = IsZeroBit(result); 8671 APSR.C = carry; 8672 APSR.V = overflow; 8673#endif 8674 8675 bool success = false; 8676 8677 uint32_t Rd; // the destination register 8678 uint32_t Rn; // the first operand 8679 uint32_t Rm; // the second operand 8680 bool setflags; 8681 ARM_ShifterType shift_t; 8682 uint32_t shift_n; // the shift applied to the value read from Rm 8683 switch (encoding) { 8684 case eEncodingT1: 8685 Rd = Bits32(opcode, 11, 8); 8686 Rn = Bits32(opcode, 19, 16); 8687 Rm = Bits32(opcode, 3, 0); 8688 setflags = BitIsSet(opcode, 20); 8689 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8690 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8691 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8692 return false; 8693 break; 8694 case eEncodingA1: 8695 Rd = Bits32(opcode, 15, 12); 8696 Rn = Bits32(opcode, 19, 16); 8697 Rm = Bits32(opcode, 3, 0); 8698 setflags = BitIsSet(opcode, 20); 8699 shift_n = DecodeImmShiftARM(opcode, shift_t); 8700 8701 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8702 if (Rd == 15 && setflags) 8703 return EmulateSUBSPcLrEtc (opcode, encoding); 8704 break; 8705 default: 8706 return false; 8707 } 8708 // Read the register value from register Rn. 8709 uint32_t val1 = ReadCoreReg(Rn, &success); 8710 if (!success) 8711 return false; 8712 8713 // Read the register value from register Rm. 8714 uint32_t val2 = ReadCoreReg(Rm, &success); 8715 if (!success) 8716 return false; 8717 8718 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8719 if (!success) 8720 return false; 8721 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8722 8723 EmulateInstruction::Context context; 8724 context.type = EmulateInstruction::eContextImmediate; 8725 context.SetNoArgs(); 8726 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8727 return false; 8728 8729 return true; 8730} 8731 8732// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8733// an immediate value, and writes the result to the destination register. It can optionally update the condition 8734// flags based on the result. 8735bool 8736EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8737{ 8738#if 0 8739 // ARM pseudo code... 8740 if ConditionPassed() then 8741 EncodingSpecificOperations(); 8742 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8743 if d == 15 then 8744 ALUWritePC(result); // setflags is always FALSE here 8745 else 8746 R[d] = result; 8747 if setflags then 8748 APSR.N = result<31>; 8749 APSR.Z = IsZeroBit(result); 8750 APSR.C = carry; 8751 APSR.V = overflow; 8752#endif 8753 8754 bool success = false; 8755 8756 uint32_t Rd; // the destination register 8757 uint32_t Rn; // the first operand 8758 bool setflags; 8759 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8760 switch (encoding) { 8761 case eEncodingA1: 8762 Rd = Bits32(opcode, 15, 12); 8763 Rn = Bits32(opcode, 19, 16); 8764 setflags = BitIsSet(opcode, 20); 8765 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8766 8767 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8768 if (Rd == 15 && setflags) 8769 return EmulateSUBSPcLrEtc (opcode, encoding); 8770 break; 8771 default: 8772 return false; 8773 } 8774 // Read the register value from the operand register Rn. 8775 uint32_t reg_val = ReadCoreReg(Rn, &success); 8776 if (!success) 8777 return false; 8778 8779 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8780 8781 EmulateInstruction::Context context; 8782 context.type = EmulateInstruction::eContextImmediate; 8783 context.SetNoArgs (); 8784 8785 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8786 return false; 8787 8788 return true; 8789} 8790 8791// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8792// optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8793// condition flags based on the result. 8794bool 8795EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8796{ 8797#if 0 8798 // ARM pseudo code... 8799 if ConditionPassed() then 8800 EncodingSpecificOperations(); 8801 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8802 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8803 if d == 15 then 8804 ALUWritePC(result); // setflags is always FALSE here 8805 else 8806 R[d] = result; 8807 if setflags then 8808 APSR.N = result<31>; 8809 APSR.Z = IsZeroBit(result); 8810 APSR.C = carry; 8811 APSR.V = overflow; 8812#endif 8813 8814 bool success = false; 8815 8816 uint32_t Rd; // the destination register 8817 uint32_t Rn; // the first operand 8818 uint32_t Rm; // the second operand 8819 bool setflags; 8820 ARM_ShifterType shift_t; 8821 uint32_t shift_n; // the shift applied to the value read from Rm 8822 switch (encoding) { 8823 case eEncodingA1: 8824 Rd = Bits32(opcode, 15, 12); 8825 Rn = Bits32(opcode, 19, 16); 8826 Rm = Bits32(opcode, 3, 0); 8827 setflags = BitIsSet(opcode, 20); 8828 shift_n = DecodeImmShiftARM(opcode, shift_t); 8829 8830 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8831 if (Rd == 15 && setflags) 8832 return EmulateSUBSPcLrEtc (opcode, encoding); 8833 break; 8834 default: 8835 return false; 8836 } 8837 // Read the register value from register Rn. 8838 uint32_t val1 = ReadCoreReg(Rn, &success); 8839 if (!success) 8840 return false; 8841 8842 // Read the register value from register Rm. 8843 uint32_t val2 = ReadCoreReg(Rm, &success); 8844 if (!success) 8845 return false; 8846 8847 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8848 if (!success) 8849 return false; 8850 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8851 8852 EmulateInstruction::Context context; 8853 context.type = EmulateInstruction::eContextImmediate; 8854 context.SetNoArgs(); 8855 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8856 return false; 8857 8858 return true; 8859} 8860 8861// Subtract with Carry (immediate) subtracts an immediate value and the value of 8862// NOT (Carry flag) from a register value, and writes the result to the destination register. 8863// It can optionally update the condition flags based on the result. 8864bool 8865EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8866{ 8867#if 0 8868 // ARM pseudo code... 8869 if ConditionPassed() then 8870 EncodingSpecificOperations(); 8871 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8872 if d == 15 then // Can only occur for ARM encoding 8873 ALUWritePC(result); // setflags is always FALSE here 8874 else 8875 R[d] = result; 8876 if setflags then 8877 APSR.N = result<31>; 8878 APSR.Z = IsZeroBit(result); 8879 APSR.C = carry; 8880 APSR.V = overflow; 8881#endif 8882 8883 bool success = false; 8884 8885 uint32_t Rd; // the destination register 8886 uint32_t Rn; // the first operand 8887 bool setflags; 8888 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8889 switch (encoding) { 8890 case eEncodingT1: 8891 Rd = Bits32(opcode, 11, 8); 8892 Rn = Bits32(opcode, 19, 16); 8893 setflags = BitIsSet(opcode, 20); 8894 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8895 if (BadReg(Rd) || BadReg(Rn)) 8896 return false; 8897 break; 8898 case eEncodingA1: 8899 Rd = Bits32(opcode, 15, 12); 8900 Rn = Bits32(opcode, 19, 16); 8901 setflags = BitIsSet(opcode, 20); 8902 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8903 8904 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8905 if (Rd == 15 && setflags) 8906 return EmulateSUBSPcLrEtc (opcode, encoding); 8907 break; 8908 default: 8909 return false; 8910 } 8911 // Read the register value from the operand register Rn. 8912 uint32_t reg_val = ReadCoreReg(Rn, &success); 8913 if (!success) 8914 return false; 8915 8916 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 8917 8918 EmulateInstruction::Context context; 8919 context.type = EmulateInstruction::eContextImmediate; 8920 context.SetNoArgs (); 8921 8922 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8923 return false; 8924 8925 return true; 8926} 8927 8928// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 8929// NOT (Carry flag) from a register value, and writes the result to the destination register. 8930// It can optionally update the condition flags based on the result. 8931bool 8932EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 8933{ 8934#if 0 8935 // ARM pseudo code... 8936 if ConditionPassed() then 8937 EncodingSpecificOperations(); 8938 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8939 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 8940 if d == 15 then // Can only occur for ARM encoding 8941 ALUWritePC(result); // setflags is always FALSE here 8942 else 8943 R[d] = result; 8944 if setflags then 8945 APSR.N = result<31>; 8946 APSR.Z = IsZeroBit(result); 8947 APSR.C = carry; 8948 APSR.V = overflow; 8949#endif 8950 8951 bool success = false; 8952 8953 uint32_t Rd; // the destination register 8954 uint32_t Rn; // the first operand 8955 uint32_t Rm; // the second operand 8956 bool setflags; 8957 ARM_ShifterType shift_t; 8958 uint32_t shift_n; // the shift applied to the value read from Rm 8959 switch (encoding) { 8960 case eEncodingT1: 8961 Rd = Rn = Bits32(opcode, 2, 0); 8962 Rm = Bits32(opcode, 5, 3); 8963 setflags = !InITBlock(); 8964 shift_t = SRType_LSL; 8965 shift_n = 0; 8966 break; 8967 case eEncodingT2: 8968 Rd = Bits32(opcode, 11, 8); 8969 Rn = Bits32(opcode, 19, 16); 8970 Rm = Bits32(opcode, 3, 0); 8971 setflags = BitIsSet(opcode, 20); 8972 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8973 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8974 return false; 8975 break; 8976 case eEncodingA1: 8977 Rd = Bits32(opcode, 15, 12); 8978 Rn = Bits32(opcode, 19, 16); 8979 Rm = Bits32(opcode, 3, 0); 8980 setflags = BitIsSet(opcode, 20); 8981 shift_n = DecodeImmShiftARM(opcode, shift_t); 8982 8983 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8984 if (Rd == 15 && setflags) 8985 return EmulateSUBSPcLrEtc (opcode, encoding); 8986 break; 8987 default: 8988 return false; 8989 } 8990 // Read the register value from register Rn. 8991 uint32_t val1 = ReadCoreReg(Rn, &success); 8992 if (!success) 8993 return false; 8994 8995 // Read the register value from register Rm. 8996 uint32_t val2 = ReadCoreReg(Rm, &success); 8997 if (!success) 8998 return false; 8999 9000 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9001 if (!success) 9002 return false; 9003 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9004 9005 EmulateInstruction::Context context; 9006 context.type = EmulateInstruction::eContextImmediate; 9007 context.SetNoArgs(); 9008 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9009 return false; 9010 9011 return true; 9012} 9013 9014// This instruction subtracts an immediate value from a register value, and writes the result 9015// to the destination register. It can optionally update the condition flags based on the result. 9016bool 9017EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9018{ 9019#if 0 9020 // ARM pseudo code... 9021 if ConditionPassed() then 9022 EncodingSpecificOperations(); 9023 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9024 R[d] = result; 9025 if setflags then 9026 APSR.N = result<31>; 9027 APSR.Z = IsZeroBit(result); 9028 APSR.C = carry; 9029 APSR.V = overflow; 9030#endif 9031 9032 bool success = false; 9033 9034 uint32_t Rd; // the destination register 9035 uint32_t Rn; // the first operand 9036 bool setflags; 9037 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9038 switch (encoding) { 9039 case eEncodingT1: 9040 Rd = Bits32(opcode, 2, 0); 9041 Rn = Bits32(opcode, 5, 3); 9042 setflags = !InITBlock(); 9043 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9044 break; 9045 case eEncodingT2: 9046 Rd = Rn = Bits32(opcode, 10, 8); 9047 setflags = !InITBlock(); 9048 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9049 break; 9050 case eEncodingT3: 9051 Rd = Bits32(opcode, 11, 8); 9052 Rn = Bits32(opcode, 19, 16); 9053 setflags = BitIsSet(opcode, 20); 9054 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9055 9056 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9057 if (Rd == 15 && setflags) 9058 return EmulateCMPImm (opcode, eEncodingT2); 9059 9060 // if Rn == '1101' then SEE SUB (SP minus immediate); 9061 if (Rn == 13) 9062 return EmulateSUBSPImm (opcode, eEncodingT2); 9063 9064 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9065 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9066 return false; 9067 break; 9068 case eEncodingT4: 9069 Rd = Bits32(opcode, 11, 8); 9070 Rn = Bits32(opcode, 19, 16); 9071 setflags = BitIsSet(opcode, 20); 9072 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9073 9074 // if Rn == '1111' then SEE ADR; 9075 if (Rn == 15) 9076 return EmulateADR (opcode, eEncodingT2); 9077 9078 // if Rn == '1101' then SEE SUB (SP minus immediate); 9079 if (Rn == 13) 9080 return EmulateSUBSPImm (opcode, eEncodingT3); 9081 9082 if (BadReg(Rd)) 9083 return false; 9084 break; 9085 default: 9086 return false; 9087 } 9088 // Read the register value from the operand register Rn. 9089 uint32_t reg_val = ReadCoreReg(Rn, &success); 9090 if (!success) 9091 return false; 9092 9093 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9094 9095 EmulateInstruction::Context context; 9096 context.type = EmulateInstruction::eContextImmediate; 9097 context.SetNoArgs (); 9098 9099 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9100 return false; 9101 9102 return true; 9103} 9104 9105// This instruction subtracts an immediate value from a register value, and writes the result 9106// to the destination register. It can optionally update the condition flags based on the result. 9107bool 9108EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9109{ 9110#if 0 9111 // ARM pseudo code... 9112 if ConditionPassed() then 9113 EncodingSpecificOperations(); 9114 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9115 if d == 15 then 9116 ALUWritePC(result); // setflags is always FALSE here 9117 else 9118 R[d] = result; 9119 if setflags then 9120 APSR.N = result<31>; 9121 APSR.Z = IsZeroBit(result); 9122 APSR.C = carry; 9123 APSR.V = overflow; 9124#endif 9125 9126 bool success = false; 9127 9128 uint32_t Rd; // the destination register 9129 uint32_t Rn; // the first operand 9130 bool setflags; 9131 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9132 switch (encoding) { 9133 case eEncodingA1: 9134 Rd = Bits32(opcode, 15, 12); 9135 Rn = Bits32(opcode, 19, 16); 9136 setflags = BitIsSet(opcode, 20); 9137 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9138 9139 // if Rn == '1111' && S == '0' then SEE ADR; 9140 if (Rn == 15 && !setflags) 9141 return EmulateADR (opcode, eEncodingA2); 9142 9143 // if Rn == '1101' then SEE SUB (SP minus immediate); 9144 if (Rn == 13) 9145 return EmulateSUBSPImm (opcode, eEncodingA1); 9146 9147 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9148 if (Rd == 15 && setflags) 9149 return EmulateSUBSPcLrEtc (opcode, encoding); 9150 break; 9151 default: 9152 return false; 9153 } 9154 // Read the register value from the operand register Rn. 9155 uint32_t reg_val = ReadCoreReg(Rn, &success); 9156 if (!success) 9157 return false; 9158 9159 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9160 9161 EmulateInstruction::Context context; 9162 context.type = EmulateInstruction::eContextImmediate; 9163 context.SetNoArgs (); 9164 9165 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9166 return false; 9167 9168 return true; 9169} 9170 9171// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9172// immediate value. It updates the condition flags based on the result, and discards the result. 9173bool 9174EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9175{ 9176#if 0 9177 // ARM pseudo code... 9178 if ConditionPassed() then 9179 EncodingSpecificOperations(); 9180 result = R[n] EOR imm32; 9181 APSR.N = result<31>; 9182 APSR.Z = IsZeroBit(result); 9183 APSR.C = carry; 9184 // APSR.V unchanged 9185#endif 9186 9187 bool success = false; 9188 9189 if (ConditionPassed(opcode)) 9190 { 9191 uint32_t Rn; 9192 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9193 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9194 switch (encoding) 9195 { 9196 case eEncodingT1: 9197 Rn = Bits32(opcode, 19, 16); 9198 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9199 if (BadReg(Rn)) 9200 return false; 9201 break; 9202 case eEncodingA1: 9203 Rn = Bits32(opcode, 19, 16); 9204 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9205 break; 9206 default: 9207 return false; 9208 } 9209 9210 // Read the first operand. 9211 uint32_t val1 = ReadCoreReg(Rn, &success); 9212 if (!success) 9213 return false; 9214 9215 uint32_t result = val1 ^ imm32; 9216 9217 EmulateInstruction::Context context; 9218 context.type = EmulateInstruction::eContextImmediate; 9219 context.SetNoArgs (); 9220 9221 if (!WriteFlags(context, result, carry)) 9222 return false; 9223 } 9224 return true; 9225} 9226 9227// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9228// optionally-shifted register value. It updates the condition flags based on the result, and discards 9229// the result. 9230bool 9231EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9232{ 9233#if 0 9234 // ARM pseudo code... 9235 if ConditionPassed() then 9236 EncodingSpecificOperations(); 9237 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9238 result = R[n] EOR shifted; 9239 APSR.N = result<31>; 9240 APSR.Z = IsZeroBit(result); 9241 APSR.C = carry; 9242 // APSR.V unchanged 9243#endif 9244 9245 bool success = false; 9246 9247 if (ConditionPassed(opcode)) 9248 { 9249 uint32_t Rn, Rm; 9250 ARM_ShifterType shift_t; 9251 uint32_t shift_n; // the shift applied to the value read from Rm 9252 uint32_t carry; 9253 switch (encoding) 9254 { 9255 case eEncodingT1: 9256 Rn = Bits32(opcode, 19, 16); 9257 Rm = Bits32(opcode, 3, 0); 9258 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9259 if (BadReg(Rn) || BadReg(Rm)) 9260 return false; 9261 break; 9262 case eEncodingA1: 9263 Rn = Bits32(opcode, 19, 16); 9264 Rm = Bits32(opcode, 3, 0); 9265 shift_n = DecodeImmShiftARM(opcode, shift_t); 9266 break; 9267 default: 9268 return false; 9269 } 9270 9271 // Read the first operand. 9272 uint32_t val1 = ReadCoreReg(Rn, &success); 9273 if (!success) 9274 return false; 9275 9276 // Read the second operand. 9277 uint32_t val2 = ReadCoreReg(Rm, &success); 9278 if (!success) 9279 return false; 9280 9281 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9282 if (!success) 9283 return false; 9284 uint32_t result = val1 ^ shifted; 9285 9286 EmulateInstruction::Context context; 9287 context.type = EmulateInstruction::eContextImmediate; 9288 context.SetNoArgs (); 9289 9290 if (!WriteFlags(context, result, carry)) 9291 return false; 9292 } 9293 return true; 9294} 9295 9296// Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9297// It updates the condition flags based on the result, and discards the result. 9298bool 9299EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9300{ 9301#if 0 9302 // ARM pseudo code... 9303 if ConditionPassed() then 9304 EncodingSpecificOperations(); 9305 result = R[n] AND imm32; 9306 APSR.N = result<31>; 9307 APSR.Z = IsZeroBit(result); 9308 APSR.C = carry; 9309 // APSR.V unchanged 9310#endif 9311 9312 bool success = false; 9313 9314 if (ConditionPassed(opcode)) 9315 { 9316 uint32_t Rn; 9317 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9318 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9319 switch (encoding) 9320 { 9321 case eEncodingT1: 9322 Rn = Bits32(opcode, 19, 16); 9323 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9324 if (BadReg(Rn)) 9325 return false; 9326 break; 9327 case eEncodingA1: 9328 Rn = Bits32(opcode, 19, 16); 9329 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9330 break; 9331 default: 9332 return false; 9333 } 9334 9335 // Read the first operand. 9336 uint32_t val1 = ReadCoreReg(Rn, &success); 9337 if (!success) 9338 return false; 9339 9340 uint32_t result = val1 & imm32; 9341 9342 EmulateInstruction::Context context; 9343 context.type = EmulateInstruction::eContextImmediate; 9344 context.SetNoArgs (); 9345 9346 if (!WriteFlags(context, result, carry)) 9347 return false; 9348 } 9349 return true; 9350} 9351 9352// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9353// It updates the condition flags based on the result, and discards the result. 9354bool 9355EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9356{ 9357#if 0 9358 // ARM pseudo code... 9359 if ConditionPassed() then 9360 EncodingSpecificOperations(); 9361 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9362 result = R[n] AND shifted; 9363 APSR.N = result<31>; 9364 APSR.Z = IsZeroBit(result); 9365 APSR.C = carry; 9366 // APSR.V unchanged 9367#endif 9368 9369 bool success = false; 9370 9371 if (ConditionPassed(opcode)) 9372 { 9373 uint32_t Rn, Rm; 9374 ARM_ShifterType shift_t; 9375 uint32_t shift_n; // the shift applied to the value read from Rm 9376 uint32_t carry; 9377 switch (encoding) 9378 { 9379 case eEncodingT1: 9380 Rn = Bits32(opcode, 2, 0); 9381 Rm = Bits32(opcode, 5, 3); 9382 shift_t = SRType_LSL; 9383 shift_n = 0; 9384 break; 9385 case eEncodingT2: 9386 Rn = Bits32(opcode, 19, 16); 9387 Rm = Bits32(opcode, 3, 0); 9388 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9389 if (BadReg(Rn) || BadReg(Rm)) 9390 return false; 9391 break; 9392 case eEncodingA1: 9393 Rn = Bits32(opcode, 19, 16); 9394 Rm = Bits32(opcode, 3, 0); 9395 shift_n = DecodeImmShiftARM(opcode, shift_t); 9396 break; 9397 default: 9398 return false; 9399 } 9400 9401 // Read the first operand. 9402 uint32_t val1 = ReadCoreReg(Rn, &success); 9403 if (!success) 9404 return false; 9405 9406 // Read the second operand. 9407 uint32_t val2 = ReadCoreReg(Rm, &success); 9408 if (!success) 9409 return false; 9410 9411 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9412 if (!success) 9413 return false; 9414 uint32_t result = val1 & shifted; 9415 9416 EmulateInstruction::Context context; 9417 context.type = EmulateInstruction::eContextImmediate; 9418 context.SetNoArgs (); 9419 9420 if (!WriteFlags(context, result, carry)) 9421 return false; 9422 } 9423 return true; 9424} 9425 9426// A8.6.216 SUB (SP minus register) 9427bool 9428EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9429{ 9430#if 0 9431 if ConditionPassed() then 9432 EncodingSpecificOperations(); 9433 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9434 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9435 if d == 15 then // Can only occur for ARM encoding 9436 ALUWritePC(result); // setflags is always FALSE here 9437 else 9438 R[d] = result; 9439 if setflags then 9440 APSR.N = result<31>; 9441 APSR.Z = IsZeroBit(result); 9442 APSR.C = carry; 9443 APSR.V = overflow; 9444#endif 9445 9446 bool success = false; 9447 9448 if (ConditionPassed(opcode)) 9449 { 9450 uint32_t d; 9451 uint32_t m; 9452 bool setflags; 9453 ARM_ShifterType shift_t; 9454 uint32_t shift_n; 9455 9456 switch (encoding) 9457 { 9458 case eEncodingT1: 9459 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9460 d = Bits32 (opcode, 11, 8); 9461 m = Bits32 (opcode, 3, 0); 9462 setflags = BitIsSet (opcode, 20); 9463 9464 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9465 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9466 9467 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9468 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9469 return false; 9470 9471 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9472 if ((d == 15) || BadReg (m)) 9473 return false; 9474 break; 9475 9476 case eEncodingA1: 9477 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9478 d = Bits32 (opcode, 15, 12); 9479 m = Bits32 (opcode, 3, 0); 9480 setflags = BitIsSet (opcode, 20); 9481 9482 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9483 if (d == 15 && setflags) 9484 EmulateSUBSPcLrEtc (opcode, encoding); 9485 9486 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9487 shift_n = DecodeImmShiftARM (opcode, shift_t); 9488 break; 9489 9490 default: 9491 return false; 9492 } 9493 9494 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9495 uint32_t Rm = ReadCoreReg (m, &success); 9496 if (!success) 9497 return false; 9498 9499 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9500 if (!success) 9501 return false; 9502 9503 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9504 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9505 if (!success) 9506 return false; 9507 9508 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9509 9510 EmulateInstruction::Context context; 9511 context.type = eContextArithmetic; 9512 RegisterInfo sp_reg; 9513 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9514 RegisterInfo dwarf_reg; 9515 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9516 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9517 9518 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9519 return false; 9520 } 9521 return true; 9522} 9523 9524 9525// A8.6.7 ADD (register-shifted register) 9526bool 9527EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9528{ 9529#if 0 9530 if ConditionPassed() then 9531 EncodingSpecificOperations(); 9532 shift_n = UInt(R[s]<7:0>); 9533 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9534 (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9535 R[d] = result; 9536 if setflags then 9537 APSR.N = result<31>; 9538 APSR.Z = IsZeroBit(result); 9539 APSR.C = carry; 9540 APSR.V = overflow; 9541#endif 9542 9543 bool success = false; 9544 9545 if (ConditionPassed(opcode)) 9546 { 9547 uint32_t d; 9548 uint32_t n; 9549 uint32_t m; 9550 uint32_t s; 9551 bool setflags; 9552 ARM_ShifterType shift_t; 9553 9554 switch (encoding) 9555 { 9556 case eEncodingA1: 9557 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9558 d = Bits32 (opcode, 15, 12); 9559 n = Bits32 (opcode, 19, 16); 9560 m = Bits32 (opcode, 3, 0); 9561 s = Bits32 (opcode, 11, 8); 9562 9563 // setflags = (S == �1�); shift_t = DecodeRegShift(type); 9564 setflags = BitIsSet (opcode, 20); 9565 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9566 9567 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9568 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9569 return false; 9570 break; 9571 9572 default: 9573 return false; 9574 } 9575 9576 // shift_n = UInt(R[s]<7:0>); 9577 uint32_t Rs = ReadCoreReg (s, &success); 9578 if (!success) 9579 return false; 9580 9581 uint32_t shift_n = Bits32 (Rs, 7, 0); 9582 9583 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9584 uint32_t Rm = ReadCoreReg (m, &success); 9585 if (!success) 9586 return false; 9587 9588 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9589 if (!success) 9590 return false; 9591 9592 // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9593 uint32_t Rn = ReadCoreReg (n, &success); 9594 if (!success) 9595 return false; 9596 9597 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9598 9599 // R[d] = result; 9600 EmulateInstruction::Context context; 9601 context.type = eContextArithmetic; 9602 RegisterInfo reg_n; 9603 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9604 RegisterInfo reg_m; 9605 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9606 9607 context.SetRegisterRegisterOperands (reg_n, reg_m); 9608 9609 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9610 return false; 9611 9612 // if setflags then 9613 // APSR.N = result<31>; 9614 // APSR.Z = IsZeroBit(result); 9615 // APSR.C = carry; 9616 // APSR.V = overflow; 9617 if (setflags) 9618 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9619 } 9620 return true; 9621} 9622 9623// A8.6.213 SUB (register) 9624bool 9625EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9626{ 9627#if 0 9628 if ConditionPassed() then 9629 EncodingSpecificOperations(); 9630 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9631 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9632 if d == 15 then // Can only occur for ARM encoding 9633 ALUWritePC(result); // setflags is always FALSE here 9634 else 9635 R[d] = result; 9636 if setflags then 9637 APSR.N = result<31>; 9638 APSR.Z = IsZeroBit(result); 9639 APSR.C = carry; 9640 APSR.V = overflow; 9641#endif 9642 9643 bool success = false; 9644 9645 if (ConditionPassed(opcode)) 9646 { 9647 uint32_t d; 9648 uint32_t n; 9649 uint32_t m; 9650 bool setflags; 9651 ARM_ShifterType shift_t; 9652 uint32_t shift_n; 9653 9654 switch (encoding) 9655 { 9656 case eEncodingT1: 9657 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9658 d = Bits32 (opcode, 2, 0); 9659 n = Bits32 (opcode, 5, 3); 9660 m = Bits32 (opcode, 8, 6); 9661 setflags = !InITBlock(); 9662 9663 // (shift_t, shift_n) = (SRType_LSL, 0); 9664 shift_t = SRType_LSL; 9665 shift_n = 0; 9666 9667 break; 9668 9669 case eEncodingT2: 9670 // if Rd == �1111� && S == �1� then SEE CMP (register); 9671 // if Rn == �1101� then SEE SUB (SP minus register); 9672 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9673 d = Bits32 (opcode, 11, 8); 9674 n = Bits32 (opcode, 19, 16); 9675 m = Bits32 (opcode, 3, 0); 9676 setflags = BitIsSet (opcode, 20); 9677 9678 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9679 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9680 9681 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9682 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9683 return false; 9684 9685 break; 9686 9687 case eEncodingA1: 9688 // if Rn == �1101� then SEE SUB (SP minus register); 9689 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9690 d = Bits32 (opcode, 15, 12); 9691 n = Bits32 (opcode, 19, 16); 9692 m = Bits32 (opcode, 3, 0); 9693 setflags = BitIsSet (opcode, 20); 9694 9695 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9696 if ((d == 15) && setflags) 9697 EmulateSUBSPcLrEtc (opcode, encoding); 9698 9699 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9700 shift_n = DecodeImmShiftARM (opcode, shift_t); 9701 9702 break; 9703 9704 default: 9705 return false; 9706 } 9707 9708 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9709 uint32_t Rm = ReadCoreReg (m, &success); 9710 if (!success) 9711 return false; 9712 9713 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9714 if (!success) 9715 return false; 9716 9717 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9718 uint32_t Rn = ReadCoreReg (n, &success); 9719 if (!success) 9720 return false; 9721 9722 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9723 9724 // if d == 15 then // Can only occur for ARM encoding 9725 // ALUWritePC(result); // setflags is always FALSE here 9726 // else 9727 // R[d] = result; 9728 // if setflags then 9729 // APSR.N = result<31>; 9730 // APSR.Z = IsZeroBit(result); 9731 // APSR.C = carry; 9732 // APSR.V = overflow; 9733 9734 EmulateInstruction::Context context; 9735 context.type = eContextArithmetic; 9736 RegisterInfo reg_n; 9737 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9738 RegisterInfo reg_m; 9739 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9740 context.SetRegisterRegisterOperands (reg_n, reg_m); 9741 9742 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9743 return false; 9744 } 9745 return true; 9746} 9747 9748// A8.6.202 STREX 9749// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9750// word from a register to memory if the executing processor has exclusive access to the memory addressed. 9751bool 9752EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9753{ 9754#if 0 9755 if ConditionPassed() then 9756 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9757 address = R[n] + imm32; 9758 if ExclusiveMonitorsPass(address,4) then 9759 MemA[address,4] = R[t]; 9760 R[d] = 0; 9761 else 9762 R[d] = 1; 9763#endif 9764 9765 bool success = false; 9766 9767 if (ConditionPassed(opcode)) 9768 { 9769 uint32_t d; 9770 uint32_t t; 9771 uint32_t n; 9772 uint32_t imm32; 9773 const uint32_t addr_byte_size = GetAddressByteSize(); 9774 9775 switch (encoding) 9776 { 9777 case eEncodingT1: 9778 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 9779 d = Bits32 (opcode, 11, 8); 9780 t = Bits32 (opcode, 15, 12); 9781 n = Bits32 (opcode, 19, 16); 9782 imm32 = Bits32 (opcode, 7, 0) << 2; 9783 9784 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9785 if (BadReg (d) || BadReg (t) || (n == 15)) 9786 return false; 9787 9788 // if d == n || d == t then UNPREDICTABLE; 9789 if ((d == n) || (d == t)) 9790 return false; 9791 9792 break; 9793 9794 case eEncodingA1: 9795 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9796 d = Bits32 (opcode, 15, 12); 9797 t = Bits32 (opcode, 3, 0); 9798 n = Bits32 (opcode, 19, 16); 9799 imm32 = 0; 9800 9801 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9802 if ((d == 15) || (t == 15) || (n == 15)) 9803 return false; 9804 9805 // if d == n || d == t then UNPREDICTABLE; 9806 if ((d == n) || (d == t)) 9807 return false; 9808 9809 break; 9810 9811 default: 9812 return false; 9813 } 9814 9815 // address = R[n] + imm32; 9816 uint32_t Rn = ReadCoreReg (n, &success); 9817 if (!success) 9818 return false; 9819 9820 addr_t address = Rn + imm32; 9821 9822 RegisterInfo base_reg; 9823 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9824 RegisterInfo data_reg; 9825 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9826 EmulateInstruction::Context context; 9827 context.type = eContextRegisterStore; 9828 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9829 9830 // if ExclusiveMonitorsPass(address,4) then 9831 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9832 // always return true. 9833 if (true) 9834 { 9835 // MemA[address,4] = R[t]; 9836 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9837 if (!success) 9838 return false; 9839 9840 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9841 return false; 9842 9843 // R[d] = 0; 9844 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9845 return false; 9846 } 9847 else 9848 { 9849 // R[d] = 1; 9850 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9851 return false; 9852 } 9853 } 9854 return true; 9855} 9856 9857// A8.6.197 STRB (immediate, ARM) 9858bool 9859EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9860{ 9861#if 0 9862 if ConditionPassed() then 9863 EncodingSpecificOperations(); 9864 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9865 address = if index then offset_addr else R[n]; 9866 MemU[address,1] = R[t]<7:0>; 9867 if wback then R[n] = offset_addr; 9868#endif 9869 9870 bool success = false; 9871 9872 if (ConditionPassed(opcode)) 9873 { 9874 uint32_t t; 9875 uint32_t n; 9876 uint32_t imm32; 9877 bool index; 9878 bool add; 9879 bool wback; 9880 9881 switch (encoding) 9882 { 9883 case eEncodingA1: 9884 // if P == �0� && W == �1� then SEE STRBT; 9885 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9886 t = Bits32 (opcode, 15, 12); 9887 n = Bits32 (opcode, 19, 16); 9888 imm32 = Bits32 (opcode, 11, 0); 9889 9890 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9891 index = BitIsSet (opcode, 24); 9892 add = BitIsSet (opcode, 23); 9893 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9894 9895 // if t == 15 then UNPREDICTABLE; 9896 if (t == 15) 9897 return false; 9898 9899 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9900 if (wback && ((n == 15) || (n == t))) 9901 return false; 9902 9903 break; 9904 9905 default: 9906 return false; 9907 } 9908 9909 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9910 uint32_t Rn = ReadCoreReg (n, &success); 9911 if (!success) 9912 return false; 9913 9914 addr_t offset_addr; 9915 if (add) 9916 offset_addr = Rn + imm32; 9917 else 9918 offset_addr = Rn - imm32; 9919 9920 // address = if index then offset_addr else R[n]; 9921 addr_t address; 9922 if (index) 9923 address = offset_addr; 9924 else 9925 address = Rn; 9926 9927 // MemU[address,1] = R[t]<7:0>; 9928 uint32_t Rt = ReadCoreReg (t, &success); 9929 if (!success) 9930 return false; 9931 9932 RegisterInfo base_reg; 9933 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9934 RegisterInfo data_reg; 9935 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9936 EmulateInstruction::Context context; 9937 context.type = eContextRegisterStore; 9938 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9939 9940 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 9941 return false; 9942 9943 // if wback then R[n] = offset_addr; 9944 if (wback) 9945 { 9946 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9947 return false; 9948 } 9949 } 9950 return true; 9951} 9952 9953// A8.6.194 STR (immediate, ARM) 9954bool 9955EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9956{ 9957#if 0 9958 if ConditionPassed() then 9959 EncodingSpecificOperations(); 9960 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9961 address = if index then offset_addr else R[n]; 9962 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9963 if wback then R[n] = offset_addr; 9964#endif 9965 9966 bool success = false; 9967 9968 if (ConditionPassed(opcode)) 9969 { 9970 uint32_t t; 9971 uint32_t n; 9972 uint32_t imm32; 9973 bool index; 9974 bool add; 9975 bool wback; 9976 9977 const uint32_t addr_byte_size = GetAddressByteSize(); 9978 9979 switch (encoding) 9980 { 9981 case eEncodingA1: 9982 // if P == �0� && W == �1� then SEE STRT; 9983 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH; 9984 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9985 t = Bits32 (opcode, 15, 12); 9986 n = Bits32 (opcode, 19, 16); 9987 imm32 = Bits32 (opcode, 11, 0); 9988 9989 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9990 index = BitIsSet (opcode, 24); 9991 add = BitIsSet (opcode, 23); 9992 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9993 9994 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9995 if (wback && ((n == 15) || (n == t))) 9996 return false; 9997 9998 break; 9999 10000 default: 10001 return false; 10002 } 10003 10004 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10005 uint32_t Rn = ReadCoreReg (n, &success); 10006 if (!success) 10007 return false; 10008 10009 addr_t offset_addr; 10010 if (add) 10011 offset_addr = Rn + imm32; 10012 else 10013 offset_addr = Rn - imm32; 10014 10015 // address = if index then offset_addr else R[n]; 10016 addr_t address; 10017 if (index) 10018 address = offset_addr; 10019 else 10020 address = Rn; 10021 10022 RegisterInfo base_reg; 10023 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10024 RegisterInfo data_reg; 10025 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10026 EmulateInstruction::Context context; 10027 context.type = eContextRegisterStore; 10028 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10029 10030 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10031 uint32_t Rt = ReadCoreReg (t, &success); 10032 if (!success) 10033 return false; 10034 10035 if (t == 15) 10036 { 10037 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10038 if (!success) 10039 return false; 10040 10041 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10042 return false; 10043 } 10044 else 10045 { 10046 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10047 return false; 10048 } 10049 10050 // if wback then R[n] = offset_addr; 10051 if (wback) 10052 { 10053 context.type = eContextAdjustBaseRegister; 10054 context.SetImmediate (offset_addr); 10055 10056 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10057 return false; 10058 } 10059 } 10060 return true; 10061} 10062 10063// A8.6.66 LDRD (immediate) 10064// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10065// words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10066bool 10067EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10068{ 10069#if 0 10070 if ConditionPassed() then 10071 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10072 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10073 address = if index then offset_addr else R[n]; 10074 R[t] = MemA[address,4]; 10075 R[t2] = MemA[address+4,4]; 10076 if wback then R[n] = offset_addr; 10077#endif 10078 10079 bool success = false; 10080 10081 if (ConditionPassed(opcode)) 10082 { 10083 uint32_t t; 10084 uint32_t t2; 10085 uint32_t n; 10086 uint32_t imm32; 10087 bool index; 10088 bool add; 10089 bool wback; 10090 10091 switch (encoding) 10092 { 10093 case eEncodingT1: 10094 //if P == �0� && W == �0� then SEE �Related encodings�; 10095 //if Rn == �1111� then SEE LDRD (literal); 10096 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10097 t = Bits32 (opcode, 15, 12); 10098 t2 = Bits32 (opcode, 11, 8); 10099 n = Bits32 (opcode, 19, 16); 10100 imm32 = Bits32 (opcode, 7, 0) << 2; 10101 10102 //index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10103 index = BitIsSet (opcode, 24); 10104 add = BitIsSet (opcode, 23); 10105 wback = BitIsSet (opcode, 21); 10106 10107 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10108 if (wback && ((n == t) || (n == t2))) 10109 return false; 10110 10111 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10112 if (BadReg (t) || BadReg (t2) || (t == t2)) 10113 return false; 10114 10115 break; 10116 10117 case eEncodingA1: 10118 //if Rn == �1111� then SEE LDRD (literal); 10119 //if Rt<0> == �1� then UNPREDICTABLE; 10120 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10121 t = Bits32 (opcode, 15, 12); 10122 if (BitIsSet (t, 0)) 10123 return false; 10124 t2 = t + 1; 10125 n = Bits32 (opcode, 19, 16); 10126 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10127 10128 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10129 index = BitIsSet (opcode, 24); 10130 add = BitIsSet (opcode, 23); 10131 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10132 10133 //if P == �0� && W == �1� then UNPREDICTABLE; 10134 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10135 return false; 10136 10137 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10138 if (wback && ((n == t) || (n == t2))) 10139 return false; 10140 10141 //if t2 == 15 then UNPREDICTABLE; 10142 if (t2 == 15) 10143 return false; 10144 10145 break; 10146 10147 default: 10148 return false; 10149 } 10150 10151 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10152 uint32_t Rn = ReadCoreReg (n, &success); 10153 if (!success) 10154 return false; 10155 10156 addr_t offset_addr; 10157 if (add) 10158 offset_addr = Rn + imm32; 10159 else 10160 offset_addr = Rn - imm32; 10161 10162 //address = if index then offset_addr else R[n]; 10163 addr_t address; 10164 if (index) 10165 address = offset_addr; 10166 else 10167 address = Rn; 10168 10169 //R[t] = MemA[address,4]; 10170 RegisterInfo base_reg; 10171 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10172 10173 EmulateInstruction::Context context; 10174 context.type = eContextRegisterLoad; 10175 context.SetRegisterPlusOffset (base_reg, address - Rn); 10176 10177 const uint32_t addr_byte_size = GetAddressByteSize(); 10178 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10179 if (!success) 10180 return false; 10181 10182 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10183 return false; 10184 10185 //R[t2] = MemA[address+4,4]; 10186 10187 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10188 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10189 if (!success) 10190 return false; 10191 10192 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10193 return false; 10194 10195 //if wback then R[n] = offset_addr; 10196 if (wback) 10197 { 10198 context.type = eContextAdjustBaseRegister; 10199 context.SetAddress (offset_addr); 10200 10201 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10202 return false; 10203 } 10204 } 10205 return true; 10206} 10207 10208// A8.6.68 LDRD (register) 10209// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10210// words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10211bool 10212EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10213{ 10214#if 0 10215 if ConditionPassed() then 10216 EncodingSpecificOperations(); 10217 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10218 address = if index then offset_addr else R[n]; 10219 R[t] = MemA[address,4]; 10220 R[t2] = MemA[address+4,4]; 10221 if wback then R[n] = offset_addr; 10222#endif 10223 10224 bool success = false; 10225 10226 if (ConditionPassed(opcode)) 10227 { 10228 uint32_t t; 10229 uint32_t t2; 10230 uint32_t n; 10231 uint32_t m; 10232 bool index; 10233 bool add; 10234 bool wback; 10235 10236 switch (encoding) 10237 { 10238 case eEncodingA1: 10239 // if Rt<0> == �1� then UNPREDICTABLE; 10240 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10241 t = Bits32 (opcode, 15, 12); 10242 if (BitIsSet (t, 0)) 10243 return false; 10244 t2 = t + 1; 10245 n = Bits32 (opcode, 19, 16); 10246 m = Bits32 (opcode, 3, 0); 10247 10248 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10249 index = BitIsSet (opcode, 24); 10250 add = BitIsSet (opcode, 23); 10251 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10252 10253 // if P == �0� && W == �1� then UNPREDICTABLE; 10254 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10255 return false; 10256 10257 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10258 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10259 return false; 10260 10261 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10262 if (wback && ((n == 15) || (n == t) || (n == t2))) 10263 return false; 10264 10265 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10266 if ((ArchVersion() < 6) && wback && (m == n)) 10267 return false; 10268 break; 10269 10270 default: 10271 return false; 10272 } 10273 10274 uint32_t Rn = ReadCoreReg (n, &success); 10275 if (!success) 10276 return false; 10277 RegisterInfo base_reg; 10278 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10279 10280 uint32_t Rm = ReadCoreReg (m, &success); 10281 if (!success) 10282 return false; 10283 RegisterInfo offset_reg; 10284 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10285 10286 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10287 addr_t offset_addr; 10288 if (add) 10289 offset_addr = Rn + Rm; 10290 else 10291 offset_addr = Rn - Rm; 10292 10293 // address = if index then offset_addr else R[n]; 10294 addr_t address; 10295 if (index) 10296 address = offset_addr; 10297 else 10298 address = Rn; 10299 10300 EmulateInstruction::Context context; 10301 context.type = eContextRegisterLoad; 10302 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10303 10304 // R[t] = MemA[address,4]; 10305 const uint32_t addr_byte_size = GetAddressByteSize(); 10306 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10307 if (!success) 10308 return false; 10309 10310 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10311 return false; 10312 10313 // R[t2] = MemA[address+4,4]; 10314 10315 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10316 if (!success) 10317 return false; 10318 10319 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10320 return false; 10321 10322 // if wback then R[n] = offset_addr; 10323 if (wback) 10324 { 10325 context.type = eContextAdjustBaseRegister; 10326 context.SetAddress (offset_addr); 10327 10328 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10329 return false; 10330 } 10331 } 10332 return true; 10333} 10334 10335// A8.6.200 STRD (immediate) 10336// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10337// stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10338bool 10339EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10340{ 10341#if 0 10342 if ConditionPassed() then 10343 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10344 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10345 address = if index then offset_addr else R[n]; 10346 MemA[address,4] = R[t]; 10347 MemA[address+4,4] = R[t2]; 10348 if wback then R[n] = offset_addr; 10349#endif 10350 10351 bool success = false; 10352 10353 if (ConditionPassed(opcode)) 10354 { 10355 uint32_t t; 10356 uint32_t t2; 10357 uint32_t n; 10358 uint32_t imm32; 10359 bool index; 10360 bool add; 10361 bool wback; 10362 10363 switch (encoding) 10364 { 10365 case eEncodingT1: 10366 // if P == �0� && W == �0� then SEE �Related encodings�; 10367 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10368 t = Bits32 (opcode, 15, 12); 10369 t2 = Bits32 (opcode, 11, 8); 10370 n = Bits32 (opcode, 19, 16); 10371 imm32 = Bits32 (opcode, 7, 0) << 2; 10372 10373 // index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10374 index = BitIsSet (opcode, 24); 10375 add = BitIsSet (opcode, 23); 10376 wback = BitIsSet (opcode, 21); 10377 10378 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10379 if (wback && ((n == t) || (n == t2))) 10380 return false; 10381 10382 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10383 if ((n == 15) || BadReg (t) || BadReg (t2)) 10384 return false; 10385 10386 break; 10387 10388 case eEncodingA1: 10389 // if Rt<0> == �1� then UNPREDICTABLE; 10390 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10391 t = Bits32 (opcode, 15, 12); 10392 if (BitIsSet (t, 0)) 10393 return false; 10394 10395 t2 = t + 1; 10396 n = Bits32 (opcode, 19, 16); 10397 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10398 10399 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10400 index = BitIsSet (opcode, 24); 10401 add = BitIsSet (opcode, 23); 10402 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10403 10404 // if P == �0� && W == �1� then UNPREDICTABLE; 10405 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10406 return false; 10407 10408 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10409 if (wback && ((n == 15) || (n == t) || (n == t2))) 10410 return false; 10411 10412 // if t2 == 15 then UNPREDICTABLE; 10413 if (t2 == 15) 10414 return false; 10415 10416 break; 10417 10418 default: 10419 return false; 10420 } 10421 10422 RegisterInfo base_reg; 10423 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10424 10425 uint32_t Rn = ReadCoreReg (n, &success); 10426 if (!success) 10427 return false; 10428 10429 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10430 addr_t offset_addr; 10431 if (add) 10432 offset_addr = Rn + imm32; 10433 else 10434 offset_addr = Rn - imm32; 10435 10436 //address = if index then offset_addr else R[n]; 10437 addr_t address; 10438 if (index) 10439 address = offset_addr; 10440 else 10441 address = Rn; 10442 10443 //MemA[address,4] = R[t]; 10444 RegisterInfo data_reg; 10445 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10446 10447 uint32_t data = ReadCoreReg (t, &success); 10448 if (!success) 10449 return false; 10450 10451 EmulateInstruction::Context context; 10452 context.type = eContextRegisterStore; 10453 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10454 10455 const uint32_t addr_byte_size = GetAddressByteSize(); 10456 10457 if (!MemAWrite (context, address, data, addr_byte_size)) 10458 return false; 10459 10460 //MemA[address+4,4] = R[t2]; 10461 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10462 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10463 10464 data = ReadCoreReg (t2, &success); 10465 if (!success) 10466 return false; 10467 10468 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10469 return false; 10470 10471 //if wback then R[n] = offset_addr; 10472 if (wback) 10473 { 10474 context.type = eContextAdjustBaseRegister; 10475 context.SetAddress (offset_addr); 10476 10477 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10478 return false; 10479 } 10480 } 10481 return true; 10482} 10483 10484 10485// A8.6.201 STRD (register) 10486bool 10487EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10488{ 10489#if 0 10490 if ConditionPassed() then 10491 EncodingSpecificOperations(); 10492 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10493 address = if index then offset_addr else R[n]; 10494 MemA[address,4] = R[t]; 10495 MemA[address+4,4] = R[t2]; 10496 if wback then R[n] = offset_addr; 10497#endif 10498 10499 bool success = false; 10500 10501 if (ConditionPassed(opcode)) 10502 { 10503 uint32_t t; 10504 uint32_t t2; 10505 uint32_t n; 10506 uint32_t m; 10507 bool index; 10508 bool add; 10509 bool wback; 10510 10511 switch (encoding) 10512 { 10513 case eEncodingA1: 10514 // if Rt<0> == �1� then UNPREDICTABLE; 10515 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10516 t = Bits32 (opcode, 15, 12); 10517 if (BitIsSet (t, 0)) 10518 return false; 10519 10520 t2 = t+1; 10521 n = Bits32 (opcode, 19, 16); 10522 m = Bits32 (opcode, 3, 0); 10523 10524 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10525 index = BitIsSet (opcode, 24); 10526 add = BitIsSet (opcode, 23); 10527 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10528 10529 // if P == �0� && W == �1� then UNPREDICTABLE; 10530 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10531 return false; 10532 10533 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10534 if ((t2 == 15) || (m == 15)) 10535 return false; 10536 10537 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10538 if (wback && ((n == 15) || (n == t) || (n == t2))) 10539 return false; 10540 10541 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10542 if ((ArchVersion() < 6) && wback && (m == n)) 10543 return false; 10544 10545 break; 10546 10547 default: 10548 return false; 10549 } 10550 10551 RegisterInfo base_reg; 10552 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10553 RegisterInfo offset_reg; 10554 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10555 RegisterInfo data_reg; 10556 10557 uint32_t Rn = ReadCoreReg (n, &success); 10558 if (!success) 10559 return false; 10560 10561 uint32_t Rm = ReadCoreReg (m, &success); 10562 if (!success) 10563 return false; 10564 10565 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10566 addr_t offset_addr; 10567 if (add) 10568 offset_addr = Rn + Rm; 10569 else 10570 offset_addr = Rn - Rm; 10571 10572 // address = if index then offset_addr else R[n]; 10573 addr_t address; 10574 if (index) 10575 address = offset_addr; 10576 else 10577 address = Rn; 10578 // MemA[address,4] = R[t]; 10579 uint32_t Rt = ReadCoreReg (t, &success); 10580 if (!success) 10581 return false; 10582 10583 EmulateInstruction::Context context; 10584 context.type = eContextRegisterStore; 10585 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10586 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10587 10588 const uint32_t addr_byte_size = GetAddressByteSize(); 10589 10590 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10591 return false; 10592 10593 // MemA[address+4,4] = R[t2]; 10594 uint32_t Rt2 = ReadCoreReg (t2, &success); 10595 if (!success) 10596 return false; 10597 10598 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10599 10600 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10601 10602 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10603 return false; 10604 10605 // if wback then R[n] = offset_addr; 10606 if (wback) 10607 { 10608 context.type = eContextAdjustBaseRegister; 10609 context.SetAddress (offset_addr); 10610 10611 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10612 return false; 10613 10614 } 10615 } 10616 return true; 10617} 10618 10619// A8.6.319 VLDM 10620// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10621// an ARM core register. 10622bool 10623EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10624{ 10625#if 0 10626 if ConditionPassed() then 10627 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10628 address = if add then R[n] else R[n]-imm32; 10629 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10630 for r = 0 to regs-1 10631 if single_regs then 10632 S[d+r] = MemA[address,4]; address = address+4; 10633 else 10634 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10635 // Combine the word-aligned words in the correct order for current endianness. 10636 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10637#endif 10638 10639 bool success = false; 10640 10641 if (ConditionPassed(opcode)) 10642 { 10643 bool single_regs; 10644 bool add; 10645 bool wback; 10646 uint32_t d; 10647 uint32_t n; 10648 uint32_t imm32; 10649 uint32_t regs; 10650 10651 switch (encoding) 10652 { 10653 case eEncodingT1: 10654 case eEncodingA1: 10655 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10656 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10657 // if P == �1� && W == �0� then SEE VLDR; 10658 // if P == U && W == �1� then UNDEFINED; 10659 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10660 return false; 10661 10662 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10663 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10664 single_regs = false; 10665 add = BitIsSet (opcode, 23); 10666 wback = BitIsSet (opcode, 21); 10667 10668 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10669 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10670 n = Bits32 (opcode, 19, 16); 10671 imm32 = Bits32 (opcode, 7, 0) << 2; 10672 10673 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�. 10674 regs = Bits32 (opcode, 7, 0) / 2; 10675 10676 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10677 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10678 return false; 10679 10680 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10681 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10682 return false; 10683 10684 break; 10685 10686 case eEncodingT2: 10687 case eEncodingA2: 10688 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10689 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10690 // if P == �1� && W == �0� then SEE VLDR; 10691 // if P == U && W == �1� then UNDEFINED; 10692 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10693 return false; 10694 10695 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10696 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10697 single_regs = true; 10698 add = BitIsSet (opcode, 23); 10699 wback = BitIsSet (opcode, 21); 10700 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10701 n = Bits32 (opcode, 19, 16); 10702 10703 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10704 imm32 = Bits32 (opcode, 7, 0) << 2; 10705 regs = Bits32 (opcode, 7, 0); 10706 10707 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10708 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10709 return false; 10710 10711 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10712 if ((regs == 0) || ((d + regs) > 32)) 10713 return false; 10714 break; 10715 10716 default: 10717 return false; 10718 } 10719 10720 RegisterInfo base_reg; 10721 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10722 10723 uint32_t Rn = ReadCoreReg (n, &success); 10724 if (!success) 10725 return false; 10726 10727 // address = if add then R[n] else R[n]-imm32; 10728 addr_t address; 10729 if (add) 10730 address = Rn; 10731 else 10732 address = Rn - imm32; 10733 10734 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10735 EmulateInstruction::Context context; 10736 10737 if (wback) 10738 { 10739 uint32_t value; 10740 if (add) 10741 value = Rn + imm32; 10742 else 10743 value = Rn - imm32; 10744 10745 context.type = eContextAdjustBaseRegister; 10746 context.SetImmediateSigned (value - Rn); 10747 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10748 return false; 10749 10750 } 10751 10752 const uint32_t addr_byte_size = GetAddressByteSize(); 10753 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10754 10755 context.type = eContextRegisterLoad; 10756 10757 // for r = 0 to regs-1 10758 for (uint32_t r = 0; r < regs; ++r) 10759 { 10760 if (single_regs) 10761 { 10762 // S[d+r] = MemA[address,4]; address = address+4; 10763 context.SetRegisterPlusOffset (base_reg, address - Rn); 10764 10765 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10766 if (!success) 10767 return false; 10768 10769 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10770 return false; 10771 10772 address = address + 4; 10773 } 10774 else 10775 { 10776 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10777 context.SetRegisterPlusOffset (base_reg, address - Rn); 10778 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10779 if (!success) 10780 return false; 10781 10782 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10783 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10784 if (!success) 10785 return false; 10786 10787 address = address + 8; 10788 // // Combine the word-aligned words in the correct order for current endianness. 10789 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10790 uint64_t data; 10791 if (GetByteOrder() == eByteOrderBig) 10792 { 10793 data = word1; 10794 data = (data << 32) | word2; 10795 } 10796 else 10797 { 10798 data = word2; 10799 data = (data << 32) | word1; 10800 } 10801 10802 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10803 return false; 10804 } 10805 } 10806 } 10807 return true; 10808} 10809 10810// A8.6.399 VSTM 10811// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10812// ARM core register. 10813bool 10814EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10815{ 10816#if 0 10817 if ConditionPassed() then 10818 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10819 address = if add then R[n] else R[n]-imm32; 10820 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10821 for r = 0 to regs-1 10822 if single_regs then 10823 MemA[address,4] = S[d+r]; address = address+4; 10824 else 10825 // Store as two word-aligned words in the correct order for current endianness. 10826 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10827 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10828 address = address+8; 10829#endif 10830 10831 bool success = false; 10832 10833 if (ConditionPassed (opcode)) 10834 { 10835 bool single_regs; 10836 bool add; 10837 bool wback; 10838 uint32_t d; 10839 uint32_t n; 10840 uint32_t imm32; 10841 uint32_t regs; 10842 10843 switch (encoding) 10844 { 10845 case eEncodingT1: 10846 case eEncodingA1: 10847 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10848 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10849 // if P == �1� && W == �0� then SEE VSTR; 10850 // if P == U && W == �1� then UNDEFINED; 10851 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10852 return false; 10853 10854 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10855 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10856 single_regs = false; 10857 add = BitIsSet (opcode, 23); 10858 wback = BitIsSet (opcode, 21); 10859 10860 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10861 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10862 n = Bits32 (opcode, 19, 16); 10863 imm32 = Bits32 (opcode, 7, 0) << 2; 10864 10865 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�. 10866 regs = Bits32 (opcode, 7, 0) / 2; 10867 10868 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10869 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10870 return false; 10871 10872 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10873 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10874 return false; 10875 10876 break; 10877 10878 case eEncodingT2: 10879 case eEncodingA2: 10880 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10881 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10882 // if P == �1� && W == �0� then SEE VSTR; 10883 // if P == U && W == �1� then UNDEFINED; 10884 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10885 return false; 10886 10887 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10888 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10889 single_regs = true; 10890 add = BitIsSet (opcode, 23); 10891 wback = BitIsSet (opcode, 21); 10892 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10893 n = Bits32 (opcode, 19, 16); 10894 10895 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10896 imm32 = Bits32 (opcode, 7, 0) << 2; 10897 regs = Bits32 (opcode, 7, 0); 10898 10899 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10900 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 10901 return false; 10902 10903 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10904 if ((regs == 0) || ((d + regs) > 32)) 10905 return false; 10906 10907 break; 10908 10909 default: 10910 return false; 10911 } 10912 10913 RegisterInfo base_reg; 10914 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10915 10916 uint32_t Rn = ReadCoreReg (n, &success); 10917 if (!success) 10918 return false; 10919 10920 // address = if add then R[n] else R[n]-imm32; 10921 addr_t address; 10922 if (add) 10923 address = Rn; 10924 else 10925 address = Rn - imm32; 10926 10927 EmulateInstruction::Context context; 10928 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10929 if (wback) 10930 { 10931 uint32_t value; 10932 if (add) 10933 value = Rn + imm32; 10934 else 10935 value = Rn - imm32; 10936 10937 context.type = eContextAdjustBaseRegister; 10938 context.SetRegisterPlusOffset (base_reg, value - Rn); 10939 10940 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10941 return false; 10942 } 10943 10944 const uint32_t addr_byte_size = GetAddressByteSize(); 10945 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10946 10947 context.type = eContextRegisterStore; 10948 // for r = 0 to regs-1 10949 for (uint32_t r = 0; r < regs; ++r) 10950 { 10951 10952 if (single_regs) 10953 { 10954 // MemA[address,4] = S[d+r]; address = address+4; 10955 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10956 if (!success) 10957 return false; 10958 10959 RegisterInfo data_reg; 10960 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10961 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10962 if (!MemAWrite (context, address, data, addr_byte_size)) 10963 return false; 10964 10965 address = address + 4; 10966 } 10967 else 10968 { 10969 // // Store as two word-aligned words in the correct order for current endianness. 10970 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10971 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10972 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10973 if (!success) 10974 return false; 10975 10976 RegisterInfo data_reg; 10977 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10978 10979 if (GetByteOrder() == eByteOrderBig) 10980 { 10981 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10982 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 10983 return false; 10984 10985 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10986 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 10987 return false; 10988 } 10989 else 10990 { 10991 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10992 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 10993 return false; 10994 10995 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10996 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 10997 return false; 10998 } 10999 // address = address+8; 11000 address = address + 8; 11001 } 11002 } 11003 } 11004 return true; 11005} 11006 11007// A8.6.320 11008// This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with 11009// an optional offset. 11010bool 11011EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 11012{ 11013#if 0 11014 if ConditionPassed() then 11015 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11016 base = if n == 15 then Align(PC,4) else R[n]; 11017 address = if add then (base + imm32) else (base - imm32); 11018 if single_reg then 11019 S[d] = MemA[address,4]; 11020 else 11021 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11022 // Combine the word-aligned words in the correct order for current endianness. 11023 D[d] = if BigEndian() then word1:word2 else word2:word1; 11024#endif 11025 11026 bool success = false; 11027 11028 if (ConditionPassed (opcode)) 11029 { 11030 bool single_reg; 11031 bool add; 11032 uint32_t imm32; 11033 uint32_t d; 11034 uint32_t n; 11035 11036 switch (encoding) 11037 { 11038 case eEncodingT1: 11039 case eEncodingA1: 11040 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11041 single_reg = false; 11042 add = BitIsSet (opcode, 23); 11043 imm32 = Bits32 (opcode, 7, 0) << 2; 11044 11045 // d = UInt(D:Vd); n = UInt(Rn); 11046 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11047 n = Bits32 (opcode, 19, 16); 11048 11049 break; 11050 11051 case eEncodingT2: 11052 case eEncodingA2: 11053 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11054 single_reg = true; 11055 add = BitIsSet (opcode, 23); 11056 imm32 = Bits32 (opcode, 7, 0) << 2; 11057 11058 // d = UInt(Vd:D); n = UInt(Rn); 11059 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11060 n = Bits32 (opcode, 19, 16); 11061 11062 break; 11063 11064 default: 11065 return false; 11066 } 11067 RegisterInfo base_reg; 11068 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11069 11070 uint32_t Rn = ReadCoreReg (n, &success); 11071 if (!success) 11072 return false; 11073 11074 // base = if n == 15 then Align(PC,4) else R[n]; 11075 uint32_t base; 11076 if (n == 15) 11077 base = AlignPC (Rn); 11078 else 11079 base = Rn; 11080 11081 // address = if add then (base + imm32) else (base - imm32); 11082 addr_t address; 11083 if (add) 11084 address = base + imm32; 11085 else 11086 address = base - imm32; 11087 11088 const uint32_t addr_byte_size = GetAddressByteSize(); 11089 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11090 11091 EmulateInstruction::Context context; 11092 context.type = eContextRegisterLoad; 11093 context.SetRegisterPlusOffset (base_reg, address - base); 11094 11095 if (single_reg) 11096 { 11097 // S[d] = MemA[address,4]; 11098 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11099 if (!success) 11100 return false; 11101 11102 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11103 return false; 11104 } 11105 else 11106 { 11107 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11108 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11109 if (!success) 11110 return false; 11111 11112 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11113 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11114 if (!success) 11115 return false; 11116 // // Combine the word-aligned words in the correct order for current endianness. 11117 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11118 uint64_t data64; 11119 if (GetByteOrder() == eByteOrderBig) 11120 { 11121 data64 = word1; 11122 data64 = (data64 << 32) | word2; 11123 } 11124 else 11125 { 11126 data64 = word2; 11127 data64 = (data64 << 32) | word1; 11128 } 11129 11130 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11131 return false; 11132 } 11133 } 11134 return true; 11135} 11136 11137// A8.6.400 VSTR 11138// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11139// optional offset. 11140bool 11141EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11142{ 11143#if 0 11144 if ConditionPassed() then 11145 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11146 address = if add then (R[n] + imm32) else (R[n] - imm32); 11147 if single_reg then 11148 MemA[address,4] = S[d]; 11149 else 11150 // Store as two word-aligned words in the correct order for current endianness. 11151 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11152 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11153#endif 11154 11155 bool success = false; 11156 11157 if (ConditionPassed (opcode)) 11158 { 11159 bool single_reg; 11160 bool add; 11161 uint32_t imm32; 11162 uint32_t d; 11163 uint32_t n; 11164 11165 switch (encoding) 11166 { 11167 case eEncodingT1: 11168 case eEncodingA1: 11169 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11170 single_reg = false; 11171 add = BitIsSet (opcode, 23); 11172 imm32 = Bits32 (opcode, 7, 0) << 2; 11173 11174 // d = UInt(D:Vd); n = UInt(Rn); 11175 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11176 n = Bits32 (opcode, 19, 16); 11177 11178 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11179 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11180 return false; 11181 11182 break; 11183 11184 case eEncodingT2: 11185 case eEncodingA2: 11186 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11187 single_reg = true; 11188 add = BitIsSet (opcode, 23); 11189 imm32 = Bits32 (opcode, 7, 0) << 2; 11190 11191 // d = UInt(Vd:D); n = UInt(Rn); 11192 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11193 n = Bits32 (opcode, 19, 16); 11194 11195 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11196 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11197 return false; 11198 11199 break; 11200 11201 default: 11202 return false; 11203 } 11204 11205 RegisterInfo base_reg; 11206 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11207 11208 uint32_t Rn = ReadCoreReg (n, &success); 11209 if (!success) 11210 return false; 11211 11212 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11213 addr_t address; 11214 if (add) 11215 address = Rn + imm32; 11216 else 11217 address = Rn - imm32; 11218 11219 const uint32_t addr_byte_size = GetAddressByteSize(); 11220 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11221 11222 RegisterInfo data_reg; 11223 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11224 EmulateInstruction::Context context; 11225 context.type = eContextRegisterStore; 11226 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11227 11228 if (single_reg) 11229 { 11230 // MemA[address,4] = S[d]; 11231 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11232 if (!success) 11233 return false; 11234 11235 if (!MemAWrite (context, address, data, addr_byte_size)) 11236 return false; 11237 } 11238 else 11239 { 11240 // // Store as two word-aligned words in the correct order for current endianness. 11241 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11242 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11243 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11244 if (!success) 11245 return false; 11246 11247 if (GetByteOrder() == eByteOrderBig) 11248 { 11249 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11250 return false; 11251 11252 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11253 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11254 return false; 11255 } 11256 else 11257 { 11258 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11259 return false; 11260 11261 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11262 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11263 return false; 11264 } 11265 } 11266 } 11267 return true; 11268} 11269 11270// A8.6.307 VLDI1 (multiple single elements) 11271// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11272// element of each register is loaded. 11273bool 11274EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11275{ 11276#if 0 11277 if ConditionPassed() then 11278 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11279 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11280 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11281 for r = 0 to regs-1 11282 for e = 0 to elements-1 11283 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11284 address = address + ebytes; 11285#endif 11286 11287 bool success = false; 11288 11289 if (ConditionPassed (opcode)) 11290 { 11291 uint32_t regs; 11292 uint32_t alignment; 11293 uint32_t ebytes; 11294 uint32_t esize; 11295 uint32_t elements; 11296 uint32_t d; 11297 uint32_t n; 11298 uint32_t m; 11299 bool wback; 11300 bool register_index; 11301 11302 switch (encoding) 11303 { 11304 case eEncodingT1: 11305 case eEncodingA1: 11306 { 11307 // case type of 11308 // when �0111� 11309 // regs = 1; if align<1> == �1� then UNDEFINED; 11310 // when �1010� 11311 // regs = 2; if align == �11� then UNDEFINED; 11312 // when �0110� 11313 // regs = 3; if align<1> == �1� then UNDEFINED; 11314 // when �0010� 11315 // regs = 4; 11316 // otherwise 11317 // SEE �Related encodings�; 11318 uint32_t type = Bits32 (opcode, 11, 8); 11319 uint32_t align = Bits32 (opcode, 5, 4); 11320 if (type == 7) // '0111' 11321 { 11322 regs = 1; 11323 if (BitIsSet (align, 1)) 11324 return false; 11325 } 11326 else if (type == 10) // '1010' 11327 { 11328 regs = 2; 11329 if (align == 3) 11330 return false; 11331 11332 } 11333 else if (type == 6) // '0110' 11334 { 11335 regs = 3; 11336 if (BitIsSet (align, 1)) 11337 return false; 11338 } 11339 else if (type == 2) // '0010' 11340 { 11341 regs = 4; 11342 } 11343 else 11344 return false; 11345 11346 // alignment = if align == �00� then 1 else 4 << UInt(align); 11347 if (align == 0) 11348 alignment = 1; 11349 else 11350 alignment = 4 << align; 11351 11352 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11353 ebytes = 1 << Bits32 (opcode, 7, 6); 11354 esize = 8 * ebytes; 11355 elements = 8 / ebytes; 11356 11357 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11358 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11359 n = Bits32 (opcode, 19, 15); 11360 m = Bits32 (opcode, 3, 0); 11361 11362 // wback = (m != 15); register_index = (m != 15 && m != 13); 11363 wback = (m != 15); 11364 register_index = ((m != 15) && (m != 13)); 11365 11366 // if d+regs > 32 then UNPREDICTABLE; 11367 if ((d + regs) > 32) 11368 return false; 11369 } 11370 break; 11371 11372 default: 11373 return false; 11374 } 11375 11376 RegisterInfo base_reg; 11377 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11378 11379 uint32_t Rn = ReadCoreReg (n, &success); 11380 if (!success) 11381 return false; 11382 11383 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11384 addr_t address = Rn; 11385 if ((address % alignment) != 0) 11386 return false; 11387 11388 EmulateInstruction::Context context; 11389 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11390 if (wback) 11391 { 11392 uint32_t Rm = ReadCoreReg (m, &success); 11393 if (!success) 11394 return false; 11395 11396 uint32_t offset; 11397 if (register_index) 11398 offset = Rm; 11399 else 11400 offset = 8 * regs; 11401 11402 uint32_t value = Rn + offset; 11403 context.type = eContextAdjustBaseRegister; 11404 context.SetRegisterPlusOffset (base_reg, offset); 11405 11406 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11407 return false; 11408 11409 } 11410 11411 // for r = 0 to regs-1 11412 for (uint32_t r = 0; r < regs; ++r) 11413 { 11414 // for e = 0 to elements-1 11415 uint64_t assembled_data = 0; 11416 for (uint32_t e = 0; e < elements; ++e) 11417 { 11418 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11419 context.type = eContextRegisterLoad; 11420 context.SetRegisterPlusOffset (base_reg, address - Rn); 11421 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11422 if (!success) 11423 return false; 11424 11425 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11426 11427 // address = address + ebytes; 11428 address = address + ebytes; 11429 } 11430 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11431 return false; 11432 } 11433 } 11434 return true; 11435} 11436 11437// A8.6.308 VLD1 (single element to one lane) 11438// 11439bool 11440EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11441{ 11442#if 0 11443 if ConditionPassed() then 11444 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11445 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11446 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11447 Elem[D[d],index,esize] = MemU[address,ebytes]; 11448#endif 11449 11450 bool success = false; 11451 11452 if (ConditionPassed (opcode)) 11453 { 11454 uint32_t ebytes; 11455 uint32_t esize; 11456 uint32_t index; 11457 uint32_t alignment; 11458 uint32_t d; 11459 uint32_t n; 11460 uint32_t m; 11461 bool wback; 11462 bool register_index; 11463 11464 switch (encoding) 11465 { 11466 case eEncodingT1: 11467 case eEncodingA1: 11468 { 11469 uint32_t size = Bits32 (opcode, 11, 10); 11470 uint32_t index_align = Bits32 (opcode, 7, 4); 11471 // if size == �11� then SEE VLD1 (single element to all lanes); 11472 if (size == 3) 11473 return EmulateVLD1SingleAll (opcode, encoding); 11474 // case size of 11475 if (size == 0) // when '00' 11476 { 11477 // if index_align<0> != �0� then UNDEFINED; 11478 if (BitIsClear (index_align, 0)) 11479 return false; 11480 11481 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11482 ebytes = 1; 11483 esize = 8; 11484 index = Bits32 (index_align, 3, 1); 11485 alignment = 1; 11486 } 11487 else if (size == 1) // when �01� 11488 { 11489 // if index_align<1> != �0� then UNDEFINED; 11490 if (BitIsClear (index_align, 1)) 11491 return false; 11492 11493 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11494 ebytes = 2; 11495 esize = 16; 11496 index = Bits32 (index_align, 3, 2); 11497 11498 // alignment = if index_align<0> == �0� then 1 else 2; 11499 if (BitIsClear (index_align, 0)) 11500 alignment = 1; 11501 else 11502 alignment = 2; 11503 } 11504 else if (size == 2) // when �10� 11505 { 11506 // if index_align<2> != �0� then UNDEFINED; 11507 if (BitIsClear (index_align, 2)) 11508 return false; 11509 11510 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11511 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11512 return false; 11513 11514 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11515 ebytes = 4; 11516 esize = 32; 11517 index = Bit32 (index_align, 3); 11518 11519 // alignment = if index_align<1:0> == �00� then 1 else 4; 11520 if (Bits32 (index_align, 1, 0) == 0) 11521 alignment = 1; 11522 else 11523 alignment = 4; 11524 } 11525 else 11526 { 11527 return false; 11528 } 11529 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11530 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11531 n = Bits32 (opcode, 19, 16); 11532 m = Bits32 (opcode, 3, 0); 11533 11534 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11535 wback = (m != 15); 11536 register_index = ((m != 15) && (m != 13)); 11537 11538 if (n == 15) 11539 return false; 11540 11541 } 11542 break; 11543 11544 default: 11545 return false; 11546 } 11547 11548 RegisterInfo base_reg; 11549 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11550 11551 uint32_t Rn = ReadCoreReg (n, &success); 11552 if (!success) 11553 return false; 11554 11555 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11556 addr_t address = Rn; 11557 if ((address % alignment) != 0) 11558 return false; 11559 11560 EmulateInstruction::Context context; 11561 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11562 if (wback) 11563 { 11564 uint32_t Rm = ReadCoreReg (m, &success); 11565 if (!success) 11566 return false; 11567 11568 uint32_t offset; 11569 if (register_index) 11570 offset = Rm; 11571 else 11572 offset = ebytes; 11573 11574 uint32_t value = Rn + offset; 11575 11576 context.type = eContextAdjustBaseRegister; 11577 context.SetRegisterPlusOffset (base_reg, offset); 11578 11579 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11580 return false; 11581 } 11582 11583 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11584 uint32_t element = MemURead (context, address, esize, 0, &success); 11585 if (!success) 11586 return false; 11587 11588 element = element << (index * esize); 11589 11590 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11591 if (!success) 11592 return false; 11593 11594 uint64_t all_ones = -1; 11595 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11596 // at element & to the right of element. 11597 if (index > 0) 11598 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11599 // now mask should be 0's where element goes & 1's 11600 // everywhere else. 11601 11602 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11603 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11604 11605 context.type = eContextRegisterLoad; 11606 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11607 return false; 11608 } 11609 return true; 11610} 11611 11612// A8.6.391 VST1 (multiple single elements) 11613// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without 11614// interleaving. Every element of each register is stored. 11615bool 11616EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11617{ 11618#if 0 11619 if ConditionPassed() then 11620 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11621 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11622 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11623 for r = 0 to regs-1 11624 for e = 0 to elements-1 11625 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11626 address = address + ebytes; 11627#endif 11628 11629 bool success = false; 11630 11631 if (ConditionPassed (opcode)) 11632 { 11633 uint32_t regs; 11634 uint32_t alignment; 11635 uint32_t ebytes; 11636 uint32_t esize; 11637 uint32_t elements; 11638 uint32_t d; 11639 uint32_t n; 11640 uint32_t m; 11641 bool wback; 11642 bool register_index; 11643 11644 switch (encoding) 11645 { 11646 case eEncodingT1: 11647 case eEncodingA1: 11648 { 11649 uint32_t type = Bits32 (opcode, 11, 8); 11650 uint32_t align = Bits32 (opcode, 5, 4); 11651 11652 // case type of 11653 if (type == 7) // when �0111� 11654 { 11655 // regs = 1; if align<1> == �1� then UNDEFINED; 11656 regs = 1; 11657 if (BitIsSet (align, 1)) 11658 return false; 11659 } 11660 else if (type == 10) // when �1010� 11661 { 11662 // regs = 2; if align == �11� then UNDEFINED; 11663 regs = 2; 11664 if (align == 3) 11665 return false; 11666 } 11667 else if (type == 6) // when �0110� 11668 { 11669 // regs = 3; if align<1> == �1� then UNDEFINED; 11670 regs = 3; 11671 if (BitIsSet (align, 1)) 11672 return false; 11673 } 11674 else if (type == 2) // when �0010� 11675 // regs = 4; 11676 regs = 4; 11677 else // otherwise 11678 // SEE �Related encodings�; 11679 return false; 11680 11681 // alignment = if align == �00� then 1 else 4 << UInt(align); 11682 if (align == 0) 11683 alignment = 1; 11684 else 11685 alignment = 4 << align; 11686 11687 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11688 ebytes = 1 << Bits32 (opcode,7, 6); 11689 esize = 8 * ebytes; 11690 elements = 8 / ebytes; 11691 11692 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11693 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11694 n = Bits32 (opcode, 19, 16); 11695 m = Bits32 (opcode, 3, 0); 11696 11697 // wback = (m != 15); register_index = (m != 15 && m != 13); 11698 wback = (m != 15); 11699 register_index = ((m != 15) && (m != 13)); 11700 11701 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11702 if ((d + regs) > 32) 11703 return false; 11704 11705 if (n == 15) 11706 return false; 11707 11708 } 11709 break; 11710 11711 default: 11712 return false; 11713 } 11714 11715 RegisterInfo base_reg; 11716 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11717 11718 uint32_t Rn = ReadCoreReg (n, &success); 11719 if (!success) 11720 return false; 11721 11722 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11723 addr_t address = Rn; 11724 if ((address % alignment) != 0) 11725 return false; 11726 11727 EmulateInstruction::Context context; 11728 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11729 if (wback) 11730 { 11731 uint32_t Rm = ReadCoreReg (m, &success); 11732 if (!success) 11733 return false; 11734 11735 uint32_t offset; 11736 if (register_index) 11737 offset = Rm; 11738 else 11739 offset = 8 * regs; 11740 11741 context.type = eContextAdjustBaseRegister; 11742 context.SetRegisterPlusOffset (base_reg, offset); 11743 11744 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11745 return false; 11746 } 11747 11748 RegisterInfo data_reg; 11749 context.type = eContextRegisterStore; 11750 // for r = 0 to regs-1 11751 for (uint32_t r = 0; r < regs; ++r) 11752 { 11753 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11754 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11755 if (!success) 11756 return false; 11757 11758 // for e = 0 to elements-1 11759 for (uint32_t e = 0; e < elements; ++e) 11760 { 11761 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11762 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11763 11764 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11765 if (!MemUWrite (context, address, word, ebytes)) 11766 return false; 11767 11768 // address = address + ebytes; 11769 address = address + ebytes; 11770 } 11771 } 11772 } 11773 return true; 11774} 11775 11776// A8.6.392 VST1 (single element from one lane) 11777// This instruction stores one element to memory from one element of a register. 11778bool 11779EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11780{ 11781#if 0 11782 if ConditionPassed() then 11783 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11784 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11785 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11786 MemU[address,ebytes] = Elem[D[d],index,esize]; 11787#endif 11788 11789 bool success = false; 11790 11791 if (ConditionPassed (opcode)) 11792 { 11793 uint32_t ebytes; 11794 uint32_t esize; 11795 uint32_t index; 11796 uint32_t alignment; 11797 uint32_t d; 11798 uint32_t n; 11799 uint32_t m; 11800 bool wback; 11801 bool register_index; 11802 11803 switch (encoding) 11804 { 11805 case eEncodingT1: 11806 case eEncodingA1: 11807 { 11808 uint32_t size = Bits32 (opcode, 11, 10); 11809 uint32_t index_align = Bits32 (opcode, 7, 4); 11810 11811 // if size == �11� then UNDEFINED; 11812 if (size == 3) 11813 return false; 11814 11815 // case size of 11816 if (size == 0) // when �00� 11817 { 11818 // if index_align<0> != �0� then UNDEFINED; 11819 if (BitIsClear (index_align, 0)) 11820 return false; 11821 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11822 ebytes = 1; 11823 esize = 8; 11824 index = Bits32 (index_align, 3, 1); 11825 alignment = 1; 11826 } 11827 else if (size == 1) // when �01� 11828 { 11829 // if index_align<1> != �0� then UNDEFINED; 11830 if (BitIsClear (index_align, 1)) 11831 return false; 11832 11833 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11834 ebytes = 2; 11835 esize = 16; 11836 index = Bits32 (index_align, 3, 2); 11837 11838 // alignment = if index_align<0> == �0� then 1 else 2; 11839 if (BitIsClear (index_align, 0)) 11840 alignment = 1; 11841 else 11842 alignment = 2; 11843 } 11844 else if (size == 2) // when �10� 11845 { 11846 // if index_align<2> != �0� then UNDEFINED; 11847 if (BitIsClear (index_align, 2)) 11848 return false; 11849 11850 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11851 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11852 return false; 11853 11854 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11855 ebytes = 4; 11856 esize = 32; 11857 index = Bit32 (index_align, 3); 11858 11859 // alignment = if index_align<1:0> == �00� then 1 else 4; 11860 if (Bits32 (index_align, 1, 0) == 0) 11861 alignment = 1; 11862 else 11863 alignment = 4; 11864 } 11865 else 11866 { 11867 return false; 11868 } 11869 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11870 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11871 n = Bits32 (opcode, 19, 16); 11872 m = Bits32 (opcode, 3, 0); 11873 11874 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11875 wback = (m != 15); 11876 register_index = ((m != 15) && (m != 13)); 11877 11878 if (n == 15) 11879 return false; 11880 } 11881 break; 11882 11883 default: 11884 return false; 11885 } 11886 11887 RegisterInfo base_reg; 11888 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11889 11890 uint32_t Rn = ReadCoreReg (n, &success); 11891 if (!success) 11892 return false; 11893 11894 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11895 addr_t address = Rn; 11896 if ((address % alignment) != 0) 11897 return false; 11898 11899 EmulateInstruction::Context context; 11900 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11901 if (wback) 11902 { 11903 uint32_t Rm = ReadCoreReg (m, &success); 11904 if (!success) 11905 return false; 11906 11907 uint32_t offset; 11908 if (register_index) 11909 offset = Rm; 11910 else 11911 offset = ebytes; 11912 11913 context.type = eContextAdjustBaseRegister; 11914 context.SetRegisterPlusOffset (base_reg, offset); 11915 11916 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11917 return false; 11918 } 11919 11920 // MemU[address,ebytes] = Elem[D[d],index,esize]; 11921 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11922 if (!success) 11923 return false; 11924 11925 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 11926 11927 RegisterInfo data_reg; 11928 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 11929 context.type = eContextRegisterStore; 11930 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11931 11932 if (!MemUWrite (context, address, word, ebytes)) 11933 return false; 11934 } 11935 return true; 11936} 11937 11938// A8.6.309 VLD1 (single element to all lanes) 11939// This instruction loads one element from memory into every element of one or two vectors. 11940bool 11941EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 11942{ 11943#if 0 11944 if ConditionPassed() then 11945 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11946 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11947 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11948 replicated_element = Replicate(MemU[address,ebytes], elements); 11949 for r = 0 to regs-1 11950 D[d+r] = replicated_element; 11951#endif 11952 11953 bool success = false; 11954 11955 if (ConditionPassed (opcode)) 11956 { 11957 uint32_t ebytes; 11958 uint32_t elements; 11959 uint32_t regs; 11960 uint32_t alignment; 11961 uint32_t d; 11962 uint32_t n; 11963 uint32_t m; 11964 bool wback; 11965 bool register_index; 11966 11967 switch (encoding) 11968 { 11969 case eEncodingT1: 11970 case eEncodingA1: 11971 { 11972 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED; 11973 uint32_t size = Bits32 (opcode, 7, 6); 11974 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 11975 return false; 11976 11977 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2; 11978 ebytes = 1 << size; 11979 elements = 8 / ebytes; 11980 if (BitIsClear (opcode, 5)) 11981 regs = 1; 11982 else 11983 regs = 2; 11984 11985 //alignment = if a == �0� then 1 else ebytes; 11986 if (BitIsClear (opcode, 4)) 11987 alignment = 1; 11988 else 11989 alignment = ebytes; 11990 11991 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11992 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11993 n = Bits32 (opcode, 19, 16); 11994 m = Bits32 (opcode, 3, 0); 11995 11996 //wback = (m != 15); register_index = (m != 15 && m != 13); 11997 wback = (m != 15); 11998 register_index = ((m != 15) && (m != 13)); 11999 12000 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12001 if ((d + regs) > 32) 12002 return false; 12003 12004 if (n == 15) 12005 return false; 12006 } 12007 break; 12008 12009 default: 12010 return false; 12011 } 12012 12013 RegisterInfo base_reg; 12014 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12015 12016 uint32_t Rn = ReadCoreReg (n, &success); 12017 if (!success) 12018 return false; 12019 12020 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12021 addr_t address = Rn; 12022 if ((address % alignment) != 0) 12023 return false; 12024 12025 EmulateInstruction::Context context; 12026 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12027 if (wback) 12028 { 12029 uint32_t Rm = ReadCoreReg (m, &success); 12030 if (!success) 12031 return false; 12032 12033 uint32_t offset; 12034 if (register_index) 12035 offset = Rm; 12036 else 12037 offset = ebytes; 12038 12039 context.type = eContextAdjustBaseRegister; 12040 context.SetRegisterPlusOffset (base_reg, offset); 12041 12042 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12043 return false; 12044 } 12045 12046 // replicated_element = Replicate(MemU[address,ebytes], elements); 12047 12048 context.type = eContextRegisterLoad; 12049 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12050 if (!success) 12051 return false; 12052 12053 uint64_t replicated_element = 0; 12054 uint32_t esize = ebytes * 8; 12055 for (uint32_t e = 0; e < elements; ++e) 12056 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12057 12058 // for r = 0 to regs-1 12059 for (uint32_t r = 0; r < regs; ++r) 12060 { 12061 // D[d+r] = replicated_element; 12062 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12063 return false; 12064 } 12065 } 12066 return true; 12067} 12068 12069// B6.2.13 SUBS PC, LR and related instructions 12070//The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12071// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12072bool 12073EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12074{ 12075#if 0 12076 if ConditionPassed() then 12077 EncodingSpecificOperations(); 12078 if CurrentInstrSet() == InstrSet_ThumbEE then 12079 UNPREDICTABLE; 12080 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12081 case opcode of 12082 when �0000� result = R[n] AND operand2; // AND 12083 when �0001� result = R[n] EOR operand2; // EOR 12084 when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12085 when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12086 when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12087 when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12088 when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12089 when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12090 when �1100� result = R[n] OR operand2; // ORR 12091 when �1101� result = operand2; // MOV 12092 when �1110� result = R[n] AND NOT(operand2); // BIC 12093 when �1111� result = NOT(operand2); // MVN 12094 CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12095 BranchWritePC(result); 12096#endif 12097 12098 bool success = false; 12099 12100 if (ConditionPassed (opcode)) 12101 { 12102 uint32_t n; 12103 uint32_t m; 12104 uint32_t imm32; 12105 bool register_form; 12106 ARM_ShifterType shift_t; 12107 uint32_t shift_n; 12108 uint32_t code; 12109 12110 switch (encoding) 12111 { 12112 case eEncodingT1: 12113 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12114 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB 12115 n = 14; 12116 imm32 = Bits32 (opcode, 7, 0); 12117 register_form = false; 12118 code = 2; 12119 12120 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12121 if (InITBlock() && !LastInITBlock()) 12122 return false; 12123 12124 break; 12125 12126 case eEncodingA1: 12127 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12128 n = Bits32 (opcode, 19, 16); 12129 imm32 = ARMExpandImm (opcode); 12130 register_form = false; 12131 code = Bits32 (opcode, 24, 21); 12132 12133 break; 12134 12135 case eEncodingA2: 12136 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12137 n = Bits32 (opcode, 19, 16); 12138 m = Bits32 (opcode, 3, 0); 12139 register_form = true; 12140 12141 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12142 shift_n = DecodeImmShiftARM (opcode, shift_t); 12143 12144 break; 12145 12146 default: 12147 return false; 12148 } 12149 12150 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12151 uint32_t operand2; 12152 if (register_form) 12153 { 12154 uint32_t Rm = ReadCoreReg (m, &success); 12155 if (!success) 12156 return false; 12157 12158 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12159 if (!success) 12160 return false; 12161 } 12162 else 12163 { 12164 operand2 = imm32; 12165 } 12166 12167 uint32_t Rn = ReadCoreReg (n, &success); 12168 if (!success) 12169 return false; 12170 12171 AddWithCarryResult result; 12172 12173 // case opcode of 12174 switch (code) 12175 { 12176 case 0: // when �0000� 12177 // result = R[n] AND operand2; // AND 12178 result.result = Rn & operand2; 12179 break; 12180 12181 case 1: // when �0001� 12182 // result = R[n] EOR operand2; // EOR 12183 result.result = Rn ^ operand2; 12184 break; 12185 12186 case 2: // when �0010� 12187 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12188 result = AddWithCarry (Rn, ~(operand2), 1); 12189 break; 12190 12191 case 3: // when �0011� 12192 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12193 result = AddWithCarry (~(Rn), operand2, 1); 12194 break; 12195 12196 case 4: // when �0100� 12197 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12198 result = AddWithCarry (Rn, operand2, 0); 12199 break; 12200 12201 case 5: // when �0101� 12202 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12203 result = AddWithCarry (Rn, operand2, APSR_C); 12204 break; 12205 12206 case 6: // when �0110� 12207 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12208 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12209 break; 12210 12211 case 7: // when �0111� 12212 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12213 result = AddWithCarry (~(Rn), operand2, APSR_C); 12214 break; 12215 12216 case 10: // when �1100� 12217 // result = R[n] OR operand2; // ORR 12218 result.result = Rn | operand2; 12219 break; 12220 12221 case 11: // when �1101� 12222 // result = operand2; // MOV 12223 result.result = operand2; 12224 break; 12225 12226 case 12: // when �1110� 12227 // result = R[n] AND NOT(operand2); // BIC 12228 result.result = Rn & ~(operand2); 12229 break; 12230 12231 case 15: // when �1111� 12232 // result = NOT(operand2); // MVN 12233 result.result = ~(operand2); 12234 break; 12235 12236 default: 12237 return false; 12238 } 12239 // CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12240 12241 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12242 // the best. 12243 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12244 if (!success) 12245 return false; 12246 12247 CPSRWriteByInstr (spsr, 15, true); 12248 12249 // BranchWritePC(result); 12250 EmulateInstruction::Context context; 12251 context.type = eContextAdjustPC; 12252 context.SetImmediate (result.result); 12253 12254 BranchWritePC (context, result.result); 12255 } 12256 return true; 12257} 12258 12259EmulateInstructionARM::ARMOpcode* 12260EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12261{ 12262 static ARMOpcode 12263 g_arm_opcodes[] = 12264 { 12265 //---------------------------------------------------------------------- 12266 // Prologue instructions 12267 //---------------------------------------------------------------------- 12268 12269 // push register(s) 12270 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12271 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12272 12273 // set r7 to point to a stack offset 12274 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12275 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12276 // copy the stack pointer to ip 12277 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12278 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12279 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12280 12281 // adjust the stack pointer 12282 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12283 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12284 12285 // push one register 12286 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12287 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12288 12289 // vector push consecutive extension register(s) 12290 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12291 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12292 12293 //---------------------------------------------------------------------- 12294 // Epilogue instructions 12295 //---------------------------------------------------------------------- 12296 12297 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12298 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12299 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12300 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12301 12302 //---------------------------------------------------------------------- 12303 // Supervisor Call (previously Software Interrupt) 12304 //---------------------------------------------------------------------- 12305 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12306 12307 //---------------------------------------------------------------------- 12308 // Branch instructions 12309 //---------------------------------------------------------------------- 12310 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12311 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 12312 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12313 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12314 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12315 // for example, "bx lr" 12316 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12317 // bxj 12318 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12319 12320 //---------------------------------------------------------------------- 12321 // Data-processing instructions 12322 //---------------------------------------------------------------------- 12323 // adc (immediate) 12324 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12325 // adc (register) 12326 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12327 // add (immediate) 12328 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12329 // add (register) 12330 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12331 // add (register-shifted register) 12332 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12333 // adr 12334 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12335 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12336 // and (immediate) 12337 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12338 // and (register) 12339 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12340 // bic (immediate) 12341 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12342 // bic (register) 12343 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12344 // eor (immediate) 12345 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12346 // eor (register) 12347 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12348 // orr (immediate) 12349 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12350 // orr (register) 12351 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12352 // rsb (immediate) 12353 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12354 // rsb (register) 12355 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12356 // rsc (immediate) 12357 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12358 // rsc (register) 12359 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12360 // sbc (immediate) 12361 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12362 // sbc (register) 12363 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12364 // sub (immediate, ARM) 12365 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12366 // sub (sp minus immediate) 12367 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12368 // sub (register) 12369 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12370 // teq (immediate) 12371 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12372 // teq (register) 12373 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12374 // tst (immediate) 12375 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12376 // tst (register) 12377 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12378 12379 // mov (immediate) 12380 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12381 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12382 // mov (register) 12383 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12384 // mvn (immediate) 12385 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12386 // mvn (register) 12387 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12388 // cmn (immediate) 12389 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12390 // cmn (register) 12391 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12392 // cmp (immediate) 12393 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12394 // cmp (register) 12395 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12396 // asr (immediate) 12397 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12398 // asr (register) 12399 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12400 // lsl (immediate) 12401 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12402 // lsl (register) 12403 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12404 // lsr (immediate) 12405 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12406 // lsr (register) 12407 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12408 // rrx is a special case encoding of ror (immediate) 12409 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12410 // ror (immediate) 12411 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12412 // ror (register) 12413 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12414 // mul 12415 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12416 12417 // subs pc, lr and related instructions 12418 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12419 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12420 12421 //---------------------------------------------------------------------- 12422 // Load instructions 12423 //---------------------------------------------------------------------- 12424 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12425 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12426 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12427 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12428 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12429 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12430 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12431 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12432 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12433 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12434 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12435 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12436 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12437 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12438 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12439 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12440 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12441 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12442 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12443 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12444 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12445 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12446 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12447 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12448 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12449 12450 //---------------------------------------------------------------------- 12451 // Store instructions 12452 //---------------------------------------------------------------------- 12453 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12454 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12455 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12456 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12457 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12458 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12459 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12460 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12461 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12462 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12463 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12464 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12465 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12466 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12467 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12468 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12469 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12470 12471 //---------------------------------------------------------------------- 12472 // Other instructions 12473 //---------------------------------------------------------------------- 12474 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12475 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12476 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12477 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12478 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12479 12480 }; 12481 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 12482 12483 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12484 { 12485 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12486 (g_arm_opcodes[i].variants & arm_isa) != 0) 12487 return &g_arm_opcodes[i]; 12488 } 12489 return NULL; 12490} 12491 12492 12493EmulateInstructionARM::ARMOpcode* 12494EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12495{ 12496 12497 static ARMOpcode 12498 g_thumb_opcodes[] = 12499 { 12500 //---------------------------------------------------------------------- 12501 // Prologue instructions 12502 //---------------------------------------------------------------------- 12503 12504 // push register(s) 12505 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12506 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12507 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12508 12509 // set r7 to point to a stack offset 12510 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12511 // copy the stack pointer to r7 12512 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12513 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12514 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12515 12516 // PC-relative load into register (see also EmulateADDSPRm) 12517 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12518 12519 // adjust the stack pointer 12520 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12521 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12522 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12523 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12524 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12525 12526 // vector push consecutive extension register(s) 12527 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12528 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12529 12530 //---------------------------------------------------------------------- 12531 // Epilogue instructions 12532 //---------------------------------------------------------------------- 12533 12534 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12535 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12536 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12537 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12538 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12539 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12540 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12541 12542 //---------------------------------------------------------------------- 12543 // Supervisor Call (previously Software Interrupt) 12544 //---------------------------------------------------------------------- 12545 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12546 12547 //---------------------------------------------------------------------- 12548 // If Then makes up to four following instructions conditional. 12549 //---------------------------------------------------------------------- 12550 // The next 5 opcode _must_ come before the if then instruction 12551 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12552 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12553 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12554 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12555 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12556 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12557 12558 //---------------------------------------------------------------------- 12559 // Branch instructions 12560 //---------------------------------------------------------------------- 12561 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12562 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12563 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12564 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12565 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12566 // J1 == J2 == 1 12567 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12568 // J1 == J2 == 1 12569 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12570 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12571 // for example, "bx lr" 12572 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12573 // bxj 12574 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12575 // compare and branch 12576 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12577 // table branch byte 12578 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12579 // table branch halfword 12580 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12581 12582 //---------------------------------------------------------------------- 12583 // Data-processing instructions 12584 //---------------------------------------------------------------------- 12585 // adc (immediate) 12586 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12587 // adc (register) 12588 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12589 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12590 // add (register) 12591 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12592 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12593 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12594 // adr 12595 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12596 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12597 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12598 // and (immediate) 12599 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12600 // and (register) 12601 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12602 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12603 // bic (immediate) 12604 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12605 // bic (register) 12606 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12607 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12608 // eor (immediate) 12609 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12610 // eor (register) 12611 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12612 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12613 // orr (immediate) 12614 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12615 // orr (register) 12616 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12617 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12618 // rsb (immediate) 12619 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12620 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12621 // rsb (register) 12622 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12623 // sbc (immediate) 12624 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12625 // sbc (register) 12626 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12627 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12628 // add (immediate, Thumb) 12629 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12630 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12631 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12632 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12633 // sub (immediate, Thumb) 12634 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12635 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12636 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12637 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12638 // sub (sp minus immediate) 12639 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12640 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12641 // sub (register) 12642 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12643 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12644 // teq (immediate) 12645 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12646 // teq (register) 12647 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12648 // tst (immediate) 12649 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12650 // tst (register) 12651 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12652 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12653 12654 12655 // move from high register to high register 12656 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12657 // move from low register to low register 12658 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12659 // mov{s}<c>.w <Rd>, <Rm> 12660 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12661 // move immediate 12662 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12663 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12664 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12665 // mvn (immediate) 12666 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12667 // mvn (register) 12668 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12669 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12670 // cmn (immediate) 12671 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12672 // cmn (register) 12673 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12674 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12675 // cmp (immediate) 12676 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12677 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12678 // cmp (register) (Rn and Rm both from r0-r7) 12679 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12680 // cmp (register) (Rn and Rm not both from r0-r7) 12681 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12682 // asr (immediate) 12683 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12684 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12685 // asr (register) 12686 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12687 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12688 // lsl (immediate) 12689 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12690 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12691 // lsl (register) 12692 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12693 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12694 // lsr (immediate) 12695 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12696 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12697 // lsr (register) 12698 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12699 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12700 // rrx is a special case encoding of ror (immediate) 12701 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12702 // ror (immediate) 12703 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12704 // ror (register) 12705 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12706 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12707 // mul 12708 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12709 // mul 12710 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12711 12712 // subs pc, lr and related instructions 12713 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12714 12715 //---------------------------------------------------------------------- 12716 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12717 // otherwise the wrong instructions will be selected. 12718 //---------------------------------------------------------------------- 12719 12720 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12721 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12722 12723 //---------------------------------------------------------------------- 12724 // Load instructions 12725 //---------------------------------------------------------------------- 12726 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12727 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12728 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12729 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12730 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12731 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12732 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12733 // Thumb2 PC-relative load into register 12734 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12735 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12736 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12737 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12738 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12739 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12740 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12741 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12742 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12743 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12744 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12745 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12746 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12747 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12748 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12749 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12750 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12751 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12752 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12753 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12754 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12755 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12756 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12757 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12758 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12759 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12760 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12761 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12762 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12763 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12764 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12765 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12766 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12767 12768 //---------------------------------------------------------------------- 12769 // Store instructions 12770 //---------------------------------------------------------------------- 12771 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12772 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12773 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12774 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12775 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12776 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12777 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12778 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12779 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12780 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12781 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12782 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12783 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12784 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12785 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12786 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12787 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12788 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12789 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12790 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12791 { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12792 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12793 12794 //---------------------------------------------------------------------- 12795 // Other instructions 12796 //---------------------------------------------------------------------- 12797 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12798 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12799 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12800 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12801 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12802 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12803 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12804 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12805 }; 12806 12807 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 12808 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12809 { 12810 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12811 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12812 return &g_thumb_opcodes[i]; 12813 } 12814 return NULL; 12815} 12816 12817bool 12818EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12819{ 12820 m_arch = arch; 12821 m_arm_isa = 0; 12822 const char *arch_cstr = arch.GetArchitectureName (); 12823 if (arch_cstr) 12824 { 12825 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12826 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12827 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12828 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12829 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12830 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12831 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12832 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12833 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12834 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12835 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12836 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12837 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12838 } 12839 return m_arm_isa != 0; 12840} 12841 12842bool 12843EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12844{ 12845 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12846 { 12847 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12848 m_opcode_mode = eModeThumb; 12849 else 12850 { 12851 AddressClass addr_class = inst_addr.GetAddressClass(); 12852 12853 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 12854 m_opcode_mode = eModeARM; 12855 else if (addr_class == eAddressClassCodeAlternateISA) 12856 m_opcode_mode = eModeThumb; 12857 else 12858 return false; 12859 } 12860 if (m_opcode_mode == eModeThumb) 12861 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 12862 else 12863 m_opcode_cpsr = CPSR_MODE_USR; 12864 return true; 12865 } 12866 return false; 12867} 12868 12869bool 12870EmulateInstructionARM::ReadInstruction () 12871{ 12872 bool success = false; 12873 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 12874 if (success) 12875 { 12876 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 12877 if (success) 12878 { 12879 Context read_inst_context; 12880 read_inst_context.type = eContextReadOpcode; 12881 read_inst_context.SetNoArgs (); 12882 12883 if (m_opcode_cpsr & MASK_CPSR_T) 12884 { 12885 m_opcode_mode = eModeThumb; 12886 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 12887 12888 if (success) 12889 { 12890 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 12891 { 12892 m_opcode.SetOpcode16 (thumb_opcode); 12893 } 12894 else 12895 { 12896 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success)); 12897 } 12898 } 12899 } 12900 else 12901 { 12902 m_opcode_mode = eModeARM; 12903 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success)); 12904 } 12905 } 12906 } 12907 if (!success) 12908 { 12909 m_opcode_mode = eModeInvalid; 12910 m_addr = LLDB_INVALID_ADDRESS; 12911 } 12912 return success; 12913} 12914 12915uint32_t 12916EmulateInstructionARM::ArchVersion () 12917{ 12918 return m_arm_isa; 12919} 12920 12921bool 12922EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) 12923{ 12924 // If we are ignoring conditions, then always return true. 12925 // this allows us to iterate over disassembly code and still 12926 // emulate an instruction even if we don't have all the right 12927 // bits set in the CPSR register... 12928 if (m_ignore_conditions) 12929 return true; 12930 12931 if (is_conditional) 12932 *is_conditional = true; 12933 12934 const uint32_t cond = CurrentCond (opcode); 12935 12936 if (cond == UINT32_MAX) 12937 return false; 12938 12939 bool result = false; 12940 switch (UnsignedBits(cond, 3, 1)) 12941 { 12942 case 0: 12943 if (m_opcode_cpsr == 0) 12944 result = true; 12945 else 12946 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 12947 break; 12948 case 1: 12949 if (m_opcode_cpsr == 0) 12950 result = true; 12951 else 12952 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 12953 break; 12954 case 2: 12955 if (m_opcode_cpsr == 0) 12956 result = true; 12957 else 12958 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 12959 break; 12960 case 3: 12961 if (m_opcode_cpsr == 0) 12962 result = true; 12963 else 12964 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 12965 break; 12966 case 4: 12967 if (m_opcode_cpsr == 0) 12968 result = true; 12969 else 12970 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12971 break; 12972 case 5: 12973 if (m_opcode_cpsr == 0) 12974 result = true; 12975 else 12976 { 12977 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12978 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12979 result = n == v; 12980 } 12981 break; 12982 case 6: 12983 if (m_opcode_cpsr == 0) 12984 result = true; 12985 else 12986 { 12987 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12988 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12989 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12990 } 12991 break; 12992 case 7: 12993 // Always execute (cond == 0b1110, or the special 0b1111 which gives 12994 // opcodes different meanings, but always means execution happpens. 12995 if (is_conditional) 12996 *is_conditional = false; 12997 result = true; 12998 break; 12999 } 13000 13001 if (cond & 1) 13002 result = !result; 13003 return result; 13004} 13005 13006uint32_t 13007EmulateInstructionARM::CurrentCond (const uint32_t opcode) 13008{ 13009 switch (m_opcode_mode) 13010 { 13011 case eModeInvalid: 13012 break; 13013 13014 case eModeARM: 13015 return UnsignedBits(opcode, 31, 28); 13016 13017 case eModeThumb: 13018 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13019 // 'cond' field of the encoding. 13020 { 13021 const uint32_t byte_size = m_opcode.GetByteSize(); 13022 if (byte_size == 2) 13023 { 13024 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 13025 return Bits32(opcode, 11, 7); 13026 } 13027 else if (byte_size == 4) 13028 { 13029 if (Bits32(opcode, 31, 27) == 0x1e && 13030 Bits32(opcode, 15, 14) == 0x02 && 13031 Bits32(opcode, 12, 12) == 0x00 && 13032 Bits32(opcode, 25, 22) <= 0x0d) 13033 { 13034 return Bits32(opcode, 25, 22); 13035 } 13036 } 13037 else 13038 // We have an invalid thumb instruction, let's bail out. 13039 break; 13040 13041 return m_it_session.GetCond(); 13042 } 13043 } 13044 return UINT32_MAX; // Return invalid value 13045} 13046 13047bool 13048EmulateInstructionARM::InITBlock() 13049{ 13050 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13051} 13052 13053bool 13054EmulateInstructionARM::LastInITBlock() 13055{ 13056 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13057} 13058 13059bool 13060EmulateInstructionARM::BadMode (uint32_t mode) 13061{ 13062 13063 switch (mode) 13064 { 13065 case 16: return false; // '10000' 13066 case 17: return false; // '10001' 13067 case 18: return false; // '10010' 13068 case 19: return false; // '10011' 13069 case 22: return false; // '10110' 13070 case 23: return false; // '10111' 13071 case 27: return false; // '11011' 13072 case 31: return false; // '11111' 13073 default: return true; 13074 } 13075 return true; 13076} 13077 13078bool 13079EmulateInstructionARM::CurrentModeIsPrivileged () 13080{ 13081 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13082 13083 if (BadMode (mode)) 13084 return false; 13085 13086 if (mode == 16) 13087 return false; 13088 13089 return true; 13090} 13091 13092void 13093EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13094{ 13095 bool privileged = CurrentModeIsPrivileged(); 13096 13097 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13098 13099 if (BitIsSet (bytemask, 3)) 13100 { 13101 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13102 if (affect_execstate) 13103 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13104 } 13105 13106 if (BitIsSet (bytemask, 2)) 13107 { 13108 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13109 } 13110 13111 if (BitIsSet (bytemask, 1)) 13112 { 13113 if (affect_execstate) 13114 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13115 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13116 if (privileged) 13117 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13118 } 13119 13120 if (BitIsSet (bytemask, 0)) 13121 { 13122 if (privileged) 13123 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13124 if (affect_execstate) 13125 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13126 if (privileged) 13127 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13128 } 13129 13130 m_opcode_cpsr = tmp_cpsr; 13131} 13132 13133 13134bool 13135EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13136{ 13137 addr_t target; 13138 13139 // Check the current instruction set. 13140 if (CurrentInstrSet() == eModeARM) 13141 target = addr & 0xfffffffc; 13142 else 13143 target = addr & 0xfffffffe; 13144 13145 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13146 return false; 13147 13148 return true; 13149} 13150 13151// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13152bool 13153EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13154{ 13155 addr_t target; 13156 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13157 // we want to record it and issue a WriteRegister callback so the clients 13158 // can track the mode changes accordingly. 13159 bool cpsr_changed = false; 13160 13161 if (BitIsSet(addr, 0)) 13162 { 13163 if (CurrentInstrSet() != eModeThumb) 13164 { 13165 SelectInstrSet(eModeThumb); 13166 cpsr_changed = true; 13167 } 13168 target = addr & 0xfffffffe; 13169 context.SetISA (eModeThumb); 13170 } 13171 else if (BitIsClear(addr, 1)) 13172 { 13173 if (CurrentInstrSet() != eModeARM) 13174 { 13175 SelectInstrSet(eModeARM); 13176 cpsr_changed = true; 13177 } 13178 target = addr & 0xfffffffc; 13179 context.SetISA (eModeARM); 13180 } 13181 else 13182 return false; // address<1:0> == '10' => UNPREDICTABLE 13183 13184 if (cpsr_changed) 13185 { 13186 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13187 return false; 13188 } 13189 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13190 return false; 13191 13192 return true; 13193} 13194 13195// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13196bool 13197EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13198{ 13199 if (ArchVersion() >= ARMv5T) 13200 return BXWritePC(context, addr); 13201 else 13202 return BranchWritePC((const Context)context, addr); 13203} 13204 13205// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13206bool 13207EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13208{ 13209 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13210 return BXWritePC(context, addr); 13211 else 13212 return BranchWritePC((const Context)context, addr); 13213} 13214 13215EmulateInstructionARM::Mode 13216EmulateInstructionARM::CurrentInstrSet () 13217{ 13218 return m_opcode_mode; 13219} 13220 13221// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13222// ReadInstruction() is performed. This function has a side effect of updating 13223// the m_new_inst_cpsr member variable if necessary. 13224bool 13225EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13226{ 13227 m_new_inst_cpsr = m_opcode_cpsr; 13228 switch (arm_or_thumb) 13229 { 13230 default: 13231 return false; 13232 case eModeARM: 13233 // Clear the T bit. 13234 m_new_inst_cpsr &= ~MASK_CPSR_T; 13235 break; 13236 case eModeThumb: 13237 // Set the T bit. 13238 m_new_inst_cpsr |= MASK_CPSR_T; 13239 break; 13240 } 13241 return true; 13242} 13243 13244// This function returns TRUE if the processor currently provides support for 13245// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13246// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13247bool 13248EmulateInstructionARM::UnalignedSupport() 13249{ 13250 return (ArchVersion() >= ARMv7); 13251} 13252 13253// The main addition and subtraction instructions can produce status information 13254// about both unsigned carry and signed overflow conditions. This status 13255// information can be used to synthesize multi-word additions and subtractions. 13256EmulateInstructionARM::AddWithCarryResult 13257EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13258{ 13259 uint32_t result; 13260 uint8_t carry_out; 13261 uint8_t overflow; 13262 13263 uint64_t unsigned_sum = x + y + carry_in; 13264 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13265 13266 result = UnsignedBits(unsigned_sum, 31, 0); 13267// carry_out = (result == unsigned_sum ? 0 : 1); 13268 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13269 13270 if (carry_in) 13271 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13272 else 13273 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13274 13275 AddWithCarryResult res = { result, carry_out, overflow }; 13276 return res; 13277} 13278 13279uint32_t 13280EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13281{ 13282 uint32_t reg_kind, reg_num; 13283 switch (num) 13284 { 13285 case SP_REG: 13286 reg_kind = eRegisterKindGeneric; 13287 reg_num = LLDB_REGNUM_GENERIC_SP; 13288 break; 13289 case LR_REG: 13290 reg_kind = eRegisterKindGeneric; 13291 reg_num = LLDB_REGNUM_GENERIC_RA; 13292 break; 13293 case PC_REG: 13294 reg_kind = eRegisterKindGeneric; 13295 reg_num = LLDB_REGNUM_GENERIC_PC; 13296 break; 13297 default: 13298 if (num < SP_REG) 13299 { 13300 reg_kind = eRegisterKindDWARF; 13301 reg_num = dwarf_r0 + num; 13302 } 13303 else 13304 { 13305 //assert(0 && "Invalid register number"); 13306 *success = false; 13307 return UINT32_MAX; 13308 } 13309 break; 13310 } 13311 13312 // Read our register. 13313 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13314 13315 // When executing an ARM instruction , PC reads as the address of the current 13316 // instruction plus 8. 13317 // When executing a Thumb instruction , PC reads as the address of the current 13318 // instruction plus 4. 13319 if (num == 15) 13320 { 13321 if (CurrentInstrSet() == eModeARM) 13322 val += 8; 13323 else 13324 val += 4; 13325 } 13326 13327 return val; 13328} 13329 13330// Write the result to the ARM core register Rd, and optionally update the 13331// condition flags based on the result. 13332// 13333// This helper method tries to encapsulate the following pseudocode from the 13334// ARM Architecture Reference Manual: 13335// 13336// if d == 15 then // Can only occur for encoding A1 13337// ALUWritePC(result); // setflags is always FALSE here 13338// else 13339// R[d] = result; 13340// if setflags then 13341// APSR.N = result<31>; 13342// APSR.Z = IsZeroBit(result); 13343// APSR.C = carry; 13344// // APSR.V unchanged 13345// 13346// In the above case, the API client does not pass in the overflow arg, which 13347// defaults to ~0u. 13348bool 13349EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13350 const uint32_t result, 13351 const uint32_t Rd, 13352 bool setflags, 13353 const uint32_t carry, 13354 const uint32_t overflow) 13355{ 13356 if (Rd == 15) 13357 { 13358 if (!ALUWritePC (context, result)) 13359 return false; 13360 } 13361 else 13362 { 13363 uint32_t reg_kind, reg_num; 13364 switch (Rd) 13365 { 13366 case SP_REG: 13367 reg_kind = eRegisterKindGeneric; 13368 reg_num = LLDB_REGNUM_GENERIC_SP; 13369 break; 13370 case LR_REG: 13371 reg_kind = eRegisterKindGeneric; 13372 reg_num = LLDB_REGNUM_GENERIC_RA; 13373 break; 13374 default: 13375 reg_kind = eRegisterKindDWARF; 13376 reg_num = dwarf_r0 + Rd; 13377 } 13378 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13379 return false; 13380 if (setflags) 13381 return WriteFlags (context, result, carry, overflow); 13382 } 13383 return true; 13384} 13385 13386// This helper method tries to encapsulate the following pseudocode from the 13387// ARM Architecture Reference Manual: 13388// 13389// APSR.N = result<31>; 13390// APSR.Z = IsZeroBit(result); 13391// APSR.C = carry; 13392// APSR.V = overflow 13393// 13394// Default arguments can be specified for carry and overflow parameters, which means 13395// not to update the respective flags. 13396bool 13397EmulateInstructionARM::WriteFlags (Context &context, 13398 const uint32_t result, 13399 const uint32_t carry, 13400 const uint32_t overflow) 13401{ 13402 m_new_inst_cpsr = m_opcode_cpsr; 13403 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13404 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13405 if (carry != ~0u) 13406 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13407 if (overflow != ~0u) 13408 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13409 if (m_new_inst_cpsr != m_opcode_cpsr) 13410 { 13411 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13412 return false; 13413 } 13414 return true; 13415} 13416 13417bool 13418EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13419{ 13420 // Advance the ITSTATE bits to their values for the next instruction. 13421 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13422 m_it_session.ITAdvance(); 13423 13424 ARMOpcode *opcode_data = NULL; 13425 13426 if (m_opcode_mode == eModeThumb) 13427 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13428 else if (m_opcode_mode == eModeARM) 13429 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13430 13431 if (opcode_data == NULL) 13432 return false; 13433 13434 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13435 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13436 13437 bool success = false; 13438 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13439 { 13440 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13441 dwarf_cpsr, 13442 0, 13443 &success); 13444 } 13445 13446 // Only return false if we are unable to read the CPSR if we care about conditions 13447 if (success == false && m_ignore_conditions == false) 13448 return false; 13449 13450 uint32_t orig_pc_value = 0; 13451 if (auto_advance_pc) 13452 { 13453 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13454 if (!success) 13455 return false; 13456 } 13457 13458 // Call the Emulate... function. 13459 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13460 if (!success) 13461 return false; 13462 13463 if (auto_advance_pc) 13464 { 13465 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13466 if (!success) 13467 return false; 13468 13469 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13470 { 13471 if (opcode_data->size == eSize32) 13472 after_pc_value += 4; 13473 else if (opcode_data->size == eSize16) 13474 after_pc_value += 2; 13475 13476 EmulateInstruction::Context context; 13477 context.type = eContextAdvancePC; 13478 context.SetNoArgs(); 13479 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13480 return false; 13481 13482 } 13483 } 13484 return true; 13485} 13486 13487bool 13488EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13489{ 13490 if (!test_data) 13491 { 13492 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13493 return false; 13494 } 13495 13496 static ConstString opcode_key ("opcode"); 13497 static ConstString before_key ("before_state"); 13498 static ConstString after_key ("after_state"); 13499 13500 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13501 13502 uint32_t test_opcode; 13503 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13504 { 13505 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13506 return false; 13507 } 13508 test_opcode = value_sp->GetUInt64Value (); 13509 13510 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13511 { 13512 m_opcode_mode = eModeARM; 13513 m_opcode.SetOpcode32 (test_opcode); 13514 } 13515 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13516 { 13517 m_opcode_mode = eModeThumb; 13518 if (test_opcode < 0x10000) 13519 m_opcode.SetOpcode16 (test_opcode); 13520 else 13521 m_opcode.SetOpcode32 (test_opcode); 13522 13523 } 13524 else 13525 { 13526 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13527 return false; 13528 } 13529 13530 EmulationStateARM before_state; 13531 EmulationStateARM after_state; 13532 13533 value_sp = test_data->GetValueForKey (before_key); 13534 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13535 { 13536 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13537 return false; 13538 } 13539 13540 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13541 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13542 { 13543 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13544 return false; 13545 } 13546 13547 value_sp = test_data->GetValueForKey (after_key); 13548 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13549 { 13550 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13551 return false; 13552 } 13553 13554 state_dictionary = value_sp->GetAsDictionary (); 13555 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13556 { 13557 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13558 return false; 13559 } 13560 13561 SetBaton ((void *) &before_state); 13562 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13563 &EmulationStateARM::WritePseudoMemory, 13564 &EmulationStateARM::ReadPseudoRegister, 13565 &EmulationStateARM::WritePseudoRegister); 13566 13567 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13568 if (!success) 13569 { 13570 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13571 return false; 13572 } 13573 13574 success = before_state.CompareState (after_state); 13575 if (!success) 13576 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13577 13578 return success; 13579} 13580// 13581// 13582//const char * 13583//EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13584//{ 13585// if (reg_kind == eRegisterKindGeneric) 13586// { 13587// switch (reg_num) 13588// { 13589// case LLDB_REGNUM_GENERIC_PC: return "pc"; 13590// case LLDB_REGNUM_GENERIC_SP: return "sp"; 13591// case LLDB_REGNUM_GENERIC_FP: return "fp"; 13592// case LLDB_REGNUM_GENERIC_RA: return "lr"; 13593// case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13594// default: return NULL; 13595// } 13596// } 13597// else if (reg_kind == eRegisterKindDWARF) 13598// { 13599// return GetARMDWARFRegisterName (reg_num); 13600// } 13601// return NULL; 13602//} 13603// 13604bool 13605EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13606{ 13607 unwind_plan.Clear(); 13608 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13609 13610 UnwindPlan::RowSP row(new UnwindPlan::Row); 13611 13612 // Our previous Call Frame Address is the stack pointer 13613 row->SetCFARegister (dwarf_sp); 13614 13615 // Our previous PC is in the LR 13616 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true); 13617 unwind_plan.AppendRow (row); 13618 13619 // All other registers are the same. 13620 13621 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13622 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 13623 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 13624 return true; 13625} 13626