EmulateInstructionARM.cpp revision 0d91b809feae0708ec372a30d0da53959eeb062c
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 printf("Encoding error: IT Mask '0000'\n"); 54 return 0; 55 } 56 return (4 - TZ); 57} 58 59// Init ITState. Note that at least one bit is always 1 in mask. 60bool ITSession::InitIT(uint32_t bits7_0) 61{ 62 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 63 if (ITCounter == 0) 64 return false; 65 66 // A8.6.50 IT 67 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 68 if (FirstCond == 0xF) 69 { 70 printf("Encoding error: IT FirstCond '1111'\n"); 71 return false; 72 } 73 if (FirstCond == 0xE && ITCounter != 1) 74 { 75 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 76 return false; 77 } 78 79 ITState = bits7_0; 80 return true; 81} 82 83// Update ITState if necessary. 84void ITSession::ITAdvance() 85{ 86 //assert(ITCounter); 87 --ITCounter; 88 if (ITCounter == 0) 89 ITState = 0; 90 else 91 { 92 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 93 SetBits32(ITState, 4, 0, NewITState4_0); 94 } 95} 96 97// Return true if we're inside an IT Block. 98bool ITSession::InITBlock() 99{ 100 return ITCounter != 0; 101} 102 103// Return true if we're the last instruction inside an IT Block. 104bool ITSession::LastInITBlock() 105{ 106 return ITCounter == 1; 107} 108 109// Get condition bits for the current thumb instruction. 110uint32_t ITSession::GetCond() 111{ 112 if (InITBlock()) 113 return Bits32(ITState, 7, 4); 114 else 115 return COND_AL; 116} 117 118// ARM constants used during decoding 119#define REG_RD 0 120#define LDM_REGLIST 1 121#define SP_REG 13 122#define LR_REG 14 123#define PC_REG 15 124#define PC_REGLIST_BIT 0x8000 125 126#define ARMv4 (1u << 0) 127#define ARMv4T (1u << 1) 128#define ARMv5T (1u << 2) 129#define ARMv5TE (1u << 3) 130#define ARMv5TEJ (1u << 4) 131#define ARMv6 (1u << 5) 132#define ARMv6K (1u << 6) 133#define ARMv6T2 (1u << 7) 134#define ARMv7 (1u << 8) 135#define ARMv7S (1u << 9) 136#define ARMv8 (1u << 10) 137#define ARMvAll (0xffffffffu) 138 139#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 140#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 141#define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 142#define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 143#define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 144#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8) 145#define ARMV7_ABOVE (ARMv7|ARMv7S|ARMv8) 146 147#define No_VFP 0 148#define VFPv1 (1u << 1) 149#define VFPv2 (1u << 2) 150#define VFPv3 (1u << 3) 151#define AdvancedSIMD (1u << 4) 152 153#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 154#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 155#define VFPv2v3 (VFPv2 | VFPv3) 156 157//---------------------------------------------------------------------- 158// 159// EmulateInstructionARM implementation 160// 161//---------------------------------------------------------------------- 162 163void 164EmulateInstructionARM::Initialize () 165{ 166 PluginManager::RegisterPlugin (GetPluginNameStatic (), 167 GetPluginDescriptionStatic (), 168 CreateInstance); 169} 170 171void 172EmulateInstructionARM::Terminate () 173{ 174 PluginManager::UnregisterPlugin (CreateInstance); 175} 176 177ConstString 178EmulateInstructionARM::GetPluginNameStatic () 179{ 180 static ConstString g_name("arm"); 181 return g_name; 182} 183 184const char * 185EmulateInstructionARM::GetPluginDescriptionStatic () 186{ 187 return "Emulate instructions for the ARM architecture."; 188} 189 190EmulateInstruction * 191EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) 192{ 193 if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type)) 194 { 195 if (arch.GetTriple().getArch() == llvm::Triple::arm) 196 { 197 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 198 199 if (emulate_insn_ap.get()) 200 return emulate_insn_ap.release(); 201 } 202 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 203 { 204 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 205 206 if (emulate_insn_ap.get()) 207 return emulate_insn_ap.release(); 208 } 209 } 210 211 return NULL; 212} 213 214bool 215EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch) 216{ 217 if (arch.GetTriple().getArch () == llvm::Triple::arm) 218 return true; 219 else if (arch.GetTriple().getArch () == llvm::Triple::thumb) 220 return true; 221 222 return false; 223} 224 225// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 226bool 227EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 228{ 229 EmulateInstruction::Context context; 230 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 231 context.SetNoArgs (); 232 233 uint32_t random_data = rand (); 234 const uint32_t addr_byte_size = GetAddressByteSize(); 235 236 if (!MemAWrite (context, address, random_data, addr_byte_size)) 237 return false; 238 239 return true; 240} 241 242// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 243bool 244EmulateInstructionARM::WriteBits32Unknown (int n) 245{ 246 EmulateInstruction::Context context; 247 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 248 context.SetNoArgs (); 249 250 bool success; 251 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 252 253 if (!success) 254 return false; 255 256 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 257 return false; 258 259 return true; 260} 261 262bool 263EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo ®_info) 264{ 265 if (reg_kind == eRegisterKindGeneric) 266 { 267 switch (reg_num) 268 { 269 case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break; 270 case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break; 271 case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break; 272 case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break; 273 case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break; 274 default: return false; 275 } 276 } 277 278 if (reg_kind == eRegisterKindDWARF) 279 return GetARMDWARFRegisterInfo(reg_num, reg_info); 280 return false; 281} 282 283uint32_t 284EmulateInstructionARM::GetFramePointerRegisterNumber () const 285{ 286 if (m_opcode_mode == eModeThumb) 287 { 288 switch (m_arch.GetTriple().getOS()) 289 { 290 case llvm::Triple::Darwin: 291 case llvm::Triple::MacOSX: 292 case llvm::Triple::IOS: 293 return 7; 294 default: 295 break; 296 } 297 } 298 return 11; 299} 300 301uint32_t 302EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 303{ 304 if (m_opcode_mode == eModeThumb) 305 { 306 switch (m_arch.GetTriple().getOS()) 307 { 308 case llvm::Triple::Darwin: 309 case llvm::Triple::MacOSX: 310 case llvm::Triple::IOS: 311 return dwarf_r7; 312 default: 313 break; 314 } 315 } 316 return dwarf_r11; 317} 318 319// Push Multiple Registers stores multiple registers to the stack, storing to 320// consecutive memory locations ending just below the address in SP, and updates 321// SP to point to the start of the stored data. 322bool 323EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 324{ 325#if 0 326 // ARM pseudo code... 327 if (ConditionPassed()) 328 { 329 EncodingSpecificOperations(); 330 NullCheckIfThumbEE(13); 331 address = SP - 4*BitCount(registers); 332 333 for (i = 0 to 14) 334 { 335 if (registers<i> == '1') 336 { 337 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 338 MemA[address,4] = bits(32) UNKNOWN; 339 else 340 MemA[address,4] = R[i]; 341 address = address + 4; 342 } 343 } 344 345 if (registers<15> == '1') // Only possible for encoding A1 or A2 346 MemA[address,4] = PCStoreValue(); 347 348 SP = SP - 4*BitCount(registers); 349 } 350#endif 351 352 bool conditional = false; 353 bool success = false; 354 if (ConditionPassed(opcode, &conditional)) 355 { 356 const uint32_t addr_byte_size = GetAddressByteSize(); 357 const addr_t sp = ReadCoreReg (SP_REG, &success); 358 if (!success) 359 return false; 360 uint32_t registers = 0; 361 uint32_t Rt; // the source register 362 switch (encoding) { 363 case eEncodingT1: 364 registers = Bits32(opcode, 7, 0); 365 // The M bit represents LR. 366 if (Bit32(opcode, 8)) 367 registers |= (1u << 14); 368 // if BitCount(registers) < 1 then UNPREDICTABLE; 369 if (BitCount(registers) < 1) 370 return false; 371 break; 372 case eEncodingT2: 373 // Ignore bits 15 & 13. 374 registers = Bits32(opcode, 15, 0) & ~0xa000; 375 // if BitCount(registers) < 2 then UNPREDICTABLE; 376 if (BitCount(registers) < 2) 377 return false; 378 break; 379 case eEncodingT3: 380 Rt = Bits32(opcode, 15, 12); 381 // if BadReg(t) then UNPREDICTABLE; 382 if (BadReg(Rt)) 383 return false; 384 registers = (1u << Rt); 385 break; 386 case eEncodingA1: 387 registers = Bits32(opcode, 15, 0); 388 // Instead of return false, let's handle the following case as well, 389 // which amounts to pushing one reg onto the full descending stacks. 390 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 391 break; 392 case eEncodingA2: 393 Rt = Bits32(opcode, 15, 12); 394 // if t == 13 then UNPREDICTABLE; 395 if (Rt == dwarf_sp) 396 return false; 397 registers = (1u << Rt); 398 break; 399 default: 400 return false; 401 } 402 addr_t sp_offset = addr_byte_size * BitCount (registers); 403 addr_t addr = sp - sp_offset; 404 uint32_t i; 405 406 EmulateInstruction::Context context; 407 if (conditional) 408 context.type = EmulateInstruction::eContextRegisterStore; 409 else 410 context.type = EmulateInstruction::eContextPushRegisterOnStack; 411 RegisterInfo reg_info; 412 RegisterInfo sp_reg; 413 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 414 for (i=0; i<15; ++i) 415 { 416 if (BitIsSet (registers, i)) 417 { 418 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 419 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 420 uint32_t reg_value = ReadCoreReg(i, &success); 421 if (!success) 422 return false; 423 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 424 return false; 425 addr += addr_byte_size; 426 } 427 } 428 429 if (BitIsSet (registers, 15)) 430 { 431 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 432 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 433 const uint32_t pc = ReadCoreReg(PC_REG, &success); 434 if (!success) 435 return false; 436 if (!MemAWrite (context, addr, pc, addr_byte_size)) 437 return false; 438 } 439 440 context.type = EmulateInstruction::eContextAdjustStackPointer; 441 context.SetImmediateSigned (-sp_offset); 442 443 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 444 return false; 445 } 446 return true; 447} 448 449// Pop Multiple Registers loads multiple registers from the stack, loading from 450// consecutive memory locations staring at the address in SP, and updates 451// SP to point just above the loaded data. 452bool 453EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 454{ 455#if 0 456 // ARM pseudo code... 457 if (ConditionPassed()) 458 { 459 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 460 address = SP; 461 for i = 0 to 14 462 if registers<i> == '1' then 463 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 464 if registers<15> == '1' then 465 if UnalignedAllowed then 466 LoadWritePC(MemU[address,4]); 467 else 468 LoadWritePC(MemA[address,4]); 469 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 470 if registers<13> == '1' then SP = bits(32) UNKNOWN; 471 } 472#endif 473 474 bool success = false; 475 476 bool conditional = false; 477 if (ConditionPassed(opcode, &conditional)) 478 { 479 const uint32_t addr_byte_size = GetAddressByteSize(); 480 const addr_t sp = ReadCoreReg (SP_REG, &success); 481 if (!success) 482 return false; 483 uint32_t registers = 0; 484 uint32_t Rt; // the destination register 485 switch (encoding) { 486 case eEncodingT1: 487 registers = Bits32(opcode, 7, 0); 488 // The P bit represents PC. 489 if (Bit32(opcode, 8)) 490 registers |= (1u << 15); 491 // if BitCount(registers) < 1 then UNPREDICTABLE; 492 if (BitCount(registers) < 1) 493 return false; 494 break; 495 case eEncodingT2: 496 // Ignore bit 13. 497 registers = Bits32(opcode, 15, 0) & ~0x2000; 498 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 499 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 500 return false; 501 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 502 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 503 return false; 504 break; 505 case eEncodingT3: 506 Rt = Bits32(opcode, 15, 12); 507 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 508 if (Rt == 13) 509 return false; 510 if (Rt == 15 && InITBlock() && !LastInITBlock()) 511 return false; 512 registers = (1u << Rt); 513 break; 514 case eEncodingA1: 515 registers = Bits32(opcode, 15, 0); 516 // Instead of return false, let's handle the following case as well, 517 // which amounts to popping one reg from the full descending stacks. 518 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 519 520 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 521 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 522 return false; 523 break; 524 case eEncodingA2: 525 Rt = Bits32(opcode, 15, 12); 526 // if t == 13 then UNPREDICTABLE; 527 if (Rt == dwarf_sp) 528 return false; 529 registers = (1u << Rt); 530 break; 531 default: 532 return false; 533 } 534 addr_t sp_offset = addr_byte_size * BitCount (registers); 535 addr_t addr = sp; 536 uint32_t i, data; 537 538 EmulateInstruction::Context context; 539 if (conditional) 540 context.type = EmulateInstruction::eContextRegisterLoad; 541 else 542 context.type = EmulateInstruction::eContextPopRegisterOffStack; 543 544 RegisterInfo sp_reg; 545 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 546 547 for (i=0; i<15; ++i) 548 { 549 if (BitIsSet (registers, i)) 550 { 551 context.SetRegisterPlusOffset (sp_reg, addr - sp); 552 data = MemARead(context, addr, 4, 0, &success); 553 if (!success) 554 return false; 555 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 556 return false; 557 addr += addr_byte_size; 558 } 559 } 560 561 if (BitIsSet (registers, 15)) 562 { 563 context.SetRegisterPlusOffset (sp_reg, addr - sp); 564 data = MemARead(context, addr, 4, 0, &success); 565 if (!success) 566 return false; 567 // In ARMv5T and above, this is an interworking branch. 568 if (!LoadWritePC(context, data)) 569 return false; 570 //addr += addr_byte_size; 571 } 572 573 context.type = EmulateInstruction::eContextAdjustStackPointer; 574 context.SetImmediateSigned (sp_offset); 575 576 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 577 return false; 578 } 579 return true; 580} 581 582// Set r7 or ip to point to saved value residing within the stack. 583// ADD (SP plus immediate) 584bool 585EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 586{ 587#if 0 588 // ARM pseudo code... 589 if (ConditionPassed()) 590 { 591 EncodingSpecificOperations(); 592 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 593 if d == 15 then 594 ALUWritePC(result); // setflags is always FALSE here 595 else 596 R[d] = result; 597 if setflags then 598 APSR.N = result<31>; 599 APSR.Z = IsZeroBit(result); 600 APSR.C = carry; 601 APSR.V = overflow; 602 } 603#endif 604 605 bool success = false; 606 607 if (ConditionPassed(opcode)) 608 { 609 const addr_t sp = ReadCoreReg (SP_REG, &success); 610 if (!success) 611 return false; 612 uint32_t Rd; // the destination register 613 uint32_t imm32; 614 switch (encoding) { 615 case eEncodingT1: 616 Rd = 7; 617 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 618 break; 619 case eEncodingA1: 620 Rd = Bits32(opcode, 15, 12); 621 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 622 break; 623 default: 624 return false; 625 } 626 addr_t sp_offset = imm32; 627 addr_t addr = sp + sp_offset; // a pointer to the stack area 628 629 EmulateInstruction::Context context; 630 context.type = eContextSetFramePointer; 631 RegisterInfo sp_reg; 632 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 633 context.SetRegisterPlusOffset (sp_reg, sp_offset); 634 635 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 636 return false; 637 } 638 return true; 639} 640 641// Set r7 or ip to the current stack pointer. 642// MOV (register) 643bool 644EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 645{ 646#if 0 647 // ARM pseudo code... 648 if (ConditionPassed()) 649 { 650 EncodingSpecificOperations(); 651 result = R[m]; 652 if d == 15 then 653 ALUWritePC(result); // setflags is always FALSE here 654 else 655 R[d] = result; 656 if setflags then 657 APSR.N = result<31>; 658 APSR.Z = IsZeroBit(result); 659 // APSR.C unchanged 660 // APSR.V unchanged 661 } 662#endif 663 664 bool success = false; 665 666 if (ConditionPassed(opcode)) 667 { 668 const addr_t sp = ReadCoreReg (SP_REG, &success); 669 if (!success) 670 return false; 671 uint32_t Rd; // the destination register 672 switch (encoding) { 673 case eEncodingT1: 674 Rd = 7; 675 break; 676 case eEncodingA1: 677 Rd = 12; 678 break; 679 default: 680 return false; 681 } 682 683 EmulateInstruction::Context context; 684 if (Rd == GetFramePointerRegisterNumber()) 685 context.type = EmulateInstruction::eContextSetFramePointer; 686 else 687 context.type = EmulateInstruction::eContextRegisterPlusOffset; 688 RegisterInfo sp_reg; 689 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 690 context.SetRegisterPlusOffset (sp_reg, 0); 691 692 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 693 return false; 694 } 695 return true; 696} 697 698// Move from high register (r8-r15) to low register (r0-r7). 699// MOV (register) 700bool 701EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 702{ 703 return EmulateMOVRdRm (opcode, encoding); 704} 705 706// Move from register to register. 707// MOV (register) 708bool 709EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 710{ 711#if 0 712 // ARM pseudo code... 713 if (ConditionPassed()) 714 { 715 EncodingSpecificOperations(); 716 result = R[m]; 717 if d == 15 then 718 ALUWritePC(result); // setflags is always FALSE here 719 else 720 R[d] = result; 721 if setflags then 722 APSR.N = result<31>; 723 APSR.Z = IsZeroBit(result); 724 // APSR.C unchanged 725 // APSR.V unchanged 726 } 727#endif 728 729 bool success = false; 730 731 if (ConditionPassed(opcode)) 732 { 733 uint32_t Rm; // the source register 734 uint32_t Rd; // the destination register 735 bool setflags; 736 switch (encoding) { 737 case eEncodingT1: 738 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 739 Rm = Bits32(opcode, 6, 3); 740 setflags = false; 741 if (Rd == 15 && InITBlock() && !LastInITBlock()) 742 return false; 743 break; 744 case eEncodingT2: 745 Rd = Bits32(opcode, 2, 0); 746 Rm = Bits32(opcode, 5, 3); 747 setflags = true; 748 if (InITBlock()) 749 return false; 750 break; 751 case eEncodingT3: 752 Rd = Bits32(opcode, 11, 8); 753 Rm = Bits32(opcode, 3, 0); 754 setflags = BitIsSet(opcode, 20); 755 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 756 if (setflags && (BadReg(Rd) || BadReg(Rm))) 757 return false; 758 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 759 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 760 return false; 761 break; 762 case eEncodingA1: 763 Rd = Bits32(opcode, 15, 12); 764 Rm = Bits32(opcode, 3, 0); 765 setflags = BitIsSet(opcode, 20); 766 767 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 768 if (Rd == 15 && setflags) 769 return EmulateSUBSPcLrEtc (opcode, encoding); 770 break; 771 default: 772 return false; 773 } 774 uint32_t result = ReadCoreReg(Rm, &success); 775 if (!success) 776 return false; 777 778 // The context specifies that Rm is to be moved into Rd. 779 EmulateInstruction::Context context; 780 context.type = EmulateInstruction::eContextRegisterLoad; 781 RegisterInfo dwarf_reg; 782 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 783 context.SetRegister (dwarf_reg); 784 785 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 786 return false; 787 } 788 return true; 789} 790 791// Move (immediate) writes an immediate value to the destination register. It 792// can optionally update the condition flags based on the value. 793// MOV (immediate) 794bool 795EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 796{ 797#if 0 798 // ARM pseudo code... 799 if (ConditionPassed()) 800 { 801 EncodingSpecificOperations(); 802 result = imm32; 803 if d == 15 then // Can only occur for ARM encoding 804 ALUWritePC(result); // setflags is always FALSE here 805 else 806 R[d] = result; 807 if setflags then 808 APSR.N = result<31>; 809 APSR.Z = IsZeroBit(result); 810 APSR.C = carry; 811 // APSR.V unchanged 812 } 813#endif 814 815 if (ConditionPassed(opcode)) 816 { 817 uint32_t Rd; // the destination register 818 uint32_t imm32; // the immediate value to be written to Rd 819 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 820 // for setflags == false, this value is a don't care 821 // initialized to 0 to silence the static analyzer 822 bool setflags; 823 switch (encoding) { 824 case eEncodingT1: 825 Rd = Bits32(opcode, 10, 8); 826 setflags = !InITBlock(); 827 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 828 carry = APSR_C; 829 830 break; 831 832 case eEncodingT2: 833 Rd = Bits32(opcode, 11, 8); 834 setflags = BitIsSet(opcode, 20); 835 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 836 if (BadReg(Rd)) 837 return false; 838 839 break; 840 841 case eEncodingT3: 842 { 843 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 844 Rd = Bits32 (opcode, 11, 8); 845 setflags = false; 846 uint32_t imm4 = Bits32 (opcode, 19, 16); 847 uint32_t imm3 = Bits32 (opcode, 14, 12); 848 uint32_t i = Bit32 (opcode, 26); 849 uint32_t imm8 = Bits32 (opcode, 7, 0); 850 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 851 852 // if BadReg(d) then UNPREDICTABLE; 853 if (BadReg (Rd)) 854 return false; 855 } 856 break; 857 858 case eEncodingA1: 859 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 860 Rd = Bits32 (opcode, 15, 12); 861 setflags = BitIsSet (opcode, 20); 862 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 863 864 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 865 if ((Rd == 15) && setflags) 866 return EmulateSUBSPcLrEtc (opcode, encoding); 867 868 break; 869 870 case eEncodingA2: 871 { 872 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 873 Rd = Bits32 (opcode, 15, 12); 874 setflags = false; 875 uint32_t imm4 = Bits32 (opcode, 19, 16); 876 uint32_t imm12 = Bits32 (opcode, 11, 0); 877 imm32 = (imm4 << 12) | imm12; 878 879 // if d == 15 then UNPREDICTABLE; 880 if (Rd == 15) 881 return false; 882 } 883 break; 884 885 default: 886 return false; 887 } 888 uint32_t result = imm32; 889 890 // The context specifies that an immediate is to be moved into Rd. 891 EmulateInstruction::Context context; 892 context.type = EmulateInstruction::eContextImmediate; 893 context.SetNoArgs (); 894 895 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 896 return false; 897 } 898 return true; 899} 900 901// MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 902// register. These 32 bits do not depend on whether the source register values are considered to be signed values or 903// unsigned values. 904// 905// Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 906// limited to only a few forms of the instruction. 907bool 908EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 909{ 910#if 0 911 if ConditionPassed() then 912 EncodingSpecificOperations(); 913 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 914 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 915 result = operand1 * operand2; 916 R[d] = result<31:0>; 917 if setflags then 918 APSR.N = result<31>; 919 APSR.Z = IsZeroBit(result); 920 if ArchVersion() == 4 then 921 APSR.C = bit UNKNOWN; 922 // else APSR.C unchanged 923 // APSR.V always unchanged 924#endif 925 926 if (ConditionPassed(opcode)) 927 { 928 uint32_t d; 929 uint32_t n; 930 uint32_t m; 931 bool setflags; 932 933 // EncodingSpecificOperations(); 934 switch (encoding) 935 { 936 case eEncodingT1: 937 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 938 d = Bits32 (opcode, 2, 0); 939 n = Bits32 (opcode, 5, 3); 940 m = Bits32 (opcode, 2, 0); 941 setflags = !InITBlock(); 942 943 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 944 if ((ArchVersion() < ARMv6) && (d == n)) 945 return false; 946 947 break; 948 949 case eEncodingT2: 950 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 951 d = Bits32 (opcode, 11, 8); 952 n = Bits32 (opcode, 19, 16); 953 m = Bits32 (opcode, 3, 0); 954 setflags = false; 955 956 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 957 if (BadReg (d) || BadReg (n) || BadReg (m)) 958 return false; 959 960 break; 961 962 case eEncodingA1: 963 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 964 d = Bits32 (opcode, 19, 16); 965 n = Bits32 (opcode, 3, 0); 966 m = Bits32 (opcode, 11, 8); 967 setflags = BitIsSet (opcode, 20); 968 969 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 970 if ((d == 15) || (n == 15) || (m == 15)) 971 return false; 972 973 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 974 if ((ArchVersion() < ARMv6) && (d == n)) 975 return false; 976 977 break; 978 979 default: 980 return false; 981 } 982 983 bool success = false; 984 985 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 986 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 987 if (!success) 988 return false; 989 990 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 991 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 992 if (!success) 993 return false; 994 995 // result = operand1 * operand2; 996 uint64_t result = operand1 * operand2; 997 998 // R[d] = result<31:0>; 999 RegisterInfo op1_reg; 1000 RegisterInfo op2_reg; 1001 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1002 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1003 1004 EmulateInstruction::Context context; 1005 context.type = eContextArithmetic; 1006 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 1007 1008 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 1009 return false; 1010 1011 // if setflags then 1012 if (setflags) 1013 { 1014 // APSR.N = result<31>; 1015 // APSR.Z = IsZeroBit(result); 1016 m_new_inst_cpsr = m_opcode_cpsr; 1017 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 1018 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1019 if (m_new_inst_cpsr != m_opcode_cpsr) 1020 { 1021 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1022 return false; 1023 } 1024 1025 // if ArchVersion() == 4 then 1026 // APSR.C = bit UNKNOWN; 1027 } 1028 } 1029 return true; 1030} 1031 1032// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1033// It can optionally update the condition flags based on the value. 1034bool 1035EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1036{ 1037#if 0 1038 // ARM pseudo code... 1039 if (ConditionPassed()) 1040 { 1041 EncodingSpecificOperations(); 1042 result = NOT(imm32); 1043 if d == 15 then // Can only occur for ARM encoding 1044 ALUWritePC(result); // setflags is always FALSE here 1045 else 1046 R[d] = result; 1047 if setflags then 1048 APSR.N = result<31>; 1049 APSR.Z = IsZeroBit(result); 1050 APSR.C = carry; 1051 // APSR.V unchanged 1052 } 1053#endif 1054 1055 if (ConditionPassed(opcode)) 1056 { 1057 uint32_t Rd; // the destination register 1058 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1059 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1060 bool setflags; 1061 switch (encoding) { 1062 case eEncodingT1: 1063 Rd = Bits32(opcode, 11, 8); 1064 setflags = BitIsSet(opcode, 20); 1065 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1066 break; 1067 case eEncodingA1: 1068 Rd = Bits32(opcode, 15, 12); 1069 setflags = BitIsSet(opcode, 20); 1070 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1071 1072 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1073 if (Rd == 15 && setflags) 1074 return EmulateSUBSPcLrEtc (opcode, encoding); 1075 break; 1076 default: 1077 return false; 1078 } 1079 uint32_t result = ~imm32; 1080 1081 // The context specifies that an immediate is to be moved into Rd. 1082 EmulateInstruction::Context context; 1083 context.type = EmulateInstruction::eContextImmediate; 1084 context.SetNoArgs (); 1085 1086 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1087 return false; 1088 } 1089 return true; 1090} 1091 1092// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1093// It can optionally update the condition flags based on the result. 1094bool 1095EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1096{ 1097#if 0 1098 // ARM pseudo code... 1099 if (ConditionPassed()) 1100 { 1101 EncodingSpecificOperations(); 1102 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1103 result = NOT(shifted); 1104 if d == 15 then // Can only occur for ARM encoding 1105 ALUWritePC(result); // setflags is always FALSE here 1106 else 1107 R[d] = result; 1108 if setflags then 1109 APSR.N = result<31>; 1110 APSR.Z = IsZeroBit(result); 1111 APSR.C = carry; 1112 // APSR.V unchanged 1113 } 1114#endif 1115 1116 if (ConditionPassed(opcode)) 1117 { 1118 uint32_t Rm; // the source register 1119 uint32_t Rd; // the destination register 1120 ARM_ShifterType shift_t; 1121 uint32_t shift_n; // the shift applied to the value read from Rm 1122 bool setflags; 1123 uint32_t carry; // the carry bit after the shift operation 1124 switch (encoding) { 1125 case eEncodingT1: 1126 Rd = Bits32(opcode, 2, 0); 1127 Rm = Bits32(opcode, 5, 3); 1128 setflags = !InITBlock(); 1129 shift_t = SRType_LSL; 1130 shift_n = 0; 1131 if (InITBlock()) 1132 return false; 1133 break; 1134 case eEncodingT2: 1135 Rd = Bits32(opcode, 11, 8); 1136 Rm = Bits32(opcode, 3, 0); 1137 setflags = BitIsSet(opcode, 20); 1138 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1139 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1140 if (BadReg(Rd) || BadReg(Rm)) 1141 return false; 1142 break; 1143 case eEncodingA1: 1144 Rd = Bits32(opcode, 15, 12); 1145 Rm = Bits32(opcode, 3, 0); 1146 setflags = BitIsSet(opcode, 20); 1147 shift_n = DecodeImmShiftARM(opcode, shift_t); 1148 break; 1149 default: 1150 return false; 1151 } 1152 bool success = false; 1153 uint32_t value = ReadCoreReg(Rm, &success); 1154 if (!success) 1155 return false; 1156 1157 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1158 if (!success) 1159 return false; 1160 uint32_t result = ~shifted; 1161 1162 // The context specifies that an immediate is to be moved into Rd. 1163 EmulateInstruction::Context context; 1164 context.type = EmulateInstruction::eContextImmediate; 1165 context.SetNoArgs (); 1166 1167 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1168 return false; 1169 } 1170 return true; 1171} 1172 1173// PC relative immediate load into register, possibly followed by ADD (SP plus register). 1174// LDR (literal) 1175bool 1176EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1177{ 1178#if 0 1179 // ARM pseudo code... 1180 if (ConditionPassed()) 1181 { 1182 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1183 base = Align(PC,4); 1184 address = if add then (base + imm32) else (base - imm32); 1185 data = MemU[address,4]; 1186 if t == 15 then 1187 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1188 elsif UnalignedSupport() || address<1:0> = '00' then 1189 R[t] = data; 1190 else // Can only apply before ARMv7 1191 if CurrentInstrSet() == InstrSet_ARM then 1192 R[t] = ROR(data, 8*UInt(address<1:0>)); 1193 else 1194 R[t] = bits(32) UNKNOWN; 1195 } 1196#endif 1197 1198 if (ConditionPassed(opcode)) 1199 { 1200 bool success = false; 1201 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1202 if (!success) 1203 return false; 1204 1205 // PC relative immediate load context 1206 EmulateInstruction::Context context; 1207 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1208 RegisterInfo pc_reg; 1209 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1210 context.SetRegisterPlusOffset (pc_reg, 0); 1211 1212 uint32_t Rt; // the destination register 1213 uint32_t imm32; // immediate offset from the PC 1214 bool add; // +imm32 or -imm32? 1215 addr_t base; // the base address 1216 addr_t address; // the PC relative address 1217 uint32_t data; // the literal data value from the PC relative load 1218 switch (encoding) { 1219 case eEncodingT1: 1220 Rt = Bits32(opcode, 10, 8); 1221 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1222 add = true; 1223 break; 1224 case eEncodingT2: 1225 Rt = Bits32(opcode, 15, 12); 1226 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1227 add = BitIsSet(opcode, 23); 1228 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1229 return false; 1230 break; 1231 default: 1232 return false; 1233 } 1234 1235 base = Align(pc, 4); 1236 if (add) 1237 address = base + imm32; 1238 else 1239 address = base - imm32; 1240 1241 context.SetRegisterPlusOffset(pc_reg, address - base); 1242 data = MemURead(context, address, 4, 0, &success); 1243 if (!success) 1244 return false; 1245 1246 if (Rt == 15) 1247 { 1248 if (Bits32(address, 1, 0) == 0) 1249 { 1250 // In ARMv5T and above, this is an interworking branch. 1251 if (!LoadWritePC(context, data)) 1252 return false; 1253 } 1254 else 1255 return false; 1256 } 1257 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1258 { 1259 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1260 return false; 1261 } 1262 else // We don't handle ARM for now. 1263 return false; 1264 1265 } 1266 return true; 1267} 1268 1269// An add operation to adjust the SP. 1270// ADD (SP plus immediate) 1271bool 1272EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1273{ 1274#if 0 1275 // ARM pseudo code... 1276 if (ConditionPassed()) 1277 { 1278 EncodingSpecificOperations(); 1279 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1280 if d == 15 then // Can only occur for ARM encoding 1281 ALUWritePC(result); // setflags is always FALSE here 1282 else 1283 R[d] = result; 1284 if setflags then 1285 APSR.N = result<31>; 1286 APSR.Z = IsZeroBit(result); 1287 APSR.C = carry; 1288 APSR.V = overflow; 1289 } 1290#endif 1291 1292 bool success = false; 1293 1294 if (ConditionPassed(opcode)) 1295 { 1296 const addr_t sp = ReadCoreReg (SP_REG, &success); 1297 if (!success) 1298 return false; 1299 uint32_t imm32; // the immediate operand 1300 uint32_t d; 1301 //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1 1302 switch (encoding) 1303 { 1304 case eEncodingT1: 1305 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1306 d = Bits32 (opcode, 10, 8); 1307 imm32 = (Bits32 (opcode, 7, 0) << 2); 1308 1309 break; 1310 1311 case eEncodingT2: 1312 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1313 d = 13; 1314 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1315 1316 break; 1317 1318 default: 1319 return false; 1320 } 1321 addr_t sp_offset = imm32; 1322 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1323 1324 EmulateInstruction::Context context; 1325 context.type = EmulateInstruction::eContextAdjustStackPointer; 1326 RegisterInfo sp_reg; 1327 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1328 context.SetRegisterPlusOffset (sp_reg, sp_offset); 1329 1330 if (d == 15) 1331 { 1332 if (!ALUWritePC (context, addr)) 1333 return false; 1334 } 1335 else 1336 { 1337 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr)) 1338 return false; 1339 1340 // Add this back if/when support eEncodingT3 eEncodingA1 1341 //if (setflags) 1342 //{ 1343 // APSR.N = result<31>; 1344 // APSR.Z = IsZeroBit(result); 1345 // APSR.C = carry; 1346 // APSR.V = overflow; 1347 //} 1348 } 1349 } 1350 return true; 1351} 1352 1353// An add operation to adjust the SP. 1354// ADD (SP plus register) 1355bool 1356EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1357{ 1358#if 0 1359 // ARM pseudo code... 1360 if (ConditionPassed()) 1361 { 1362 EncodingSpecificOperations(); 1363 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1364 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1365 if d == 15 then 1366 ALUWritePC(result); // setflags is always FALSE here 1367 else 1368 R[d] = result; 1369 if setflags then 1370 APSR.N = result<31>; 1371 APSR.Z = IsZeroBit(result); 1372 APSR.C = carry; 1373 APSR.V = overflow; 1374 } 1375#endif 1376 1377 bool success = false; 1378 1379 if (ConditionPassed(opcode)) 1380 { 1381 const addr_t sp = ReadCoreReg (SP_REG, &success); 1382 if (!success) 1383 return false; 1384 uint32_t Rm; // the second operand 1385 switch (encoding) { 1386 case eEncodingT2: 1387 Rm = Bits32(opcode, 6, 3); 1388 break; 1389 default: 1390 return false; 1391 } 1392 int32_t reg_value = ReadCoreReg(Rm, &success); 1393 if (!success) 1394 return false; 1395 1396 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1397 1398 EmulateInstruction::Context context; 1399 context.type = eContextArithmetic; 1400 RegisterInfo sp_reg; 1401 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1402 1403 RegisterInfo other_reg; 1404 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1405 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1406 1407 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1408 return false; 1409 } 1410 return true; 1411} 1412 1413// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1414// at a PC-relative address, and changes instruction set from ARM to Thumb, or 1415// from Thumb to ARM. 1416// BLX (immediate) 1417bool 1418EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1419{ 1420#if 0 1421 // ARM pseudo code... 1422 if (ConditionPassed()) 1423 { 1424 EncodingSpecificOperations(); 1425 if CurrentInstrSet() == InstrSet_ARM then 1426 LR = PC - 4; 1427 else 1428 LR = PC<31:1> : '1'; 1429 if targetInstrSet == InstrSet_ARM then 1430 targetAddress = Align(PC,4) + imm32; 1431 else 1432 targetAddress = PC + imm32; 1433 SelectInstrSet(targetInstrSet); 1434 BranchWritePC(targetAddress); 1435 } 1436#endif 1437 1438 bool success = true; 1439 1440 if (ConditionPassed(opcode)) 1441 { 1442 EmulateInstruction::Context context; 1443 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1444 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1445 if (!success) 1446 return false; 1447 addr_t lr; // next instruction address 1448 addr_t target; // target address 1449 int32_t imm32; // PC-relative offset 1450 switch (encoding) { 1451 case eEncodingT1: 1452 { 1453 lr = pc | 1u; // return address 1454 uint32_t S = Bit32(opcode, 26); 1455 uint32_t imm10 = Bits32(opcode, 25, 16); 1456 uint32_t J1 = Bit32(opcode, 13); 1457 uint32_t J2 = Bit32(opcode, 11); 1458 uint32_t imm11 = Bits32(opcode, 10, 0); 1459 uint32_t I1 = !(J1 ^ S); 1460 uint32_t I2 = !(J2 ^ S); 1461 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1462 imm32 = llvm::SignExtend32<25>(imm25); 1463 target = pc + imm32; 1464 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1465 if (InITBlock() && !LastInITBlock()) 1466 return false; 1467 break; 1468 } 1469 case eEncodingT2: 1470 { 1471 lr = pc | 1u; // return address 1472 uint32_t S = Bit32(opcode, 26); 1473 uint32_t imm10H = Bits32(opcode, 25, 16); 1474 uint32_t J1 = Bit32(opcode, 13); 1475 uint32_t J2 = Bit32(opcode, 11); 1476 uint32_t imm10L = Bits32(opcode, 10, 1); 1477 uint32_t I1 = !(J1 ^ S); 1478 uint32_t I2 = !(J2 ^ S); 1479 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1480 imm32 = llvm::SignExtend32<25>(imm25); 1481 target = Align(pc, 4) + imm32; 1482 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1483 if (InITBlock() && !LastInITBlock()) 1484 return false; 1485 break; 1486 } 1487 case eEncodingA1: 1488 lr = pc - 4; // return address 1489 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1490 target = Align(pc, 4) + imm32; 1491 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1492 break; 1493 case eEncodingA2: 1494 lr = pc - 4; // return address 1495 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1496 target = pc + imm32; 1497 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1498 break; 1499 default: 1500 return false; 1501 } 1502 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1503 return false; 1504 if (!BranchWritePC(context, target)) 1505 return false; 1506 } 1507 return true; 1508} 1509 1510// Branch with Link and Exchange (register) calls a subroutine at an address and 1511// instruction set specified by a register. 1512// BLX (register) 1513bool 1514EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1515{ 1516#if 0 1517 // ARM pseudo code... 1518 if (ConditionPassed()) 1519 { 1520 EncodingSpecificOperations(); 1521 target = R[m]; 1522 if CurrentInstrSet() == InstrSet_ARM then 1523 next_instr_addr = PC - 4; 1524 LR = next_instr_addr; 1525 else 1526 next_instr_addr = PC - 2; 1527 LR = next_instr_addr<31:1> : '1'; 1528 BXWritePC(target); 1529 } 1530#endif 1531 1532 bool success = false; 1533 1534 if (ConditionPassed(opcode)) 1535 { 1536 EmulateInstruction::Context context; 1537 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1538 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1539 addr_t lr; // next instruction address 1540 if (!success) 1541 return false; 1542 uint32_t Rm; // the register with the target address 1543 switch (encoding) { 1544 case eEncodingT1: 1545 lr = (pc - 2) | 1u; // return address 1546 Rm = Bits32(opcode, 6, 3); 1547 // if m == 15 then UNPREDICTABLE; 1548 if (Rm == 15) 1549 return false; 1550 if (InITBlock() && !LastInITBlock()) 1551 return false; 1552 break; 1553 case eEncodingA1: 1554 lr = pc - 4; // return address 1555 Rm = Bits32(opcode, 3, 0); 1556 // if m == 15 then UNPREDICTABLE; 1557 if (Rm == 15) 1558 return false; 1559 break; 1560 default: 1561 return false; 1562 } 1563 addr_t target = ReadCoreReg (Rm, &success); 1564 if (!success) 1565 return false; 1566 RegisterInfo dwarf_reg; 1567 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1568 context.SetRegister (dwarf_reg); 1569 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1570 return false; 1571 if (!BXWritePC(context, target)) 1572 return false; 1573 } 1574 return true; 1575} 1576 1577// Branch and Exchange causes a branch to an address and instruction set specified by a register. 1578bool 1579EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1580{ 1581#if 0 1582 // ARM pseudo code... 1583 if (ConditionPassed()) 1584 { 1585 EncodingSpecificOperations(); 1586 BXWritePC(R[m]); 1587 } 1588#endif 1589 1590 if (ConditionPassed(opcode)) 1591 { 1592 EmulateInstruction::Context context; 1593 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1594 uint32_t Rm; // the register with the target address 1595 switch (encoding) { 1596 case eEncodingT1: 1597 Rm = Bits32(opcode, 6, 3); 1598 if (InITBlock() && !LastInITBlock()) 1599 return false; 1600 break; 1601 case eEncodingA1: 1602 Rm = Bits32(opcode, 3, 0); 1603 break; 1604 default: 1605 return false; 1606 } 1607 bool success = false; 1608 addr_t target = ReadCoreReg (Rm, &success); 1609 if (!success) 1610 return false; 1611 1612 RegisterInfo dwarf_reg; 1613 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1614 context.SetRegister (dwarf_reg); 1615 if (!BXWritePC(context, target)) 1616 return false; 1617 } 1618 return true; 1619} 1620 1621// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1622// address and instruction set specified by a register as though it were a BX instruction. 1623// 1624// TODO: Emulate Jazelle architecture? 1625// We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1626bool 1627EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1628{ 1629#if 0 1630 // ARM pseudo code... 1631 if (ConditionPassed()) 1632 { 1633 EncodingSpecificOperations(); 1634 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1635 BXWritePC(R[m]); 1636 else 1637 if JazelleAcceptsExecution() then 1638 SwitchToJazelleExecution(); 1639 else 1640 SUBARCHITECTURE_DEFINED handler call; 1641 } 1642#endif 1643 1644 if (ConditionPassed(opcode)) 1645 { 1646 EmulateInstruction::Context context; 1647 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1648 uint32_t Rm; // the register with the target address 1649 switch (encoding) { 1650 case eEncodingT1: 1651 Rm = Bits32(opcode, 19, 16); 1652 if (BadReg(Rm)) 1653 return false; 1654 if (InITBlock() && !LastInITBlock()) 1655 return false; 1656 break; 1657 case eEncodingA1: 1658 Rm = Bits32(opcode, 3, 0); 1659 if (Rm == 15) 1660 return false; 1661 break; 1662 default: 1663 return false; 1664 } 1665 bool success = false; 1666 addr_t target = ReadCoreReg (Rm, &success); 1667 if (!success) 1668 return false; 1669 1670 RegisterInfo dwarf_reg; 1671 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1672 context.SetRegister (dwarf_reg); 1673 if (!BXWritePC(context, target)) 1674 return false; 1675 } 1676 return true; 1677} 1678 1679// Set r7 to point to some ip offset. 1680// SUB (immediate) 1681bool 1682EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1683{ 1684#if 0 1685 // ARM pseudo code... 1686 if (ConditionPassed()) 1687 { 1688 EncodingSpecificOperations(); 1689 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1690 if d == 15 then // Can only occur for ARM encoding 1691 ALUWritePC(result); // setflags is always FALSE here 1692 else 1693 R[d] = result; 1694 if setflags then 1695 APSR.N = result<31>; 1696 APSR.Z = IsZeroBit(result); 1697 APSR.C = carry; 1698 APSR.V = overflow; 1699 } 1700#endif 1701 1702 if (ConditionPassed(opcode)) 1703 { 1704 bool success = false; 1705 const addr_t ip = ReadCoreReg (12, &success); 1706 if (!success) 1707 return false; 1708 uint32_t imm32; 1709 switch (encoding) { 1710 case eEncodingA1: 1711 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1712 break; 1713 default: 1714 return false; 1715 } 1716 addr_t ip_offset = imm32; 1717 addr_t addr = ip - ip_offset; // the adjusted ip value 1718 1719 EmulateInstruction::Context context; 1720 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1721 RegisterInfo dwarf_reg; 1722 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1723 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1724 1725 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1726 return false; 1727 } 1728 return true; 1729} 1730 1731// Set ip to point to some stack offset. 1732// SUB (SP minus immediate) 1733bool 1734EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1735{ 1736#if 0 1737 // ARM pseudo code... 1738 if (ConditionPassed()) 1739 { 1740 EncodingSpecificOperations(); 1741 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1742 if d == 15 then // Can only occur for ARM encoding 1743 ALUWritePC(result); // setflags is always FALSE here 1744 else 1745 R[d] = result; 1746 if setflags then 1747 APSR.N = result<31>; 1748 APSR.Z = IsZeroBit(result); 1749 APSR.C = carry; 1750 APSR.V = overflow; 1751 } 1752#endif 1753 1754 if (ConditionPassed(opcode)) 1755 { 1756 bool success = false; 1757 const addr_t sp = ReadCoreReg (SP_REG, &success); 1758 if (!success) 1759 return false; 1760 uint32_t imm32; 1761 switch (encoding) { 1762 case eEncodingA1: 1763 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1764 break; 1765 default: 1766 return false; 1767 } 1768 addr_t sp_offset = imm32; 1769 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1770 1771 EmulateInstruction::Context context; 1772 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1773 RegisterInfo dwarf_reg; 1774 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1775 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1776 1777 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1778 return false; 1779 } 1780 return true; 1781} 1782 1783// This instruction subtracts an immediate value from the SP value, and writes 1784// the result to the destination register. 1785// 1786// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1787bool 1788EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1789{ 1790#if 0 1791 // ARM pseudo code... 1792 if (ConditionPassed()) 1793 { 1794 EncodingSpecificOperations(); 1795 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1796 if d == 15 then // Can only occur for ARM encoding 1797 ALUWritePC(result); // setflags is always FALSE here 1798 else 1799 R[d] = result; 1800 if setflags then 1801 APSR.N = result<31>; 1802 APSR.Z = IsZeroBit(result); 1803 APSR.C = carry; 1804 APSR.V = overflow; 1805 } 1806#endif 1807 1808 bool success = false; 1809 if (ConditionPassed(opcode)) 1810 { 1811 const addr_t sp = ReadCoreReg (SP_REG, &success); 1812 if (!success) 1813 return false; 1814 1815 uint32_t Rd; 1816 bool setflags; 1817 uint32_t imm32; 1818 switch (encoding) { 1819 case eEncodingT1: 1820 Rd = 13; 1821 setflags = false; 1822 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1823 break; 1824 case eEncodingT2: 1825 Rd = Bits32(opcode, 11, 8); 1826 setflags = BitIsSet(opcode, 20); 1827 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1828 if (Rd == 15 && setflags) 1829 return EmulateCMPImm(opcode, eEncodingT2); 1830 if (Rd == 15 && !setflags) 1831 return false; 1832 break; 1833 case eEncodingT3: 1834 Rd = Bits32(opcode, 11, 8); 1835 setflags = false; 1836 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1837 if (Rd == 15) 1838 return false; 1839 break; 1840 case eEncodingA1: 1841 Rd = Bits32(opcode, 15, 12); 1842 setflags = BitIsSet(opcode, 20); 1843 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1844 1845 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1846 if (Rd == 15 && setflags) 1847 return EmulateSUBSPcLrEtc (opcode, encoding); 1848 break; 1849 default: 1850 return false; 1851 } 1852 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1853 1854 EmulateInstruction::Context context; 1855 if (Rd == 13) 1856 { 1857 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1858 // value gets passed down to context.SetImmediateSigned. 1859 context.type = EmulateInstruction::eContextAdjustStackPointer; 1860 context.SetImmediateSigned (-imm64); // the stack pointer offset 1861 } 1862 else 1863 { 1864 context.type = EmulateInstruction::eContextImmediate; 1865 context.SetNoArgs (); 1866 } 1867 1868 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1869 return false; 1870 } 1871 return true; 1872} 1873 1874// A store operation to the stack that also updates the SP. 1875bool 1876EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1877{ 1878#if 0 1879 // ARM pseudo code... 1880 if (ConditionPassed()) 1881 { 1882 EncodingSpecificOperations(); 1883 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1884 address = if index then offset_addr else R[n]; 1885 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1886 if wback then R[n] = offset_addr; 1887 } 1888#endif 1889 1890 bool conditional = false; 1891 bool success = false; 1892 if (ConditionPassed(opcode, &conditional)) 1893 { 1894 const uint32_t addr_byte_size = GetAddressByteSize(); 1895 const addr_t sp = ReadCoreReg (SP_REG, &success); 1896 if (!success) 1897 return false; 1898 uint32_t Rt; // the source register 1899 uint32_t imm12; 1900 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1901 1902 bool index; 1903 bool add; 1904 bool wback; 1905 switch (encoding) { 1906 case eEncodingA1: 1907 Rt = Bits32(opcode, 15, 12); 1908 imm12 = Bits32(opcode, 11, 0); 1909 Rn = Bits32 (opcode, 19, 16); 1910 1911 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1912 return false; 1913 1914 index = BitIsSet (opcode, 24); 1915 add = BitIsSet (opcode, 23); 1916 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1917 1918 if (wback && ((Rn == 15) || (Rn == Rt))) 1919 return false; 1920 break; 1921 default: 1922 return false; 1923 } 1924 addr_t offset_addr; 1925 if (add) 1926 offset_addr = sp + imm12; 1927 else 1928 offset_addr = sp - imm12; 1929 1930 addr_t addr; 1931 if (index) 1932 addr = offset_addr; 1933 else 1934 addr = sp; 1935 1936 EmulateInstruction::Context context; 1937 if (conditional) 1938 context.type = EmulateInstruction::eContextRegisterStore; 1939 else 1940 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1941 RegisterInfo sp_reg; 1942 RegisterInfo dwarf_reg; 1943 1944 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1945 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 1946 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 1947 if (Rt != 15) 1948 { 1949 uint32_t reg_value = ReadCoreReg(Rt, &success); 1950 if (!success) 1951 return false; 1952 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1953 return false; 1954 } 1955 else 1956 { 1957 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1958 if (!success) 1959 return false; 1960 if (!MemUWrite (context, addr, pc, addr_byte_size)) 1961 return false; 1962 } 1963 1964 1965 if (wback) 1966 { 1967 context.type = EmulateInstruction::eContextAdjustStackPointer; 1968 context.SetImmediateSigned (addr - sp); 1969 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 1970 return false; 1971 } 1972 } 1973 return true; 1974} 1975 1976// Vector Push stores multiple extension registers to the stack. 1977// It also updates SP to point to the start of the stored data. 1978bool 1979EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 1980{ 1981#if 0 1982 // ARM pseudo code... 1983 if (ConditionPassed()) 1984 { 1985 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1986 address = SP - imm32; 1987 SP = SP - imm32; 1988 if single_regs then 1989 for r = 0 to regs-1 1990 MemA[address,4] = S[d+r]; address = address+4; 1991 else 1992 for r = 0 to regs-1 1993 // Store as two word-aligned words in the correct order for current endianness. 1994 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1995 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1996 address = address+8; 1997 } 1998#endif 1999 2000 bool success = false; 2001 bool conditional = false; 2002 if (ConditionPassed(opcode, &conditional)) 2003 { 2004 const uint32_t addr_byte_size = GetAddressByteSize(); 2005 const addr_t sp = ReadCoreReg (SP_REG, &success); 2006 if (!success) 2007 return false; 2008 bool single_regs; 2009 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2010 uint32_t imm32; // stack offset 2011 uint32_t regs; // number of registers 2012 switch (encoding) { 2013 case eEncodingT1: 2014 case eEncodingA1: 2015 single_regs = false; 2016 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2017 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2018 // If UInt(imm8) is odd, see "FSTMX". 2019 regs = Bits32(opcode, 7, 0) / 2; 2020 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2021 if (regs == 0 || regs > 16 || (d + regs) > 32) 2022 return false; 2023 break; 2024 case eEncodingT2: 2025 case eEncodingA2: 2026 single_regs = true; 2027 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2028 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2029 regs = Bits32(opcode, 7, 0); 2030 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2031 if (regs == 0 || regs > 16 || (d + regs) > 32) 2032 return false; 2033 break; 2034 default: 2035 return false; 2036 } 2037 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2038 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2039 addr_t sp_offset = imm32; 2040 addr_t addr = sp - sp_offset; 2041 uint32_t i; 2042 2043 EmulateInstruction::Context context; 2044 if (conditional) 2045 context.type = EmulateInstruction::eContextRegisterStore; 2046 else 2047 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2048 RegisterInfo dwarf_reg; 2049 RegisterInfo sp_reg; 2050 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2051 for (i=0; i<regs; ++i) 2052 { 2053 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2054 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2055 // uint64_t to accommodate 64-bit registers. 2056 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2057 if (!success) 2058 return false; 2059 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2060 return false; 2061 addr += reg_byte_size; 2062 } 2063 2064 context.type = EmulateInstruction::eContextAdjustStackPointer; 2065 context.SetImmediateSigned (-sp_offset); 2066 2067 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2068 return false; 2069 } 2070 return true; 2071} 2072 2073// Vector Pop loads multiple extension registers from the stack. 2074// It also updates SP to point just above the loaded data. 2075bool 2076EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2077{ 2078#if 0 2079 // ARM pseudo code... 2080 if (ConditionPassed()) 2081 { 2082 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2083 address = SP; 2084 SP = SP + imm32; 2085 if single_regs then 2086 for r = 0 to regs-1 2087 S[d+r] = MemA[address,4]; address = address+4; 2088 else 2089 for r = 0 to regs-1 2090 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2091 // Combine the word-aligned words in the correct order for current endianness. 2092 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2093 } 2094#endif 2095 2096 bool success = false; 2097 bool conditional = false; 2098 if (ConditionPassed(opcode, &conditional)) 2099 { 2100 const uint32_t addr_byte_size = GetAddressByteSize(); 2101 const addr_t sp = ReadCoreReg (SP_REG, &success); 2102 if (!success) 2103 return false; 2104 bool single_regs; 2105 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2106 uint32_t imm32; // stack offset 2107 uint32_t regs; // number of registers 2108 switch (encoding) { 2109 case eEncodingT1: 2110 case eEncodingA1: 2111 single_regs = false; 2112 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2113 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2114 // If UInt(imm8) is odd, see "FLDMX". 2115 regs = Bits32(opcode, 7, 0) / 2; 2116 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2117 if (regs == 0 || regs > 16 || (d + regs) > 32) 2118 return false; 2119 break; 2120 case eEncodingT2: 2121 case eEncodingA2: 2122 single_regs = true; 2123 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2124 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2125 regs = Bits32(opcode, 7, 0); 2126 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2127 if (regs == 0 || regs > 16 || (d + regs) > 32) 2128 return false; 2129 break; 2130 default: 2131 return false; 2132 } 2133 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2134 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2135 addr_t sp_offset = imm32; 2136 addr_t addr = sp; 2137 uint32_t i; 2138 uint64_t data; // uint64_t to accomodate 64-bit registers. 2139 2140 EmulateInstruction::Context context; 2141 if (conditional) 2142 context.type = EmulateInstruction::eContextRegisterLoad; 2143 else 2144 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2145 RegisterInfo dwarf_reg; 2146 RegisterInfo sp_reg; 2147 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2148 for (i=0; i<regs; ++i) 2149 { 2150 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2151 context.SetRegisterPlusOffset (sp_reg, addr - sp); 2152 data = MemARead(context, addr, reg_byte_size, 0, &success); 2153 if (!success) 2154 return false; 2155 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2156 return false; 2157 addr += reg_byte_size; 2158 } 2159 2160 context.type = EmulateInstruction::eContextAdjustStackPointer; 2161 context.SetImmediateSigned (sp_offset); 2162 2163 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2164 return false; 2165 } 2166 return true; 2167} 2168 2169// SVC (previously SWI) 2170bool 2171EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2172{ 2173#if 0 2174 // ARM pseudo code... 2175 if (ConditionPassed()) 2176 { 2177 EncodingSpecificOperations(); 2178 CallSupervisor(); 2179 } 2180#endif 2181 2182 bool success = false; 2183 2184 if (ConditionPassed(opcode)) 2185 { 2186 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2187 addr_t lr; // next instruction address 2188 if (!success) 2189 return false; 2190 uint32_t imm32; // the immediate constant 2191 uint32_t mode; // ARM or Thumb mode 2192 switch (encoding) { 2193 case eEncodingT1: 2194 lr = (pc + 2) | 1u; // return address 2195 imm32 = Bits32(opcode, 7, 0); 2196 mode = eModeThumb; 2197 break; 2198 case eEncodingA1: 2199 lr = pc + 4; // return address 2200 imm32 = Bits32(opcode, 23, 0); 2201 mode = eModeARM; 2202 break; 2203 default: 2204 return false; 2205 } 2206 2207 EmulateInstruction::Context context; 2208 context.type = EmulateInstruction::eContextSupervisorCall; 2209 context.SetISAAndImmediate (mode, imm32); 2210 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2211 return false; 2212 } 2213 return true; 2214} 2215 2216// If Then makes up to four following instructions (the IT block) conditional. 2217bool 2218EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2219{ 2220#if 0 2221 // ARM pseudo code... 2222 EncodingSpecificOperations(); 2223 ITSTATE.IT<7:0> = firstcond:mask; 2224#endif 2225 2226 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2227 return true; 2228} 2229 2230bool 2231EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2232{ 2233 // NOP, nothing to do... 2234 return true; 2235} 2236 2237// Branch causes a branch to a target address. 2238bool 2239EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2240{ 2241#if 0 2242 // ARM pseudo code... 2243 if (ConditionPassed()) 2244 { 2245 EncodingSpecificOperations(); 2246 BranchWritePC(PC + imm32); 2247 } 2248#endif 2249 2250 bool success = false; 2251 2252 if (ConditionPassed(opcode)) 2253 { 2254 EmulateInstruction::Context context; 2255 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2256 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2257 if (!success) 2258 return false; 2259 addr_t target; // target address 2260 int32_t imm32; // PC-relative offset 2261 switch (encoding) { 2262 case eEncodingT1: 2263 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2264 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2265 target = pc + imm32; 2266 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2267 break; 2268 case eEncodingT2: 2269 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2270 target = pc + imm32; 2271 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2272 break; 2273 case eEncodingT3: 2274 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2275 { 2276 uint32_t S = Bit32(opcode, 26); 2277 uint32_t imm6 = Bits32(opcode, 21, 16); 2278 uint32_t J1 = Bit32(opcode, 13); 2279 uint32_t J2 = Bit32(opcode, 11); 2280 uint32_t imm11 = Bits32(opcode, 10, 0); 2281 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2282 imm32 = llvm::SignExtend32<21>(imm21); 2283 target = pc + imm32; 2284 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2285 break; 2286 } 2287 case eEncodingT4: 2288 { 2289 uint32_t S = Bit32(opcode, 26); 2290 uint32_t imm10 = Bits32(opcode, 25, 16); 2291 uint32_t J1 = Bit32(opcode, 13); 2292 uint32_t J2 = Bit32(opcode, 11); 2293 uint32_t imm11 = Bits32(opcode, 10, 0); 2294 uint32_t I1 = !(J1 ^ S); 2295 uint32_t I2 = !(J2 ^ S); 2296 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2297 imm32 = llvm::SignExtend32<25>(imm25); 2298 target = pc + imm32; 2299 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2300 break; 2301 } 2302 case eEncodingA1: 2303 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2304 target = pc + imm32; 2305 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2306 break; 2307 default: 2308 return false; 2309 } 2310 if (!BranchWritePC(context, target)) 2311 return false; 2312 } 2313 return true; 2314} 2315 2316// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2317// zero and conditionally branch forward a constant value. They do not affect the condition flags. 2318// CBNZ, CBZ 2319bool 2320EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2321{ 2322#if 0 2323 // ARM pseudo code... 2324 EncodingSpecificOperations(); 2325 if nonzero ^ IsZero(R[n]) then 2326 BranchWritePC(PC + imm32); 2327#endif 2328 2329 bool success = false; 2330 2331 // Read the register value from the operand register Rn. 2332 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2333 if (!success) 2334 return false; 2335 2336 EmulateInstruction::Context context; 2337 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2338 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2339 if (!success) 2340 return false; 2341 2342 addr_t target; // target address 2343 uint32_t imm32; // PC-relative offset to branch forward 2344 bool nonzero; 2345 switch (encoding) { 2346 case eEncodingT1: 2347 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2348 nonzero = BitIsSet(opcode, 11); 2349 target = pc + imm32; 2350 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2351 break; 2352 default: 2353 return false; 2354 } 2355 if (nonzero ^ (reg_val == 0)) 2356 if (!BranchWritePC(context, target)) 2357 return false; 2358 2359 return true; 2360} 2361 2362// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2363// A base register provides a pointer to the table, and a second register supplies an index into the table. 2364// The branch length is twice the value of the byte returned from the table. 2365// 2366// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2367// A base register provides a pointer to the table, and a second register supplies an index into the table. 2368// The branch length is twice the value of the halfword returned from the table. 2369// TBB, TBH 2370bool 2371EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2372{ 2373#if 0 2374 // ARM pseudo code... 2375 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2376 if is_tbh then 2377 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2378 else 2379 halfwords = UInt(MemU[R[n]+R[m], 1]); 2380 BranchWritePC(PC + 2*halfwords); 2381#endif 2382 2383 bool success = false; 2384 2385 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2386 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2387 bool is_tbh; // true if table branch halfword 2388 switch (encoding) { 2389 case eEncodingT1: 2390 Rn = Bits32(opcode, 19, 16); 2391 Rm = Bits32(opcode, 3, 0); 2392 is_tbh = BitIsSet(opcode, 4); 2393 if (Rn == 13 || BadReg(Rm)) 2394 return false; 2395 if (InITBlock() && !LastInITBlock()) 2396 return false; 2397 break; 2398 default: 2399 return false; 2400 } 2401 2402 // Read the address of the table from the operand register Rn. 2403 // The PC can be used, in which case the table immediately follows this instruction. 2404 uint32_t base = ReadCoreReg(Rm, &success); 2405 if (!success) 2406 return false; 2407 2408 // the table index 2409 uint32_t index = ReadCoreReg(Rm, &success); 2410 if (!success) 2411 return false; 2412 2413 // the offsetted table address 2414 addr_t addr = base + (is_tbh ? index*2 : index); 2415 2416 // PC-relative offset to branch forward 2417 EmulateInstruction::Context context; 2418 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2419 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2420 if (!success) 2421 return false; 2422 2423 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2424 if (!success) 2425 return false; 2426 2427 // target address 2428 addr_t target = pc + offset; 2429 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2430 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2431 2432 if (!BranchWritePC(context, target)) 2433 return false; 2434 2435 return true; 2436} 2437 2438// This instruction adds an immediate value to a register value, and writes the result to the destination register. 2439// It can optionally update the condition flags based on the result. 2440bool 2441EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2442{ 2443#if 0 2444 if ConditionPassed() then 2445 EncodingSpecificOperations(); 2446 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2447 R[d] = result; 2448 if setflags then 2449 APSR.N = result<31>; 2450 APSR.Z = IsZeroBit(result); 2451 APSR.C = carry; 2452 APSR.V = overflow; 2453#endif 2454 2455 bool success = false; 2456 2457 if (ConditionPassed(opcode)) 2458 { 2459 uint32_t d; 2460 uint32_t n; 2461 bool setflags; 2462 uint32_t imm32; 2463 uint32_t carry_out; 2464 2465 //EncodingSpecificOperations(); 2466 switch (encoding) 2467 { 2468 case eEncodingT1: 2469 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2470 d = Bits32 (opcode, 2, 0); 2471 n = Bits32 (opcode, 5, 3); 2472 setflags = !InITBlock(); 2473 imm32 = Bits32 (opcode, 8,6); 2474 2475 break; 2476 2477 case eEncodingT2: 2478 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2479 d = Bits32 (opcode, 10, 8); 2480 n = Bits32 (opcode, 10, 8); 2481 setflags = !InITBlock(); 2482 imm32 = Bits32 (opcode, 7, 0); 2483 2484 break; 2485 2486 case eEncodingT3: 2487 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2488 // if Rn == '1101' then SEE ADD (SP plus immediate); 2489 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2490 d = Bits32 (opcode, 11, 8); 2491 n = Bits32 (opcode, 19, 16); 2492 setflags = BitIsSet (opcode, 20); 2493 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2494 2495 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2496 if (BadReg (d) || (n == 15)) 2497 return false; 2498 2499 break; 2500 2501 case eEncodingT4: 2502 { 2503 // if Rn == '1111' then SEE ADR; 2504 // if Rn == '1101' then SEE ADD (SP plus immediate); 2505 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2506 d = Bits32 (opcode, 11, 8); 2507 n = Bits32 (opcode, 19, 16); 2508 setflags = false; 2509 uint32_t i = Bit32 (opcode, 26); 2510 uint32_t imm3 = Bits32 (opcode, 14, 12); 2511 uint32_t imm8 = Bits32 (opcode, 7, 0); 2512 imm32 = (i << 11) | (imm3 << 8) | imm8; 2513 2514 // if BadReg(d) then UNPREDICTABLE; 2515 if (BadReg (d)) 2516 return false; 2517 2518 break; 2519 } 2520 default: 2521 return false; 2522 } 2523 2524 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2525 if (!success) 2526 return false; 2527 2528 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2529 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2530 2531 RegisterInfo reg_n; 2532 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2533 2534 EmulateInstruction::Context context; 2535 context.type = eContextArithmetic; 2536 context.SetRegisterPlusOffset (reg_n, imm32); 2537 2538 //R[d] = result; 2539 //if setflags then 2540 //APSR.N = result<31>; 2541 //APSR.Z = IsZeroBit(result); 2542 //APSR.C = carry; 2543 //APSR.V = overflow; 2544 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2545 return false; 2546 2547 } 2548 return true; 2549} 2550 2551// This instruction adds an immediate value to a register value, and writes the result to the destination 2552// register. It can optionally update the condition flags based on the result. 2553bool 2554EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2555{ 2556#if 0 2557 // ARM pseudo code... 2558 if ConditionPassed() then 2559 EncodingSpecificOperations(); 2560 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2561 if d == 15 then 2562 ALUWritePC(result); // setflags is always FALSE here 2563 else 2564 R[d] = result; 2565 if setflags then 2566 APSR.N = result<31>; 2567 APSR.Z = IsZeroBit(result); 2568 APSR.C = carry; 2569 APSR.V = overflow; 2570#endif 2571 2572 bool success = false; 2573 2574 if (ConditionPassed(opcode)) 2575 { 2576 uint32_t Rd, Rn; 2577 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2578 bool setflags; 2579 switch (encoding) 2580 { 2581 case eEncodingA1: 2582 Rd = Bits32(opcode, 15, 12); 2583 Rn = Bits32(opcode, 19, 16); 2584 setflags = BitIsSet(opcode, 20); 2585 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2586 break; 2587 default: 2588 return false; 2589 } 2590 2591 // Read the first operand. 2592 uint32_t val1 = ReadCoreReg(Rn, &success); 2593 if (!success) 2594 return false; 2595 2596 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2597 2598 EmulateInstruction::Context context; 2599 context.type = eContextArithmetic; 2600 RegisterInfo dwarf_reg; 2601 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2602 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2603 2604 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2605 return false; 2606 } 2607 return true; 2608} 2609 2610// This instruction adds a register value and an optionally-shifted register value, and writes the result 2611// to the destination register. It can optionally update the condition flags based on the result. 2612bool 2613EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2614{ 2615#if 0 2616 // ARM pseudo code... 2617 if ConditionPassed() then 2618 EncodingSpecificOperations(); 2619 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2620 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2621 if d == 15 then 2622 ALUWritePC(result); // setflags is always FALSE here 2623 else 2624 R[d] = result; 2625 if setflags then 2626 APSR.N = result<31>; 2627 APSR.Z = IsZeroBit(result); 2628 APSR.C = carry; 2629 APSR.V = overflow; 2630#endif 2631 2632 bool success = false; 2633 2634 if (ConditionPassed(opcode)) 2635 { 2636 uint32_t Rd, Rn, Rm; 2637 ARM_ShifterType shift_t; 2638 uint32_t shift_n; // the shift applied to the value read from Rm 2639 bool setflags; 2640 switch (encoding) 2641 { 2642 case eEncodingT1: 2643 Rd = Bits32(opcode, 2, 0); 2644 Rn = Bits32(opcode, 5, 3); 2645 Rm = Bits32(opcode, 8, 6); 2646 setflags = !InITBlock(); 2647 shift_t = SRType_LSL; 2648 shift_n = 0; 2649 break; 2650 case eEncodingT2: 2651 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2652 Rm = Bits32(opcode, 6, 3); 2653 setflags = false; 2654 shift_t = SRType_LSL; 2655 shift_n = 0; 2656 if (Rn == 15 && Rm == 15) 2657 return false; 2658 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2659 return false; 2660 break; 2661 case eEncodingA1: 2662 Rd = Bits32(opcode, 15, 12); 2663 Rn = Bits32(opcode, 19, 16); 2664 Rm = Bits32(opcode, 3, 0); 2665 setflags = BitIsSet(opcode, 20); 2666 shift_n = DecodeImmShiftARM(opcode, shift_t); 2667 break; 2668 default: 2669 return false; 2670 } 2671 2672 // Read the first operand. 2673 uint32_t val1 = ReadCoreReg(Rn, &success); 2674 if (!success) 2675 return false; 2676 2677 // Read the second operand. 2678 uint32_t val2 = ReadCoreReg(Rm, &success); 2679 if (!success) 2680 return false; 2681 2682 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2683 if (!success) 2684 return false; 2685 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2686 2687 EmulateInstruction::Context context; 2688 context.type = eContextArithmetic; 2689 RegisterInfo op1_reg; 2690 RegisterInfo op2_reg; 2691 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2692 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2693 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2694 2695 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2696 return false; 2697 } 2698 return true; 2699} 2700 2701// Compare Negative (immediate) adds a register value and an immediate value. 2702// It updates the condition flags based on the result, and discards the result. 2703bool 2704EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2705{ 2706#if 0 2707 // ARM pseudo code... 2708 if ConditionPassed() then 2709 EncodingSpecificOperations(); 2710 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2711 APSR.N = result<31>; 2712 APSR.Z = IsZeroBit(result); 2713 APSR.C = carry; 2714 APSR.V = overflow; 2715#endif 2716 2717 bool success = false; 2718 2719 uint32_t Rn; // the first operand 2720 uint32_t imm32; // the immediate value to be compared with 2721 switch (encoding) { 2722 case eEncodingT1: 2723 Rn = Bits32(opcode, 19, 16); 2724 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2725 if (Rn == 15) 2726 return false; 2727 break; 2728 case eEncodingA1: 2729 Rn = Bits32(opcode, 19, 16); 2730 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2731 break; 2732 default: 2733 return false; 2734 } 2735 // Read the register value from the operand register Rn. 2736 uint32_t reg_val = ReadCoreReg(Rn, &success); 2737 if (!success) 2738 return false; 2739 2740 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2741 2742 EmulateInstruction::Context context; 2743 context.type = EmulateInstruction::eContextImmediate; 2744 context.SetNoArgs (); 2745 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2746 return false; 2747 2748 return true; 2749} 2750 2751// Compare Negative (register) adds a register value and an optionally-shifted register value. 2752// It updates the condition flags based on the result, and discards the result. 2753bool 2754EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2755{ 2756#if 0 2757 // ARM pseudo code... 2758 if ConditionPassed() then 2759 EncodingSpecificOperations(); 2760 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2761 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2762 APSR.N = result<31>; 2763 APSR.Z = IsZeroBit(result); 2764 APSR.C = carry; 2765 APSR.V = overflow; 2766#endif 2767 2768 bool success = false; 2769 2770 uint32_t Rn; // the first operand 2771 uint32_t Rm; // the second operand 2772 ARM_ShifterType shift_t; 2773 uint32_t shift_n; // the shift applied to the value read from Rm 2774 switch (encoding) { 2775 case eEncodingT1: 2776 Rn = Bits32(opcode, 2, 0); 2777 Rm = Bits32(opcode, 5, 3); 2778 shift_t = SRType_LSL; 2779 shift_n = 0; 2780 break; 2781 case eEncodingT2: 2782 Rn = Bits32(opcode, 19, 16); 2783 Rm = Bits32(opcode, 3, 0); 2784 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2785 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2786 if (Rn == 15 || BadReg(Rm)) 2787 return false; 2788 break; 2789 case eEncodingA1: 2790 Rn = Bits32(opcode, 19, 16); 2791 Rm = Bits32(opcode, 3, 0); 2792 shift_n = DecodeImmShiftARM(opcode, shift_t); 2793 break; 2794 default: 2795 return false; 2796 } 2797 // Read the register value from register Rn. 2798 uint32_t val1 = ReadCoreReg(Rn, &success); 2799 if (!success) 2800 return false; 2801 2802 // Read the register value from register Rm. 2803 uint32_t val2 = ReadCoreReg(Rm, &success); 2804 if (!success) 2805 return false; 2806 2807 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2808 if (!success) 2809 return false; 2810 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2811 2812 EmulateInstruction::Context context; 2813 context.type = EmulateInstruction::eContextImmediate; 2814 context.SetNoArgs(); 2815 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2816 return false; 2817 2818 return true; 2819} 2820 2821// Compare (immediate) subtracts an immediate value from a register value. 2822// It updates the condition flags based on the result, and discards the result. 2823bool 2824EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2825{ 2826#if 0 2827 // ARM pseudo code... 2828 if ConditionPassed() then 2829 EncodingSpecificOperations(); 2830 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2831 APSR.N = result<31>; 2832 APSR.Z = IsZeroBit(result); 2833 APSR.C = carry; 2834 APSR.V = overflow; 2835#endif 2836 2837 bool success = false; 2838 2839 uint32_t Rn; // the first operand 2840 uint32_t imm32; // the immediate value to be compared with 2841 switch (encoding) { 2842 case eEncodingT1: 2843 Rn = Bits32(opcode, 10, 8); 2844 imm32 = Bits32(opcode, 7, 0); 2845 break; 2846 case eEncodingT2: 2847 Rn = Bits32(opcode, 19, 16); 2848 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2849 if (Rn == 15) 2850 return false; 2851 break; 2852 case eEncodingA1: 2853 Rn = Bits32(opcode, 19, 16); 2854 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2855 break; 2856 default: 2857 return false; 2858 } 2859 // Read the register value from the operand register Rn. 2860 uint32_t reg_val = ReadCoreReg(Rn, &success); 2861 if (!success) 2862 return false; 2863 2864 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2865 2866 EmulateInstruction::Context context; 2867 context.type = EmulateInstruction::eContextImmediate; 2868 context.SetNoArgs (); 2869 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2870 return false; 2871 2872 return true; 2873} 2874 2875// Compare (register) subtracts an optionally-shifted register value from a register value. 2876// It updates the condition flags based on the result, and discards the result. 2877bool 2878EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2879{ 2880#if 0 2881 // ARM pseudo code... 2882 if ConditionPassed() then 2883 EncodingSpecificOperations(); 2884 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2885 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2886 APSR.N = result<31>; 2887 APSR.Z = IsZeroBit(result); 2888 APSR.C = carry; 2889 APSR.V = overflow; 2890#endif 2891 2892 bool success = false; 2893 2894 uint32_t Rn; // the first operand 2895 uint32_t Rm; // the second operand 2896 ARM_ShifterType shift_t; 2897 uint32_t shift_n; // the shift applied to the value read from Rm 2898 switch (encoding) { 2899 case eEncodingT1: 2900 Rn = Bits32(opcode, 2, 0); 2901 Rm = Bits32(opcode, 5, 3); 2902 shift_t = SRType_LSL; 2903 shift_n = 0; 2904 break; 2905 case eEncodingT2: 2906 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2907 Rm = Bits32(opcode, 6, 3); 2908 shift_t = SRType_LSL; 2909 shift_n = 0; 2910 if (Rn < 8 && Rm < 8) 2911 return false; 2912 if (Rn == 15 || Rm == 15) 2913 return false; 2914 break; 2915 case eEncodingA1: 2916 Rn = Bits32(opcode, 19, 16); 2917 Rm = Bits32(opcode, 3, 0); 2918 shift_n = DecodeImmShiftARM(opcode, shift_t); 2919 break; 2920 default: 2921 return false; 2922 } 2923 // Read the register value from register Rn. 2924 uint32_t val1 = ReadCoreReg(Rn, &success); 2925 if (!success) 2926 return false; 2927 2928 // Read the register value from register Rm. 2929 uint32_t val2 = ReadCoreReg(Rm, &success); 2930 if (!success) 2931 return false; 2932 2933 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2934 if (!success) 2935 return false; 2936 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 2937 2938 EmulateInstruction::Context context; 2939 context.type = EmulateInstruction::eContextImmediate; 2940 context.SetNoArgs(); 2941 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2942 return false; 2943 2944 return true; 2945} 2946 2947// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2948// shifting in copies of its sign bit, and writes the result to the destination register. It can 2949// optionally update the condition flags based on the result. 2950bool 2951EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 2952{ 2953#if 0 2954 // ARM pseudo code... 2955 if ConditionPassed() then 2956 EncodingSpecificOperations(); 2957 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2958 if d == 15 then // Can only occur for ARM encoding 2959 ALUWritePC(result); // setflags is always FALSE here 2960 else 2961 R[d] = result; 2962 if setflags then 2963 APSR.N = result<31>; 2964 APSR.Z = IsZeroBit(result); 2965 APSR.C = carry; 2966 // APSR.V unchanged 2967#endif 2968 2969 return EmulateShiftImm (opcode, encoding, SRType_ASR); 2970} 2971 2972// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 2973// shifting in copies of its sign bit, and writes the result to the destination register. 2974// The variable number of bits is read from the bottom byte of a register. It can optionally update 2975// the condition flags based on the result. 2976bool 2977EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 2978{ 2979#if 0 2980 // ARM pseudo code... 2981 if ConditionPassed() then 2982 EncodingSpecificOperations(); 2983 shift_n = UInt(R[m]<7:0>); 2984 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2985 R[d] = result; 2986 if setflags then 2987 APSR.N = result<31>; 2988 APSR.Z = IsZeroBit(result); 2989 APSR.C = carry; 2990 // APSR.V unchanged 2991#endif 2992 2993 return EmulateShiftReg (opcode, encoding, SRType_ASR); 2994} 2995 2996// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 2997// shifting in zeros, and writes the result to the destination register. It can optionally 2998// update the condition flags based on the result. 2999bool 3000EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 3001{ 3002#if 0 3003 // ARM pseudo code... 3004 if ConditionPassed() then 3005 EncodingSpecificOperations(); 3006 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3007 if d == 15 then // Can only occur for ARM encoding 3008 ALUWritePC(result); // setflags is always FALSE here 3009 else 3010 R[d] = result; 3011 if setflags then 3012 APSR.N = result<31>; 3013 APSR.Z = IsZeroBit(result); 3014 APSR.C = carry; 3015 // APSR.V unchanged 3016#endif 3017 3018 return EmulateShiftImm (opcode, encoding, SRType_LSL); 3019} 3020 3021// Logical Shift Left (register) shifts a register value left by a variable number of bits, 3022// shifting in zeros, and writes the result to the destination register. The variable number 3023// of bits is read from the bottom byte of a register. It can optionally update the condition 3024// flags based on the result. 3025bool 3026EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 3027{ 3028#if 0 3029 // ARM pseudo code... 3030 if ConditionPassed() then 3031 EncodingSpecificOperations(); 3032 shift_n = UInt(R[m]<7:0>); 3033 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3034 R[d] = result; 3035 if setflags then 3036 APSR.N = result<31>; 3037 APSR.Z = IsZeroBit(result); 3038 APSR.C = carry; 3039 // APSR.V unchanged 3040#endif 3041 3042 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3043} 3044 3045// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3046// shifting in zeros, and writes the result to the destination register. It can optionally 3047// update the condition flags based on the result. 3048bool 3049EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3050{ 3051#if 0 3052 // ARM pseudo code... 3053 if ConditionPassed() then 3054 EncodingSpecificOperations(); 3055 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3056 if d == 15 then // Can only occur for ARM encoding 3057 ALUWritePC(result); // setflags is always FALSE here 3058 else 3059 R[d] = result; 3060 if setflags then 3061 APSR.N = result<31>; 3062 APSR.Z = IsZeroBit(result); 3063 APSR.C = carry; 3064 // APSR.V unchanged 3065#endif 3066 3067 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3068} 3069 3070// Logical Shift Right (register) shifts a register value right by a variable number of bits, 3071// shifting in zeros, and writes the result to the destination register. The variable number 3072// of bits is read from the bottom byte of a register. It can optionally update the condition 3073// flags based on the result. 3074bool 3075EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3076{ 3077#if 0 3078 // ARM pseudo code... 3079 if ConditionPassed() then 3080 EncodingSpecificOperations(); 3081 shift_n = UInt(R[m]<7:0>); 3082 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3083 R[d] = result; 3084 if setflags then 3085 APSR.N = result<31>; 3086 APSR.Z = IsZeroBit(result); 3087 APSR.C = carry; 3088 // APSR.V unchanged 3089#endif 3090 3091 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3092} 3093 3094// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3095// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3096// It can optionally update the condition flags based on the result. 3097bool 3098EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3099{ 3100#if 0 3101 // ARM pseudo code... 3102 if ConditionPassed() then 3103 EncodingSpecificOperations(); 3104 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3105 if d == 15 then // Can only occur for ARM encoding 3106 ALUWritePC(result); // setflags is always FALSE here 3107 else 3108 R[d] = result; 3109 if setflags then 3110 APSR.N = result<31>; 3111 APSR.Z = IsZeroBit(result); 3112 APSR.C = carry; 3113 // APSR.V unchanged 3114#endif 3115 3116 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3117} 3118 3119// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3120// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3121// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3122// flags based on the result. 3123bool 3124EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3125{ 3126#if 0 3127 // ARM pseudo code... 3128 if ConditionPassed() then 3129 EncodingSpecificOperations(); 3130 shift_n = UInt(R[m]<7:0>); 3131 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3132 R[d] = result; 3133 if setflags then 3134 APSR.N = result<31>; 3135 APSR.Z = IsZeroBit(result); 3136 APSR.C = carry; 3137 // APSR.V unchanged 3138#endif 3139 3140 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3141} 3142 3143// Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3144// with the carry flag shifted into bit [31]. 3145// 3146// RRX can optionally update the condition flags based on the result. 3147// In that case, bit [0] is shifted into the carry flag. 3148bool 3149EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3150{ 3151#if 0 3152 // ARM pseudo code... 3153 if ConditionPassed() then 3154 EncodingSpecificOperations(); 3155 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3156 if d == 15 then // Can only occur for ARM encoding 3157 ALUWritePC(result); // setflags is always FALSE here 3158 else 3159 R[d] = result; 3160 if setflags then 3161 APSR.N = result<31>; 3162 APSR.Z = IsZeroBit(result); 3163 APSR.C = carry; 3164 // APSR.V unchanged 3165#endif 3166 3167 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3168} 3169 3170bool 3171EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3172{ 3173// assert(shift_type == SRType_ASR 3174// || shift_type == SRType_LSL 3175// || shift_type == SRType_LSR 3176// || shift_type == SRType_ROR 3177// || shift_type == SRType_RRX); 3178 3179 bool success = false; 3180 3181 if (ConditionPassed(opcode)) 3182 { 3183 uint32_t Rd; // the destination register 3184 uint32_t Rm; // the first operand register 3185 uint32_t imm5; // encoding for the shift amount 3186 uint32_t carry; // the carry bit after the shift operation 3187 bool setflags; 3188 3189 // Special case handling! 3190 // A8.6.139 ROR (immediate) -- Encoding T1 3191 ARMEncoding use_encoding = encoding; 3192 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3193 { 3194 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3195 // have the same decoding of bit fields as the other Thumb2 shift operations. 3196 use_encoding = eEncodingT2; 3197 } 3198 3199 switch (use_encoding) { 3200 case eEncodingT1: 3201 // Due to the above special case handling! 3202 if (shift_type == SRType_ROR) 3203 return false; 3204 3205 Rd = Bits32(opcode, 2, 0); 3206 Rm = Bits32(opcode, 5, 3); 3207 setflags = !InITBlock(); 3208 imm5 = Bits32(opcode, 10, 6); 3209 break; 3210 case eEncodingT2: 3211 // A8.6.141 RRX 3212 // There's no imm form of RRX instructions. 3213 if (shift_type == SRType_RRX) 3214 return false; 3215 3216 Rd = Bits32(opcode, 11, 8); 3217 Rm = Bits32(opcode, 3, 0); 3218 setflags = BitIsSet(opcode, 20); 3219 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3220 if (BadReg(Rd) || BadReg(Rm)) 3221 return false; 3222 break; 3223 case eEncodingA1: 3224 Rd = Bits32(opcode, 15, 12); 3225 Rm = Bits32(opcode, 3, 0); 3226 setflags = BitIsSet(opcode, 20); 3227 imm5 = Bits32(opcode, 11, 7); 3228 break; 3229 default: 3230 return false; 3231 } 3232 3233 // A8.6.139 ROR (immediate) 3234 if (shift_type == SRType_ROR && imm5 == 0) 3235 shift_type = SRType_RRX; 3236 3237 // Get the first operand. 3238 uint32_t value = ReadCoreReg (Rm, &success); 3239 if (!success) 3240 return false; 3241 3242 // Decode the shift amount if not RRX. 3243 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3244 3245 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3246 if (!success) 3247 return false; 3248 3249 // The context specifies that an immediate is to be moved into Rd. 3250 EmulateInstruction::Context context; 3251 context.type = EmulateInstruction::eContextImmediate; 3252 context.SetNoArgs (); 3253 3254 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3255 return false; 3256 } 3257 return true; 3258} 3259 3260bool 3261EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3262{ 3263 // assert(shift_type == SRType_ASR 3264 // || shift_type == SRType_LSL 3265 // || shift_type == SRType_LSR 3266 // || shift_type == SRType_ROR); 3267 3268 bool success = false; 3269 3270 if (ConditionPassed(opcode)) 3271 { 3272 uint32_t Rd; // the destination register 3273 uint32_t Rn; // the first operand register 3274 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3275 uint32_t carry; // the carry bit after the shift operation 3276 bool setflags; 3277 switch (encoding) { 3278 case eEncodingT1: 3279 Rd = Bits32(opcode, 2, 0); 3280 Rn = Rd; 3281 Rm = Bits32(opcode, 5, 3); 3282 setflags = !InITBlock(); 3283 break; 3284 case eEncodingT2: 3285 Rd = Bits32(opcode, 11, 8); 3286 Rn = Bits32(opcode, 19, 16); 3287 Rm = Bits32(opcode, 3, 0); 3288 setflags = BitIsSet(opcode, 20); 3289 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3290 return false; 3291 break; 3292 case eEncodingA1: 3293 Rd = Bits32(opcode, 15, 12); 3294 Rn = Bits32(opcode, 3, 0); 3295 Rm = Bits32(opcode, 11, 8); 3296 setflags = BitIsSet(opcode, 20); 3297 if (Rd == 15 || Rn == 15 || Rm == 15) 3298 return false; 3299 break; 3300 default: 3301 return false; 3302 } 3303 3304 // Get the first operand. 3305 uint32_t value = ReadCoreReg (Rn, &success); 3306 if (!success) 3307 return false; 3308 // Get the Rm register content. 3309 uint32_t val = ReadCoreReg (Rm, &success); 3310 if (!success) 3311 return false; 3312 3313 // Get the shift amount. 3314 uint32_t amt = Bits32(val, 7, 0); 3315 3316 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3317 if (!success) 3318 return false; 3319 3320 // The context specifies that an immediate is to be moved into Rd. 3321 EmulateInstruction::Context context; 3322 context.type = EmulateInstruction::eContextImmediate; 3323 context.SetNoArgs (); 3324 3325 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3326 return false; 3327 } 3328 return true; 3329} 3330 3331// LDM loads multiple registers from consecutive memory locations, using an 3332// address from a base register. Optionally the address just above the highest of those locations 3333// can be written back to the base register. 3334bool 3335EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3336{ 3337#if 0 3338 // ARM pseudo code... 3339 if ConditionPassed() 3340 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3341 address = R[n]; 3342 3343 for i = 0 to 14 3344 if registers<i> == '1' then 3345 R[i] = MemA[address, 4]; address = address + 4; 3346 if registers<15> == '1' then 3347 LoadWritePC (MemA[address, 4]); 3348 3349 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3350 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3351 3352#endif 3353 3354 bool success = false; 3355 bool conditional = false; 3356 if (ConditionPassed(opcode, &conditional)) 3357 { 3358 uint32_t n; 3359 uint32_t registers = 0; 3360 bool wback; 3361 const uint32_t addr_byte_size = GetAddressByteSize(); 3362 switch (encoding) 3363 { 3364 case eEncodingT1: 3365 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3366 n = Bits32 (opcode, 10, 8); 3367 registers = Bits32 (opcode, 7, 0); 3368 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3369 wback = BitIsClear (registers, n); 3370 // if BitCount(registers) < 1 then UNPREDICTABLE; 3371 if (BitCount(registers) < 1) 3372 return false; 3373 break; 3374 case eEncodingT2: 3375 // if W == '1' && Rn == '1101' then SEE POP; 3376 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3377 n = Bits32 (opcode, 19, 16); 3378 registers = Bits32 (opcode, 15, 0); 3379 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3380 wback = BitIsSet (opcode, 21); 3381 3382 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3383 if ((n == 15) 3384 || (BitCount (registers) < 2) 3385 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3386 return false; 3387 3388 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3389 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3390 return false; 3391 3392 // if wback && registers<n> == '1' then UNPREDICTABLE; 3393 if (wback 3394 && BitIsSet (registers, n)) 3395 return false; 3396 break; 3397 3398 case eEncodingA1: 3399 n = Bits32 (opcode, 19, 16); 3400 registers = Bits32 (opcode, 15, 0); 3401 wback = BitIsSet (opcode, 21); 3402 if ((n == 15) 3403 || (BitCount (registers) < 1)) 3404 return false; 3405 break; 3406 default: 3407 return false; 3408 } 3409 3410 int32_t offset = 0; 3411 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3412 if (!success) 3413 return false; 3414 3415 EmulateInstruction::Context context; 3416 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3417 RegisterInfo dwarf_reg; 3418 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3419 context.SetRegisterPlusOffset (dwarf_reg, offset); 3420 3421 for (int i = 0; i < 14; ++i) 3422 { 3423 if (BitIsSet (registers, i)) 3424 { 3425 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3426 context.SetRegisterPlusOffset (dwarf_reg, offset); 3427 if (wback && (n == 13)) // Pop Instruction 3428 { 3429 if (conditional) 3430 context.type = EmulateInstruction::eContextRegisterLoad; 3431 else 3432 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3433 } 3434 3435 // R[i] = MemA [address, 4]; address = address + 4; 3436 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3437 if (!success) 3438 return false; 3439 3440 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3441 return false; 3442 3443 offset += addr_byte_size; 3444 } 3445 } 3446 3447 if (BitIsSet (registers, 15)) 3448 { 3449 //LoadWritePC (MemA [address, 4]); 3450 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3451 context.SetRegisterPlusOffset (dwarf_reg, offset); 3452 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3453 if (!success) 3454 return false; 3455 // In ARMv5T and above, this is an interworking branch. 3456 if (!LoadWritePC(context, data)) 3457 return false; 3458 } 3459 3460 if (wback && BitIsClear (registers, n)) 3461 { 3462 // R[n] = R[n] + 4 * BitCount (registers) 3463 int32_t offset = addr_byte_size * BitCount (registers); 3464 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3465 context.SetRegisterPlusOffset (dwarf_reg, offset); 3466 3467 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3468 return false; 3469 } 3470 if (wback && BitIsSet (registers, n)) 3471 // R[n] bits(32) UNKNOWN; 3472 return WriteBits32Unknown (n); 3473 } 3474 return true; 3475} 3476 3477// LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3478// The consecutive memory locations end at this address and the address just below the lowest of those locations 3479// can optionally be written back to the base register. 3480bool 3481EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3482{ 3483#if 0 3484 // ARM pseudo code... 3485 if ConditionPassed() then 3486 EncodingSpecificOperations(); 3487 address = R[n] - 4*BitCount(registers) + 4; 3488 3489 for i = 0 to 14 3490 if registers<i> == '1' then 3491 R[i] = MemA[address,4]; address = address + 4; 3492 3493 if registers<15> == '1' then 3494 LoadWritePC(MemA[address,4]); 3495 3496 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3497 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3498#endif 3499 3500 bool success = false; 3501 3502 if (ConditionPassed(opcode)) 3503 { 3504 uint32_t n; 3505 uint32_t registers = 0; 3506 bool wback; 3507 const uint32_t addr_byte_size = GetAddressByteSize(); 3508 3509 // EncodingSpecificOperations(); 3510 switch (encoding) 3511 { 3512 case eEncodingA1: 3513 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3514 n = Bits32 (opcode, 19, 16); 3515 registers = Bits32 (opcode, 15, 0); 3516 wback = BitIsSet (opcode, 21); 3517 3518 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3519 if ((n == 15) || (BitCount (registers) < 1)) 3520 return false; 3521 3522 break; 3523 3524 default: 3525 return false; 3526 } 3527 // address = R[n] - 4*BitCount(registers) + 4; 3528 3529 int32_t offset = 0; 3530 addr_t Rn = ReadCoreReg (n, &success); 3531 3532 if (!success) 3533 return false; 3534 3535 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3536 3537 EmulateInstruction::Context context; 3538 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3539 RegisterInfo dwarf_reg; 3540 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3541 context.SetRegisterPlusOffset (dwarf_reg, offset); 3542 3543 // for i = 0 to 14 3544 for (int i = 0; i < 14; ++i) 3545 { 3546 // if registers<i> == '1' then 3547 if (BitIsSet (registers, i)) 3548 { 3549 // R[i] = MemA[address,4]; address = address + 4; 3550 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3551 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3552 if (!success) 3553 return false; 3554 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3555 return false; 3556 offset += addr_byte_size; 3557 } 3558 } 3559 3560 // if registers<15> == '1' then 3561 // LoadWritePC(MemA[address,4]); 3562 if (BitIsSet (registers, 15)) 3563 { 3564 context.SetRegisterPlusOffset (dwarf_reg, offset); 3565 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3566 if (!success) 3567 return false; 3568 // In ARMv5T and above, this is an interworking branch. 3569 if (!LoadWritePC(context, data)) 3570 return false; 3571 } 3572 3573 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3574 if (wback && BitIsClear (registers, n)) 3575 { 3576 if (!success) 3577 return false; 3578 3579 offset = (addr_byte_size * BitCount (registers)) * -1; 3580 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3581 context.SetImmediateSigned (offset); 3582 addr_t addr = Rn + offset; 3583 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3584 return false; 3585 } 3586 3587 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3588 if (wback && BitIsSet (registers, n)) 3589 return WriteBits32Unknown (n); 3590 } 3591 return true; 3592} 3593 3594// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3595// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3596// be optionally written back to the base register. 3597bool 3598EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3599{ 3600#if 0 3601 // ARM pseudo code... 3602 if ConditionPassed() then 3603 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3604 address = R[n] - 4*BitCount(registers); 3605 3606 for i = 0 to 14 3607 if registers<i> == '1' then 3608 R[i] = MemA[address,4]; address = address + 4; 3609 if registers<15> == '1' then 3610 LoadWritePC(MemA[address,4]); 3611 3612 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3613 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3614#endif 3615 3616 bool success = false; 3617 3618 if (ConditionPassed(opcode)) 3619 { 3620 uint32_t n; 3621 uint32_t registers = 0; 3622 bool wback; 3623 const uint32_t addr_byte_size = GetAddressByteSize(); 3624 switch (encoding) 3625 { 3626 case eEncodingT1: 3627 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3628 n = Bits32 (opcode, 19, 16); 3629 registers = Bits32 (opcode, 15, 0); 3630 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3631 wback = BitIsSet (opcode, 21); 3632 3633 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3634 if ((n == 15) 3635 || (BitCount (registers) < 2) 3636 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3637 return false; 3638 3639 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3640 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3641 return false; 3642 3643 // if wback && registers<n> == '1' then UNPREDICTABLE; 3644 if (wback && BitIsSet (registers, n)) 3645 return false; 3646 3647 break; 3648 3649 case eEncodingA1: 3650 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3651 n = Bits32 (opcode, 19, 16); 3652 registers = Bits32 (opcode, 15, 0); 3653 wback = BitIsSet (opcode, 21); 3654 3655 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3656 if ((n == 15) || (BitCount (registers) < 1)) 3657 return false; 3658 3659 break; 3660 3661 default: 3662 return false; 3663 } 3664 3665 // address = R[n] - 4*BitCount(registers); 3666 3667 int32_t offset = 0; 3668 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3669 3670 if (!success) 3671 return false; 3672 3673 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3674 EmulateInstruction::Context context; 3675 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3676 RegisterInfo dwarf_reg; 3677 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3678 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3679 3680 for (int i = 0; i < 14; ++i) 3681 { 3682 if (BitIsSet (registers, i)) 3683 { 3684 // R[i] = MemA[address,4]; address = address + 4; 3685 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3686 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3687 if (!success) 3688 return false; 3689 3690 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3691 return false; 3692 3693 offset += addr_byte_size; 3694 } 3695 } 3696 3697 // if registers<15> == '1' then 3698 // LoadWritePC(MemA[address,4]); 3699 if (BitIsSet (registers, 15)) 3700 { 3701 context.SetRegisterPlusOffset (dwarf_reg, offset); 3702 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3703 if (!success) 3704 return false; 3705 // In ARMv5T and above, this is an interworking branch. 3706 if (!LoadWritePC(context, data)) 3707 return false; 3708 } 3709 3710 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3711 if (wback && BitIsClear (registers, n)) 3712 { 3713 if (!success) 3714 return false; 3715 3716 offset = (addr_byte_size * BitCount (registers)) * -1; 3717 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3718 context.SetImmediateSigned (offset); 3719 addr_t addr = Rn + offset; 3720 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3721 return false; 3722 } 3723 3724 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3725 if (wback && BitIsSet (registers, n)) 3726 return WriteBits32Unknown (n); 3727 } 3728 return true; 3729} 3730 3731// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3732// consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3733// optinoally be written back to the base register. 3734bool 3735EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3736{ 3737#if 0 3738 if ConditionPassed() then 3739 EncodingSpecificOperations(); 3740 address = R[n] + 4; 3741 3742 for i = 0 to 14 3743 if registers<i> == '1' then 3744 R[i] = MemA[address,4]; address = address + 4; 3745 if registers<15> == '1' then 3746 LoadWritePC(MemA[address,4]); 3747 3748 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3749 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3750#endif 3751 3752 bool success = false; 3753 3754 if (ConditionPassed(opcode)) 3755 { 3756 uint32_t n; 3757 uint32_t registers = 0; 3758 bool wback; 3759 const uint32_t addr_byte_size = GetAddressByteSize(); 3760 switch (encoding) 3761 { 3762 case eEncodingA1: 3763 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3764 n = Bits32 (opcode, 19, 16); 3765 registers = Bits32 (opcode, 15, 0); 3766 wback = BitIsSet (opcode, 21); 3767 3768 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3769 if ((n == 15) || (BitCount (registers) < 1)) 3770 return false; 3771 3772 break; 3773 default: 3774 return false; 3775 } 3776 // address = R[n] + 4; 3777 3778 int32_t offset = 0; 3779 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3780 3781 if (!success) 3782 return false; 3783 3784 addr_t address = Rn + addr_byte_size; 3785 3786 EmulateInstruction::Context context; 3787 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3788 RegisterInfo dwarf_reg; 3789 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3790 context.SetRegisterPlusOffset (dwarf_reg, offset); 3791 3792 for (int i = 0; i < 14; ++i) 3793 { 3794 if (BitIsSet (registers, i)) 3795 { 3796 // R[i] = MemA[address,4]; address = address + 4; 3797 3798 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3799 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3800 if (!success) 3801 return false; 3802 3803 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3804 return false; 3805 3806 offset += addr_byte_size; 3807 } 3808 } 3809 3810 // if registers<15> == '1' then 3811 // LoadWritePC(MemA[address,4]); 3812 if (BitIsSet (registers, 15)) 3813 { 3814 context.SetRegisterPlusOffset (dwarf_reg, offset); 3815 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3816 if (!success) 3817 return false; 3818 // In ARMv5T and above, this is an interworking branch. 3819 if (!LoadWritePC(context, data)) 3820 return false; 3821 } 3822 3823 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3824 if (wback && BitIsClear (registers, n)) 3825 { 3826 if (!success) 3827 return false; 3828 3829 offset = addr_byte_size * BitCount (registers); 3830 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3831 context.SetImmediateSigned (offset); 3832 addr_t addr = Rn + offset; 3833 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3834 return false; 3835 } 3836 3837 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3838 if (wback && BitIsSet (registers, n)) 3839 return WriteBits32Unknown (n); 3840 } 3841 return true; 3842} 3843 3844// Load Register (immediate) calculates an address from a base register value and 3845// an immediate offset, loads a word from memory, and writes to a register. 3846// LDR (immediate, Thumb) 3847bool 3848EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3849{ 3850#if 0 3851 // ARM pseudo code... 3852 if (ConditionPassed()) 3853 { 3854 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3855 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3856 address = if index then offset_addr else R[n]; 3857 data = MemU[address,4]; 3858 if wback then R[n] = offset_addr; 3859 if t == 15 then 3860 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3861 elsif UnalignedSupport() || address<1:0> = '00' then 3862 R[t] = data; 3863 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3864 } 3865#endif 3866 3867 bool success = false; 3868 3869 if (ConditionPassed(opcode)) 3870 { 3871 uint32_t Rt; // the destination register 3872 uint32_t Rn; // the base register 3873 uint32_t imm32; // the immediate offset used to form the address 3874 addr_t offset_addr; // the offset address 3875 addr_t address; // the calculated address 3876 uint32_t data; // the literal data value from memory load 3877 bool add, index, wback; 3878 switch (encoding) { 3879 case eEncodingT1: 3880 Rt = Bits32(opcode, 2, 0); 3881 Rn = Bits32(opcode, 5, 3); 3882 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3883 // index = TRUE; add = TRUE; wback = FALSE 3884 add = true; 3885 index = true; 3886 wback = false; 3887 3888 break; 3889 3890 case eEncodingT2: 3891 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3892 Rt = Bits32 (opcode, 10, 8); 3893 Rn = 13; 3894 imm32 = Bits32 (opcode, 7, 0) << 2; 3895 3896 // index = TRUE; add = TRUE; wback = FALSE; 3897 index = true; 3898 add = true; 3899 wback = false; 3900 3901 break; 3902 3903 case eEncodingT3: 3904 // if Rn == '1111' then SEE LDR (literal); 3905 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3906 Rt = Bits32 (opcode, 15, 12); 3907 Rn = Bits32 (opcode, 19, 16); 3908 imm32 = Bits32 (opcode, 11, 0); 3909 3910 // index = TRUE; add = TRUE; wback = FALSE; 3911 index = true; 3912 add = true; 3913 wback = false; 3914 3915 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3916 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3917 return false; 3918 3919 break; 3920 3921 case eEncodingT4: 3922 // if Rn == '1111' then SEE LDR (literal); 3923 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3924 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3925 // if P == '0' && W == '0' then UNDEFINED; 3926 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3927 return false; 3928 3929 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3930 Rt = Bits32 (opcode, 15, 12); 3931 Rn = Bits32 (opcode, 19, 16); 3932 imm32 = Bits32 (opcode, 7, 0); 3933 3934 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3935 index = BitIsSet (opcode, 10); 3936 add = BitIsSet (opcode, 9); 3937 wback = BitIsSet (opcode, 8); 3938 3939 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3940 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3941 return false; 3942 3943 break; 3944 3945 default: 3946 return false; 3947 } 3948 uint32_t base = ReadCoreReg (Rn, &success); 3949 if (!success) 3950 return false; 3951 if (add) 3952 offset_addr = base + imm32; 3953 else 3954 offset_addr = base - imm32; 3955 3956 address = (index ? offset_addr : base); 3957 3958 RegisterInfo base_reg; 3959 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 3960 if (wback) 3961 { 3962 EmulateInstruction::Context ctx; 3963 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 3964 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3965 3966 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3967 return false; 3968 } 3969 3970 // Prepare to write to the Rt register. 3971 EmulateInstruction::Context context; 3972 context.type = EmulateInstruction::eContextRegisterLoad; 3973 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3974 3975 // Read memory from the address. 3976 data = MemURead(context, address, 4, 0, &success); 3977 if (!success) 3978 return false; 3979 3980 if (Rt == 15) 3981 { 3982 if (Bits32(address, 1, 0) == 0) 3983 { 3984 if (!LoadWritePC(context, data)) 3985 return false; 3986 } 3987 else 3988 return false; 3989 } 3990 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3991 { 3992 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3993 return false; 3994 } 3995 else 3996 WriteBits32Unknown (Rt); 3997 } 3998 return true; 3999} 4000 4001// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 4002// from a base register. The consecutive memory locations start at this address, and teh address just above the last 4003// of those locations can optionally be written back to the base register. 4004bool 4005EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 4006{ 4007#if 0 4008 if ConditionPassed() then 4009 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4010 address = R[n]; 4011 4012 for i = 0 to 14 4013 if registers<i> == '1' then 4014 if i == n && wback && i != LowestSetBit(registers) then 4015 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4016 else 4017 MemA[address,4] = R[i]; 4018 address = address + 4; 4019 4020 if registers<15> == '1' then // Only possible for encoding A1 4021 MemA[address,4] = PCStoreValue(); 4022 if wback then R[n] = R[n] + 4*BitCount(registers); 4023#endif 4024 4025 bool success = false; 4026 4027 if (ConditionPassed(opcode)) 4028 { 4029 uint32_t n; 4030 uint32_t registers = 0; 4031 bool wback; 4032 const uint32_t addr_byte_size = GetAddressByteSize(); 4033 4034 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4035 switch (encoding) 4036 { 4037 case eEncodingT1: 4038 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4039 n = Bits32 (opcode, 10, 8); 4040 registers = Bits32 (opcode, 7, 0); 4041 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4042 wback = true; 4043 4044 // if BitCount(registers) < 1 then UNPREDICTABLE; 4045 if (BitCount (registers) < 1) 4046 return false; 4047 4048 break; 4049 4050 case eEncodingT2: 4051 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4052 n = Bits32 (opcode, 19, 16); 4053 registers = Bits32 (opcode, 15, 0); 4054 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4055 wback = BitIsSet (opcode, 21); 4056 4057 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4058 if ((n == 15) || (BitCount (registers) < 2)) 4059 return false; 4060 4061 // if wback && registers<n> == '1' then UNPREDICTABLE; 4062 if (wback && BitIsSet (registers, n)) 4063 return false; 4064 4065 break; 4066 4067 case eEncodingA1: 4068 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4069 n = Bits32 (opcode, 19, 16); 4070 registers = Bits32 (opcode, 15, 0); 4071 wback = BitIsSet (opcode, 21); 4072 4073 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4074 if ((n == 15) || (BitCount (registers) < 1)) 4075 return false; 4076 4077 break; 4078 4079 default: 4080 return false; 4081 } 4082 4083 // address = R[n]; 4084 int32_t offset = 0; 4085 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4086 if (!success) 4087 return false; 4088 4089 EmulateInstruction::Context context; 4090 context.type = EmulateInstruction::eContextRegisterStore; 4091 RegisterInfo base_reg; 4092 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4093 4094 // for i = 0 to 14 4095 int lowest_set_bit = 14; 4096 for (int i = 0; i < 14; ++i) 4097 { 4098 // if registers<i> == '1' then 4099 if (BitIsSet (registers, i)) 4100 { 4101 if (i < lowest_set_bit) 4102 lowest_set_bit = i; 4103 // if i == n && wback && i != LowestSetBit(registers) then 4104 if ((i == n) && wback && (i != lowest_set_bit)) 4105 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4106 WriteBits32UnknownToMemory (address + offset); 4107 else 4108 { 4109 // MemA[address,4] = R[i]; 4110 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4111 if (!success) 4112 return false; 4113 4114 RegisterInfo data_reg; 4115 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4116 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4117 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4118 return false; 4119 } 4120 4121 // address = address + 4; 4122 offset += addr_byte_size; 4123 } 4124 } 4125 4126 // if registers<15> == '1' then // Only possible for encoding A1 4127 // MemA[address,4] = PCStoreValue(); 4128 if (BitIsSet (registers, 15)) 4129 { 4130 RegisterInfo pc_reg; 4131 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4132 context.SetRegisterPlusOffset (pc_reg, 8); 4133 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4134 if (!success) 4135 return false; 4136 4137 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4138 return false; 4139 } 4140 4141 // if wback then R[n] = R[n] + 4*BitCount(registers); 4142 if (wback) 4143 { 4144 offset = addr_byte_size * BitCount (registers); 4145 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4146 context.SetImmediateSigned (offset); 4147 addr_t data = address + offset; 4148 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4149 return false; 4150 } 4151 } 4152 return true; 4153} 4154 4155// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4156// from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4157// of those locations can optionally be written back to the base register. 4158bool 4159EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4160{ 4161#if 0 4162 if ConditionPassed() then 4163 EncodingSpecificOperations(); 4164 address = R[n] - 4*BitCount(registers) + 4; 4165 4166 for i = 0 to 14 4167 if registers<i> == '1' then 4168 if i == n && wback && i != LowestSetBit(registers) then 4169 MemA[address,4] = bits(32) UNKNOWN; 4170 else 4171 MemA[address,4] = R[i]; 4172 address = address + 4; 4173 4174 if registers<15> == '1' then 4175 MemA[address,4] = PCStoreValue(); 4176 4177 if wback then R[n] = R[n] - 4*BitCount(registers); 4178#endif 4179 4180 bool success = false; 4181 4182 if (ConditionPassed(opcode)) 4183 { 4184 uint32_t n; 4185 uint32_t registers = 0; 4186 bool wback; 4187 const uint32_t addr_byte_size = GetAddressByteSize(); 4188 4189 // EncodingSpecificOperations(); 4190 switch (encoding) 4191 { 4192 case eEncodingA1: 4193 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4194 n = Bits32 (opcode, 19, 16); 4195 registers = Bits32 (opcode, 15, 0); 4196 wback = BitIsSet (opcode, 21); 4197 4198 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4199 if ((n == 15) || (BitCount (registers) < 1)) 4200 return false; 4201 break; 4202 default: 4203 return false; 4204 } 4205 4206 // address = R[n] - 4*BitCount(registers) + 4; 4207 int32_t offset = 0; 4208 addr_t Rn = ReadCoreReg (n, &success); 4209 if (!success) 4210 return false; 4211 4212 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4213 4214 EmulateInstruction::Context context; 4215 context.type = EmulateInstruction::eContextRegisterStore; 4216 RegisterInfo base_reg; 4217 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4218 4219 // for i = 0 to 14 4220 int lowest_bit_set = 14; 4221 for (int i = 0; i < 14; ++i) 4222 { 4223 // if registers<i> == '1' then 4224 if (BitIsSet (registers, i)) 4225 { 4226 if (i < lowest_bit_set) 4227 lowest_bit_set = i; 4228 //if i == n && wback && i != LowestSetBit(registers) then 4229 if ((i == n) && wback && (i != lowest_bit_set)) 4230 // MemA[address,4] = bits(32) UNKNOWN; 4231 WriteBits32UnknownToMemory (address + offset); 4232 else 4233 { 4234 // MemA[address,4] = R[i]; 4235 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4236 if (!success) 4237 return false; 4238 4239 RegisterInfo data_reg; 4240 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4241 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4242 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4243 return false; 4244 } 4245 4246 // address = address + 4; 4247 offset += addr_byte_size; 4248 } 4249 } 4250 4251 // if registers<15> == '1' then 4252 // MemA[address,4] = PCStoreValue(); 4253 if (BitIsSet (registers, 15)) 4254 { 4255 RegisterInfo pc_reg; 4256 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4257 context.SetRegisterPlusOffset (pc_reg, 8); 4258 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4259 if (!success) 4260 return false; 4261 4262 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4263 return false; 4264 } 4265 4266 // if wback then R[n] = R[n] - 4*BitCount(registers); 4267 if (wback) 4268 { 4269 offset = (addr_byte_size * BitCount (registers)) * -1; 4270 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4271 context.SetImmediateSigned (offset); 4272 addr_t data = Rn + offset; 4273 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4274 return false; 4275 } 4276 } 4277 return true; 4278} 4279 4280// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4281// from a base register. The consecutive memory locations end just below this address, and the address of the first of 4282// those locations can optionally be written back to the base register. 4283bool 4284EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4285{ 4286#if 0 4287 if ConditionPassed() then 4288 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4289 address = R[n] - 4*BitCount(registers); 4290 4291 for i = 0 to 14 4292 if registers<i> == '1' then 4293 if i == n && wback && i != LowestSetBit(registers) then 4294 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4295 else 4296 MemA[address,4] = R[i]; 4297 address = address + 4; 4298 4299 if registers<15> == '1' then // Only possible for encoding A1 4300 MemA[address,4] = PCStoreValue(); 4301 4302 if wback then R[n] = R[n] - 4*BitCount(registers); 4303#endif 4304 4305 4306 bool success = false; 4307 4308 if (ConditionPassed(opcode)) 4309 { 4310 uint32_t n; 4311 uint32_t registers = 0; 4312 bool wback; 4313 const uint32_t addr_byte_size = GetAddressByteSize(); 4314 4315 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4316 switch (encoding) 4317 { 4318 case eEncodingT1: 4319 // if W == '1' && Rn == '1101' then SEE PUSH; 4320 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4321 { 4322 // See PUSH 4323 } 4324 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4325 n = Bits32 (opcode, 19, 16); 4326 registers = Bits32 (opcode, 15, 0); 4327 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4328 wback = BitIsSet (opcode, 21); 4329 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4330 if ((n == 15) || BitCount (registers) < 2) 4331 return false; 4332 // if wback && registers<n> == '1' then UNPREDICTABLE; 4333 if (wback && BitIsSet (registers, n)) 4334 return false; 4335 break; 4336 4337 case eEncodingA1: 4338 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH; 4339 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4340 { 4341 // See Push 4342 } 4343 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4344 n = Bits32 (opcode, 19, 16); 4345 registers = Bits32 (opcode, 15, 0); 4346 wback = BitIsSet (opcode, 21); 4347 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4348 if ((n == 15) || BitCount (registers) < 1) 4349 return false; 4350 break; 4351 4352 default: 4353 return false; 4354 } 4355 4356 // address = R[n] - 4*BitCount(registers); 4357 4358 int32_t offset = 0; 4359 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4360 if (!success) 4361 return false; 4362 4363 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4364 4365 EmulateInstruction::Context context; 4366 context.type = EmulateInstruction::eContextRegisterStore; 4367 RegisterInfo base_reg; 4368 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4369 4370 // for i = 0 to 14 4371 uint32_t lowest_set_bit = 14; 4372 for (int i = 0; i < 14; ++i) 4373 { 4374 // if registers<i> == '1' then 4375 if (BitIsSet (registers, i)) 4376 { 4377 if (i < lowest_set_bit) 4378 lowest_set_bit = i; 4379 // if i == n && wback && i != LowestSetBit(registers) then 4380 if ((i == n) && wback && (i != lowest_set_bit)) 4381 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4382 WriteBits32UnknownToMemory (address + offset); 4383 else 4384 { 4385 // MemA[address,4] = R[i]; 4386 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4387 if (!success) 4388 return false; 4389 4390 RegisterInfo data_reg; 4391 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4392 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4393 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4394 return false; 4395 } 4396 4397 // address = address + 4; 4398 offset += addr_byte_size; 4399 } 4400 } 4401 4402 // if registers<15> == '1' then // Only possible for encoding A1 4403 // MemA[address,4] = PCStoreValue(); 4404 if (BitIsSet (registers, 15)) 4405 { 4406 RegisterInfo pc_reg; 4407 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4408 context.SetRegisterPlusOffset (pc_reg, 8); 4409 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4410 if (!success) 4411 return false; 4412 4413 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4414 return false; 4415 } 4416 4417 // if wback then R[n] = R[n] - 4*BitCount(registers); 4418 if (wback) 4419 { 4420 offset = (addr_byte_size * BitCount (registers)) * -1; 4421 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4422 context.SetImmediateSigned (offset); 4423 addr_t data = Rn + offset; 4424 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4425 return false; 4426 } 4427 } 4428 return true; 4429} 4430 4431// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4432// from a base register. The consecutive memory locations start just above this address, and the address of the last 4433// of those locations can optionally be written back to the base register. 4434bool 4435EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4436{ 4437#if 0 4438 if ConditionPassed() then 4439 EncodingSpecificOperations(); 4440 address = R[n] + 4; 4441 4442 for i = 0 to 14 4443 if registers<i> == '1' then 4444 if i == n && wback && i != LowestSetBit(registers) then 4445 MemA[address,4] = bits(32) UNKNOWN; 4446 else 4447 MemA[address,4] = R[i]; 4448 address = address + 4; 4449 4450 if registers<15> == '1' then 4451 MemA[address,4] = PCStoreValue(); 4452 4453 if wback then R[n] = R[n] + 4*BitCount(registers); 4454#endif 4455 4456 bool success = false; 4457 4458 if (ConditionPassed(opcode)) 4459 { 4460 uint32_t n; 4461 uint32_t registers = 0; 4462 bool wback; 4463 const uint32_t addr_byte_size = GetAddressByteSize(); 4464 4465 // EncodingSpecificOperations(); 4466 switch (encoding) 4467 { 4468 case eEncodingA1: 4469 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4470 n = Bits32 (opcode, 19, 16); 4471 registers = Bits32 (opcode, 15, 0); 4472 wback = BitIsSet (opcode, 21); 4473 4474 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4475 if ((n == 15) && (BitCount (registers) < 1)) 4476 return false; 4477 break; 4478 default: 4479 return false; 4480 } 4481 // address = R[n] + 4; 4482 4483 int32_t offset = 0; 4484 addr_t Rn = ReadCoreReg (n, &success); 4485 if (!success) 4486 return false; 4487 4488 addr_t address = Rn + addr_byte_size; 4489 4490 EmulateInstruction::Context context; 4491 context.type = EmulateInstruction::eContextRegisterStore; 4492 RegisterInfo base_reg; 4493 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4494 4495 uint32_t lowest_set_bit = 14; 4496 // for i = 0 to 14 4497 for (int i = 0; i < 14; ++i) 4498 { 4499 // if registers<i> == '1' then 4500 if (BitIsSet (registers, i)) 4501 { 4502 if (i < lowest_set_bit) 4503 lowest_set_bit = i; 4504 // if i == n && wback && i != LowestSetBit(registers) then 4505 if ((i == n) && wback && (i != lowest_set_bit)) 4506 // MemA[address,4] = bits(32) UNKNOWN; 4507 WriteBits32UnknownToMemory (address + offset); 4508 // else 4509 else 4510 { 4511 // MemA[address,4] = R[i]; 4512 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4513 if (!success) 4514 return false; 4515 4516 RegisterInfo data_reg; 4517 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4518 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4519 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4520 return false; 4521 } 4522 4523 // address = address + 4; 4524 offset += addr_byte_size; 4525 } 4526 } 4527 4528 // if registers<15> == '1' then 4529 // MemA[address,4] = PCStoreValue(); 4530 if (BitIsSet (registers, 15)) 4531 { 4532 RegisterInfo pc_reg; 4533 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4534 context.SetRegisterPlusOffset (pc_reg, 8); 4535 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4536 if (!success) 4537 return false; 4538 4539 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4540 return false; 4541 } 4542 4543 // if wback then R[n] = R[n] + 4*BitCount(registers); 4544 if (wback) 4545 { 4546 offset = addr_byte_size * BitCount (registers); 4547 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4548 context.SetImmediateSigned (offset); 4549 addr_t data = Rn + offset; 4550 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4551 return false; 4552 } 4553 } 4554 return true; 4555} 4556 4557// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 4558// from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4559bool 4560EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4561{ 4562#if 0 4563 if ConditionPassed() then 4564 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4565 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4566 address = if index then offset_addr else R[n]; 4567 if UnalignedSupport() || address<1:0> == '00' then 4568 MemU[address,4] = R[t]; 4569 else // Can only occur before ARMv7 4570 MemU[address,4] = bits(32) UNKNOWN; 4571 if wback then R[n] = offset_addr; 4572#endif 4573 4574 bool success = false; 4575 4576 if (ConditionPassed(opcode)) 4577 { 4578 const uint32_t addr_byte_size = GetAddressByteSize(); 4579 4580 uint32_t t; 4581 uint32_t n; 4582 uint32_t imm32; 4583 bool index; 4584 bool add; 4585 bool wback; 4586 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4587 switch (encoding) 4588 { 4589 case eEncodingT1: 4590 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4591 t = Bits32 (opcode, 2, 0); 4592 n = Bits32 (opcode, 5, 3); 4593 imm32 = Bits32 (opcode, 10, 6) << 2; 4594 4595 // index = TRUE; add = TRUE; wback = FALSE; 4596 index = true; 4597 add = false; 4598 wback = false; 4599 break; 4600 4601 case eEncodingT2: 4602 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4603 t = Bits32 (opcode, 10, 8); 4604 n = 13; 4605 imm32 = Bits32 (opcode, 7, 0) << 2; 4606 4607 // index = TRUE; add = TRUE; wback = FALSE; 4608 index = true; 4609 add = true; 4610 wback = false; 4611 break; 4612 4613 case eEncodingT3: 4614 // if Rn == '1111' then UNDEFINED; 4615 if (Bits32 (opcode, 19, 16) == 15) 4616 return false; 4617 4618 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4619 t = Bits32 (opcode, 15, 12); 4620 n = Bits32 (opcode, 19, 16); 4621 imm32 = Bits32 (opcode, 11, 0); 4622 4623 // index = TRUE; add = TRUE; wback = FALSE; 4624 index = true; 4625 add = true; 4626 wback = false; 4627 4628 // if t == 15 then UNPREDICTABLE; 4629 if (t == 15) 4630 return false; 4631 break; 4632 4633 case eEncodingT4: 4634 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4635 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4636 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4637 if ((Bits32 (opcode, 19, 16) == 15) 4638 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4639 return false; 4640 4641 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4642 t = Bits32 (opcode, 15, 12); 4643 n = Bits32 (opcode, 19, 16); 4644 imm32 = Bits32 (opcode, 7, 0); 4645 4646 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4647 index = BitIsSet (opcode, 10); 4648 add = BitIsSet (opcode, 9); 4649 wback = BitIsSet (opcode, 8); 4650 4651 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4652 if ((t == 15) || (wback && (n == t))) 4653 return false; 4654 break; 4655 4656 default: 4657 return false; 4658 } 4659 4660 addr_t offset_addr; 4661 addr_t address; 4662 4663 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4664 uint32_t base_address = ReadCoreReg (n, &success); 4665 if (!success) 4666 return false; 4667 4668 if (add) 4669 offset_addr = base_address + imm32; 4670 else 4671 offset_addr = base_address - imm32; 4672 4673 // address = if index then offset_addr else R[n]; 4674 if (index) 4675 address = offset_addr; 4676 else 4677 address = base_address; 4678 4679 EmulateInstruction::Context context; 4680 context.type = eContextRegisterStore; 4681 RegisterInfo base_reg; 4682 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4683 4684 // if UnalignedSupport() || address<1:0> == '00' then 4685 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4686 { 4687 // MemU[address,4] = R[t]; 4688 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4689 if (!success) 4690 return false; 4691 4692 RegisterInfo data_reg; 4693 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4694 int32_t offset = address - base_address; 4695 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4696 if (!MemUWrite (context, address, data, addr_byte_size)) 4697 return false; 4698 } 4699 else 4700 { 4701 // MemU[address,4] = bits(32) UNKNOWN; 4702 WriteBits32UnknownToMemory (address); 4703 } 4704 4705 // if wback then R[n] = offset_addr; 4706 if (wback) 4707 { 4708 context.type = eContextRegisterLoad; 4709 context.SetAddress (offset_addr); 4710 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4711 return false; 4712 } 4713 } 4714 return true; 4715} 4716 4717// STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4718// word from a register to memory. The offset register value can optionally be shifted. 4719bool 4720EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4721{ 4722#if 0 4723 if ConditionPassed() then 4724 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4725 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4726 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4727 address = if index then offset_addr else R[n]; 4728 if t == 15 then // Only possible for encoding A1 4729 data = PCStoreValue(); 4730 else 4731 data = R[t]; 4732 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4733 MemU[address,4] = data; 4734 else // Can only occur before ARMv7 4735 MemU[address,4] = bits(32) UNKNOWN; 4736 if wback then R[n] = offset_addr; 4737#endif 4738 4739 bool success = false; 4740 4741 if (ConditionPassed(opcode)) 4742 { 4743 const uint32_t addr_byte_size = GetAddressByteSize(); 4744 4745 uint32_t t; 4746 uint32_t n; 4747 uint32_t m; 4748 ARM_ShifterType shift_t; 4749 uint32_t shift_n; 4750 bool index; 4751 bool add; 4752 bool wback; 4753 4754 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4755 switch (encoding) 4756 { 4757 case eEncodingT1: 4758 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4759 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4760 t = Bits32 (opcode, 2, 0); 4761 n = Bits32 (opcode, 5, 3); 4762 m = Bits32 (opcode, 8, 6); 4763 4764 // index = TRUE; add = TRUE; wback = FALSE; 4765 index = true; 4766 add = true; 4767 wback = false; 4768 4769 // (shift_t, shift_n) = (SRType_LSL, 0); 4770 shift_t = SRType_LSL; 4771 shift_n = 0; 4772 break; 4773 4774 case eEncodingT2: 4775 // if Rn == '1111' then UNDEFINED; 4776 if (Bits32 (opcode, 19, 16) == 15) 4777 return false; 4778 4779 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4780 t = Bits32 (opcode, 15, 12); 4781 n = Bits32 (opcode, 19, 16); 4782 m = Bits32 (opcode, 3, 0); 4783 4784 // index = TRUE; add = TRUE; wback = FALSE; 4785 index = true; 4786 add = true; 4787 wback = false; 4788 4789 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4790 shift_t = SRType_LSL; 4791 shift_n = Bits32 (opcode, 5, 4); 4792 4793 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4794 if ((t == 15) || (BadReg (m))) 4795 return false; 4796 break; 4797 4798 case eEncodingA1: 4799 { 4800 // if P == '0' && W == '1' then SEE STRT; 4801 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4802 t = Bits32 (opcode, 15, 12); 4803 n = Bits32 (opcode, 19, 16); 4804 m = Bits32 (opcode, 3, 0); 4805 4806 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4807 index = BitIsSet (opcode, 24); 4808 add = BitIsSet (opcode, 23); 4809 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4810 4811 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4812 uint32_t typ = Bits32 (opcode, 6, 5); 4813 uint32_t imm5 = Bits32 (opcode, 11, 7); 4814 shift_n = DecodeImmShift(typ, imm5, shift_t); 4815 4816 // if m == 15 then UNPREDICTABLE; 4817 if (m == 15) 4818 return false; 4819 4820 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4821 if (wback && ((n == 15) || (n == t))) 4822 return false; 4823 4824 break; 4825 } 4826 default: 4827 return false; 4828 } 4829 4830 addr_t offset_addr; 4831 addr_t address; 4832 int32_t offset = 0; 4833 4834 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4835 if (!success) 4836 return false; 4837 4838 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4839 if (!success) 4840 return false; 4841 4842 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4843 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4844 if (!success) 4845 return false; 4846 4847 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4848 if (add) 4849 offset_addr = base_address + offset; 4850 else 4851 offset_addr = base_address - offset; 4852 4853 // address = if index then offset_addr else R[n]; 4854 if (index) 4855 address = offset_addr; 4856 else 4857 address = base_address; 4858 4859 uint32_t data; 4860 // if t == 15 then // Only possible for encoding A1 4861 if (t == 15) 4862 // data = PCStoreValue(); 4863 data = ReadCoreReg (PC_REG, &success); 4864 else 4865 // data = R[t]; 4866 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4867 4868 if (!success) 4869 return false; 4870 4871 EmulateInstruction::Context context; 4872 context.type = eContextRegisterStore; 4873 4874 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4875 if (UnalignedSupport () 4876 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4877 || CurrentInstrSet() == eModeARM) 4878 { 4879 // MemU[address,4] = data; 4880 4881 RegisterInfo base_reg; 4882 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4883 4884 RegisterInfo data_reg; 4885 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4886 4887 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4888 if (!MemUWrite (context, address, data, addr_byte_size)) 4889 return false; 4890 4891 } 4892 else 4893 // MemU[address,4] = bits(32) UNKNOWN; 4894 WriteBits32UnknownToMemory (address); 4895 4896 // if wback then R[n] = offset_addr; 4897 if (wback) 4898 { 4899 context.type = eContextRegisterLoad; 4900 context.SetAddress (offset_addr); 4901 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4902 return false; 4903 } 4904 4905 } 4906 return true; 4907} 4908 4909bool 4910EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 4911{ 4912#if 0 4913 if ConditionPassed() then 4914 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4915 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4916 address = if index then offset_addr else R[n]; 4917 MemU[address,1] = R[t]<7:0>; 4918 if wback then R[n] = offset_addr; 4919#endif 4920 4921 4922 bool success = false; 4923 4924 if (ConditionPassed(opcode)) 4925 { 4926 uint32_t t; 4927 uint32_t n; 4928 uint32_t imm32; 4929 bool index; 4930 bool add; 4931 bool wback; 4932 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4933 switch (encoding) 4934 { 4935 case eEncodingT1: 4936 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4937 t = Bits32 (opcode, 2, 0); 4938 n = Bits32 (opcode, 5, 3); 4939 imm32 = Bits32 (opcode, 10, 6); 4940 4941 // index = TRUE; add = TRUE; wback = FALSE; 4942 index = true; 4943 add = true; 4944 wback = false; 4945 break; 4946 4947 case eEncodingT2: 4948 // if Rn == '1111' then UNDEFINED; 4949 if (Bits32 (opcode, 19, 16) == 15) 4950 return false; 4951 4952 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4953 t = Bits32 (opcode, 15, 12); 4954 n = Bits32 (opcode, 19, 16); 4955 imm32 = Bits32 (opcode, 11, 0); 4956 4957 // index = TRUE; add = TRUE; wback = FALSE; 4958 index = true; 4959 add = true; 4960 wback = false; 4961 4962 // if BadReg(t) then UNPREDICTABLE; 4963 if (BadReg (t)) 4964 return false; 4965 break; 4966 4967 case eEncodingT3: 4968 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 4969 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4970 if (Bits32 (opcode, 19, 16) == 15) 4971 return false; 4972 4973 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4974 t = Bits32 (opcode, 15, 12); 4975 n = Bits32 (opcode, 19, 16); 4976 imm32 = Bits32 (opcode, 7, 0); 4977 4978 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4979 index = BitIsSet (opcode, 10); 4980 add = BitIsSet (opcode, 9); 4981 wback = BitIsSet (opcode, 8); 4982 4983 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 4984 if ((BadReg (t)) || (wback && (n == t))) 4985 return false; 4986 break; 4987 4988 default: 4989 return false; 4990 } 4991 4992 addr_t offset_addr; 4993 addr_t address; 4994 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4995 if (!success) 4996 return false; 4997 4998 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4999 if (add) 5000 offset_addr = base_address + imm32; 5001 else 5002 offset_addr = base_address - imm32; 5003 5004 // address = if index then offset_addr else R[n]; 5005 if (index) 5006 address = offset_addr; 5007 else 5008 address = base_address; 5009 5010 // MemU[address,1] = R[t]<7:0> 5011 RegisterInfo base_reg; 5012 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5013 5014 RegisterInfo data_reg; 5015 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5016 5017 EmulateInstruction::Context context; 5018 context.type = eContextRegisterStore; 5019 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5020 5021 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5022 if (!success) 5023 return false; 5024 5025 data = Bits32 (data, 7, 0); 5026 5027 if (!MemUWrite (context, address, data, 1)) 5028 return false; 5029 5030 // if wback then R[n] = offset_addr; 5031 if (wback) 5032 { 5033 context.type = eContextRegisterLoad; 5034 context.SetAddress (offset_addr); 5035 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5036 return false; 5037 } 5038 5039 } 5040 5041 return true; 5042} 5043 5044// STRH (register) calculates an address from a base register value and an offset register value, and stores a 5045// halfword from a register to memory. The offset register alue can be shifted left by 0, 1, 2, or 3 bits. 5046bool 5047EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5048{ 5049#if 0 5050 if ConditionPassed() then 5051 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5052 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5053 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5054 address = if index then offset_addr else R[n]; 5055 if UnalignedSupport() || address<0> == '0' then 5056 MemU[address,2] = R[t]<15:0>; 5057 else // Can only occur before ARMv7 5058 MemU[address,2] = bits(16) UNKNOWN; 5059 if wback then R[n] = offset_addr; 5060#endif 5061 5062 bool success = false; 5063 5064 if (ConditionPassed(opcode)) 5065 { 5066 uint32_t t; 5067 uint32_t n; 5068 uint32_t m; 5069 bool index; 5070 bool add; 5071 bool wback; 5072 ARM_ShifterType shift_t; 5073 uint32_t shift_n; 5074 5075 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5076 switch (encoding) 5077 { 5078 case eEncodingT1: 5079 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5080 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5081 t = Bits32 (opcode, 2, 0); 5082 n = Bits32 (opcode, 5, 3); 5083 m = Bits32 (opcode, 8, 6); 5084 5085 // index = TRUE; add = TRUE; wback = FALSE; 5086 index = true; 5087 add = true; 5088 wback = false; 5089 5090 // (shift_t, shift_n) = (SRType_LSL, 0); 5091 shift_t = SRType_LSL; 5092 shift_n = 0; 5093 5094 break; 5095 5096 case eEncodingT2: 5097 // if Rn == '1111' then UNDEFINED; 5098 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5099 t = Bits32 (opcode, 15, 12); 5100 n = Bits32 (opcode, 19, 16); 5101 m = Bits32 (opcode, 3, 0); 5102 if (n == 15) 5103 return false; 5104 5105 // index = TRUE; add = TRUE; wback = FALSE; 5106 index = true; 5107 add = true; 5108 wback = false; 5109 5110 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5111 shift_t = SRType_LSL; 5112 shift_n = Bits32 (opcode, 5, 4); 5113 5114 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5115 if (BadReg (t) || BadReg (m)) 5116 return false; 5117 5118 break; 5119 5120 case eEncodingA1: 5121 // if P == '0' && W == '1' then SEE STRHT; 5122 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5123 t = Bits32 (opcode, 15, 12); 5124 n = Bits32 (opcode, 19, 16); 5125 m = Bits32 (opcode, 3, 0); 5126 5127 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5128 index = BitIsSet (opcode, 24); 5129 add = BitIsSet (opcode, 23); 5130 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5131 5132 // (shift_t, shift_n) = (SRType_LSL, 0); 5133 shift_t = SRType_LSL; 5134 shift_n = 0; 5135 5136 // if t == 15 || m == 15 then UNPREDICTABLE; 5137 if ((t == 15) || (m == 15)) 5138 return false; 5139 5140 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5141 if (wback && ((n == 15) || (n == t))) 5142 return false; 5143 5144 break; 5145 5146 default: 5147 return false; 5148 } 5149 5150 uint32_t Rm = ReadCoreReg (m, &success); 5151 if (!success) 5152 return false; 5153 5154 uint32_t Rn = ReadCoreReg (n, &success); 5155 if (!success) 5156 return false; 5157 5158 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5159 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5160 if (!success) 5161 return false; 5162 5163 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5164 addr_t offset_addr; 5165 if (add) 5166 offset_addr = Rn + offset; 5167 else 5168 offset_addr = Rn - offset; 5169 5170 // address = if index then offset_addr else R[n]; 5171 addr_t address; 5172 if (index) 5173 address = offset_addr; 5174 else 5175 address = Rn; 5176 5177 EmulateInstruction::Context context; 5178 context.type = eContextRegisterStore; 5179 RegisterInfo base_reg; 5180 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5181 RegisterInfo offset_reg; 5182 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5183 5184 // if UnalignedSupport() || address<0> == '0' then 5185 if (UnalignedSupport() || BitIsClear (address, 0)) 5186 { 5187 // MemU[address,2] = R[t]<15:0>; 5188 uint32_t Rt = ReadCoreReg (t, &success); 5189 if (!success) 5190 return false; 5191 5192 EmulateInstruction::Context context; 5193 context.type = eContextRegisterStore; 5194 RegisterInfo base_reg; 5195 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5196 RegisterInfo offset_reg; 5197 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5198 RegisterInfo data_reg; 5199 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5200 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5201 5202 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5203 return false; 5204 } 5205 else // Can only occur before ARMv7 5206 { 5207 // MemU[address,2] = bits(16) UNKNOWN; 5208 } 5209 5210 // if wback then R[n] = offset_addr; 5211 if (wback) 5212 { 5213 context.type = eContextAdjustBaseRegister; 5214 context.SetAddress (offset_addr); 5215 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5216 return false; 5217 } 5218 } 5219 5220 return true; 5221} 5222 5223// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5224// and writes the result to the destination register. It can optionally update the condition flags 5225// based on the result. 5226bool 5227EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5228{ 5229#if 0 5230 // ARM pseudo code... 5231 if ConditionPassed() then 5232 EncodingSpecificOperations(); 5233 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5234 if d == 15 then // Can only occur for ARM encoding 5235 ALUWritePC(result); // setflags is always FALSE here 5236 else 5237 R[d] = result; 5238 if setflags then 5239 APSR.N = result<31>; 5240 APSR.Z = IsZeroBit(result); 5241 APSR.C = carry; 5242 APSR.V = overflow; 5243#endif 5244 5245 bool success = false; 5246 5247 if (ConditionPassed(opcode)) 5248 { 5249 uint32_t Rd, Rn; 5250 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5251 bool setflags; 5252 switch (encoding) 5253 { 5254 case eEncodingT1: 5255 Rd = Bits32(opcode, 11, 8); 5256 Rn = Bits32(opcode, 19, 16); 5257 setflags = BitIsSet(opcode, 20); 5258 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5259 if (BadReg(Rd) || BadReg(Rn)) 5260 return false; 5261 break; 5262 case eEncodingA1: 5263 Rd = Bits32(opcode, 15, 12); 5264 Rn = Bits32(opcode, 19, 16); 5265 setflags = BitIsSet(opcode, 20); 5266 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5267 5268 if (Rd == 15 && setflags) 5269 return EmulateSUBSPcLrEtc (opcode, encoding); 5270 break; 5271 default: 5272 return false; 5273 } 5274 5275 // Read the first operand. 5276 int32_t val1 = ReadCoreReg(Rn, &success); 5277 if (!success) 5278 return false; 5279 5280 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5281 5282 EmulateInstruction::Context context; 5283 context.type = EmulateInstruction::eContextImmediate; 5284 context.SetNoArgs (); 5285 5286 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5287 return false; 5288 } 5289 return true; 5290} 5291 5292// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5293// register value, and writes the result to the destination register. It can optionally update the 5294// condition flags based on the result. 5295bool 5296EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5297{ 5298#if 0 5299 // ARM pseudo code... 5300 if ConditionPassed() then 5301 EncodingSpecificOperations(); 5302 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5303 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5304 if d == 15 then // Can only occur for ARM encoding 5305 ALUWritePC(result); // setflags is always FALSE here 5306 else 5307 R[d] = result; 5308 if setflags then 5309 APSR.N = result<31>; 5310 APSR.Z = IsZeroBit(result); 5311 APSR.C = carry; 5312 APSR.V = overflow; 5313#endif 5314 5315 bool success = false; 5316 5317 if (ConditionPassed(opcode)) 5318 { 5319 uint32_t Rd, Rn, Rm; 5320 ARM_ShifterType shift_t; 5321 uint32_t shift_n; // the shift applied to the value read from Rm 5322 bool setflags; 5323 switch (encoding) 5324 { 5325 case eEncodingT1: 5326 Rd = Rn = Bits32(opcode, 2, 0); 5327 Rm = Bits32(opcode, 5, 3); 5328 setflags = !InITBlock(); 5329 shift_t = SRType_LSL; 5330 shift_n = 0; 5331 break; 5332 case eEncodingT2: 5333 Rd = Bits32(opcode, 11, 8); 5334 Rn = Bits32(opcode, 19, 16); 5335 Rm = Bits32(opcode, 3, 0); 5336 setflags = BitIsSet(opcode, 20); 5337 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5338 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5339 return false; 5340 break; 5341 case eEncodingA1: 5342 Rd = Bits32(opcode, 15, 12); 5343 Rn = Bits32(opcode, 19, 16); 5344 Rm = Bits32(opcode, 3, 0); 5345 setflags = BitIsSet(opcode, 20); 5346 shift_n = DecodeImmShiftARM(opcode, shift_t); 5347 5348 if (Rd == 15 && setflags) 5349 return EmulateSUBSPcLrEtc (opcode, encoding); 5350 break; 5351 default: 5352 return false; 5353 } 5354 5355 // Read the first operand. 5356 int32_t val1 = ReadCoreReg(Rn, &success); 5357 if (!success) 5358 return false; 5359 5360 // Read the second operand. 5361 int32_t val2 = ReadCoreReg(Rm, &success); 5362 if (!success) 5363 return false; 5364 5365 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5366 if (!success) 5367 return false; 5368 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5369 5370 EmulateInstruction::Context context; 5371 context.type = EmulateInstruction::eContextImmediate; 5372 context.SetNoArgs (); 5373 5374 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5375 return false; 5376 } 5377 return true; 5378} 5379 5380// This instruction adds an immediate value to the PC value to form a PC-relative address, 5381// and writes the result to the destination register. 5382bool 5383EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5384{ 5385#if 0 5386 // ARM pseudo code... 5387 if ConditionPassed() then 5388 EncodingSpecificOperations(); 5389 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5390 if d == 15 then // Can only occur for ARM encodings 5391 ALUWritePC(result); 5392 else 5393 R[d] = result; 5394#endif 5395 5396 bool success = false; 5397 5398 if (ConditionPassed(opcode)) 5399 { 5400 uint32_t Rd; 5401 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5402 bool add; 5403 switch (encoding) 5404 { 5405 case eEncodingT1: 5406 Rd = Bits32(opcode, 10, 8); 5407 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5408 add = true; 5409 break; 5410 case eEncodingT2: 5411 case eEncodingT3: 5412 Rd = Bits32(opcode, 11, 8); 5413 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5414 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5415 if (BadReg(Rd)) 5416 return false; 5417 break; 5418 case eEncodingA1: 5419 case eEncodingA2: 5420 Rd = Bits32(opcode, 15, 12); 5421 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5422 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5423 break; 5424 default: 5425 return false; 5426 } 5427 5428 // Read the PC value. 5429 uint32_t pc = ReadCoreReg(PC_REG, &success); 5430 if (!success) 5431 return false; 5432 5433 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5434 5435 EmulateInstruction::Context context; 5436 context.type = EmulateInstruction::eContextImmediate; 5437 context.SetNoArgs (); 5438 5439 if (!WriteCoreReg(context, result, Rd)) 5440 return false; 5441 } 5442 return true; 5443} 5444 5445// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5446// to the destination register. It can optionally update the condition flags based on the result. 5447bool 5448EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5449{ 5450#if 0 5451 // ARM pseudo code... 5452 if ConditionPassed() then 5453 EncodingSpecificOperations(); 5454 result = R[n] AND imm32; 5455 if d == 15 then // Can only occur for ARM encoding 5456 ALUWritePC(result); // setflags is always FALSE here 5457 else 5458 R[d] = result; 5459 if setflags then 5460 APSR.N = result<31>; 5461 APSR.Z = IsZeroBit(result); 5462 APSR.C = carry; 5463 // APSR.V unchanged 5464#endif 5465 5466 bool success = false; 5467 5468 if (ConditionPassed(opcode)) 5469 { 5470 uint32_t Rd, Rn; 5471 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5472 bool setflags; 5473 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5474 switch (encoding) 5475 { 5476 case eEncodingT1: 5477 Rd = Bits32(opcode, 11, 8); 5478 Rn = Bits32(opcode, 19, 16); 5479 setflags = BitIsSet(opcode, 20); 5480 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5481 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5482 if (Rd == 15 && setflags) 5483 return EmulateTSTImm(opcode, eEncodingT1); 5484 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5485 return false; 5486 break; 5487 case eEncodingA1: 5488 Rd = Bits32(opcode, 15, 12); 5489 Rn = Bits32(opcode, 19, 16); 5490 setflags = BitIsSet(opcode, 20); 5491 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5492 5493 if (Rd == 15 && setflags) 5494 return EmulateSUBSPcLrEtc (opcode, encoding); 5495 break; 5496 default: 5497 return false; 5498 } 5499 5500 // Read the first operand. 5501 uint32_t val1 = ReadCoreReg(Rn, &success); 5502 if (!success) 5503 return false; 5504 5505 uint32_t result = val1 & imm32; 5506 5507 EmulateInstruction::Context context; 5508 context.type = EmulateInstruction::eContextImmediate; 5509 context.SetNoArgs (); 5510 5511 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5512 return false; 5513 } 5514 return true; 5515} 5516 5517// This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5518// and writes the result to the destination register. It can optionally update the condition flags 5519// based on the result. 5520bool 5521EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5522{ 5523#if 0 5524 // ARM pseudo code... 5525 if ConditionPassed() then 5526 EncodingSpecificOperations(); 5527 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5528 result = R[n] AND shifted; 5529 if d == 15 then // Can only occur for ARM encoding 5530 ALUWritePC(result); // setflags is always FALSE here 5531 else 5532 R[d] = result; 5533 if setflags then 5534 APSR.N = result<31>; 5535 APSR.Z = IsZeroBit(result); 5536 APSR.C = carry; 5537 // APSR.V unchanged 5538#endif 5539 5540 bool success = false; 5541 5542 if (ConditionPassed(opcode)) 5543 { 5544 uint32_t Rd, Rn, Rm; 5545 ARM_ShifterType shift_t; 5546 uint32_t shift_n; // the shift applied to the value read from Rm 5547 bool setflags; 5548 uint32_t carry; 5549 switch (encoding) 5550 { 5551 case eEncodingT1: 5552 Rd = Rn = Bits32(opcode, 2, 0); 5553 Rm = Bits32(opcode, 5, 3); 5554 setflags = !InITBlock(); 5555 shift_t = SRType_LSL; 5556 shift_n = 0; 5557 break; 5558 case eEncodingT2: 5559 Rd = Bits32(opcode, 11, 8); 5560 Rn = Bits32(opcode, 19, 16); 5561 Rm = Bits32(opcode, 3, 0); 5562 setflags = BitIsSet(opcode, 20); 5563 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5564 // if Rd == '1111' && S == '1' then SEE TST (register); 5565 if (Rd == 15 && setflags) 5566 return EmulateTSTReg(opcode, eEncodingT2); 5567 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5568 return false; 5569 break; 5570 case eEncodingA1: 5571 Rd = Bits32(opcode, 15, 12); 5572 Rn = Bits32(opcode, 19, 16); 5573 Rm = Bits32(opcode, 3, 0); 5574 setflags = BitIsSet(opcode, 20); 5575 shift_n = DecodeImmShiftARM(opcode, shift_t); 5576 5577 if (Rd == 15 && setflags) 5578 return EmulateSUBSPcLrEtc (opcode, encoding); 5579 break; 5580 default: 5581 return false; 5582 } 5583 5584 // Read the first operand. 5585 uint32_t val1 = ReadCoreReg(Rn, &success); 5586 if (!success) 5587 return false; 5588 5589 // Read the second operand. 5590 uint32_t val2 = ReadCoreReg(Rm, &success); 5591 if (!success) 5592 return false; 5593 5594 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5595 if (!success) 5596 return false; 5597 uint32_t result = val1 & shifted; 5598 5599 EmulateInstruction::Context context; 5600 context.type = EmulateInstruction::eContextImmediate; 5601 context.SetNoArgs (); 5602 5603 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5604 return false; 5605 } 5606 return true; 5607} 5608 5609// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5610// immediate value, and writes the result to the destination register. It can optionally update the 5611// condition flags based on the result. 5612bool 5613EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5614{ 5615#if 0 5616 // ARM pseudo code... 5617 if ConditionPassed() then 5618 EncodingSpecificOperations(); 5619 result = R[n] AND NOT(imm32); 5620 if d == 15 then // Can only occur for ARM encoding 5621 ALUWritePC(result); // setflags is always FALSE here 5622 else 5623 R[d] = result; 5624 if setflags then 5625 APSR.N = result<31>; 5626 APSR.Z = IsZeroBit(result); 5627 APSR.C = carry; 5628 // APSR.V unchanged 5629#endif 5630 5631 bool success = false; 5632 5633 if (ConditionPassed(opcode)) 5634 { 5635 uint32_t Rd, Rn; 5636 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5637 bool setflags; 5638 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5639 switch (encoding) 5640 { 5641 case eEncodingT1: 5642 Rd = Bits32(opcode, 11, 8); 5643 Rn = Bits32(opcode, 19, 16); 5644 setflags = BitIsSet(opcode, 20); 5645 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5646 if (BadReg(Rd) || BadReg(Rn)) 5647 return false; 5648 break; 5649 case eEncodingA1: 5650 Rd = Bits32(opcode, 15, 12); 5651 Rn = Bits32(opcode, 19, 16); 5652 setflags = BitIsSet(opcode, 20); 5653 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5654 5655 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5656 if (Rd == 15 && setflags) 5657 return EmulateSUBSPcLrEtc (opcode, encoding); 5658 break; 5659 default: 5660 return false; 5661 } 5662 5663 // Read the first operand. 5664 uint32_t val1 = ReadCoreReg(Rn, &success); 5665 if (!success) 5666 return false; 5667 5668 uint32_t result = val1 & ~imm32; 5669 5670 EmulateInstruction::Context context; 5671 context.type = EmulateInstruction::eContextImmediate; 5672 context.SetNoArgs (); 5673 5674 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5675 return false; 5676 } 5677 return true; 5678} 5679 5680// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5681// optionally-shifted register value, and writes the result to the destination register. 5682// It can optionally update the condition flags based on the result. 5683bool 5684EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5685{ 5686#if 0 5687 // ARM pseudo code... 5688 if ConditionPassed() then 5689 EncodingSpecificOperations(); 5690 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5691 result = R[n] AND NOT(shifted); 5692 if d == 15 then // Can only occur for ARM encoding 5693 ALUWritePC(result); // setflags is always FALSE here 5694 else 5695 R[d] = result; 5696 if setflags then 5697 APSR.N = result<31>; 5698 APSR.Z = IsZeroBit(result); 5699 APSR.C = carry; 5700 // APSR.V unchanged 5701#endif 5702 5703 bool success = false; 5704 5705 if (ConditionPassed(opcode)) 5706 { 5707 uint32_t Rd, Rn, Rm; 5708 ARM_ShifterType shift_t; 5709 uint32_t shift_n; // the shift applied to the value read from Rm 5710 bool setflags; 5711 uint32_t carry; 5712 switch (encoding) 5713 { 5714 case eEncodingT1: 5715 Rd = Rn = Bits32(opcode, 2, 0); 5716 Rm = Bits32(opcode, 5, 3); 5717 setflags = !InITBlock(); 5718 shift_t = SRType_LSL; 5719 shift_n = 0; 5720 break; 5721 case eEncodingT2: 5722 Rd = Bits32(opcode, 11, 8); 5723 Rn = Bits32(opcode, 19, 16); 5724 Rm = Bits32(opcode, 3, 0); 5725 setflags = BitIsSet(opcode, 20); 5726 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5727 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5728 return false; 5729 break; 5730 case eEncodingA1: 5731 Rd = Bits32(opcode, 15, 12); 5732 Rn = Bits32(opcode, 19, 16); 5733 Rm = Bits32(opcode, 3, 0); 5734 setflags = BitIsSet(opcode, 20); 5735 shift_n = DecodeImmShiftARM(opcode, shift_t); 5736 5737 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5738 if (Rd == 15 && setflags) 5739 return EmulateSUBSPcLrEtc (opcode, encoding); 5740 break; 5741 default: 5742 return false; 5743 } 5744 5745 // Read the first operand. 5746 uint32_t val1 = ReadCoreReg(Rn, &success); 5747 if (!success) 5748 return false; 5749 5750 // Read the second operand. 5751 uint32_t val2 = ReadCoreReg(Rm, &success); 5752 if (!success) 5753 return false; 5754 5755 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5756 if (!success) 5757 return false; 5758 uint32_t result = val1 & ~shifted; 5759 5760 EmulateInstruction::Context context; 5761 context.type = EmulateInstruction::eContextImmediate; 5762 context.SetNoArgs (); 5763 5764 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5765 return false; 5766 } 5767 return true; 5768} 5769 5770// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5771// from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5772bool 5773EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5774{ 5775#if 0 5776 if ConditionPassed() then 5777 EncodingSpecificOperations(); 5778 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5779 address = if index then offset_addr else R[n]; 5780 data = MemU[address,4]; 5781 if wback then R[n] = offset_addr; 5782 if t == 15 then 5783 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5784 elsif UnalignedSupport() || address<1:0> = '00' then 5785 R[t] = data; 5786 else // Can only apply before ARMv7 5787 R[t] = ROR(data, 8*UInt(address<1:0>)); 5788#endif 5789 5790 bool success = false; 5791 5792 if (ConditionPassed(opcode)) 5793 { 5794 const uint32_t addr_byte_size = GetAddressByteSize(); 5795 5796 uint32_t t; 5797 uint32_t n; 5798 uint32_t imm32; 5799 bool index; 5800 bool add; 5801 bool wback; 5802 5803 switch (encoding) 5804 { 5805 case eEncodingA1: 5806 // if Rn == '1111' then SEE LDR (literal); 5807 // if P == '0' && W == '1' then SEE LDRT; 5808 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5809 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5810 t = Bits32 (opcode, 15, 12); 5811 n = Bits32 (opcode, 19, 16); 5812 imm32 = Bits32 (opcode, 11, 0); 5813 5814 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5815 index = BitIsSet (opcode, 24); 5816 add = BitIsSet (opcode, 23); 5817 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5818 5819 // if wback && n == t then UNPREDICTABLE; 5820 if (wback && (n == t)) 5821 return false; 5822 5823 break; 5824 5825 default: 5826 return false; 5827 } 5828 5829 addr_t address; 5830 addr_t offset_addr; 5831 addr_t base_address = ReadCoreReg (n, &success); 5832 if (!success) 5833 return false; 5834 5835 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5836 if (add) 5837 offset_addr = base_address + imm32; 5838 else 5839 offset_addr = base_address - imm32; 5840 5841 // address = if index then offset_addr else R[n]; 5842 if (index) 5843 address = offset_addr; 5844 else 5845 address = base_address; 5846 5847 // data = MemU[address,4]; 5848 5849 RegisterInfo base_reg; 5850 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5851 5852 EmulateInstruction::Context context; 5853 context.type = eContextRegisterLoad; 5854 context.SetRegisterPlusOffset (base_reg, address - base_address); 5855 5856 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5857 if (!success) 5858 return false; 5859 5860 // if wback then R[n] = offset_addr; 5861 if (wback) 5862 { 5863 context.type = eContextAdjustBaseRegister; 5864 context.SetAddress (offset_addr); 5865 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5866 return false; 5867 } 5868 5869 // if t == 15 then 5870 if (t == 15) 5871 { 5872 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5873 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5874 { 5875 // LoadWritePC (data); 5876 context.type = eContextRegisterLoad; 5877 context.SetRegisterPlusOffset (base_reg, address - base_address); 5878 LoadWritePC (context, data); 5879 } 5880 else 5881 return false; 5882 } 5883 // elsif UnalignedSupport() || address<1:0> = '00' then 5884 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5885 { 5886 // R[t] = data; 5887 context.type = eContextRegisterLoad; 5888 context.SetRegisterPlusOffset (base_reg, address - base_address); 5889 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5890 return false; 5891 } 5892 // else // Can only apply before ARMv7 5893 else 5894 { 5895 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5896 data = ROR (data, Bits32 (address, 1, 0), &success); 5897 if (!success) 5898 return false; 5899 context.type = eContextRegisterLoad; 5900 context.SetImmediate (data); 5901 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5902 return false; 5903 } 5904 5905 } 5906 return true; 5907} 5908 5909// LDR (register) calculates an address from a base register value and an offset register value, loads a word 5910// from memory, and writes it to a resgister. The offset register value can optionally be shifted. 5911bool 5912EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5913{ 5914#if 0 5915 if ConditionPassed() then 5916 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5917 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5918 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5919 address = if index then offset_addr else R[n]; 5920 data = MemU[address,4]; 5921 if wback then R[n] = offset_addr; 5922 if t == 15 then 5923 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5924 elsif UnalignedSupport() || address<1:0> = '00' then 5925 R[t] = data; 5926 else // Can only apply before ARMv7 5927 if CurrentInstrSet() == InstrSet_ARM then 5928 R[t] = ROR(data, 8*UInt(address<1:0>)); 5929 else 5930 R[t] = bits(32) UNKNOWN; 5931#endif 5932 5933 bool success = false; 5934 5935 if (ConditionPassed(opcode)) 5936 { 5937 const uint32_t addr_byte_size = GetAddressByteSize(); 5938 5939 uint32_t t; 5940 uint32_t n; 5941 uint32_t m; 5942 bool index; 5943 bool add; 5944 bool wback; 5945 ARM_ShifterType shift_t; 5946 uint32_t shift_n; 5947 5948 switch (encoding) 5949 { 5950 case eEncodingT1: 5951 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5952 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5953 t = Bits32 (opcode, 2, 0); 5954 n = Bits32 (opcode, 5, 3); 5955 m = Bits32 (opcode, 8, 6); 5956 5957 // index = TRUE; add = TRUE; wback = FALSE; 5958 index = true; 5959 add = true; 5960 wback = false; 5961 5962 // (shift_t, shift_n) = (SRType_LSL, 0); 5963 shift_t = SRType_LSL; 5964 shift_n = 0; 5965 5966 break; 5967 5968 case eEncodingT2: 5969 // if Rn == '1111' then SEE LDR (literal); 5970 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5971 t = Bits32 (opcode, 15, 12); 5972 n = Bits32 (opcode, 19, 16); 5973 m = Bits32 (opcode, 3, 0); 5974 5975 // index = TRUE; add = TRUE; wback = FALSE; 5976 index = true; 5977 add = true; 5978 wback = false; 5979 5980 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5981 shift_t = SRType_LSL; 5982 shift_n = Bits32 (opcode, 5, 4); 5983 5984 // if BadReg(m) then UNPREDICTABLE; 5985 if (BadReg (m)) 5986 return false; 5987 5988 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5989 if ((t == 15) && InITBlock() && !LastInITBlock()) 5990 return false; 5991 5992 break; 5993 5994 case eEncodingA1: 5995 { 5996 // if P == '0' && W == '1' then SEE LDRT; 5997 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5998 t = Bits32 (opcode, 15, 12); 5999 n = Bits32 (opcode, 19, 16); 6000 m = Bits32 (opcode, 3, 0); 6001 6002 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6003 index = BitIsSet (opcode, 24); 6004 add = BitIsSet (opcode, 23); 6005 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6006 6007 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6008 uint32_t type = Bits32 (opcode, 6, 5); 6009 uint32_t imm5 = Bits32 (opcode, 11, 7); 6010 shift_n = DecodeImmShift (type, imm5, shift_t); 6011 6012 // if m == 15 then UNPREDICTABLE; 6013 if (m == 15) 6014 return false; 6015 6016 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6017 if (wback && ((n == 15) || (n == t))) 6018 return false; 6019 } 6020 break; 6021 6022 6023 default: 6024 return false; 6025 } 6026 6027 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6028 if (!success) 6029 return false; 6030 6031 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6032 if (!success) 6033 return false; 6034 6035 addr_t offset_addr; 6036 addr_t address; 6037 6038 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6039 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6040 if (!success) 6041 return false; 6042 6043 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6044 if (add) 6045 offset_addr = Rn + offset; 6046 else 6047 offset_addr = Rn - offset; 6048 6049 // address = if index then offset_addr else R[n]; 6050 if (index) 6051 address = offset_addr; 6052 else 6053 address = Rn; 6054 6055 // data = MemU[address,4]; 6056 RegisterInfo base_reg; 6057 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6058 6059 EmulateInstruction::Context context; 6060 context.type = eContextRegisterLoad; 6061 context.SetRegisterPlusOffset (base_reg, address - Rn); 6062 6063 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6064 if (!success) 6065 return false; 6066 6067 // if wback then R[n] = offset_addr; 6068 if (wback) 6069 { 6070 context.type = eContextAdjustBaseRegister; 6071 context.SetAddress (offset_addr); 6072 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6073 return false; 6074 } 6075 6076 // if t == 15 then 6077 if (t == 15) 6078 { 6079 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6080 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6081 { 6082 context.type = eContextRegisterLoad; 6083 context.SetRegisterPlusOffset (base_reg, address - Rn); 6084 LoadWritePC (context, data); 6085 } 6086 else 6087 return false; 6088 } 6089 // elsif UnalignedSupport() || address<1:0> = '00' then 6090 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6091 { 6092 // R[t] = data; 6093 context.type = eContextRegisterLoad; 6094 context.SetRegisterPlusOffset (base_reg, address - Rn); 6095 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6096 return false; 6097 } 6098 else // Can only apply before ARMv7 6099 { 6100 // if CurrentInstrSet() == InstrSet_ARM then 6101 if (CurrentInstrSet () == eModeARM) 6102 { 6103 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6104 data = ROR (data, Bits32 (address, 1, 0), &success); 6105 if (!success) 6106 return false; 6107 context.type = eContextRegisterLoad; 6108 context.SetImmediate (data); 6109 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6110 return false; 6111 } 6112 else 6113 { 6114 // R[t] = bits(32) UNKNOWN; 6115 WriteBits32Unknown (t); 6116 } 6117 } 6118 } 6119 return true; 6120} 6121 6122// LDRB (immediate, Thumb) 6123bool 6124EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6125{ 6126#if 0 6127 if ConditionPassed() then 6128 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6129 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6130 address = if index then offset_addr else R[n]; 6131 R[t] = ZeroExtend(MemU[address,1], 32); 6132 if wback then R[n] = offset_addr; 6133#endif 6134 6135 bool success = false; 6136 6137 if (ConditionPassed(opcode)) 6138 { 6139 uint32_t t; 6140 uint32_t n; 6141 uint32_t imm32; 6142 bool index; 6143 bool add; 6144 bool wback; 6145 6146 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6147 switch (encoding) 6148 { 6149 case eEncodingT1: 6150 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6151 t = Bits32 (opcode, 2, 0); 6152 n = Bits32 (opcode, 5, 3); 6153 imm32 = Bits32 (opcode, 10, 6); 6154 6155 // index = TRUE; add = TRUE; wback = FALSE; 6156 index = true; 6157 add = true; 6158 wback= false; 6159 6160 break; 6161 6162 case eEncodingT2: 6163 // if Rt == '1111' then SEE PLD; 6164 // if Rn == '1111' then SEE LDRB (literal); 6165 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6166 t = Bits32 (opcode, 15, 12); 6167 n = Bits32 (opcode, 19, 16); 6168 imm32 = Bits32 (opcode, 11, 0); 6169 6170 // index = TRUE; add = TRUE; wback = FALSE; 6171 index = true; 6172 add = true; 6173 wback = false; 6174 6175 // if t == 13 then UNPREDICTABLE; 6176 if (t == 13) 6177 return false; 6178 6179 break; 6180 6181 case eEncodingT3: 6182 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6183 // if Rn == '1111' then SEE LDRB (literal); 6184 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6185 // if P == '0' && W == '0' then UNDEFINED; 6186 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6187 return false; 6188 6189 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6190 t = Bits32 (opcode, 15, 12); 6191 n = Bits32 (opcode, 19, 16); 6192 imm32 = Bits32 (opcode, 7, 0); 6193 6194 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6195 index = BitIsSet (opcode, 10); 6196 add = BitIsSet (opcode, 9); 6197 wback = BitIsSet (opcode, 8); 6198 6199 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6200 if (BadReg (t) || (wback && (n == t))) 6201 return false; 6202 6203 break; 6204 6205 default: 6206 return false; 6207 } 6208 6209 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6210 if (!success) 6211 return false; 6212 6213 addr_t address; 6214 addr_t offset_addr; 6215 6216 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6217 if (add) 6218 offset_addr = Rn + imm32; 6219 else 6220 offset_addr = Rn - imm32; 6221 6222 // address = if index then offset_addr else R[n]; 6223 if (index) 6224 address = offset_addr; 6225 else 6226 address = Rn; 6227 6228 // R[t] = ZeroExtend(MemU[address,1], 32); 6229 RegisterInfo base_reg; 6230 RegisterInfo data_reg; 6231 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6232 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6233 6234 EmulateInstruction::Context context; 6235 context.type = eContextRegisterLoad; 6236 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6237 6238 uint64_t data = MemURead (context, address, 1, 0, &success); 6239 if (!success) 6240 return false; 6241 6242 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6243 return false; 6244 6245 // if wback then R[n] = offset_addr; 6246 if (wback) 6247 { 6248 context.type = eContextAdjustBaseRegister; 6249 context.SetAddress (offset_addr); 6250 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6251 return false; 6252 } 6253 } 6254 return true; 6255} 6256 6257// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6258// zero-extends it to form a 32-bit word and writes it to a register. 6259bool 6260EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6261{ 6262#if 0 6263 if ConditionPassed() then 6264 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6265 base = Align(PC,4); 6266 address = if add then (base + imm32) else (base - imm32); 6267 R[t] = ZeroExtend(MemU[address,1], 32); 6268#endif 6269 6270 bool success = false; 6271 6272 if (ConditionPassed(opcode)) 6273 { 6274 uint32_t t; 6275 uint32_t imm32; 6276 bool add; 6277 switch (encoding) 6278 { 6279 case eEncodingT1: 6280 // if Rt == '1111' then SEE PLD; 6281 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6282 t = Bits32 (opcode, 15, 12); 6283 imm32 = Bits32 (opcode, 11, 0); 6284 add = BitIsSet (opcode, 23); 6285 6286 // if t == 13 then UNPREDICTABLE; 6287 if (t == 13) 6288 return false; 6289 6290 break; 6291 6292 case eEncodingA1: 6293 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6294 t = Bits32 (opcode, 15, 12); 6295 imm32 = Bits32 (opcode, 11, 0); 6296 add = BitIsSet (opcode, 23); 6297 6298 // if t == 15 then UNPREDICTABLE; 6299 if (t == 15) 6300 return false; 6301 break; 6302 6303 default: 6304 return false; 6305 } 6306 6307 // base = Align(PC,4); 6308 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6309 if (!success) 6310 return false; 6311 6312 uint32_t base = AlignPC (pc_val); 6313 6314 addr_t address; 6315 // address = if add then (base + imm32) else (base - imm32); 6316 if (add) 6317 address = base + imm32; 6318 else 6319 address = base - imm32; 6320 6321 // R[t] = ZeroExtend(MemU[address,1], 32); 6322 EmulateInstruction::Context context; 6323 context.type = eContextRelativeBranchImmediate; 6324 context.SetImmediate (address - base); 6325 6326 uint64_t data = MemURead (context, address, 1, 0, &success); 6327 if (!success) 6328 return false; 6329 6330 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6331 return false; 6332 } 6333 return true; 6334} 6335 6336// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6337// memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6338// optionally be shifted. 6339bool 6340EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6341{ 6342#if 0 6343 if ConditionPassed() then 6344 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6345 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6346 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6347 address = if index then offset_addr else R[n]; 6348 R[t] = ZeroExtend(MemU[address,1],32); 6349 if wback then R[n] = offset_addr; 6350#endif 6351 6352 bool success = false; 6353 6354 if (ConditionPassed(opcode)) 6355 { 6356 uint32_t t; 6357 uint32_t n; 6358 uint32_t m; 6359 bool index; 6360 bool add; 6361 bool wback; 6362 ARM_ShifterType shift_t; 6363 uint32_t shift_n; 6364 6365 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6366 switch (encoding) 6367 { 6368 case eEncodingT1: 6369 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6370 t = Bits32 (opcode, 2, 0); 6371 n = Bits32 (opcode, 5, 3); 6372 m = Bits32 (opcode, 8, 6); 6373 6374 // index = TRUE; add = TRUE; wback = FALSE; 6375 index = true; 6376 add = true; 6377 wback = false; 6378 6379 // (shift_t, shift_n) = (SRType_LSL, 0); 6380 shift_t = SRType_LSL; 6381 shift_n = 0; 6382 break; 6383 6384 case eEncodingT2: 6385 // if Rt == '1111' then SEE PLD; 6386 // if Rn == '1111' then SEE LDRB (literal); 6387 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6388 t = Bits32 (opcode, 15, 12); 6389 n = Bits32 (opcode, 19, 16); 6390 m = Bits32 (opcode, 3, 0); 6391 6392 // index = TRUE; add = TRUE; wback = FALSE; 6393 index = true; 6394 add = true; 6395 wback = false; 6396 6397 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6398 shift_t = SRType_LSL; 6399 shift_n = Bits32 (opcode, 5, 4); 6400 6401 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6402 if ((t == 13) || BadReg (m)) 6403 return false; 6404 break; 6405 6406 case eEncodingA1: 6407 { 6408 // if P == '0' && W == '1' then SEE LDRBT; 6409 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6410 t = Bits32 (opcode, 15, 12); 6411 n = Bits32 (opcode, 19, 16); 6412 m = Bits32 (opcode, 3, 0); 6413 6414 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6415 index = BitIsSet (opcode, 24); 6416 add = BitIsSet (opcode, 23); 6417 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6418 6419 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6420 uint32_t type = Bits32 (opcode, 6, 5); 6421 uint32_t imm5 = Bits32 (opcode, 11, 7); 6422 shift_n = DecodeImmShift (type, imm5, shift_t); 6423 6424 // if t == 15 || m == 15 then UNPREDICTABLE; 6425 if ((t == 15) || (m == 15)) 6426 return false; 6427 6428 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6429 if (wback && ((n == 15) || (n == t))) 6430 return false; 6431 } 6432 break; 6433 6434 default: 6435 return false; 6436 } 6437 6438 addr_t offset_addr; 6439 addr_t address; 6440 6441 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6442 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6443 if (!success) 6444 return false; 6445 6446 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6447 if (!success) 6448 return false; 6449 6450 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6451 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6452 if (!success) 6453 return false; 6454 6455 if (add) 6456 offset_addr = Rn + offset; 6457 else 6458 offset_addr = Rn - offset; 6459 6460 // address = if index then offset_addr else R[n]; 6461 if (index) 6462 address = offset_addr; 6463 else 6464 address = Rn; 6465 6466 // R[t] = ZeroExtend(MemU[address,1],32); 6467 RegisterInfo base_reg; 6468 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6469 6470 EmulateInstruction::Context context; 6471 context.type = eContextRegisterLoad; 6472 context.SetRegisterPlusOffset (base_reg, address - Rn); 6473 6474 uint64_t data = MemURead (context, address, 1, 0, &success); 6475 if (!success) 6476 return false; 6477 6478 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6479 return false; 6480 6481 // if wback then R[n] = offset_addr; 6482 if (wback) 6483 { 6484 context.type = eContextAdjustBaseRegister; 6485 context.SetAddress (offset_addr); 6486 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6487 return false; 6488 } 6489 } 6490 return true; 6491} 6492 6493// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6494// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6495// post-indexed, or pre-indexed addressing. 6496bool 6497EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6498{ 6499#if 0 6500 if ConditionPassed() then 6501 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6502 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6503 address = if index then offset_addr else R[n]; 6504 data = MemU[address,2]; 6505 if wback then R[n] = offset_addr; 6506 if UnalignedSupport() || address<0> = '0' then 6507 R[t] = ZeroExtend(data, 32); 6508 else // Can only apply before ARMv7 6509 R[t] = bits(32) UNKNOWN; 6510#endif 6511 6512 6513 bool success = false; 6514 6515 if (ConditionPassed(opcode)) 6516 { 6517 uint32_t t; 6518 uint32_t n; 6519 uint32_t imm32; 6520 bool index; 6521 bool add; 6522 bool wback; 6523 6524 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6525 switch (encoding) 6526 { 6527 case eEncodingT1: 6528 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6529 t = Bits32 (opcode, 2, 0); 6530 n = Bits32 (opcode, 5, 3); 6531 imm32 = Bits32 (opcode, 10, 6) << 1; 6532 6533 // index = TRUE; add = TRUE; wback = FALSE; 6534 index = true; 6535 add = true; 6536 wback = false; 6537 6538 break; 6539 6540 case eEncodingT2: 6541 // if Rt == '1111' then SEE "Unallocated memory hints"; 6542 // if Rn == '1111' then SEE LDRH (literal); 6543 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6544 t = Bits32 (opcode, 15, 12); 6545 n = Bits32 (opcode, 19, 16); 6546 imm32 = Bits32 (opcode, 11, 0); 6547 6548 // index = TRUE; add = TRUE; wback = FALSE; 6549 index = true; 6550 add = true; 6551 wback = false; 6552 6553 // if t == 13 then UNPREDICTABLE; 6554 if (t == 13) 6555 return false; 6556 break; 6557 6558 case eEncodingT3: 6559 // if Rn == '1111' then SEE LDRH (literal); 6560 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6561 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6562 // if P == '0' && W == '0' then UNDEFINED; 6563 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6564 return false; 6565 6566 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6567 t = Bits32 (opcode, 15, 12); 6568 n = Bits32 (opcode, 19, 16); 6569 imm32 = Bits32 (opcode, 7, 0); 6570 6571 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6572 index = BitIsSet (opcode, 10); 6573 add = BitIsSet (opcode, 9); 6574 wback = BitIsSet (opcode, 8); 6575 6576 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6577 if (BadReg (t) || (wback && (n == t))) 6578 return false; 6579 break; 6580 6581 default: 6582 return false; 6583 } 6584 6585 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6586 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6587 if (!success) 6588 return false; 6589 6590 addr_t offset_addr; 6591 addr_t address; 6592 6593 if (add) 6594 offset_addr = Rn + imm32; 6595 else 6596 offset_addr = Rn - imm32; 6597 6598 // address = if index then offset_addr else R[n]; 6599 if (index) 6600 address = offset_addr; 6601 else 6602 address = Rn; 6603 6604 // data = MemU[address,2]; 6605 RegisterInfo base_reg; 6606 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6607 6608 EmulateInstruction::Context context; 6609 context.type = eContextRegisterLoad; 6610 context.SetRegisterPlusOffset (base_reg, address - Rn); 6611 6612 uint64_t data = MemURead (context, address, 2, 0, &success); 6613 if (!success) 6614 return false; 6615 6616 // if wback then R[n] = offset_addr; 6617 if (wback) 6618 { 6619 context.type = eContextAdjustBaseRegister; 6620 context.SetAddress (offset_addr); 6621 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6622 return false; 6623 } 6624 6625 // if UnalignedSupport() || address<0> = '0' then 6626 if (UnalignedSupport () || BitIsClear (address, 0)) 6627 { 6628 // R[t] = ZeroExtend(data, 32); 6629 context.type = eContextRegisterLoad; 6630 context.SetRegisterPlusOffset (base_reg, address - Rn); 6631 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6632 return false; 6633 } 6634 else // Can only apply before ARMv7 6635 { 6636 // R[t] = bits(32) UNKNOWN; 6637 WriteBits32Unknown (t); 6638 } 6639 } 6640 return true; 6641} 6642 6643// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6644// zero-extends it to form a 32-bit word, and writes it to a register. 6645bool 6646EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6647{ 6648#if 0 6649 if ConditionPassed() then 6650 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6651 base = Align(PC,4); 6652 address = if add then (base + imm32) else (base - imm32); 6653 data = MemU[address,2]; 6654 if UnalignedSupport() || address<0> = '0' then 6655 R[t] = ZeroExtend(data, 32); 6656 else // Can only apply before ARMv7 6657 R[t] = bits(32) UNKNOWN; 6658#endif 6659 6660 bool success = false; 6661 6662 if (ConditionPassed(opcode)) 6663 { 6664 uint32_t t; 6665 uint32_t imm32; 6666 bool add; 6667 6668 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6669 switch (encoding) 6670 { 6671 case eEncodingT1: 6672 // if Rt == '1111' then SEE "Unallocated memory hints"; 6673 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6674 t = Bits32 (opcode, 15, 12); 6675 imm32 = Bits32 (opcode, 11, 0); 6676 add = BitIsSet (opcode, 23); 6677 6678 // if t == 13 then UNPREDICTABLE; 6679 if (t == 13) 6680 return false; 6681 6682 break; 6683 6684 case eEncodingA1: 6685 { 6686 uint32_t imm4H = Bits32 (opcode, 11, 8); 6687 uint32_t imm4L = Bits32 (opcode, 3, 0); 6688 6689 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6690 t = Bits32 (opcode, 15, 12); 6691 imm32 = (imm4H << 4) | imm4L; 6692 add = BitIsSet (opcode, 23); 6693 6694 // if t == 15 then UNPREDICTABLE; 6695 if (t == 15) 6696 return false; 6697 break; 6698 } 6699 6700 default: 6701 return false; 6702 } 6703 6704 // base = Align(PC,4); 6705 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6706 if (!success) 6707 return false; 6708 6709 addr_t base = AlignPC (pc_value); 6710 addr_t address; 6711 6712 // address = if add then (base + imm32) else (base - imm32); 6713 if (add) 6714 address = base + imm32; 6715 else 6716 address = base - imm32; 6717 6718 // data = MemU[address,2]; 6719 RegisterInfo base_reg; 6720 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6721 6722 EmulateInstruction::Context context; 6723 context.type = eContextRegisterLoad; 6724 context.SetRegisterPlusOffset (base_reg, address - base); 6725 6726 uint64_t data = MemURead (context, address, 2, 0, &success); 6727 if (!success) 6728 return false; 6729 6730 6731 // if UnalignedSupport() || address<0> = '0' then 6732 if (UnalignedSupport () || BitIsClear (address, 0)) 6733 { 6734 // R[t] = ZeroExtend(data, 32); 6735 context.type = eContextRegisterLoad; 6736 context.SetRegisterPlusOffset (base_reg, address - base); 6737 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6738 return false; 6739 6740 } 6741 else // Can only apply before ARMv7 6742 { 6743 // R[t] = bits(32) UNKNOWN; 6744 WriteBits32Unknown (t); 6745 } 6746 } 6747 return true; 6748} 6749 6750// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6751// from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6752// be shifted left by 0, 1, 2, or 3 bits. 6753bool 6754EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6755{ 6756#if 0 6757 if ConditionPassed() then 6758 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6759 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6760 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6761 address = if index then offset_addr else R[n]; 6762 data = MemU[address,2]; 6763 if wback then R[n] = offset_addr; 6764 if UnalignedSupport() || address<0> = '0' then 6765 R[t] = ZeroExtend(data, 32); 6766 else // Can only apply before ARMv7 6767 R[t] = bits(32) UNKNOWN; 6768#endif 6769 6770 bool success = false; 6771 6772 if (ConditionPassed(opcode)) 6773 { 6774 uint32_t t; 6775 uint32_t n; 6776 uint32_t m; 6777 bool index; 6778 bool add; 6779 bool wback; 6780 ARM_ShifterType shift_t; 6781 uint32_t shift_n; 6782 6783 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6784 switch (encoding) 6785 { 6786 case eEncodingT1: 6787 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6788 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6789 t = Bits32 (opcode, 2, 0); 6790 n = Bits32 (opcode, 5, 3); 6791 m = Bits32 (opcode, 8, 6); 6792 6793 // index = TRUE; add = TRUE; wback = FALSE; 6794 index = true; 6795 add = true; 6796 wback = false; 6797 6798 // (shift_t, shift_n) = (SRType_LSL, 0); 6799 shift_t = SRType_LSL; 6800 shift_n = 0; 6801 6802 break; 6803 6804 case eEncodingT2: 6805 // if Rn == '1111' then SEE LDRH (literal); 6806 // if Rt == '1111' then SEE "Unallocated memory hints"; 6807 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6808 t = Bits32 (opcode, 15, 12); 6809 n = Bits32 (opcode, 19, 16); 6810 m = Bits32 (opcode, 3, 0); 6811 6812 // index = TRUE; add = TRUE; wback = FALSE; 6813 index = true; 6814 add = true; 6815 wback = false; 6816 6817 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6818 shift_t = SRType_LSL; 6819 shift_n = Bits32 (opcode, 5, 4); 6820 6821 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6822 if ((t == 13) || BadReg (m)) 6823 return false; 6824 break; 6825 6826 case eEncodingA1: 6827 // if P == '0' && W == '1' then SEE LDRHT; 6828 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6829 t = Bits32 (opcode, 15, 12); 6830 n = Bits32 (opcode, 19, 16); 6831 m = Bits32 (opcode, 3, 0); 6832 6833 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6834 index = BitIsSet (opcode, 24); 6835 add = BitIsSet (opcode, 23); 6836 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6837 6838 // (shift_t, shift_n) = (SRType_LSL, 0); 6839 shift_t = SRType_LSL; 6840 shift_n = 0; 6841 6842 // if t == 15 || m == 15 then UNPREDICTABLE; 6843 if ((t == 15) || (m == 15)) 6844 return false; 6845 6846 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6847 if (wback && ((n == 15) || (n == t))) 6848 return false; 6849 6850 break; 6851 6852 default: 6853 return false; 6854 } 6855 6856 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6857 6858 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6859 if (!success) 6860 return false; 6861 6862 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6863 if (!success) 6864 return false; 6865 6866 addr_t offset_addr; 6867 addr_t address; 6868 6869 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6870 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6871 if (!success) 6872 return false; 6873 6874 if (add) 6875 offset_addr = Rn + offset; 6876 else 6877 offset_addr = Rn - offset; 6878 6879 // address = if index then offset_addr else R[n]; 6880 if (index) 6881 address = offset_addr; 6882 else 6883 address = Rn; 6884 6885 // data = MemU[address,2]; 6886 RegisterInfo base_reg; 6887 RegisterInfo offset_reg; 6888 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6889 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 6890 6891 EmulateInstruction::Context context; 6892 context.type = eContextRegisterLoad; 6893 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6894 uint64_t data = MemURead (context, address, 2, 0, &success); 6895 if (!success) 6896 return false; 6897 6898 // if wback then R[n] = offset_addr; 6899 if (wback) 6900 { 6901 context.type = eContextAdjustBaseRegister; 6902 context.SetAddress (offset_addr); 6903 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6904 return false; 6905 } 6906 6907 // if UnalignedSupport() || address<0> = '0' then 6908 if (UnalignedSupport() || BitIsClear (address, 0)) 6909 { 6910 // R[t] = ZeroExtend(data, 32); 6911 context.type = eContextRegisterLoad; 6912 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6913 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6914 return false; 6915 } 6916 else // Can only apply before ARMv7 6917 { 6918 // R[t] = bits(32) UNKNOWN; 6919 WriteBits32Unknown (t); 6920 } 6921 } 6922 return true; 6923} 6924 6925// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6926// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6927// or pre-indexed addressing. 6928bool 6929EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6930{ 6931#if 0 6932 if ConditionPassed() then 6933 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6934 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6935 address = if index then offset_addr else R[n]; 6936 R[t] = SignExtend(MemU[address,1], 32); 6937 if wback then R[n] = offset_addr; 6938#endif 6939 6940 bool success = false; 6941 6942 if (ConditionPassed(opcode)) 6943 { 6944 uint32_t t; 6945 uint32_t n; 6946 uint32_t imm32; 6947 bool index; 6948 bool add; 6949 bool wback; 6950 6951 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6952 switch (encoding) 6953 { 6954 case eEncodingT1: 6955 // if Rt == '1111' then SEE PLI; 6956 // if Rn == '1111' then SEE LDRSB (literal); 6957 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6958 t = Bits32 (opcode, 15, 12); 6959 n = Bits32 (opcode, 19, 16); 6960 imm32 = Bits32 (opcode, 11, 0); 6961 6962 // index = TRUE; add = TRUE; wback = FALSE; 6963 index = true; 6964 add = true; 6965 wback = false; 6966 6967 // if t == 13 then UNPREDICTABLE; 6968 if (t == 13) 6969 return false; 6970 6971 break; 6972 6973 case eEncodingT2: 6974 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 6975 // if Rn == '1111' then SEE LDRSB (literal); 6976 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 6977 // if P == '0' && W == '0' then UNDEFINED; 6978 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6979 return false; 6980 6981 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6982 t = Bits32 (opcode, 15, 12); 6983 n = Bits32 (opcode, 19, 16); 6984 imm32 = Bits32 (opcode, 7, 0); 6985 6986 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6987 index = BitIsSet (opcode, 10); 6988 add = BitIsSet (opcode, 9); 6989 wback = BitIsSet (opcode, 8); 6990 6991 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6992 if (((t == 13) || ((t == 15) 6993 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 6994 || (wback && (n == t))) 6995 return false; 6996 6997 break; 6998 6999 case eEncodingA1: 7000 { 7001 // if Rn == '1111' then SEE LDRSB (literal); 7002 // if P == '0' && W == '1' then SEE LDRSBT; 7003 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7004 t = Bits32 (opcode, 15, 12); 7005 n = Bits32 (opcode, 19, 16); 7006 7007 uint32_t imm4H = Bits32 (opcode, 11, 8); 7008 uint32_t imm4L = Bits32 (opcode, 3, 0); 7009 imm32 = (imm4H << 4) | imm4L; 7010 7011 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7012 index = BitIsSet (opcode, 24); 7013 add = BitIsSet (opcode, 23); 7014 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7015 7016 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7017 if ((t == 15) || (wback && (n == t))) 7018 return false; 7019 7020 break; 7021 } 7022 7023 default: 7024 return false; 7025 } 7026 7027 uint64_t Rn = ReadCoreReg (n, &success); 7028 if (!success) 7029 return false; 7030 7031 addr_t offset_addr; 7032 addr_t address; 7033 7034 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7035 if (add) 7036 offset_addr = Rn + imm32; 7037 else 7038 offset_addr = Rn - imm32; 7039 7040 // address = if index then offset_addr else R[n]; 7041 if (index) 7042 address = offset_addr; 7043 else 7044 address = Rn; 7045 7046 // R[t] = SignExtend(MemU[address,1], 32); 7047 RegisterInfo base_reg; 7048 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7049 7050 EmulateInstruction::Context context; 7051 context.type = eContextRegisterLoad; 7052 context.SetRegisterPlusOffset (base_reg, address - Rn); 7053 7054 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7055 if (!success) 7056 return false; 7057 7058 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7059 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7060 return false; 7061 7062 // if wback then R[n] = offset_addr; 7063 if (wback) 7064 { 7065 context.type = eContextAdjustBaseRegister; 7066 context.SetAddress (offset_addr); 7067 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7068 return false; 7069 } 7070 } 7071 7072 return true; 7073} 7074 7075// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7076// sign-extends it to form a 32-bit word, and writes tit to a register. 7077bool 7078EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7079{ 7080#if 0 7081 if ConditionPassed() then 7082 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7083 base = Align(PC,4); 7084 address = if add then (base + imm32) else (base - imm32); 7085 R[t] = SignExtend(MemU[address,1], 32); 7086#endif 7087 7088 bool success = false; 7089 7090 if (ConditionPassed(opcode)) 7091 { 7092 uint32_t t; 7093 uint32_t imm32; 7094 bool add; 7095 7096 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7097 switch (encoding) 7098 { 7099 case eEncodingT1: 7100 // if Rt == '1111' then SEE PLI; 7101 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7102 t = Bits32 (opcode, 15, 12); 7103 imm32 = Bits32 (opcode, 11, 0); 7104 add = BitIsSet (opcode, 23); 7105 7106 // if t == 13 then UNPREDICTABLE; 7107 if (t == 13) 7108 return false; 7109 7110 break; 7111 7112 case eEncodingA1: 7113 { 7114 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7115 t = Bits32 (opcode, 15, 12); 7116 uint32_t imm4H = Bits32 (opcode, 11, 8); 7117 uint32_t imm4L = Bits32 (opcode, 3, 0); 7118 imm32 = (imm4H << 4) | imm4L; 7119 add = BitIsSet (opcode, 23); 7120 7121 // if t == 15 then UNPREDICTABLE; 7122 if (t == 15) 7123 return false; 7124 7125 break; 7126 } 7127 7128 default: 7129 return false; 7130 } 7131 7132 // base = Align(PC,4); 7133 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7134 if (!success) 7135 return false; 7136 uint64_t base = AlignPC (pc_value); 7137 7138 // address = if add then (base + imm32) else (base - imm32); 7139 addr_t address; 7140 if (add) 7141 address = base + imm32; 7142 else 7143 address = base - imm32; 7144 7145 // R[t] = SignExtend(MemU[address,1], 32); 7146 RegisterInfo base_reg; 7147 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7148 7149 EmulateInstruction::Context context; 7150 context.type = eContextRegisterLoad; 7151 context.SetRegisterPlusOffset (base_reg, address - base); 7152 7153 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7154 if (!success) 7155 return false; 7156 7157 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7158 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7159 return false; 7160 } 7161 return true; 7162} 7163 7164// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7165// memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7166// shifted left by 0, 1, 2, or 3 bits. 7167bool 7168EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7169{ 7170#if 0 7171 if ConditionPassed() then 7172 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7173 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7174 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7175 address = if index then offset_addr else R[n]; 7176 R[t] = SignExtend(MemU[address,1], 32); 7177 if wback then R[n] = offset_addr; 7178#endif 7179 7180 bool success = false; 7181 7182 if (ConditionPassed(opcode)) 7183 { 7184 uint32_t t; 7185 uint32_t n; 7186 uint32_t m; 7187 bool index; 7188 bool add; 7189 bool wback; 7190 ARM_ShifterType shift_t; 7191 uint32_t shift_n; 7192 7193 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7194 switch (encoding) 7195 { 7196 case eEncodingT1: 7197 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7198 t = Bits32 (opcode, 2, 0); 7199 n = Bits32 (opcode, 5, 3); 7200 m = Bits32 (opcode, 8, 6); 7201 7202 // index = TRUE; add = TRUE; wback = FALSE; 7203 index = true; 7204 add = true; 7205 wback = false; 7206 7207 // (shift_t, shift_n) = (SRType_LSL, 0); 7208 shift_t = SRType_LSL; 7209 shift_n = 0; 7210 7211 break; 7212 7213 case eEncodingT2: 7214 // if Rt == '1111' then SEE PLI; 7215 // if Rn == '1111' then SEE LDRSB (literal); 7216 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7217 t = Bits32 (opcode, 15, 12); 7218 n = Bits32 (opcode, 19, 16); 7219 m = Bits32 (opcode, 3, 0); 7220 7221 // index = TRUE; add = TRUE; wback = FALSE; 7222 index = true; 7223 add = true; 7224 wback = false; 7225 7226 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7227 shift_t = SRType_LSL; 7228 shift_n = Bits32 (opcode, 5, 4); 7229 7230 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7231 if ((t == 13) || BadReg (m)) 7232 return false; 7233 break; 7234 7235 case eEncodingA1: 7236 // if P == '0' && W == '1' then SEE LDRSBT; 7237 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7238 t = Bits32 (opcode, 15, 12); 7239 n = Bits32 (opcode, 19, 16); 7240 m = Bits32 (opcode, 3, 0); 7241 7242 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7243 index = BitIsSet (opcode, 24); 7244 add = BitIsSet (opcode, 23); 7245 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7246 7247 // (shift_t, shift_n) = (SRType_LSL, 0); 7248 shift_t = SRType_LSL; 7249 shift_n = 0; 7250 7251 // if t == 15 || m == 15 then UNPREDICTABLE; 7252 if ((t == 15) || (m == 15)) 7253 return false; 7254 7255 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7256 if (wback && ((n == 15) || (n == t))) 7257 return false; 7258 break; 7259 7260 default: 7261 return false; 7262 } 7263 7264 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7265 if (!success) 7266 return false; 7267 7268 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7269 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7270 if (!success) 7271 return false; 7272 7273 addr_t offset_addr; 7274 addr_t address; 7275 7276 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7277 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7278 if (!success) 7279 return false; 7280 7281 if (add) 7282 offset_addr = Rn + offset; 7283 else 7284 offset_addr = Rn - offset; 7285 7286 // address = if index then offset_addr else R[n]; 7287 if (index) 7288 address = offset_addr; 7289 else 7290 address = Rn; 7291 7292 // R[t] = SignExtend(MemU[address,1], 32); 7293 RegisterInfo base_reg; 7294 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7295 RegisterInfo offset_reg; 7296 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7297 7298 EmulateInstruction::Context context; 7299 context.type = eContextRegisterLoad; 7300 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7301 7302 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7303 if (!success) 7304 return false; 7305 7306 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7307 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7308 return false; 7309 7310 // if wback then R[n] = offset_addr; 7311 if (wback) 7312 { 7313 context.type = eContextAdjustBaseRegister; 7314 context.SetAddress (offset_addr); 7315 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7316 return false; 7317 } 7318 } 7319 return true; 7320} 7321 7322// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7323// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7324// pre-indexed addressing. 7325bool 7326EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7327{ 7328#if 0 7329 if ConditionPassed() then 7330 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7331 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7332 address = if index then offset_addr else R[n]; 7333 data = MemU[address,2]; 7334 if wback then R[n] = offset_addr; 7335 if UnalignedSupport() || address<0> = '0' then 7336 R[t] = SignExtend(data, 32); 7337 else // Can only apply before ARMv7 7338 R[t] = bits(32) UNKNOWN; 7339#endif 7340 7341 bool success = false; 7342 7343 if (ConditionPassed(opcode)) 7344 { 7345 uint32_t t; 7346 uint32_t n; 7347 uint32_t imm32; 7348 bool index; 7349 bool add; 7350 bool wback; 7351 7352 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7353 switch (encoding) 7354 { 7355 case eEncodingT1: 7356 // if Rn == '1111' then SEE LDRSH (literal); 7357 // if Rt == '1111' then SEE "Unallocated memory hints"; 7358 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7359 t = Bits32 (opcode, 15, 12); 7360 n = Bits32 (opcode, 19, 16); 7361 imm32 = Bits32 (opcode, 11, 0); 7362 7363 // index = TRUE; add = TRUE; wback = FALSE; 7364 index = true; 7365 add = true; 7366 wback = false; 7367 7368 // if t == 13 then UNPREDICTABLE; 7369 if (t == 13) 7370 return false; 7371 7372 break; 7373 7374 case eEncodingT2: 7375 // if Rn == '1111' then SEE LDRSH (literal); 7376 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7377 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7378 // if P == '0' && W == '0' then UNDEFINED; 7379 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7380 return false; 7381 7382 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7383 t = Bits32 (opcode, 15, 12); 7384 n = Bits32 (opcode, 19, 16); 7385 imm32 = Bits32 (opcode, 7, 0); 7386 7387 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7388 index = BitIsSet (opcode, 10); 7389 add = BitIsSet (opcode, 9); 7390 wback = BitIsSet (opcode, 8); 7391 7392 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7393 if (BadReg (t) || (wback && (n == t))) 7394 return false; 7395 7396 break; 7397 7398 case eEncodingA1: 7399 { 7400 // if Rn == '1111' then SEE LDRSH (literal); 7401 // if P == '0' && W == '1' then SEE LDRSHT; 7402 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7403 t = Bits32 (opcode, 15, 12); 7404 n = Bits32 (opcode, 19, 16); 7405 uint32_t imm4H = Bits32 (opcode, 11,8); 7406 uint32_t imm4L = Bits32 (opcode, 3, 0); 7407 imm32 = (imm4H << 4) | imm4L; 7408 7409 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7410 index = BitIsSet (opcode, 24); 7411 add = BitIsSet (opcode, 23); 7412 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7413 7414 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7415 if ((t == 15) || (wback && (n == t))) 7416 return false; 7417 7418 break; 7419 } 7420 7421 default: 7422 return false; 7423 } 7424 7425 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7426 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7427 if (!success) 7428 return false; 7429 7430 addr_t offset_addr; 7431 if (add) 7432 offset_addr = Rn + imm32; 7433 else 7434 offset_addr = Rn - imm32; 7435 7436 // address = if index then offset_addr else R[n]; 7437 addr_t address; 7438 if (index) 7439 address = offset_addr; 7440 else 7441 address = Rn; 7442 7443 // data = MemU[address,2]; 7444 RegisterInfo base_reg; 7445 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7446 7447 EmulateInstruction::Context context; 7448 context.type = eContextRegisterLoad; 7449 context.SetRegisterPlusOffset (base_reg, address - Rn); 7450 7451 uint64_t data = MemURead (context, address, 2, 0, &success); 7452 if (!success) 7453 return false; 7454 7455 // if wback then R[n] = offset_addr; 7456 if (wback) 7457 { 7458 context.type = eContextAdjustBaseRegister; 7459 context.SetAddress (offset_addr); 7460 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7461 return false; 7462 } 7463 7464 // if UnalignedSupport() || address<0> = '0' then 7465 if (UnalignedSupport() || BitIsClear (address, 0)) 7466 { 7467 // R[t] = SignExtend(data, 32); 7468 int64_t signed_data = llvm::SignExtend64<16>(data); 7469 context.type = eContextRegisterLoad; 7470 context.SetRegisterPlusOffset (base_reg, address - Rn); 7471 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7472 return false; 7473 } 7474 else // Can only apply before ARMv7 7475 { 7476 // R[t] = bits(32) UNKNOWN; 7477 WriteBits32Unknown (t); 7478 } 7479 } 7480 return true; 7481} 7482 7483// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7484// sign-extends it to from a 32-bit word, and writes it to a register. 7485bool 7486EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7487{ 7488#if 0 7489 if ConditionPassed() then 7490 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7491 base = Align(PC,4); 7492 address = if add then (base + imm32) else (base - imm32); 7493 data = MemU[address,2]; 7494 if UnalignedSupport() || address<0> = '0' then 7495 R[t] = SignExtend(data, 32); 7496 else // Can only apply before ARMv7 7497 R[t] = bits(32) UNKNOWN; 7498#endif 7499 7500 bool success = false; 7501 7502 if (ConditionPassed(opcode)) 7503 { 7504 uint32_t t; 7505 uint32_t imm32; 7506 bool add; 7507 7508 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7509 switch (encoding) 7510 { 7511 case eEncodingT1: 7512 // if Rt == '1111' then SEE "Unallocated memory hints"; 7513 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7514 t = Bits32 (opcode, 15, 12); 7515 imm32 = Bits32 (opcode, 11, 0); 7516 add = BitIsSet (opcode, 23); 7517 7518 // if t == 13 then UNPREDICTABLE; 7519 if (t == 13) 7520 return false; 7521 7522 break; 7523 7524 case eEncodingA1: 7525 { 7526 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7527 t = Bits32 (opcode, 15, 12); 7528 uint32_t imm4H = Bits32 (opcode, 11, 8); 7529 uint32_t imm4L = Bits32 (opcode, 3, 0); 7530 imm32 = (imm4H << 4) | imm4L; 7531 add = BitIsSet (opcode, 23); 7532 7533 // if t == 15 then UNPREDICTABLE; 7534 if (t == 15) 7535 return false; 7536 7537 break; 7538 } 7539 default: 7540 return false; 7541 } 7542 7543 // base = Align(PC,4); 7544 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7545 if (!success) 7546 return false; 7547 7548 uint64_t base = AlignPC (pc_value); 7549 7550 addr_t address; 7551 // address = if add then (base + imm32) else (base - imm32); 7552 if (add) 7553 address = base + imm32; 7554 else 7555 address = base - imm32; 7556 7557 // data = MemU[address,2]; 7558 RegisterInfo base_reg; 7559 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7560 7561 EmulateInstruction::Context context; 7562 context.type = eContextRegisterLoad; 7563 context.SetRegisterPlusOffset (base_reg, imm32); 7564 7565 uint64_t data = MemURead (context, address, 2, 0, &success); 7566 if (!success) 7567 return false; 7568 7569 // if UnalignedSupport() || address<0> = '0' then 7570 if (UnalignedSupport() || BitIsClear (address, 0)) 7571 { 7572 // R[t] = SignExtend(data, 32); 7573 int64_t signed_data = llvm::SignExtend64<16>(data); 7574 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7575 return false; 7576 } 7577 else // Can only apply before ARMv7 7578 { 7579 // R[t] = bits(32) UNKNOWN; 7580 WriteBits32Unknown (t); 7581 } 7582 } 7583 return true; 7584} 7585 7586// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7587// from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7588// shifted left by 0, 1, 2, or 3 bits. 7589bool 7590EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7591{ 7592#if 0 7593 if ConditionPassed() then 7594 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7595 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7596 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7597 address = if index then offset_addr else R[n]; 7598 data = MemU[address,2]; 7599 if wback then R[n] = offset_addr; 7600 if UnalignedSupport() || address<0> = '0' then 7601 R[t] = SignExtend(data, 32); 7602 else // Can only apply before ARMv7 7603 R[t] = bits(32) UNKNOWN; 7604#endif 7605 7606 bool success = false; 7607 7608 if (ConditionPassed(opcode)) 7609 { 7610 uint32_t t; 7611 uint32_t n; 7612 uint32_t m; 7613 bool index; 7614 bool add; 7615 bool wback; 7616 ARM_ShifterType shift_t; 7617 uint32_t shift_n; 7618 7619 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7620 switch (encoding) 7621 { 7622 case eEncodingT1: 7623 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7624 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7625 t = Bits32 (opcode, 2, 0); 7626 n = Bits32 (opcode, 5, 3); 7627 m = Bits32 (opcode, 8, 6); 7628 7629 // index = TRUE; add = TRUE; wback = FALSE; 7630 index = true; 7631 add = true; 7632 wback = false; 7633 7634 // (shift_t, shift_n) = (SRType_LSL, 0); 7635 shift_t = SRType_LSL; 7636 shift_n = 0; 7637 7638 break; 7639 7640 case eEncodingT2: 7641 // if Rn == '1111' then SEE LDRSH (literal); 7642 // if Rt == '1111' then SEE "Unallocated memory hints"; 7643 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7644 t = Bits32 (opcode, 15, 12); 7645 n = Bits32 (opcode, 19, 16); 7646 m = Bits32 (opcode, 3, 0); 7647 7648 // index = TRUE; add = TRUE; wback = FALSE; 7649 index = true; 7650 add = true; 7651 wback = false; 7652 7653 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7654 shift_t = SRType_LSL; 7655 shift_n = Bits32 (opcode, 5, 4); 7656 7657 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7658 if ((t == 13) || BadReg (m)) 7659 return false; 7660 7661 break; 7662 7663 case eEncodingA1: 7664 // if P == '0' && W == '1' then SEE LDRSHT; 7665 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7666 t = Bits32 (opcode, 15, 12); 7667 n = Bits32 (opcode, 19, 16); 7668 m = Bits32 (opcode, 3, 0); 7669 7670 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7671 index = BitIsSet (opcode, 24); 7672 add = BitIsSet (opcode, 23); 7673 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7674 7675 // (shift_t, shift_n) = (SRType_LSL, 0); 7676 shift_t = SRType_LSL; 7677 shift_n = 0; 7678 7679 // if t == 15 || m == 15 then UNPREDICTABLE; 7680 if ((t == 15) || (m == 15)) 7681 return false; 7682 7683 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7684 if (wback && ((n == 15) || (n == t))) 7685 return false; 7686 7687 break; 7688 7689 default: 7690 return false; 7691 } 7692 7693 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7694 if (!success) 7695 return false; 7696 7697 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7698 if (!success) 7699 return false; 7700 7701 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7702 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7703 if (!success) 7704 return false; 7705 7706 addr_t offset_addr; 7707 addr_t address; 7708 7709 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7710 if (add) 7711 offset_addr = Rn + offset; 7712 else 7713 offset_addr = Rn - offset; 7714 7715 // address = if index then offset_addr else R[n]; 7716 if (index) 7717 address = offset_addr; 7718 else 7719 address = Rn; 7720 7721 // data = MemU[address,2]; 7722 RegisterInfo base_reg; 7723 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7724 7725 RegisterInfo offset_reg; 7726 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7727 7728 EmulateInstruction::Context context; 7729 context.type = eContextRegisterLoad; 7730 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7731 7732 uint64_t data = MemURead (context, address, 2, 0, &success); 7733 if (!success) 7734 return false; 7735 7736 // if wback then R[n] = offset_addr; 7737 if (wback) 7738 { 7739 context.type = eContextAdjustBaseRegister; 7740 context.SetAddress (offset_addr); 7741 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7742 return false; 7743 } 7744 7745 // if UnalignedSupport() || address<0> = '0' then 7746 if (UnalignedSupport() || BitIsClear (address, 0)) 7747 { 7748 // R[t] = SignExtend(data, 32); 7749 context.type = eContextRegisterLoad; 7750 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7751 7752 int64_t signed_data = llvm::SignExtend64<16>(data); 7753 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7754 return false; 7755 } 7756 else // Can only apply before ARMv7 7757 { 7758 // R[t] = bits(32) UNKNOWN; 7759 WriteBits32Unknown (t); 7760 } 7761 } 7762 return true; 7763} 7764 7765// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7766// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7767bool 7768EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7769{ 7770#if 0 7771 if ConditionPassed() then 7772 EncodingSpecificOperations(); 7773 rotated = ROR(R[m], rotation); 7774 R[d] = SignExtend(rotated<7:0>, 32); 7775#endif 7776 7777 bool success = false; 7778 7779 if (ConditionPassed(opcode)) 7780 { 7781 uint32_t d; 7782 uint32_t m; 7783 uint32_t rotation; 7784 7785 // EncodingSpecificOperations(); 7786 switch (encoding) 7787 { 7788 case eEncodingT1: 7789 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7790 d = Bits32 (opcode, 2, 0); 7791 m = Bits32 (opcode, 5, 3); 7792 rotation = 0; 7793 7794 break; 7795 7796 case eEncodingT2: 7797 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7798 d = Bits32 (opcode, 11, 8); 7799 m = Bits32 (opcode, 3, 0); 7800 rotation = Bits32 (opcode, 5, 4) << 3; 7801 7802 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7803 if (BadReg (d) || BadReg (m)) 7804 return false; 7805 7806 break; 7807 7808 case eEncodingA1: 7809 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7810 d = Bits32 (opcode, 15, 12); 7811 m = Bits32 (opcode, 3, 0); 7812 rotation = Bits32 (opcode, 11, 10) << 3; 7813 7814 // if d == 15 || m == 15 then UNPREDICTABLE; 7815 if ((d == 15) || (m == 15)) 7816 return false; 7817 7818 break; 7819 7820 default: 7821 return false; 7822 } 7823 7824 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7825 if (!success) 7826 return false; 7827 7828 // rotated = ROR(R[m], rotation); 7829 uint64_t rotated = ROR (Rm, rotation, &success); 7830 if (!success) 7831 return false; 7832 7833 // R[d] = SignExtend(rotated<7:0>, 32); 7834 int64_t data = llvm::SignExtend64<8>(rotated); 7835 7836 RegisterInfo source_reg; 7837 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7838 7839 EmulateInstruction::Context context; 7840 context.type = eContextRegisterLoad; 7841 context.SetRegister (source_reg); 7842 7843 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7844 return false; 7845 } 7846 return true; 7847} 7848 7849// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7850// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7851bool 7852EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7853{ 7854#if 0 7855 if ConditionPassed() then 7856 EncodingSpecificOperations(); 7857 rotated = ROR(R[m], rotation); 7858 R[d] = SignExtend(rotated<15:0>, 32); 7859#endif 7860 7861 bool success = false; 7862 7863 if (ConditionPassed(opcode)) 7864 { 7865 uint32_t d; 7866 uint32_t m; 7867 uint32_t rotation; 7868 7869 // EncodingSpecificOperations(); 7870 switch (encoding) 7871 { 7872 case eEncodingT1: 7873 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7874 d = Bits32 (opcode, 2, 0); 7875 m = Bits32 (opcode, 5, 3); 7876 rotation = 0; 7877 7878 break; 7879 7880 case eEncodingT2: 7881 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7882 d = Bits32 (opcode, 11, 8); 7883 m = Bits32 (opcode, 3, 0); 7884 rotation = Bits32 (opcode, 5, 4) << 3; 7885 7886 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7887 if (BadReg (d) || BadReg (m)) 7888 return false; 7889 7890 break; 7891 7892 case eEncodingA1: 7893 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7894 d = Bits32 (opcode, 15, 12); 7895 m = Bits32 (opcode, 3, 0); 7896 rotation = Bits32 (opcode, 11, 10) << 3; 7897 7898 // if d == 15 || m == 15 then UNPREDICTABLE; 7899 if ((d == 15) || (m == 15)) 7900 return false; 7901 7902 break; 7903 7904 default: 7905 return false; 7906 } 7907 7908 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7909 if (!success) 7910 return false; 7911 7912 // rotated = ROR(R[m], rotation); 7913 uint64_t rotated = ROR (Rm, rotation, &success); 7914 if (!success) 7915 return false; 7916 7917 // R[d] = SignExtend(rotated<15:0>, 32); 7918 RegisterInfo source_reg; 7919 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7920 7921 EmulateInstruction::Context context; 7922 context.type = eContextRegisterLoad; 7923 context.SetRegister (source_reg); 7924 7925 int64_t data = llvm::SignExtend64<16> (rotated); 7926 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7927 return false; 7928 } 7929 7930 return true; 7931} 7932 7933// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 7934// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7935bool 7936EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 7937{ 7938#if 0 7939 if ConditionPassed() then 7940 EncodingSpecificOperations(); 7941 rotated = ROR(R[m], rotation); 7942 R[d] = ZeroExtend(rotated<7:0>, 32); 7943#endif 7944 7945 bool success = false; 7946 7947 if (ConditionPassed(opcode)) 7948 { 7949 uint32_t d; 7950 uint32_t m; 7951 uint32_t rotation; 7952 7953 // EncodingSpecificOperations(); 7954 switch (encoding) 7955 { 7956 case eEncodingT1: 7957 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7958 d = Bits32 (opcode, 2, 0); 7959 m = Bits32 (opcode, 5, 3); 7960 rotation = 0; 7961 7962 break; 7963 7964 case eEncodingT2: 7965 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7966 d = Bits32 (opcode, 11, 8); 7967 m = Bits32 (opcode, 3, 0); 7968 rotation = Bits32 (opcode, 5, 4) << 3; 7969 7970 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7971 if (BadReg (d) || BadReg (m)) 7972 return false; 7973 7974 break; 7975 7976 case eEncodingA1: 7977 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7978 d = Bits32 (opcode, 15, 12); 7979 m = Bits32 (opcode, 3, 0); 7980 rotation = Bits32 (opcode, 11, 10) << 3; 7981 7982 // if d == 15 || m == 15 then UNPREDICTABLE; 7983 if ((d == 15) || (m == 15)) 7984 return false; 7985 7986 break; 7987 7988 default: 7989 return false; 7990 } 7991 7992 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7993 if (!success) 7994 return false; 7995 7996 // rotated = ROR(R[m], rotation); 7997 uint64_t rotated = ROR (Rm, rotation, &success); 7998 if (!success) 7999 return false; 8000 8001 // R[d] = ZeroExtend(rotated<7:0>, 32); 8002 RegisterInfo source_reg; 8003 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8004 8005 EmulateInstruction::Context context; 8006 context.type = eContextRegisterLoad; 8007 context.SetRegister (source_reg); 8008 8009 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 8010 return false; 8011 } 8012 return true; 8013} 8014 8015// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 8016// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 8017bool 8018EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 8019{ 8020#if 0 8021 if ConditionPassed() then 8022 EncodingSpecificOperations(); 8023 rotated = ROR(R[m], rotation); 8024 R[d] = ZeroExtend(rotated<15:0>, 32); 8025#endif 8026 8027 bool success = false; 8028 8029 if (ConditionPassed(opcode)) 8030 { 8031 uint32_t d; 8032 uint32_t m; 8033 uint32_t rotation; 8034 8035 switch (encoding) 8036 { 8037 case eEncodingT1: 8038 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8039 d = Bits32 (opcode, 2, 0); 8040 m = Bits32 (opcode, 5, 3); 8041 rotation = 0; 8042 8043 break; 8044 8045 case eEncodingT2: 8046 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8047 d = Bits32 (opcode, 11, 8); 8048 m = Bits32 (opcode, 3, 0); 8049 rotation = Bits32 (opcode, 5, 4) << 3; 8050 8051 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8052 if (BadReg (d) || BadReg (m)) 8053 return false; 8054 8055 break; 8056 8057 case eEncodingA1: 8058 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8059 d = Bits32 (opcode, 15, 12); 8060 m = Bits32 (opcode, 3, 0); 8061 rotation = Bits32 (opcode, 11, 10) << 3; 8062 8063 // if d == 15 || m == 15 then UNPREDICTABLE; 8064 if ((d == 15) || (m == 15)) 8065 return false; 8066 8067 break; 8068 8069 default: 8070 return false; 8071 } 8072 8073 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8074 if (!success) 8075 return false; 8076 8077 // rotated = ROR(R[m], rotation); 8078 uint64_t rotated = ROR (Rm, rotation, &success); 8079 if (!success) 8080 return false; 8081 8082 // R[d] = ZeroExtend(rotated<15:0>, 32); 8083 RegisterInfo source_reg; 8084 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8085 8086 EmulateInstruction::Context context; 8087 context.type = eContextRegisterLoad; 8088 context.SetRegister (source_reg); 8089 8090 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8091 return false; 8092 } 8093 return true; 8094} 8095 8096// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8097// word respectively. 8098bool 8099EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8100{ 8101#if 0 8102 if ConditionPassed() then 8103 EncodingSpecificOperations(); 8104 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8105 UNPREDICTABLE; 8106 else 8107 address = if increment then R[n] else R[n]-8; 8108 if wordhigher then address = address+4; 8109 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8110 BranchWritePC(MemA[address,4]); 8111 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8112#endif 8113 8114 bool success = false; 8115 8116 if (ConditionPassed(opcode)) 8117 { 8118 uint32_t n; 8119 bool wback; 8120 bool increment; 8121 bool wordhigher; 8122 8123 // EncodingSpecificOperations(); 8124 switch (encoding) 8125 { 8126 case eEncodingT1: 8127 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8128 n = Bits32 (opcode, 19, 16); 8129 wback = BitIsSet (opcode, 21); 8130 increment = false; 8131 wordhigher = false; 8132 8133 // if n == 15 then UNPREDICTABLE; 8134 if (n == 15) 8135 return false; 8136 8137 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8138 if (InITBlock() && !LastInITBlock()) 8139 return false; 8140 8141 break; 8142 8143 case eEncodingT2: 8144 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8145 n = Bits32 (opcode, 19, 16); 8146 wback = BitIsSet (opcode, 21); 8147 increment = true; 8148 wordhigher = false; 8149 8150 // if n == 15 then UNPREDICTABLE; 8151 if (n == 15) 8152 return false; 8153 8154 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8155 if (InITBlock() && !LastInITBlock()) 8156 return false; 8157 8158 break; 8159 8160 case eEncodingA1: 8161 // n = UInt(Rn); 8162 n = Bits32 (opcode, 19, 16); 8163 8164 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8165 wback = BitIsSet (opcode, 21); 8166 increment = BitIsSet (opcode, 23); 8167 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8168 8169 // if n == 15 then UNPREDICTABLE; 8170 if (n == 15) 8171 return false; 8172 8173 break; 8174 8175 default: 8176 return false; 8177 } 8178 8179 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8180 if (!CurrentModeIsPrivileged ()) 8181 // UNPREDICTABLE; 8182 return false; 8183 else 8184 { 8185 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8186 if (!success) 8187 return false; 8188 8189 addr_t address; 8190 // address = if increment then R[n] else R[n]-8; 8191 if (increment) 8192 address = Rn; 8193 else 8194 address = Rn - 8; 8195 8196 // if wordhigher then address = address+4; 8197 if (wordhigher) 8198 address = address + 4; 8199 8200 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8201 RegisterInfo base_reg; 8202 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8203 8204 EmulateInstruction::Context context; 8205 context.type = eContextReturnFromException; 8206 context.SetRegisterPlusOffset (base_reg, address - Rn); 8207 8208 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8209 if (!success) 8210 return false; 8211 8212 CPSRWriteByInstr (data, 15, true); 8213 8214 // BranchWritePC(MemA[address,4]); 8215 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8216 if (!success) 8217 return false; 8218 8219 BranchWritePC (context, data2); 8220 8221 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8222 if (wback) 8223 { 8224 context.type = eContextAdjustBaseRegister; 8225 if (increment) 8226 { 8227 context.SetOffset (8); 8228 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8229 return false; 8230 } 8231 else 8232 { 8233 context.SetOffset (-8); 8234 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8235 return false; 8236 } 8237 } // if wback 8238 } 8239 } // if ConditionPassed() 8240 return true; 8241} 8242 8243// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8244// and writes the result to the destination register. It can optionally update the condition flags based on 8245// the result. 8246bool 8247EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8248{ 8249#if 0 8250 // ARM pseudo code... 8251 if ConditionPassed() then 8252 EncodingSpecificOperations(); 8253 result = R[n] EOR imm32; 8254 if d == 15 then // Can only occur for ARM encoding 8255 ALUWritePC(result); // setflags is always FALSE here 8256 else 8257 R[d] = result; 8258 if setflags then 8259 APSR.N = result<31>; 8260 APSR.Z = IsZeroBit(result); 8261 APSR.C = carry; 8262 // APSR.V unchanged 8263#endif 8264 8265 bool success = false; 8266 8267 if (ConditionPassed(opcode)) 8268 { 8269 uint32_t Rd, Rn; 8270 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8271 bool setflags; 8272 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8273 switch (encoding) 8274 { 8275 case eEncodingT1: 8276 Rd = Bits32(opcode, 11, 8); 8277 Rn = Bits32(opcode, 19, 16); 8278 setflags = BitIsSet(opcode, 20); 8279 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8280 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8281 if (Rd == 15 && setflags) 8282 return EmulateTEQImm (opcode, eEncodingT1); 8283 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8284 return false; 8285 break; 8286 case eEncodingA1: 8287 Rd = Bits32(opcode, 15, 12); 8288 Rn = Bits32(opcode, 19, 16); 8289 setflags = BitIsSet(opcode, 20); 8290 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8291 8292 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8293 if (Rd == 15 && setflags) 8294 return EmulateSUBSPcLrEtc (opcode, encoding); 8295 break; 8296 default: 8297 return false; 8298 } 8299 8300 // Read the first operand. 8301 uint32_t val1 = ReadCoreReg(Rn, &success); 8302 if (!success) 8303 return false; 8304 8305 uint32_t result = val1 ^ imm32; 8306 8307 EmulateInstruction::Context context; 8308 context.type = EmulateInstruction::eContextImmediate; 8309 context.SetNoArgs (); 8310 8311 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8312 return false; 8313 } 8314 return true; 8315} 8316 8317// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8318// optionally-shifted register value, and writes the result to the destination register. 8319// It can optionally update the condition flags based on the result. 8320bool 8321EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8322{ 8323#if 0 8324 // ARM pseudo code... 8325 if ConditionPassed() then 8326 EncodingSpecificOperations(); 8327 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8328 result = R[n] EOR shifted; 8329 if d == 15 then // Can only occur for ARM encoding 8330 ALUWritePC(result); // setflags is always FALSE here 8331 else 8332 R[d] = result; 8333 if setflags then 8334 APSR.N = result<31>; 8335 APSR.Z = IsZeroBit(result); 8336 APSR.C = carry; 8337 // APSR.V unchanged 8338#endif 8339 8340 bool success = false; 8341 8342 if (ConditionPassed(opcode)) 8343 { 8344 uint32_t Rd, Rn, Rm; 8345 ARM_ShifterType shift_t; 8346 uint32_t shift_n; // the shift applied to the value read from Rm 8347 bool setflags; 8348 uint32_t carry; 8349 switch (encoding) 8350 { 8351 case eEncodingT1: 8352 Rd = Rn = Bits32(opcode, 2, 0); 8353 Rm = Bits32(opcode, 5, 3); 8354 setflags = !InITBlock(); 8355 shift_t = SRType_LSL; 8356 shift_n = 0; 8357 break; 8358 case eEncodingT2: 8359 Rd = Bits32(opcode, 11, 8); 8360 Rn = Bits32(opcode, 19, 16); 8361 Rm = Bits32(opcode, 3, 0); 8362 setflags = BitIsSet(opcode, 20); 8363 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8364 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8365 if (Rd == 15 && setflags) 8366 return EmulateTEQReg (opcode, eEncodingT1); 8367 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8368 return false; 8369 break; 8370 case eEncodingA1: 8371 Rd = Bits32(opcode, 15, 12); 8372 Rn = Bits32(opcode, 19, 16); 8373 Rm = Bits32(opcode, 3, 0); 8374 setflags = BitIsSet(opcode, 20); 8375 shift_n = DecodeImmShiftARM(opcode, shift_t); 8376 8377 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8378 if (Rd == 15 && setflags) 8379 return EmulateSUBSPcLrEtc (opcode, encoding); 8380 break; 8381 default: 8382 return false; 8383 } 8384 8385 // Read the first operand. 8386 uint32_t val1 = ReadCoreReg(Rn, &success); 8387 if (!success) 8388 return false; 8389 8390 // Read the second operand. 8391 uint32_t val2 = ReadCoreReg(Rm, &success); 8392 if (!success) 8393 return false; 8394 8395 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8396 if (!success) 8397 return false; 8398 uint32_t result = val1 ^ shifted; 8399 8400 EmulateInstruction::Context context; 8401 context.type = EmulateInstruction::eContextImmediate; 8402 context.SetNoArgs (); 8403 8404 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8405 return false; 8406 } 8407 return true; 8408} 8409 8410// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8411// writes the result to the destination register. It can optionally update the condition flags based 8412// on the result. 8413bool 8414EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8415{ 8416#if 0 8417 // ARM pseudo code... 8418 if ConditionPassed() then 8419 EncodingSpecificOperations(); 8420 result = R[n] OR imm32; 8421 if d == 15 then // Can only occur for ARM encoding 8422 ALUWritePC(result); // setflags is always FALSE here 8423 else 8424 R[d] = result; 8425 if setflags then 8426 APSR.N = result<31>; 8427 APSR.Z = IsZeroBit(result); 8428 APSR.C = carry; 8429 // APSR.V unchanged 8430#endif 8431 8432 bool success = false; 8433 8434 if (ConditionPassed(opcode)) 8435 { 8436 uint32_t Rd, Rn; 8437 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8438 bool setflags; 8439 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8440 switch (encoding) 8441 { 8442 case eEncodingT1: 8443 Rd = Bits32(opcode, 11, 8); 8444 Rn = Bits32(opcode, 19, 16); 8445 setflags = BitIsSet(opcode, 20); 8446 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8447 // if Rn == '1111' then SEE MOV (immediate); 8448 if (Rn == 15) 8449 return EmulateMOVRdImm (opcode, eEncodingT2); 8450 if (BadReg(Rd) || Rn == 13) 8451 return false; 8452 break; 8453 case eEncodingA1: 8454 Rd = Bits32(opcode, 15, 12); 8455 Rn = Bits32(opcode, 19, 16); 8456 setflags = BitIsSet(opcode, 20); 8457 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8458 8459 if (Rd == 15 && setflags) 8460 return EmulateSUBSPcLrEtc (opcode, encoding); 8461 break; 8462 default: 8463 return false; 8464 } 8465 8466 // Read the first operand. 8467 uint32_t val1 = ReadCoreReg(Rn, &success); 8468 if (!success) 8469 return false; 8470 8471 uint32_t result = val1 | imm32; 8472 8473 EmulateInstruction::Context context; 8474 context.type = EmulateInstruction::eContextImmediate; 8475 context.SetNoArgs (); 8476 8477 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8478 return false; 8479 } 8480 return true; 8481} 8482 8483// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8484// value, and writes the result to the destination register. It can optionally update the condition flags based 8485// on the result. 8486bool 8487EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8488{ 8489#if 0 8490 // ARM pseudo code... 8491 if ConditionPassed() then 8492 EncodingSpecificOperations(); 8493 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8494 result = R[n] OR shifted; 8495 if d == 15 then // Can only occur for ARM encoding 8496 ALUWritePC(result); // setflags is always FALSE here 8497 else 8498 R[d] = result; 8499 if setflags then 8500 APSR.N = result<31>; 8501 APSR.Z = IsZeroBit(result); 8502 APSR.C = carry; 8503 // APSR.V unchanged 8504#endif 8505 8506 bool success = false; 8507 8508 if (ConditionPassed(opcode)) 8509 { 8510 uint32_t Rd, Rn, Rm; 8511 ARM_ShifterType shift_t; 8512 uint32_t shift_n; // the shift applied to the value read from Rm 8513 bool setflags; 8514 uint32_t carry; 8515 switch (encoding) 8516 { 8517 case eEncodingT1: 8518 Rd = Rn = Bits32(opcode, 2, 0); 8519 Rm = Bits32(opcode, 5, 3); 8520 setflags = !InITBlock(); 8521 shift_t = SRType_LSL; 8522 shift_n = 0; 8523 break; 8524 case eEncodingT2: 8525 Rd = Bits32(opcode, 11, 8); 8526 Rn = Bits32(opcode, 19, 16); 8527 Rm = Bits32(opcode, 3, 0); 8528 setflags = BitIsSet(opcode, 20); 8529 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8530 // if Rn == '1111' then SEE MOV (register); 8531 if (Rn == 15) 8532 return EmulateMOVRdRm (opcode, eEncodingT3); 8533 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8534 return false; 8535 break; 8536 case eEncodingA1: 8537 Rd = Bits32(opcode, 15, 12); 8538 Rn = Bits32(opcode, 19, 16); 8539 Rm = Bits32(opcode, 3, 0); 8540 setflags = BitIsSet(opcode, 20); 8541 shift_n = DecodeImmShiftARM(opcode, shift_t); 8542 8543 if (Rd == 15 && setflags) 8544 return EmulateSUBSPcLrEtc (opcode, encoding); 8545 break; 8546 default: 8547 return false; 8548 } 8549 8550 // Read the first operand. 8551 uint32_t val1 = ReadCoreReg(Rn, &success); 8552 if (!success) 8553 return false; 8554 8555 // Read the second operand. 8556 uint32_t val2 = ReadCoreReg(Rm, &success); 8557 if (!success) 8558 return false; 8559 8560 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8561 if (!success) 8562 return false; 8563 uint32_t result = val1 | shifted; 8564 8565 EmulateInstruction::Context context; 8566 context.type = EmulateInstruction::eContextImmediate; 8567 context.SetNoArgs (); 8568 8569 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8570 return false; 8571 } 8572 return true; 8573} 8574 8575// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8576// the destination register. It can optionally update the condition flags based on the result. 8577bool 8578EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8579{ 8580#if 0 8581 // ARM pseudo code... 8582 if ConditionPassed() then 8583 EncodingSpecificOperations(); 8584 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8585 if d == 15 then // Can only occur for ARM encoding 8586 ALUWritePC(result); // setflags is always FALSE here 8587 else 8588 R[d] = result; 8589 if setflags then 8590 APSR.N = result<31>; 8591 APSR.Z = IsZeroBit(result); 8592 APSR.C = carry; 8593 APSR.V = overflow; 8594#endif 8595 8596 bool success = false; 8597 8598 uint32_t Rd; // the destination register 8599 uint32_t Rn; // the first operand 8600 bool setflags; 8601 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8602 switch (encoding) { 8603 case eEncodingT1: 8604 Rd = Bits32(opcode, 2, 0); 8605 Rn = Bits32(opcode, 5, 3); 8606 setflags = !InITBlock(); 8607 imm32 = 0; 8608 break; 8609 case eEncodingT2: 8610 Rd = Bits32(opcode, 11, 8); 8611 Rn = Bits32(opcode, 19, 16); 8612 setflags = BitIsSet(opcode, 20); 8613 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8614 if (BadReg(Rd) || BadReg(Rn)) 8615 return false; 8616 break; 8617 case eEncodingA1: 8618 Rd = Bits32(opcode, 15, 12); 8619 Rn = Bits32(opcode, 19, 16); 8620 setflags = BitIsSet(opcode, 20); 8621 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8622 8623 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8624 if (Rd == 15 && setflags) 8625 return EmulateSUBSPcLrEtc (opcode, encoding); 8626 break; 8627 default: 8628 return false; 8629 } 8630 // Read the register value from the operand register Rn. 8631 uint32_t reg_val = ReadCoreReg(Rn, &success); 8632 if (!success) 8633 return false; 8634 8635 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8636 8637 EmulateInstruction::Context context; 8638 context.type = EmulateInstruction::eContextImmediate; 8639 context.SetNoArgs (); 8640 8641 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8642 return false; 8643 8644 return true; 8645} 8646 8647// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8648// result to the destination register. It can optionally update the condition flags based on the result. 8649bool 8650EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8651{ 8652#if 0 8653 // ARM pseudo code... 8654 if ConditionPassed() then 8655 EncodingSpecificOperations(); 8656 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8657 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8658 if d == 15 then // Can only occur for ARM encoding 8659 ALUWritePC(result); // setflags is always FALSE here 8660 else 8661 R[d] = result; 8662 if setflags then 8663 APSR.N = result<31>; 8664 APSR.Z = IsZeroBit(result); 8665 APSR.C = carry; 8666 APSR.V = overflow; 8667#endif 8668 8669 bool success = false; 8670 8671 uint32_t Rd; // the destination register 8672 uint32_t Rn; // the first operand 8673 uint32_t Rm; // the second operand 8674 bool setflags; 8675 ARM_ShifterType shift_t; 8676 uint32_t shift_n; // the shift applied to the value read from Rm 8677 switch (encoding) { 8678 case eEncodingT1: 8679 Rd = Bits32(opcode, 11, 8); 8680 Rn = Bits32(opcode, 19, 16); 8681 Rm = Bits32(opcode, 3, 0); 8682 setflags = BitIsSet(opcode, 20); 8683 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8684 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8685 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8686 return false; 8687 break; 8688 case eEncodingA1: 8689 Rd = Bits32(opcode, 15, 12); 8690 Rn = Bits32(opcode, 19, 16); 8691 Rm = Bits32(opcode, 3, 0); 8692 setflags = BitIsSet(opcode, 20); 8693 shift_n = DecodeImmShiftARM(opcode, shift_t); 8694 8695 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8696 if (Rd == 15 && setflags) 8697 return EmulateSUBSPcLrEtc (opcode, encoding); 8698 break; 8699 default: 8700 return false; 8701 } 8702 // Read the register value from register Rn. 8703 uint32_t val1 = ReadCoreReg(Rn, &success); 8704 if (!success) 8705 return false; 8706 8707 // Read the register value from register Rm. 8708 uint32_t val2 = ReadCoreReg(Rm, &success); 8709 if (!success) 8710 return false; 8711 8712 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8713 if (!success) 8714 return false; 8715 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8716 8717 EmulateInstruction::Context context; 8718 context.type = EmulateInstruction::eContextImmediate; 8719 context.SetNoArgs(); 8720 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8721 return false; 8722 8723 return true; 8724} 8725 8726// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8727// an immediate value, and writes the result to the destination register. It can optionally update the condition 8728// flags based on the result. 8729bool 8730EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8731{ 8732#if 0 8733 // ARM pseudo code... 8734 if ConditionPassed() then 8735 EncodingSpecificOperations(); 8736 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8737 if d == 15 then 8738 ALUWritePC(result); // setflags is always FALSE here 8739 else 8740 R[d] = result; 8741 if setflags then 8742 APSR.N = result<31>; 8743 APSR.Z = IsZeroBit(result); 8744 APSR.C = carry; 8745 APSR.V = overflow; 8746#endif 8747 8748 bool success = false; 8749 8750 uint32_t Rd; // the destination register 8751 uint32_t Rn; // the first operand 8752 bool setflags; 8753 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8754 switch (encoding) { 8755 case eEncodingA1: 8756 Rd = Bits32(opcode, 15, 12); 8757 Rn = Bits32(opcode, 19, 16); 8758 setflags = BitIsSet(opcode, 20); 8759 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8760 8761 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8762 if (Rd == 15 && setflags) 8763 return EmulateSUBSPcLrEtc (opcode, encoding); 8764 break; 8765 default: 8766 return false; 8767 } 8768 // Read the register value from the operand register Rn. 8769 uint32_t reg_val = ReadCoreReg(Rn, &success); 8770 if (!success) 8771 return false; 8772 8773 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8774 8775 EmulateInstruction::Context context; 8776 context.type = EmulateInstruction::eContextImmediate; 8777 context.SetNoArgs (); 8778 8779 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8780 return false; 8781 8782 return true; 8783} 8784 8785// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8786// optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8787// condition flags based on the result. 8788bool 8789EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8790{ 8791#if 0 8792 // ARM pseudo code... 8793 if ConditionPassed() then 8794 EncodingSpecificOperations(); 8795 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8796 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8797 if d == 15 then 8798 ALUWritePC(result); // setflags is always FALSE here 8799 else 8800 R[d] = result; 8801 if setflags then 8802 APSR.N = result<31>; 8803 APSR.Z = IsZeroBit(result); 8804 APSR.C = carry; 8805 APSR.V = overflow; 8806#endif 8807 8808 bool success = false; 8809 8810 uint32_t Rd; // the destination register 8811 uint32_t Rn; // the first operand 8812 uint32_t Rm; // the second operand 8813 bool setflags; 8814 ARM_ShifterType shift_t; 8815 uint32_t shift_n; // the shift applied to the value read from Rm 8816 switch (encoding) { 8817 case eEncodingA1: 8818 Rd = Bits32(opcode, 15, 12); 8819 Rn = Bits32(opcode, 19, 16); 8820 Rm = Bits32(opcode, 3, 0); 8821 setflags = BitIsSet(opcode, 20); 8822 shift_n = DecodeImmShiftARM(opcode, shift_t); 8823 8824 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8825 if (Rd == 15 && setflags) 8826 return EmulateSUBSPcLrEtc (opcode, encoding); 8827 break; 8828 default: 8829 return false; 8830 } 8831 // Read the register value from register Rn. 8832 uint32_t val1 = ReadCoreReg(Rn, &success); 8833 if (!success) 8834 return false; 8835 8836 // Read the register value from register Rm. 8837 uint32_t val2 = ReadCoreReg(Rm, &success); 8838 if (!success) 8839 return false; 8840 8841 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8842 if (!success) 8843 return false; 8844 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8845 8846 EmulateInstruction::Context context; 8847 context.type = EmulateInstruction::eContextImmediate; 8848 context.SetNoArgs(); 8849 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8850 return false; 8851 8852 return true; 8853} 8854 8855// Subtract with Carry (immediate) subtracts an immediate value and the value of 8856// NOT (Carry flag) from a register value, and writes the result to the destination register. 8857// It can optionally update the condition flags based on the result. 8858bool 8859EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8860{ 8861#if 0 8862 // ARM pseudo code... 8863 if ConditionPassed() then 8864 EncodingSpecificOperations(); 8865 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8866 if d == 15 then // Can only occur for ARM encoding 8867 ALUWritePC(result); // setflags is always FALSE here 8868 else 8869 R[d] = result; 8870 if setflags then 8871 APSR.N = result<31>; 8872 APSR.Z = IsZeroBit(result); 8873 APSR.C = carry; 8874 APSR.V = overflow; 8875#endif 8876 8877 bool success = false; 8878 8879 uint32_t Rd; // the destination register 8880 uint32_t Rn; // the first operand 8881 bool setflags; 8882 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8883 switch (encoding) { 8884 case eEncodingT1: 8885 Rd = Bits32(opcode, 11, 8); 8886 Rn = Bits32(opcode, 19, 16); 8887 setflags = BitIsSet(opcode, 20); 8888 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8889 if (BadReg(Rd) || BadReg(Rn)) 8890 return false; 8891 break; 8892 case eEncodingA1: 8893 Rd = Bits32(opcode, 15, 12); 8894 Rn = Bits32(opcode, 19, 16); 8895 setflags = BitIsSet(opcode, 20); 8896 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8897 8898 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8899 if (Rd == 15 && setflags) 8900 return EmulateSUBSPcLrEtc (opcode, encoding); 8901 break; 8902 default: 8903 return false; 8904 } 8905 // Read the register value from the operand register Rn. 8906 uint32_t reg_val = ReadCoreReg(Rn, &success); 8907 if (!success) 8908 return false; 8909 8910 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 8911 8912 EmulateInstruction::Context context; 8913 context.type = EmulateInstruction::eContextImmediate; 8914 context.SetNoArgs (); 8915 8916 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8917 return false; 8918 8919 return true; 8920} 8921 8922// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 8923// NOT (Carry flag) from a register value, and writes the result to the destination register. 8924// It can optionally update the condition flags based on the result. 8925bool 8926EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 8927{ 8928#if 0 8929 // ARM pseudo code... 8930 if ConditionPassed() then 8931 EncodingSpecificOperations(); 8932 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8933 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 8934 if d == 15 then // Can only occur for ARM encoding 8935 ALUWritePC(result); // setflags is always FALSE here 8936 else 8937 R[d] = result; 8938 if setflags then 8939 APSR.N = result<31>; 8940 APSR.Z = IsZeroBit(result); 8941 APSR.C = carry; 8942 APSR.V = overflow; 8943#endif 8944 8945 bool success = false; 8946 8947 uint32_t Rd; // the destination register 8948 uint32_t Rn; // the first operand 8949 uint32_t Rm; // the second operand 8950 bool setflags; 8951 ARM_ShifterType shift_t; 8952 uint32_t shift_n; // the shift applied to the value read from Rm 8953 switch (encoding) { 8954 case eEncodingT1: 8955 Rd = Rn = Bits32(opcode, 2, 0); 8956 Rm = Bits32(opcode, 5, 3); 8957 setflags = !InITBlock(); 8958 shift_t = SRType_LSL; 8959 shift_n = 0; 8960 break; 8961 case eEncodingT2: 8962 Rd = Bits32(opcode, 11, 8); 8963 Rn = Bits32(opcode, 19, 16); 8964 Rm = Bits32(opcode, 3, 0); 8965 setflags = BitIsSet(opcode, 20); 8966 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8967 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8968 return false; 8969 break; 8970 case eEncodingA1: 8971 Rd = Bits32(opcode, 15, 12); 8972 Rn = Bits32(opcode, 19, 16); 8973 Rm = Bits32(opcode, 3, 0); 8974 setflags = BitIsSet(opcode, 20); 8975 shift_n = DecodeImmShiftARM(opcode, shift_t); 8976 8977 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8978 if (Rd == 15 && setflags) 8979 return EmulateSUBSPcLrEtc (opcode, encoding); 8980 break; 8981 default: 8982 return false; 8983 } 8984 // Read the register value from register Rn. 8985 uint32_t val1 = ReadCoreReg(Rn, &success); 8986 if (!success) 8987 return false; 8988 8989 // Read the register value from register Rm. 8990 uint32_t val2 = ReadCoreReg(Rm, &success); 8991 if (!success) 8992 return false; 8993 8994 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8995 if (!success) 8996 return false; 8997 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 8998 8999 EmulateInstruction::Context context; 9000 context.type = EmulateInstruction::eContextImmediate; 9001 context.SetNoArgs(); 9002 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9003 return false; 9004 9005 return true; 9006} 9007 9008// This instruction subtracts an immediate value from a register value, and writes the result 9009// to the destination register. It can optionally update the condition flags based on the result. 9010bool 9011EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9012{ 9013#if 0 9014 // ARM pseudo code... 9015 if ConditionPassed() then 9016 EncodingSpecificOperations(); 9017 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9018 R[d] = result; 9019 if setflags then 9020 APSR.N = result<31>; 9021 APSR.Z = IsZeroBit(result); 9022 APSR.C = carry; 9023 APSR.V = overflow; 9024#endif 9025 9026 bool success = false; 9027 9028 uint32_t Rd; // the destination register 9029 uint32_t Rn; // the first operand 9030 bool setflags; 9031 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9032 switch (encoding) { 9033 case eEncodingT1: 9034 Rd = Bits32(opcode, 2, 0); 9035 Rn = Bits32(opcode, 5, 3); 9036 setflags = !InITBlock(); 9037 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9038 break; 9039 case eEncodingT2: 9040 Rd = Rn = Bits32(opcode, 10, 8); 9041 setflags = !InITBlock(); 9042 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9043 break; 9044 case eEncodingT3: 9045 Rd = Bits32(opcode, 11, 8); 9046 Rn = Bits32(opcode, 19, 16); 9047 setflags = BitIsSet(opcode, 20); 9048 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9049 9050 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9051 if (Rd == 15 && setflags) 9052 return EmulateCMPImm (opcode, eEncodingT2); 9053 9054 // if Rn == '1101' then SEE SUB (SP minus immediate); 9055 if (Rn == 13) 9056 return EmulateSUBSPImm (opcode, eEncodingT2); 9057 9058 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9059 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9060 return false; 9061 break; 9062 case eEncodingT4: 9063 Rd = Bits32(opcode, 11, 8); 9064 Rn = Bits32(opcode, 19, 16); 9065 setflags = BitIsSet(opcode, 20); 9066 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9067 9068 // if Rn == '1111' then SEE ADR; 9069 if (Rn == 15) 9070 return EmulateADR (opcode, eEncodingT2); 9071 9072 // if Rn == '1101' then SEE SUB (SP minus immediate); 9073 if (Rn == 13) 9074 return EmulateSUBSPImm (opcode, eEncodingT3); 9075 9076 if (BadReg(Rd)) 9077 return false; 9078 break; 9079 default: 9080 return false; 9081 } 9082 // Read the register value from the operand register Rn. 9083 uint32_t reg_val = ReadCoreReg(Rn, &success); 9084 if (!success) 9085 return false; 9086 9087 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9088 9089 EmulateInstruction::Context context; 9090 context.type = EmulateInstruction::eContextImmediate; 9091 context.SetNoArgs (); 9092 9093 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9094 return false; 9095 9096 return true; 9097} 9098 9099// This instruction subtracts an immediate value from a register value, and writes the result 9100// to the destination register. It can optionally update the condition flags based on the result. 9101bool 9102EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9103{ 9104#if 0 9105 // ARM pseudo code... 9106 if ConditionPassed() then 9107 EncodingSpecificOperations(); 9108 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9109 if d == 15 then 9110 ALUWritePC(result); // setflags is always FALSE here 9111 else 9112 R[d] = result; 9113 if setflags then 9114 APSR.N = result<31>; 9115 APSR.Z = IsZeroBit(result); 9116 APSR.C = carry; 9117 APSR.V = overflow; 9118#endif 9119 9120 bool success = false; 9121 9122 uint32_t Rd; // the destination register 9123 uint32_t Rn; // the first operand 9124 bool setflags; 9125 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9126 switch (encoding) { 9127 case eEncodingA1: 9128 Rd = Bits32(opcode, 15, 12); 9129 Rn = Bits32(opcode, 19, 16); 9130 setflags = BitIsSet(opcode, 20); 9131 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9132 9133 // if Rn == '1111' && S == '0' then SEE ADR; 9134 if (Rn == 15 && !setflags) 9135 return EmulateADR (opcode, eEncodingA2); 9136 9137 // if Rn == '1101' then SEE SUB (SP minus immediate); 9138 if (Rn == 13) 9139 return EmulateSUBSPImm (opcode, eEncodingA1); 9140 9141 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9142 if (Rd == 15 && setflags) 9143 return EmulateSUBSPcLrEtc (opcode, encoding); 9144 break; 9145 default: 9146 return false; 9147 } 9148 // Read the register value from the operand register Rn. 9149 uint32_t reg_val = ReadCoreReg(Rn, &success); 9150 if (!success) 9151 return false; 9152 9153 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9154 9155 EmulateInstruction::Context context; 9156 context.type = EmulateInstruction::eContextImmediate; 9157 context.SetNoArgs (); 9158 9159 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9160 return false; 9161 9162 return true; 9163} 9164 9165// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9166// immediate value. It updates the condition flags based on the result, and discards the result. 9167bool 9168EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9169{ 9170#if 0 9171 // ARM pseudo code... 9172 if ConditionPassed() then 9173 EncodingSpecificOperations(); 9174 result = R[n] EOR imm32; 9175 APSR.N = result<31>; 9176 APSR.Z = IsZeroBit(result); 9177 APSR.C = carry; 9178 // APSR.V unchanged 9179#endif 9180 9181 bool success = false; 9182 9183 if (ConditionPassed(opcode)) 9184 { 9185 uint32_t Rn; 9186 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9187 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9188 switch (encoding) 9189 { 9190 case eEncodingT1: 9191 Rn = Bits32(opcode, 19, 16); 9192 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9193 if (BadReg(Rn)) 9194 return false; 9195 break; 9196 case eEncodingA1: 9197 Rn = Bits32(opcode, 19, 16); 9198 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9199 break; 9200 default: 9201 return false; 9202 } 9203 9204 // Read the first operand. 9205 uint32_t val1 = ReadCoreReg(Rn, &success); 9206 if (!success) 9207 return false; 9208 9209 uint32_t result = val1 ^ imm32; 9210 9211 EmulateInstruction::Context context; 9212 context.type = EmulateInstruction::eContextImmediate; 9213 context.SetNoArgs (); 9214 9215 if (!WriteFlags(context, result, carry)) 9216 return false; 9217 } 9218 return true; 9219} 9220 9221// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9222// optionally-shifted register value. It updates the condition flags based on the result, and discards 9223// the result. 9224bool 9225EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9226{ 9227#if 0 9228 // ARM pseudo code... 9229 if ConditionPassed() then 9230 EncodingSpecificOperations(); 9231 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9232 result = R[n] EOR shifted; 9233 APSR.N = result<31>; 9234 APSR.Z = IsZeroBit(result); 9235 APSR.C = carry; 9236 // APSR.V unchanged 9237#endif 9238 9239 bool success = false; 9240 9241 if (ConditionPassed(opcode)) 9242 { 9243 uint32_t Rn, Rm; 9244 ARM_ShifterType shift_t; 9245 uint32_t shift_n; // the shift applied to the value read from Rm 9246 uint32_t carry; 9247 switch (encoding) 9248 { 9249 case eEncodingT1: 9250 Rn = Bits32(opcode, 19, 16); 9251 Rm = Bits32(opcode, 3, 0); 9252 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9253 if (BadReg(Rn) || BadReg(Rm)) 9254 return false; 9255 break; 9256 case eEncodingA1: 9257 Rn = Bits32(opcode, 19, 16); 9258 Rm = Bits32(opcode, 3, 0); 9259 shift_n = DecodeImmShiftARM(opcode, shift_t); 9260 break; 9261 default: 9262 return false; 9263 } 9264 9265 // Read the first operand. 9266 uint32_t val1 = ReadCoreReg(Rn, &success); 9267 if (!success) 9268 return false; 9269 9270 // Read the second operand. 9271 uint32_t val2 = ReadCoreReg(Rm, &success); 9272 if (!success) 9273 return false; 9274 9275 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9276 if (!success) 9277 return false; 9278 uint32_t result = val1 ^ shifted; 9279 9280 EmulateInstruction::Context context; 9281 context.type = EmulateInstruction::eContextImmediate; 9282 context.SetNoArgs (); 9283 9284 if (!WriteFlags(context, result, carry)) 9285 return false; 9286 } 9287 return true; 9288} 9289 9290// Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9291// It updates the condition flags based on the result, and discards the result. 9292bool 9293EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9294{ 9295#if 0 9296 // ARM pseudo code... 9297 if ConditionPassed() then 9298 EncodingSpecificOperations(); 9299 result = R[n] AND imm32; 9300 APSR.N = result<31>; 9301 APSR.Z = IsZeroBit(result); 9302 APSR.C = carry; 9303 // APSR.V unchanged 9304#endif 9305 9306 bool success = false; 9307 9308 if (ConditionPassed(opcode)) 9309 { 9310 uint32_t Rn; 9311 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9312 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9313 switch (encoding) 9314 { 9315 case eEncodingT1: 9316 Rn = Bits32(opcode, 19, 16); 9317 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9318 if (BadReg(Rn)) 9319 return false; 9320 break; 9321 case eEncodingA1: 9322 Rn = Bits32(opcode, 19, 16); 9323 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9324 break; 9325 default: 9326 return false; 9327 } 9328 9329 // Read the first operand. 9330 uint32_t val1 = ReadCoreReg(Rn, &success); 9331 if (!success) 9332 return false; 9333 9334 uint32_t result = val1 & imm32; 9335 9336 EmulateInstruction::Context context; 9337 context.type = EmulateInstruction::eContextImmediate; 9338 context.SetNoArgs (); 9339 9340 if (!WriteFlags(context, result, carry)) 9341 return false; 9342 } 9343 return true; 9344} 9345 9346// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9347// It updates the condition flags based on the result, and discards the result. 9348bool 9349EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9350{ 9351#if 0 9352 // ARM pseudo code... 9353 if ConditionPassed() then 9354 EncodingSpecificOperations(); 9355 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9356 result = R[n] AND shifted; 9357 APSR.N = result<31>; 9358 APSR.Z = IsZeroBit(result); 9359 APSR.C = carry; 9360 // APSR.V unchanged 9361#endif 9362 9363 bool success = false; 9364 9365 if (ConditionPassed(opcode)) 9366 { 9367 uint32_t Rn, Rm; 9368 ARM_ShifterType shift_t; 9369 uint32_t shift_n; // the shift applied to the value read from Rm 9370 uint32_t carry; 9371 switch (encoding) 9372 { 9373 case eEncodingT1: 9374 Rn = Bits32(opcode, 2, 0); 9375 Rm = Bits32(opcode, 5, 3); 9376 shift_t = SRType_LSL; 9377 shift_n = 0; 9378 break; 9379 case eEncodingT2: 9380 Rn = Bits32(opcode, 19, 16); 9381 Rm = Bits32(opcode, 3, 0); 9382 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9383 if (BadReg(Rn) || BadReg(Rm)) 9384 return false; 9385 break; 9386 case eEncodingA1: 9387 Rn = Bits32(opcode, 19, 16); 9388 Rm = Bits32(opcode, 3, 0); 9389 shift_n = DecodeImmShiftARM(opcode, shift_t); 9390 break; 9391 default: 9392 return false; 9393 } 9394 9395 // Read the first operand. 9396 uint32_t val1 = ReadCoreReg(Rn, &success); 9397 if (!success) 9398 return false; 9399 9400 // Read the second operand. 9401 uint32_t val2 = ReadCoreReg(Rm, &success); 9402 if (!success) 9403 return false; 9404 9405 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9406 if (!success) 9407 return false; 9408 uint32_t result = val1 & shifted; 9409 9410 EmulateInstruction::Context context; 9411 context.type = EmulateInstruction::eContextImmediate; 9412 context.SetNoArgs (); 9413 9414 if (!WriteFlags(context, result, carry)) 9415 return false; 9416 } 9417 return true; 9418} 9419 9420// A8.6.216 SUB (SP minus register) 9421bool 9422EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9423{ 9424#if 0 9425 if ConditionPassed() then 9426 EncodingSpecificOperations(); 9427 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9428 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9429 if d == 15 then // Can only occur for ARM encoding 9430 ALUWritePC(result); // setflags is always FALSE here 9431 else 9432 R[d] = result; 9433 if setflags then 9434 APSR.N = result<31>; 9435 APSR.Z = IsZeroBit(result); 9436 APSR.C = carry; 9437 APSR.V = overflow; 9438#endif 9439 9440 bool success = false; 9441 9442 if (ConditionPassed(opcode)) 9443 { 9444 uint32_t d; 9445 uint32_t m; 9446 bool setflags; 9447 ARM_ShifterType shift_t; 9448 uint32_t shift_n; 9449 9450 switch (encoding) 9451 { 9452 case eEncodingT1: 9453 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9454 d = Bits32 (opcode, 11, 8); 9455 m = Bits32 (opcode, 3, 0); 9456 setflags = BitIsSet (opcode, 20); 9457 9458 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9459 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9460 9461 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9462 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9463 return false; 9464 9465 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9466 if ((d == 15) || BadReg (m)) 9467 return false; 9468 break; 9469 9470 case eEncodingA1: 9471 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9472 d = Bits32 (opcode, 15, 12); 9473 m = Bits32 (opcode, 3, 0); 9474 setflags = BitIsSet (opcode, 20); 9475 9476 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9477 if (d == 15 && setflags) 9478 EmulateSUBSPcLrEtc (opcode, encoding); 9479 9480 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9481 shift_n = DecodeImmShiftARM (opcode, shift_t); 9482 break; 9483 9484 default: 9485 return false; 9486 } 9487 9488 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9489 uint32_t Rm = ReadCoreReg (m, &success); 9490 if (!success) 9491 return false; 9492 9493 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9494 if (!success) 9495 return false; 9496 9497 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9498 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9499 if (!success) 9500 return false; 9501 9502 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9503 9504 EmulateInstruction::Context context; 9505 context.type = eContextArithmetic; 9506 RegisterInfo sp_reg; 9507 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9508 RegisterInfo dwarf_reg; 9509 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9510 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9511 9512 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9513 return false; 9514 } 9515 return true; 9516} 9517 9518 9519// A8.6.7 ADD (register-shifted register) 9520bool 9521EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9522{ 9523#if 0 9524 if ConditionPassed() then 9525 EncodingSpecificOperations(); 9526 shift_n = UInt(R[s]<7:0>); 9527 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9528 (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9529 R[d] = result; 9530 if setflags then 9531 APSR.N = result<31>; 9532 APSR.Z = IsZeroBit(result); 9533 APSR.C = carry; 9534 APSR.V = overflow; 9535#endif 9536 9537 bool success = false; 9538 9539 if (ConditionPassed(opcode)) 9540 { 9541 uint32_t d; 9542 uint32_t n; 9543 uint32_t m; 9544 uint32_t s; 9545 bool setflags; 9546 ARM_ShifterType shift_t; 9547 9548 switch (encoding) 9549 { 9550 case eEncodingA1: 9551 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9552 d = Bits32 (opcode, 15, 12); 9553 n = Bits32 (opcode, 19, 16); 9554 m = Bits32 (opcode, 3, 0); 9555 s = Bits32 (opcode, 11, 8); 9556 9557 // setflags = (S == �1�); shift_t = DecodeRegShift(type); 9558 setflags = BitIsSet (opcode, 20); 9559 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9560 9561 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9562 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9563 return false; 9564 break; 9565 9566 default: 9567 return false; 9568 } 9569 9570 // shift_n = UInt(R[s]<7:0>); 9571 uint32_t Rs = ReadCoreReg (s, &success); 9572 if (!success) 9573 return false; 9574 9575 uint32_t shift_n = Bits32 (Rs, 7, 0); 9576 9577 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9578 uint32_t Rm = ReadCoreReg (m, &success); 9579 if (!success) 9580 return false; 9581 9582 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9583 if (!success) 9584 return false; 9585 9586 // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9587 uint32_t Rn = ReadCoreReg (n, &success); 9588 if (!success) 9589 return false; 9590 9591 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9592 9593 // R[d] = result; 9594 EmulateInstruction::Context context; 9595 context.type = eContextArithmetic; 9596 RegisterInfo reg_n; 9597 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9598 RegisterInfo reg_m; 9599 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9600 9601 context.SetRegisterRegisterOperands (reg_n, reg_m); 9602 9603 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9604 return false; 9605 9606 // if setflags then 9607 // APSR.N = result<31>; 9608 // APSR.Z = IsZeroBit(result); 9609 // APSR.C = carry; 9610 // APSR.V = overflow; 9611 if (setflags) 9612 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9613 } 9614 return true; 9615} 9616 9617// A8.6.213 SUB (register) 9618bool 9619EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9620{ 9621#if 0 9622 if ConditionPassed() then 9623 EncodingSpecificOperations(); 9624 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9625 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9626 if d == 15 then // Can only occur for ARM encoding 9627 ALUWritePC(result); // setflags is always FALSE here 9628 else 9629 R[d] = result; 9630 if setflags then 9631 APSR.N = result<31>; 9632 APSR.Z = IsZeroBit(result); 9633 APSR.C = carry; 9634 APSR.V = overflow; 9635#endif 9636 9637 bool success = false; 9638 9639 if (ConditionPassed(opcode)) 9640 { 9641 uint32_t d; 9642 uint32_t n; 9643 uint32_t m; 9644 bool setflags; 9645 ARM_ShifterType shift_t; 9646 uint32_t shift_n; 9647 9648 switch (encoding) 9649 { 9650 case eEncodingT1: 9651 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9652 d = Bits32 (opcode, 2, 0); 9653 n = Bits32 (opcode, 5, 3); 9654 m = Bits32 (opcode, 8, 6); 9655 setflags = !InITBlock(); 9656 9657 // (shift_t, shift_n) = (SRType_LSL, 0); 9658 shift_t = SRType_LSL; 9659 shift_n = 0; 9660 9661 break; 9662 9663 case eEncodingT2: 9664 // if Rd == �1111� && S == �1� then SEE CMP (register); 9665 // if Rn == �1101� then SEE SUB (SP minus register); 9666 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9667 d = Bits32 (opcode, 11, 8); 9668 n = Bits32 (opcode, 19, 16); 9669 m = Bits32 (opcode, 3, 0); 9670 setflags = BitIsSet (opcode, 20); 9671 9672 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9673 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9674 9675 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9676 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9677 return false; 9678 9679 break; 9680 9681 case eEncodingA1: 9682 // if Rn == �1101� then SEE SUB (SP minus register); 9683 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9684 d = Bits32 (opcode, 15, 12); 9685 n = Bits32 (opcode, 19, 16); 9686 m = Bits32 (opcode, 3, 0); 9687 setflags = BitIsSet (opcode, 20); 9688 9689 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9690 if ((d == 15) && setflags) 9691 EmulateSUBSPcLrEtc (opcode, encoding); 9692 9693 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9694 shift_n = DecodeImmShiftARM (opcode, shift_t); 9695 9696 break; 9697 9698 default: 9699 return false; 9700 } 9701 9702 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9703 uint32_t Rm = ReadCoreReg (m, &success); 9704 if (!success) 9705 return false; 9706 9707 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9708 if (!success) 9709 return false; 9710 9711 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9712 uint32_t Rn = ReadCoreReg (n, &success); 9713 if (!success) 9714 return false; 9715 9716 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9717 9718 // if d == 15 then // Can only occur for ARM encoding 9719 // ALUWritePC(result); // setflags is always FALSE here 9720 // else 9721 // R[d] = result; 9722 // if setflags then 9723 // APSR.N = result<31>; 9724 // APSR.Z = IsZeroBit(result); 9725 // APSR.C = carry; 9726 // APSR.V = overflow; 9727 9728 EmulateInstruction::Context context; 9729 context.type = eContextArithmetic; 9730 RegisterInfo reg_n; 9731 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9732 RegisterInfo reg_m; 9733 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9734 context.SetRegisterRegisterOperands (reg_n, reg_m); 9735 9736 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9737 return false; 9738 } 9739 return true; 9740} 9741 9742// A8.6.202 STREX 9743// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9744// word from a register to memory if the executing processor has exclusive access to the memory addressed. 9745bool 9746EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9747{ 9748#if 0 9749 if ConditionPassed() then 9750 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9751 address = R[n] + imm32; 9752 if ExclusiveMonitorsPass(address,4) then 9753 MemA[address,4] = R[t]; 9754 R[d] = 0; 9755 else 9756 R[d] = 1; 9757#endif 9758 9759 bool success = false; 9760 9761 if (ConditionPassed(opcode)) 9762 { 9763 uint32_t d; 9764 uint32_t t; 9765 uint32_t n; 9766 uint32_t imm32; 9767 const uint32_t addr_byte_size = GetAddressByteSize(); 9768 9769 switch (encoding) 9770 { 9771 case eEncodingT1: 9772 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 9773 d = Bits32 (opcode, 11, 8); 9774 t = Bits32 (opcode, 15, 12); 9775 n = Bits32 (opcode, 19, 16); 9776 imm32 = Bits32 (opcode, 7, 0) << 2; 9777 9778 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9779 if (BadReg (d) || BadReg (t) || (n == 15)) 9780 return false; 9781 9782 // if d == n || d == t then UNPREDICTABLE; 9783 if ((d == n) || (d == t)) 9784 return false; 9785 9786 break; 9787 9788 case eEncodingA1: 9789 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9790 d = Bits32 (opcode, 15, 12); 9791 t = Bits32 (opcode, 3, 0); 9792 n = Bits32 (opcode, 19, 16); 9793 imm32 = 0; 9794 9795 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9796 if ((d == 15) || (t == 15) || (n == 15)) 9797 return false; 9798 9799 // if d == n || d == t then UNPREDICTABLE; 9800 if ((d == n) || (d == t)) 9801 return false; 9802 9803 break; 9804 9805 default: 9806 return false; 9807 } 9808 9809 // address = R[n] + imm32; 9810 uint32_t Rn = ReadCoreReg (n, &success); 9811 if (!success) 9812 return false; 9813 9814 addr_t address = Rn + imm32; 9815 9816 RegisterInfo base_reg; 9817 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9818 RegisterInfo data_reg; 9819 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9820 EmulateInstruction::Context context; 9821 context.type = eContextRegisterStore; 9822 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9823 9824 // if ExclusiveMonitorsPass(address,4) then 9825 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9826 // always return true. 9827 if (true) 9828 { 9829 // MemA[address,4] = R[t]; 9830 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9831 if (!success) 9832 return false; 9833 9834 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9835 return false; 9836 9837 // R[d] = 0; 9838 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9839 return false; 9840 } 9841 else 9842 { 9843 // R[d] = 1; 9844 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9845 return false; 9846 } 9847 } 9848 return true; 9849} 9850 9851// A8.6.197 STRB (immediate, ARM) 9852bool 9853EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9854{ 9855#if 0 9856 if ConditionPassed() then 9857 EncodingSpecificOperations(); 9858 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9859 address = if index then offset_addr else R[n]; 9860 MemU[address,1] = R[t]<7:0>; 9861 if wback then R[n] = offset_addr; 9862#endif 9863 9864 bool success = false; 9865 9866 if (ConditionPassed(opcode)) 9867 { 9868 uint32_t t; 9869 uint32_t n; 9870 uint32_t imm32; 9871 bool index; 9872 bool add; 9873 bool wback; 9874 9875 switch (encoding) 9876 { 9877 case eEncodingA1: 9878 // if P == �0� && W == �1� then SEE STRBT; 9879 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9880 t = Bits32 (opcode, 15, 12); 9881 n = Bits32 (opcode, 19, 16); 9882 imm32 = Bits32 (opcode, 11, 0); 9883 9884 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9885 index = BitIsSet (opcode, 24); 9886 add = BitIsSet (opcode, 23); 9887 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9888 9889 // if t == 15 then UNPREDICTABLE; 9890 if (t == 15) 9891 return false; 9892 9893 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9894 if (wback && ((n == 15) || (n == t))) 9895 return false; 9896 9897 break; 9898 9899 default: 9900 return false; 9901 } 9902 9903 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9904 uint32_t Rn = ReadCoreReg (n, &success); 9905 if (!success) 9906 return false; 9907 9908 addr_t offset_addr; 9909 if (add) 9910 offset_addr = Rn + imm32; 9911 else 9912 offset_addr = Rn - imm32; 9913 9914 // address = if index then offset_addr else R[n]; 9915 addr_t address; 9916 if (index) 9917 address = offset_addr; 9918 else 9919 address = Rn; 9920 9921 // MemU[address,1] = R[t]<7:0>; 9922 uint32_t Rt = ReadCoreReg (t, &success); 9923 if (!success) 9924 return false; 9925 9926 RegisterInfo base_reg; 9927 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9928 RegisterInfo data_reg; 9929 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9930 EmulateInstruction::Context context; 9931 context.type = eContextRegisterStore; 9932 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9933 9934 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 9935 return false; 9936 9937 // if wback then R[n] = offset_addr; 9938 if (wback) 9939 { 9940 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9941 return false; 9942 } 9943 } 9944 return true; 9945} 9946 9947// A8.6.194 STR (immediate, ARM) 9948bool 9949EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9950{ 9951#if 0 9952 if ConditionPassed() then 9953 EncodingSpecificOperations(); 9954 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9955 address = if index then offset_addr else R[n]; 9956 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9957 if wback then R[n] = offset_addr; 9958#endif 9959 9960 bool success = false; 9961 9962 if (ConditionPassed(opcode)) 9963 { 9964 uint32_t t; 9965 uint32_t n; 9966 uint32_t imm32; 9967 bool index; 9968 bool add; 9969 bool wback; 9970 9971 const uint32_t addr_byte_size = GetAddressByteSize(); 9972 9973 switch (encoding) 9974 { 9975 case eEncodingA1: 9976 // if P == �0� && W == �1� then SEE STRT; 9977 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH; 9978 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9979 t = Bits32 (opcode, 15, 12); 9980 n = Bits32 (opcode, 19, 16); 9981 imm32 = Bits32 (opcode, 11, 0); 9982 9983 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9984 index = BitIsSet (opcode, 24); 9985 add = BitIsSet (opcode, 23); 9986 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9987 9988 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9989 if (wback && ((n == 15) || (n == t))) 9990 return false; 9991 9992 break; 9993 9994 default: 9995 return false; 9996 } 9997 9998 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9999 uint32_t Rn = ReadCoreReg (n, &success); 10000 if (!success) 10001 return false; 10002 10003 addr_t offset_addr; 10004 if (add) 10005 offset_addr = Rn + imm32; 10006 else 10007 offset_addr = Rn - imm32; 10008 10009 // address = if index then offset_addr else R[n]; 10010 addr_t address; 10011 if (index) 10012 address = offset_addr; 10013 else 10014 address = Rn; 10015 10016 RegisterInfo base_reg; 10017 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10018 RegisterInfo data_reg; 10019 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10020 EmulateInstruction::Context context; 10021 context.type = eContextRegisterStore; 10022 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10023 10024 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10025 uint32_t Rt = ReadCoreReg (t, &success); 10026 if (!success) 10027 return false; 10028 10029 if (t == 15) 10030 { 10031 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10032 if (!success) 10033 return false; 10034 10035 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10036 return false; 10037 } 10038 else 10039 { 10040 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10041 return false; 10042 } 10043 10044 // if wback then R[n] = offset_addr; 10045 if (wback) 10046 { 10047 context.type = eContextAdjustBaseRegister; 10048 context.SetImmediate (offset_addr); 10049 10050 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10051 return false; 10052 } 10053 } 10054 return true; 10055} 10056 10057// A8.6.66 LDRD (immediate) 10058// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10059// words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10060bool 10061EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10062{ 10063#if 0 10064 if ConditionPassed() then 10065 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10066 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10067 address = if index then offset_addr else R[n]; 10068 R[t] = MemA[address,4]; 10069 R[t2] = MemA[address+4,4]; 10070 if wback then R[n] = offset_addr; 10071#endif 10072 10073 bool success = false; 10074 10075 if (ConditionPassed(opcode)) 10076 { 10077 uint32_t t; 10078 uint32_t t2; 10079 uint32_t n; 10080 uint32_t imm32; 10081 bool index; 10082 bool add; 10083 bool wback; 10084 10085 switch (encoding) 10086 { 10087 case eEncodingT1: 10088 //if P == �0� && W == �0� then SEE �Related encodings�; 10089 //if Rn == �1111� then SEE LDRD (literal); 10090 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10091 t = Bits32 (opcode, 15, 12); 10092 t2 = Bits32 (opcode, 11, 8); 10093 n = Bits32 (opcode, 19, 16); 10094 imm32 = Bits32 (opcode, 7, 0) << 2; 10095 10096 //index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10097 index = BitIsSet (opcode, 24); 10098 add = BitIsSet (opcode, 23); 10099 wback = BitIsSet (opcode, 21); 10100 10101 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10102 if (wback && ((n == t) || (n == t2))) 10103 return false; 10104 10105 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10106 if (BadReg (t) || BadReg (t2) || (t == t2)) 10107 return false; 10108 10109 break; 10110 10111 case eEncodingA1: 10112 //if Rn == �1111� then SEE LDRD (literal); 10113 //if Rt<0> == �1� then UNPREDICTABLE; 10114 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10115 t = Bits32 (opcode, 15, 12); 10116 if (BitIsSet (t, 0)) 10117 return false; 10118 t2 = t + 1; 10119 n = Bits32 (opcode, 19, 16); 10120 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10121 10122 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10123 index = BitIsSet (opcode, 24); 10124 add = BitIsSet (opcode, 23); 10125 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10126 10127 //if P == �0� && W == �1� then UNPREDICTABLE; 10128 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10129 return false; 10130 10131 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10132 if (wback && ((n == t) || (n == t2))) 10133 return false; 10134 10135 //if t2 == 15 then UNPREDICTABLE; 10136 if (t2 == 15) 10137 return false; 10138 10139 break; 10140 10141 default: 10142 return false; 10143 } 10144 10145 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10146 uint32_t Rn = ReadCoreReg (n, &success); 10147 if (!success) 10148 return false; 10149 10150 addr_t offset_addr; 10151 if (add) 10152 offset_addr = Rn + imm32; 10153 else 10154 offset_addr = Rn - imm32; 10155 10156 //address = if index then offset_addr else R[n]; 10157 addr_t address; 10158 if (index) 10159 address = offset_addr; 10160 else 10161 address = Rn; 10162 10163 //R[t] = MemA[address,4]; 10164 RegisterInfo base_reg; 10165 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10166 10167 EmulateInstruction::Context context; 10168 context.type = eContextRegisterLoad; 10169 context.SetRegisterPlusOffset (base_reg, address - Rn); 10170 10171 const uint32_t addr_byte_size = GetAddressByteSize(); 10172 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10173 if (!success) 10174 return false; 10175 10176 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10177 return false; 10178 10179 //R[t2] = MemA[address+4,4]; 10180 10181 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10182 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10183 if (!success) 10184 return false; 10185 10186 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10187 return false; 10188 10189 //if wback then R[n] = offset_addr; 10190 if (wback) 10191 { 10192 context.type = eContextAdjustBaseRegister; 10193 context.SetAddress (offset_addr); 10194 10195 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10196 return false; 10197 } 10198 } 10199 return true; 10200} 10201 10202// A8.6.68 LDRD (register) 10203// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10204// words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10205bool 10206EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10207{ 10208#if 0 10209 if ConditionPassed() then 10210 EncodingSpecificOperations(); 10211 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10212 address = if index then offset_addr else R[n]; 10213 R[t] = MemA[address,4]; 10214 R[t2] = MemA[address+4,4]; 10215 if wback then R[n] = offset_addr; 10216#endif 10217 10218 bool success = false; 10219 10220 if (ConditionPassed(opcode)) 10221 { 10222 uint32_t t; 10223 uint32_t t2; 10224 uint32_t n; 10225 uint32_t m; 10226 bool index; 10227 bool add; 10228 bool wback; 10229 10230 switch (encoding) 10231 { 10232 case eEncodingA1: 10233 // if Rt<0> == �1� then UNPREDICTABLE; 10234 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10235 t = Bits32 (opcode, 15, 12); 10236 if (BitIsSet (t, 0)) 10237 return false; 10238 t2 = t + 1; 10239 n = Bits32 (opcode, 19, 16); 10240 m = Bits32 (opcode, 3, 0); 10241 10242 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10243 index = BitIsSet (opcode, 24); 10244 add = BitIsSet (opcode, 23); 10245 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10246 10247 // if P == �0� && W == �1� then UNPREDICTABLE; 10248 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10249 return false; 10250 10251 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10252 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10253 return false; 10254 10255 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10256 if (wback && ((n == 15) || (n == t) || (n == t2))) 10257 return false; 10258 10259 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10260 if ((ArchVersion() < 6) && wback && (m == n)) 10261 return false; 10262 break; 10263 10264 default: 10265 return false; 10266 } 10267 10268 uint32_t Rn = ReadCoreReg (n, &success); 10269 if (!success) 10270 return false; 10271 RegisterInfo base_reg; 10272 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10273 10274 uint32_t Rm = ReadCoreReg (m, &success); 10275 if (!success) 10276 return false; 10277 RegisterInfo offset_reg; 10278 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10279 10280 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10281 addr_t offset_addr; 10282 if (add) 10283 offset_addr = Rn + Rm; 10284 else 10285 offset_addr = Rn - Rm; 10286 10287 // address = if index then offset_addr else R[n]; 10288 addr_t address; 10289 if (index) 10290 address = offset_addr; 10291 else 10292 address = Rn; 10293 10294 EmulateInstruction::Context context; 10295 context.type = eContextRegisterLoad; 10296 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10297 10298 // R[t] = MemA[address,4]; 10299 const uint32_t addr_byte_size = GetAddressByteSize(); 10300 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10301 if (!success) 10302 return false; 10303 10304 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10305 return false; 10306 10307 // R[t2] = MemA[address+4,4]; 10308 10309 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10310 if (!success) 10311 return false; 10312 10313 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10314 return false; 10315 10316 // if wback then R[n] = offset_addr; 10317 if (wback) 10318 { 10319 context.type = eContextAdjustBaseRegister; 10320 context.SetAddress (offset_addr); 10321 10322 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10323 return false; 10324 } 10325 } 10326 return true; 10327} 10328 10329// A8.6.200 STRD (immediate) 10330// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10331// stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10332bool 10333EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10334{ 10335#if 0 10336 if ConditionPassed() then 10337 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10338 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10339 address = if index then offset_addr else R[n]; 10340 MemA[address,4] = R[t]; 10341 MemA[address+4,4] = R[t2]; 10342 if wback then R[n] = offset_addr; 10343#endif 10344 10345 bool success = false; 10346 10347 if (ConditionPassed(opcode)) 10348 { 10349 uint32_t t; 10350 uint32_t t2; 10351 uint32_t n; 10352 uint32_t imm32; 10353 bool index; 10354 bool add; 10355 bool wback; 10356 10357 switch (encoding) 10358 { 10359 case eEncodingT1: 10360 // if P == �0� && W == �0� then SEE �Related encodings�; 10361 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10362 t = Bits32 (opcode, 15, 12); 10363 t2 = Bits32 (opcode, 11, 8); 10364 n = Bits32 (opcode, 19, 16); 10365 imm32 = Bits32 (opcode, 7, 0) << 2; 10366 10367 // index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10368 index = BitIsSet (opcode, 24); 10369 add = BitIsSet (opcode, 23); 10370 wback = BitIsSet (opcode, 21); 10371 10372 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10373 if (wback && ((n == t) || (n == t2))) 10374 return false; 10375 10376 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10377 if ((n == 15) || BadReg (t) || BadReg (t2)) 10378 return false; 10379 10380 break; 10381 10382 case eEncodingA1: 10383 // if Rt<0> == �1� then UNPREDICTABLE; 10384 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10385 t = Bits32 (opcode, 15, 12); 10386 if (BitIsSet (t, 0)) 10387 return false; 10388 10389 t2 = t + 1; 10390 n = Bits32 (opcode, 19, 16); 10391 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10392 10393 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10394 index = BitIsSet (opcode, 24); 10395 add = BitIsSet (opcode, 23); 10396 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10397 10398 // if P == �0� && W == �1� then UNPREDICTABLE; 10399 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10400 return false; 10401 10402 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10403 if (wback && ((n == 15) || (n == t) || (n == t2))) 10404 return false; 10405 10406 // if t2 == 15 then UNPREDICTABLE; 10407 if (t2 == 15) 10408 return false; 10409 10410 break; 10411 10412 default: 10413 return false; 10414 } 10415 10416 RegisterInfo base_reg; 10417 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10418 10419 uint32_t Rn = ReadCoreReg (n, &success); 10420 if (!success) 10421 return false; 10422 10423 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10424 addr_t offset_addr; 10425 if (add) 10426 offset_addr = Rn + imm32; 10427 else 10428 offset_addr = Rn - imm32; 10429 10430 //address = if index then offset_addr else R[n]; 10431 addr_t address; 10432 if (index) 10433 address = offset_addr; 10434 else 10435 address = Rn; 10436 10437 //MemA[address,4] = R[t]; 10438 RegisterInfo data_reg; 10439 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10440 10441 uint32_t data = ReadCoreReg (t, &success); 10442 if (!success) 10443 return false; 10444 10445 EmulateInstruction::Context context; 10446 context.type = eContextRegisterStore; 10447 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10448 10449 const uint32_t addr_byte_size = GetAddressByteSize(); 10450 10451 if (!MemAWrite (context, address, data, addr_byte_size)) 10452 return false; 10453 10454 //MemA[address+4,4] = R[t2]; 10455 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10456 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10457 10458 data = ReadCoreReg (t2, &success); 10459 if (!success) 10460 return false; 10461 10462 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10463 return false; 10464 10465 //if wback then R[n] = offset_addr; 10466 if (wback) 10467 { 10468 context.type = eContextAdjustBaseRegister; 10469 context.SetAddress (offset_addr); 10470 10471 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10472 return false; 10473 } 10474 } 10475 return true; 10476} 10477 10478 10479// A8.6.201 STRD (register) 10480bool 10481EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10482{ 10483#if 0 10484 if ConditionPassed() then 10485 EncodingSpecificOperations(); 10486 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10487 address = if index then offset_addr else R[n]; 10488 MemA[address,4] = R[t]; 10489 MemA[address+4,4] = R[t2]; 10490 if wback then R[n] = offset_addr; 10491#endif 10492 10493 bool success = false; 10494 10495 if (ConditionPassed(opcode)) 10496 { 10497 uint32_t t; 10498 uint32_t t2; 10499 uint32_t n; 10500 uint32_t m; 10501 bool index; 10502 bool add; 10503 bool wback; 10504 10505 switch (encoding) 10506 { 10507 case eEncodingA1: 10508 // if Rt<0> == �1� then UNPREDICTABLE; 10509 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10510 t = Bits32 (opcode, 15, 12); 10511 if (BitIsSet (t, 0)) 10512 return false; 10513 10514 t2 = t+1; 10515 n = Bits32 (opcode, 19, 16); 10516 m = Bits32 (opcode, 3, 0); 10517 10518 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10519 index = BitIsSet (opcode, 24); 10520 add = BitIsSet (opcode, 23); 10521 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10522 10523 // if P == �0� && W == �1� then UNPREDICTABLE; 10524 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10525 return false; 10526 10527 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10528 if ((t2 == 15) || (m == 15)) 10529 return false; 10530 10531 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10532 if (wback && ((n == 15) || (n == t) || (n == t2))) 10533 return false; 10534 10535 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10536 if ((ArchVersion() < 6) && wback && (m == n)) 10537 return false; 10538 10539 break; 10540 10541 default: 10542 return false; 10543 } 10544 10545 RegisterInfo base_reg; 10546 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10547 RegisterInfo offset_reg; 10548 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10549 RegisterInfo data_reg; 10550 10551 uint32_t Rn = ReadCoreReg (n, &success); 10552 if (!success) 10553 return false; 10554 10555 uint32_t Rm = ReadCoreReg (m, &success); 10556 if (!success) 10557 return false; 10558 10559 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10560 addr_t offset_addr; 10561 if (add) 10562 offset_addr = Rn + Rm; 10563 else 10564 offset_addr = Rn - Rm; 10565 10566 // address = if index then offset_addr else R[n]; 10567 addr_t address; 10568 if (index) 10569 address = offset_addr; 10570 else 10571 address = Rn; 10572 // MemA[address,4] = R[t]; 10573 uint32_t Rt = ReadCoreReg (t, &success); 10574 if (!success) 10575 return false; 10576 10577 EmulateInstruction::Context context; 10578 context.type = eContextRegisterStore; 10579 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10580 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10581 10582 const uint32_t addr_byte_size = GetAddressByteSize(); 10583 10584 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10585 return false; 10586 10587 // MemA[address+4,4] = R[t2]; 10588 uint32_t Rt2 = ReadCoreReg (t2, &success); 10589 if (!success) 10590 return false; 10591 10592 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10593 10594 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10595 10596 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10597 return false; 10598 10599 // if wback then R[n] = offset_addr; 10600 if (wback) 10601 { 10602 context.type = eContextAdjustBaseRegister; 10603 context.SetAddress (offset_addr); 10604 10605 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10606 return false; 10607 10608 } 10609 } 10610 return true; 10611} 10612 10613// A8.6.319 VLDM 10614// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10615// an ARM core register. 10616bool 10617EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10618{ 10619#if 0 10620 if ConditionPassed() then 10621 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10622 address = if add then R[n] else R[n]-imm32; 10623 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10624 for r = 0 to regs-1 10625 if single_regs then 10626 S[d+r] = MemA[address,4]; address = address+4; 10627 else 10628 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10629 // Combine the word-aligned words in the correct order for current endianness. 10630 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10631#endif 10632 10633 bool success = false; 10634 10635 if (ConditionPassed(opcode)) 10636 { 10637 bool single_regs; 10638 bool add; 10639 bool wback; 10640 uint32_t d; 10641 uint32_t n; 10642 uint32_t imm32; 10643 uint32_t regs; 10644 10645 switch (encoding) 10646 { 10647 case eEncodingT1: 10648 case eEncodingA1: 10649 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10650 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10651 // if P == �1� && W == �0� then SEE VLDR; 10652 // if P == U && W == �1� then UNDEFINED; 10653 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10654 return false; 10655 10656 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10657 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10658 single_regs = false; 10659 add = BitIsSet (opcode, 23); 10660 wback = BitIsSet (opcode, 21); 10661 10662 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10663 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10664 n = Bits32 (opcode, 19, 16); 10665 imm32 = Bits32 (opcode, 7, 0) << 2; 10666 10667 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�. 10668 regs = Bits32 (opcode, 7, 0) / 2; 10669 10670 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10671 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10672 return false; 10673 10674 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10675 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10676 return false; 10677 10678 break; 10679 10680 case eEncodingT2: 10681 case eEncodingA2: 10682 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10683 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10684 // if P == �1� && W == �0� then SEE VLDR; 10685 // if P == U && W == �1� then UNDEFINED; 10686 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10687 return false; 10688 10689 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10690 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10691 single_regs = true; 10692 add = BitIsSet (opcode, 23); 10693 wback = BitIsSet (opcode, 21); 10694 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10695 n = Bits32 (opcode, 19, 16); 10696 10697 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10698 imm32 = Bits32 (opcode, 7, 0) << 2; 10699 regs = Bits32 (opcode, 7, 0); 10700 10701 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10702 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10703 return false; 10704 10705 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10706 if ((regs == 0) || ((d + regs) > 32)) 10707 return false; 10708 break; 10709 10710 default: 10711 return false; 10712 } 10713 10714 RegisterInfo base_reg; 10715 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10716 10717 uint32_t Rn = ReadCoreReg (n, &success); 10718 if (!success) 10719 return false; 10720 10721 // address = if add then R[n] else R[n]-imm32; 10722 addr_t address; 10723 if (add) 10724 address = Rn; 10725 else 10726 address = Rn - imm32; 10727 10728 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10729 EmulateInstruction::Context context; 10730 10731 if (wback) 10732 { 10733 uint32_t value; 10734 if (add) 10735 value = Rn + imm32; 10736 else 10737 value = Rn - imm32; 10738 10739 context.type = eContextAdjustBaseRegister; 10740 context.SetImmediateSigned (value - Rn); 10741 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10742 return false; 10743 10744 } 10745 10746 const uint32_t addr_byte_size = GetAddressByteSize(); 10747 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10748 10749 context.type = eContextRegisterLoad; 10750 10751 // for r = 0 to regs-1 10752 for (uint32_t r = 0; r < regs; ++r) 10753 { 10754 if (single_regs) 10755 { 10756 // S[d+r] = MemA[address,4]; address = address+4; 10757 context.SetRegisterPlusOffset (base_reg, address - Rn); 10758 10759 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10760 if (!success) 10761 return false; 10762 10763 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10764 return false; 10765 10766 address = address + 4; 10767 } 10768 else 10769 { 10770 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10771 context.SetRegisterPlusOffset (base_reg, address - Rn); 10772 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10773 if (!success) 10774 return false; 10775 10776 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10777 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10778 if (!success) 10779 return false; 10780 10781 address = address + 8; 10782 // // Combine the word-aligned words in the correct order for current endianness. 10783 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10784 uint64_t data; 10785 if (GetByteOrder() == eByteOrderBig) 10786 { 10787 data = word1; 10788 data = (data << 32) | word2; 10789 } 10790 else 10791 { 10792 data = word2; 10793 data = (data << 32) | word1; 10794 } 10795 10796 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10797 return false; 10798 } 10799 } 10800 } 10801 return true; 10802} 10803 10804// A8.6.399 VSTM 10805// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10806// ARM core register. 10807bool 10808EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10809{ 10810#if 0 10811 if ConditionPassed() then 10812 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10813 address = if add then R[n] else R[n]-imm32; 10814 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10815 for r = 0 to regs-1 10816 if single_regs then 10817 MemA[address,4] = S[d+r]; address = address+4; 10818 else 10819 // Store as two word-aligned words in the correct order for current endianness. 10820 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10821 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10822 address = address+8; 10823#endif 10824 10825 bool success = false; 10826 10827 if (ConditionPassed (opcode)) 10828 { 10829 bool single_regs; 10830 bool add; 10831 bool wback; 10832 uint32_t d; 10833 uint32_t n; 10834 uint32_t imm32; 10835 uint32_t regs; 10836 10837 switch (encoding) 10838 { 10839 case eEncodingT1: 10840 case eEncodingA1: 10841 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10842 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10843 // if P == �1� && W == �0� then SEE VSTR; 10844 // if P == U && W == �1� then UNDEFINED; 10845 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10846 return false; 10847 10848 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10849 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10850 single_regs = false; 10851 add = BitIsSet (opcode, 23); 10852 wback = BitIsSet (opcode, 21); 10853 10854 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10855 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10856 n = Bits32 (opcode, 19, 16); 10857 imm32 = Bits32 (opcode, 7, 0) << 2; 10858 10859 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�. 10860 regs = Bits32 (opcode, 7, 0) / 2; 10861 10862 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10863 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10864 return false; 10865 10866 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10867 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10868 return false; 10869 10870 break; 10871 10872 case eEncodingT2: 10873 case eEncodingA2: 10874 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10875 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10876 // if P == �1� && W == �0� then SEE VSTR; 10877 // if P == U && W == �1� then UNDEFINED; 10878 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10879 return false; 10880 10881 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10882 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10883 single_regs = true; 10884 add = BitIsSet (opcode, 23); 10885 wback = BitIsSet (opcode, 21); 10886 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10887 n = Bits32 (opcode, 19, 16); 10888 10889 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10890 imm32 = Bits32 (opcode, 7, 0) << 2; 10891 regs = Bits32 (opcode, 7, 0); 10892 10893 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10894 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 10895 return false; 10896 10897 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10898 if ((regs == 0) || ((d + regs) > 32)) 10899 return false; 10900 10901 break; 10902 10903 default: 10904 return false; 10905 } 10906 10907 RegisterInfo base_reg; 10908 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10909 10910 uint32_t Rn = ReadCoreReg (n, &success); 10911 if (!success) 10912 return false; 10913 10914 // address = if add then R[n] else R[n]-imm32; 10915 addr_t address; 10916 if (add) 10917 address = Rn; 10918 else 10919 address = Rn - imm32; 10920 10921 EmulateInstruction::Context context; 10922 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10923 if (wback) 10924 { 10925 uint32_t value; 10926 if (add) 10927 value = Rn + imm32; 10928 else 10929 value = Rn - imm32; 10930 10931 context.type = eContextAdjustBaseRegister; 10932 context.SetRegisterPlusOffset (base_reg, value - Rn); 10933 10934 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10935 return false; 10936 } 10937 10938 const uint32_t addr_byte_size = GetAddressByteSize(); 10939 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10940 10941 context.type = eContextRegisterStore; 10942 // for r = 0 to regs-1 10943 for (int r = 0; r < regs; ++r) 10944 { 10945 10946 if (single_regs) 10947 { 10948 // MemA[address,4] = S[d+r]; address = address+4; 10949 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10950 if (!success) 10951 return false; 10952 10953 RegisterInfo data_reg; 10954 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10955 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10956 if (!MemAWrite (context, address, data, addr_byte_size)) 10957 return false; 10958 10959 address = address + 4; 10960 } 10961 else 10962 { 10963 // // Store as two word-aligned words in the correct order for current endianness. 10964 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10965 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10966 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10967 if (!success) 10968 return false; 10969 10970 RegisterInfo data_reg; 10971 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10972 10973 if (GetByteOrder() == eByteOrderBig) 10974 { 10975 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10976 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 10977 return false; 10978 10979 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10980 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 10981 return false; 10982 } 10983 else 10984 { 10985 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10986 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 10987 return false; 10988 10989 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10990 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 10991 return false; 10992 } 10993 // address = address+8; 10994 address = address + 8; 10995 } 10996 } 10997 } 10998 return true; 10999} 11000 11001// A8.6.320 11002// This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with 11003// an optional offset. 11004bool 11005EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 11006{ 11007#if 0 11008 if ConditionPassed() then 11009 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11010 base = if n == 15 then Align(PC,4) else R[n]; 11011 address = if add then (base + imm32) else (base - imm32); 11012 if single_reg then 11013 S[d] = MemA[address,4]; 11014 else 11015 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11016 // Combine the word-aligned words in the correct order for current endianness. 11017 D[d] = if BigEndian() then word1:word2 else word2:word1; 11018#endif 11019 11020 bool success = false; 11021 11022 if (ConditionPassed (opcode)) 11023 { 11024 bool single_reg; 11025 bool add; 11026 uint32_t imm32; 11027 uint32_t d; 11028 uint32_t n; 11029 11030 switch (encoding) 11031 { 11032 case eEncodingT1: 11033 case eEncodingA1: 11034 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11035 single_reg = false; 11036 add = BitIsSet (opcode, 23); 11037 imm32 = Bits32 (opcode, 7, 0) << 2; 11038 11039 // d = UInt(D:Vd); n = UInt(Rn); 11040 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11041 n = Bits32 (opcode, 19, 16); 11042 11043 break; 11044 11045 case eEncodingT2: 11046 case eEncodingA2: 11047 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11048 single_reg = true; 11049 add = BitIsSet (opcode, 23); 11050 imm32 = Bits32 (opcode, 7, 0) << 2; 11051 11052 // d = UInt(Vd:D); n = UInt(Rn); 11053 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11054 n = Bits32 (opcode, 19, 16); 11055 11056 break; 11057 11058 default: 11059 return false; 11060 } 11061 RegisterInfo base_reg; 11062 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11063 11064 uint32_t Rn = ReadCoreReg (n, &success); 11065 if (!success) 11066 return false; 11067 11068 // base = if n == 15 then Align(PC,4) else R[n]; 11069 uint32_t base; 11070 if (n == 15) 11071 base = AlignPC (Rn); 11072 else 11073 base = Rn; 11074 11075 // address = if add then (base + imm32) else (base - imm32); 11076 addr_t address; 11077 if (add) 11078 address = base + imm32; 11079 else 11080 address = base - imm32; 11081 11082 const uint32_t addr_byte_size = GetAddressByteSize(); 11083 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11084 11085 EmulateInstruction::Context context; 11086 context.type = eContextRegisterLoad; 11087 context.SetRegisterPlusOffset (base_reg, address - base); 11088 11089 if (single_reg) 11090 { 11091 // S[d] = MemA[address,4]; 11092 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11093 if (!success) 11094 return false; 11095 11096 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11097 return false; 11098 } 11099 else 11100 { 11101 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11102 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11103 if (!success) 11104 return false; 11105 11106 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11107 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11108 if (!success) 11109 return false; 11110 // // Combine the word-aligned words in the correct order for current endianness. 11111 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11112 uint64_t data64; 11113 if (GetByteOrder() == eByteOrderBig) 11114 { 11115 data64 = word1; 11116 data64 = (data64 << 32) | word2; 11117 } 11118 else 11119 { 11120 data64 = word2; 11121 data64 = (data64 << 32) | word1; 11122 } 11123 11124 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11125 return false; 11126 } 11127 } 11128 return true; 11129} 11130 11131// A8.6.400 VSTR 11132// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11133// optional offset. 11134bool 11135EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11136{ 11137#if 0 11138 if ConditionPassed() then 11139 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11140 address = if add then (R[n] + imm32) else (R[n] - imm32); 11141 if single_reg then 11142 MemA[address,4] = S[d]; 11143 else 11144 // Store as two word-aligned words in the correct order for current endianness. 11145 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11146 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11147#endif 11148 11149 bool success = false; 11150 11151 if (ConditionPassed (opcode)) 11152 { 11153 bool single_reg; 11154 bool add; 11155 uint32_t imm32; 11156 uint32_t d; 11157 uint32_t n; 11158 11159 switch (encoding) 11160 { 11161 case eEncodingT1: 11162 case eEncodingA1: 11163 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11164 single_reg = false; 11165 add = BitIsSet (opcode, 23); 11166 imm32 = Bits32 (opcode, 7, 0) << 2; 11167 11168 // d = UInt(D:Vd); n = UInt(Rn); 11169 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11170 n = Bits32 (opcode, 19, 16); 11171 11172 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11173 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11174 return false; 11175 11176 break; 11177 11178 case eEncodingT2: 11179 case eEncodingA2: 11180 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11181 single_reg = true; 11182 add = BitIsSet (opcode, 23); 11183 imm32 = Bits32 (opcode, 7, 0) << 2; 11184 11185 // d = UInt(Vd:D); n = UInt(Rn); 11186 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11187 n = Bits32 (opcode, 19, 16); 11188 11189 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11190 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11191 return false; 11192 11193 break; 11194 11195 default: 11196 return false; 11197 } 11198 11199 RegisterInfo base_reg; 11200 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11201 11202 uint32_t Rn = ReadCoreReg (n, &success); 11203 if (!success) 11204 return false; 11205 11206 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11207 addr_t address; 11208 if (add) 11209 address = Rn + imm32; 11210 else 11211 address = Rn - imm32; 11212 11213 const uint32_t addr_byte_size = GetAddressByteSize(); 11214 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11215 11216 RegisterInfo data_reg; 11217 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11218 EmulateInstruction::Context context; 11219 context.type = eContextRegisterStore; 11220 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11221 11222 if (single_reg) 11223 { 11224 // MemA[address,4] = S[d]; 11225 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11226 if (!success) 11227 return false; 11228 11229 if (!MemAWrite (context, address, data, addr_byte_size)) 11230 return false; 11231 } 11232 else 11233 { 11234 // // Store as two word-aligned words in the correct order for current endianness. 11235 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11236 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11237 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11238 if (!success) 11239 return false; 11240 11241 if (GetByteOrder() == eByteOrderBig) 11242 { 11243 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11244 return false; 11245 11246 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11247 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11248 return false; 11249 } 11250 else 11251 { 11252 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11253 return false; 11254 11255 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11256 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11257 return false; 11258 } 11259 } 11260 } 11261 return true; 11262} 11263 11264// A8.6.307 VLDI1 (multiple single elements) 11265// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11266// element of each register is loaded. 11267bool 11268EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11269{ 11270#if 0 11271 if ConditionPassed() then 11272 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11273 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11274 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11275 for r = 0 to regs-1 11276 for e = 0 to elements-1 11277 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11278 address = address + ebytes; 11279#endif 11280 11281 bool success = false; 11282 11283 if (ConditionPassed (opcode)) 11284 { 11285 uint32_t regs; 11286 uint32_t alignment; 11287 uint32_t ebytes; 11288 uint32_t esize; 11289 uint32_t elements; 11290 uint32_t d; 11291 uint32_t n; 11292 uint32_t m; 11293 bool wback; 11294 bool register_index; 11295 11296 switch (encoding) 11297 { 11298 case eEncodingT1: 11299 case eEncodingA1: 11300 { 11301 // case type of 11302 // when �0111� 11303 // regs = 1; if align<1> == �1� then UNDEFINED; 11304 // when �1010� 11305 // regs = 2; if align == �11� then UNDEFINED; 11306 // when �0110� 11307 // regs = 3; if align<1> == �1� then UNDEFINED; 11308 // when �0010� 11309 // regs = 4; 11310 // otherwise 11311 // SEE �Related encodings�; 11312 uint32_t type = Bits32 (opcode, 11, 8); 11313 uint32_t align = Bits32 (opcode, 5, 4); 11314 if (type == 7) // '0111' 11315 { 11316 regs = 1; 11317 if (BitIsSet (align, 1)) 11318 return false; 11319 } 11320 else if (type == 10) // '1010' 11321 { 11322 regs = 2; 11323 if (align == 3) 11324 return false; 11325 11326 } 11327 else if (type == 6) // '0110' 11328 { 11329 regs = 3; 11330 if (BitIsSet (align, 1)) 11331 return false; 11332 } 11333 else if (type == 2) // '0010' 11334 { 11335 regs = 4; 11336 } 11337 else 11338 return false; 11339 11340 // alignment = if align == �00� then 1 else 4 << UInt(align); 11341 if (align == 0) 11342 alignment = 1; 11343 else 11344 alignment = 4 << align; 11345 11346 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11347 ebytes = 1 << Bits32 (opcode, 7, 6); 11348 esize = 8 * ebytes; 11349 elements = 8 / ebytes; 11350 11351 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11352 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11353 n = Bits32 (opcode, 19, 15); 11354 m = Bits32 (opcode, 3, 0); 11355 11356 // wback = (m != 15); register_index = (m != 15 && m != 13); 11357 wback = (m != 15); 11358 register_index = ((m != 15) && (m != 13)); 11359 11360 // if d+regs > 32 then UNPREDICTABLE; 11361 if ((d + regs) > 32) 11362 return false; 11363 } 11364 break; 11365 11366 default: 11367 return false; 11368 } 11369 11370 RegisterInfo base_reg; 11371 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11372 11373 uint32_t Rn = ReadCoreReg (n, &success); 11374 if (!success) 11375 return false; 11376 11377 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11378 addr_t address = Rn; 11379 if ((address % alignment) != 0) 11380 return false; 11381 11382 EmulateInstruction::Context context; 11383 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11384 if (wback) 11385 { 11386 uint32_t Rm = ReadCoreReg (m, &success); 11387 if (!success) 11388 return false; 11389 11390 uint32_t offset; 11391 if (register_index) 11392 offset = Rm; 11393 else 11394 offset = 8 * regs; 11395 11396 uint32_t value = Rn + offset; 11397 context.type = eContextAdjustBaseRegister; 11398 context.SetRegisterPlusOffset (base_reg, offset); 11399 11400 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11401 return false; 11402 11403 } 11404 11405 // for r = 0 to regs-1 11406 for (int r = 0; r < regs; ++r) 11407 { 11408 // for e = 0 to elements-1 11409 uint64_t assembled_data = 0; 11410 for (int e = 0; e < elements; ++e) 11411 { 11412 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11413 context.type = eContextRegisterLoad; 11414 context.SetRegisterPlusOffset (base_reg, address - Rn); 11415 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11416 if (!success) 11417 return false; 11418 11419 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11420 11421 // address = address + ebytes; 11422 address = address + ebytes; 11423 } 11424 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11425 return false; 11426 } 11427 } 11428 return true; 11429} 11430 11431// A8.6.308 VLD1 (single element to one lane) 11432// 11433bool 11434EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11435{ 11436#if 0 11437 if ConditionPassed() then 11438 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11439 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11440 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11441 Elem[D[d],index,esize] = MemU[address,ebytes]; 11442#endif 11443 11444 bool success = false; 11445 11446 if (ConditionPassed (opcode)) 11447 { 11448 uint32_t ebytes; 11449 uint32_t esize; 11450 uint32_t index; 11451 uint32_t alignment; 11452 uint32_t d; 11453 uint32_t n; 11454 uint32_t m; 11455 bool wback; 11456 bool register_index; 11457 11458 switch (encoding) 11459 { 11460 case eEncodingT1: 11461 case eEncodingA1: 11462 { 11463 uint32_t size = Bits32 (opcode, 11, 10); 11464 uint32_t index_align = Bits32 (opcode, 7, 4); 11465 // if size == �11� then SEE VLD1 (single element to all lanes); 11466 if (size == 3) 11467 return EmulateVLD1SingleAll (opcode, encoding); 11468 // case size of 11469 if (size == 0) // when '00' 11470 { 11471 // if index_align<0> != �0� then UNDEFINED; 11472 if (BitIsClear (index_align, 0)) 11473 return false; 11474 11475 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11476 ebytes = 1; 11477 esize = 8; 11478 index = Bits32 (index_align, 3, 1); 11479 alignment = 1; 11480 } 11481 else if (size == 1) // when �01� 11482 { 11483 // if index_align<1> != �0� then UNDEFINED; 11484 if (BitIsClear (index_align, 1)) 11485 return false; 11486 11487 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11488 ebytes = 2; 11489 esize = 16; 11490 index = Bits32 (index_align, 3, 2); 11491 11492 // alignment = if index_align<0> == �0� then 1 else 2; 11493 if (BitIsClear (index_align, 0)) 11494 alignment = 1; 11495 else 11496 alignment = 2; 11497 } 11498 else if (size == 2) // when �10� 11499 { 11500 // if index_align<2> != �0� then UNDEFINED; 11501 if (BitIsClear (index_align, 2)) 11502 return false; 11503 11504 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11505 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11506 return false; 11507 11508 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11509 ebytes = 4; 11510 esize = 32; 11511 index = Bit32 (index_align, 3); 11512 11513 // alignment = if index_align<1:0> == �00� then 1 else 4; 11514 if (Bits32 (index_align, 1, 0) == 0) 11515 alignment = 1; 11516 else 11517 alignment = 4; 11518 } 11519 else 11520 { 11521 return false; 11522 } 11523 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11524 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11525 n = Bits32 (opcode, 19, 16); 11526 m = Bits32 (opcode, 3, 0); 11527 11528 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11529 wback = (m != 15); 11530 register_index = ((m != 15) && (m != 13)); 11531 11532 if (n == 15) 11533 return false; 11534 11535 } 11536 break; 11537 11538 default: 11539 return false; 11540 } 11541 11542 RegisterInfo base_reg; 11543 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11544 11545 uint32_t Rn = ReadCoreReg (n, &success); 11546 if (!success) 11547 return false; 11548 11549 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11550 addr_t address = Rn; 11551 if ((address % alignment) != 0) 11552 return false; 11553 11554 EmulateInstruction::Context context; 11555 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11556 if (wback) 11557 { 11558 uint32_t Rm = ReadCoreReg (m, &success); 11559 if (!success) 11560 return false; 11561 11562 uint32_t offset; 11563 if (register_index) 11564 offset = Rm; 11565 else 11566 offset = ebytes; 11567 11568 uint32_t value = Rn + offset; 11569 11570 context.type = eContextAdjustBaseRegister; 11571 context.SetRegisterPlusOffset (base_reg, offset); 11572 11573 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11574 return false; 11575 } 11576 11577 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11578 uint32_t element = MemURead (context, address, esize, 0, &success); 11579 if (!success) 11580 return false; 11581 11582 element = element << (index * esize); 11583 11584 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11585 if (!success) 11586 return false; 11587 11588 uint64_t all_ones = -1; 11589 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11590 // at element & to the right of element. 11591 if (index > 0) 11592 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11593 // now mask should be 0's where element goes & 1's 11594 // everywhere else. 11595 11596 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11597 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11598 11599 context.type = eContextRegisterLoad; 11600 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11601 return false; 11602 } 11603 return true; 11604} 11605 11606// A8.6.391 VST1 (multiple single elements) 11607// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without 11608// interleaving. Every element of each register is stored. 11609bool 11610EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11611{ 11612#if 0 11613 if ConditionPassed() then 11614 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11615 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11616 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11617 for r = 0 to regs-1 11618 for e = 0 to elements-1 11619 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11620 address = address + ebytes; 11621#endif 11622 11623 bool success = false; 11624 11625 if (ConditionPassed (opcode)) 11626 { 11627 uint32_t regs; 11628 uint32_t alignment; 11629 uint32_t ebytes; 11630 uint32_t esize; 11631 uint32_t elements; 11632 uint32_t d; 11633 uint32_t n; 11634 uint32_t m; 11635 bool wback; 11636 bool register_index; 11637 11638 switch (encoding) 11639 { 11640 case eEncodingT1: 11641 case eEncodingA1: 11642 { 11643 uint32_t type = Bits32 (opcode, 11, 8); 11644 uint32_t align = Bits32 (opcode, 5, 4); 11645 11646 // case type of 11647 if (type == 7) // when �0111� 11648 { 11649 // regs = 1; if align<1> == �1� then UNDEFINED; 11650 regs = 1; 11651 if (BitIsSet (align, 1)) 11652 return false; 11653 } 11654 else if (type == 10) // when �1010� 11655 { 11656 // regs = 2; if align == �11� then UNDEFINED; 11657 regs = 2; 11658 if (align == 3) 11659 return false; 11660 } 11661 else if (type == 6) // when �0110� 11662 { 11663 // regs = 3; if align<1> == �1� then UNDEFINED; 11664 regs = 3; 11665 if (BitIsSet (align, 1)) 11666 return false; 11667 } 11668 else if (type == 2) // when �0010� 11669 // regs = 4; 11670 regs = 4; 11671 else // otherwise 11672 // SEE �Related encodings�; 11673 return false; 11674 11675 // alignment = if align == �00� then 1 else 4 << UInt(align); 11676 if (align == 0) 11677 alignment = 1; 11678 else 11679 alignment = 4 << align; 11680 11681 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11682 ebytes = 1 << Bits32 (opcode,7, 6); 11683 esize = 8 * ebytes; 11684 elements = 8 / ebytes; 11685 11686 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11687 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11688 n = Bits32 (opcode, 19, 16); 11689 m = Bits32 (opcode, 3, 0); 11690 11691 // wback = (m != 15); register_index = (m != 15 && m != 13); 11692 wback = (m != 15); 11693 register_index = ((m != 15) && (m != 13)); 11694 11695 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11696 if ((d + regs) > 32) 11697 return false; 11698 11699 if (n == 15) 11700 return false; 11701 11702 } 11703 break; 11704 11705 default: 11706 return false; 11707 } 11708 11709 RegisterInfo base_reg; 11710 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11711 11712 uint32_t Rn = ReadCoreReg (n, &success); 11713 if (!success) 11714 return false; 11715 11716 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11717 addr_t address = Rn; 11718 if ((address % alignment) != 0) 11719 return false; 11720 11721 EmulateInstruction::Context context; 11722 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11723 if (wback) 11724 { 11725 uint32_t Rm = ReadCoreReg (m, &success); 11726 if (!success) 11727 return false; 11728 11729 uint32_t offset; 11730 if (register_index) 11731 offset = Rm; 11732 else 11733 offset = 8 * regs; 11734 11735 context.type = eContextAdjustBaseRegister; 11736 context.SetRegisterPlusOffset (base_reg, offset); 11737 11738 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11739 return false; 11740 } 11741 11742 RegisterInfo data_reg; 11743 context.type = eContextRegisterStore; 11744 // for r = 0 to regs-1 11745 for (int r = 0; r < regs; ++r) 11746 { 11747 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11748 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11749 if (!success) 11750 return false; 11751 11752 // for e = 0 to elements-1 11753 for (int e = 0; e < elements; ++e) 11754 { 11755 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11756 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11757 11758 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11759 if (!MemUWrite (context, address, word, ebytes)) 11760 return false; 11761 11762 // address = address + ebytes; 11763 address = address + ebytes; 11764 } 11765 } 11766 } 11767 return true; 11768} 11769 11770// A8.6.392 VST1 (single element from one lane) 11771// This instruction stores one element to memory from one element of a register. 11772bool 11773EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11774{ 11775#if 0 11776 if ConditionPassed() then 11777 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11778 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11779 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11780 MemU[address,ebytes] = Elem[D[d],index,esize]; 11781#endif 11782 11783 bool success = false; 11784 11785 if (ConditionPassed (opcode)) 11786 { 11787 uint32_t ebytes; 11788 uint32_t esize; 11789 uint32_t index; 11790 uint32_t alignment; 11791 uint32_t d; 11792 uint32_t n; 11793 uint32_t m; 11794 bool wback; 11795 bool register_index; 11796 11797 switch (encoding) 11798 { 11799 case eEncodingT1: 11800 case eEncodingA1: 11801 { 11802 uint32_t size = Bits32 (opcode, 11, 10); 11803 uint32_t index_align = Bits32 (opcode, 7, 4); 11804 11805 // if size == �11� then UNDEFINED; 11806 if (size == 3) 11807 return false; 11808 11809 // case size of 11810 if (size == 0) // when �00� 11811 { 11812 // if index_align<0> != �0� then UNDEFINED; 11813 if (BitIsClear (index_align, 0)) 11814 return false; 11815 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11816 ebytes = 1; 11817 esize = 8; 11818 index = Bits32 (index_align, 3, 1); 11819 alignment = 1; 11820 } 11821 else if (size == 1) // when �01� 11822 { 11823 // if index_align<1> != �0� then UNDEFINED; 11824 if (BitIsClear (index_align, 1)) 11825 return false; 11826 11827 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11828 ebytes = 2; 11829 esize = 16; 11830 index = Bits32 (index_align, 3, 2); 11831 11832 // alignment = if index_align<0> == �0� then 1 else 2; 11833 if (BitIsClear (index_align, 0)) 11834 alignment = 1; 11835 else 11836 alignment = 2; 11837 } 11838 else if (size == 2) // when �10� 11839 { 11840 // if index_align<2> != �0� then UNDEFINED; 11841 if (BitIsClear (index_align, 2)) 11842 return false; 11843 11844 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11845 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11846 return false; 11847 11848 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11849 ebytes = 4; 11850 esize = 32; 11851 index = Bit32 (index_align, 3); 11852 11853 // alignment = if index_align<1:0> == �00� then 1 else 4; 11854 if (Bits32 (index_align, 1, 0) == 0) 11855 alignment = 1; 11856 else 11857 alignment = 4; 11858 } 11859 else 11860 { 11861 return false; 11862 } 11863 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11864 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11865 n = Bits32 (opcode, 19, 16); 11866 m = Bits32 (opcode, 3, 0); 11867 11868 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11869 wback = (m != 15); 11870 register_index = ((m != 15) && (m != 13)); 11871 11872 if (n == 15) 11873 return false; 11874 } 11875 break; 11876 11877 default: 11878 return false; 11879 } 11880 11881 RegisterInfo base_reg; 11882 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11883 11884 uint32_t Rn = ReadCoreReg (n, &success); 11885 if (!success) 11886 return false; 11887 11888 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11889 addr_t address = Rn; 11890 if ((address % alignment) != 0) 11891 return false; 11892 11893 EmulateInstruction::Context context; 11894 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11895 if (wback) 11896 { 11897 uint32_t Rm = ReadCoreReg (m, &success); 11898 if (!success) 11899 return false; 11900 11901 uint32_t offset; 11902 if (register_index) 11903 offset = Rm; 11904 else 11905 offset = ebytes; 11906 11907 context.type = eContextAdjustBaseRegister; 11908 context.SetRegisterPlusOffset (base_reg, offset); 11909 11910 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11911 return false; 11912 } 11913 11914 // MemU[address,ebytes] = Elem[D[d],index,esize]; 11915 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11916 if (!success) 11917 return false; 11918 11919 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 11920 11921 RegisterInfo data_reg; 11922 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 11923 context.type = eContextRegisterStore; 11924 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11925 11926 if (!MemUWrite (context, address, word, ebytes)) 11927 return false; 11928 } 11929 return true; 11930} 11931 11932// A8.6.309 VLD1 (single element to all lanes) 11933// This instruction loads one element from memory into every element of one or two vectors. 11934bool 11935EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 11936{ 11937#if 0 11938 if ConditionPassed() then 11939 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11940 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11941 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11942 replicated_element = Replicate(MemU[address,ebytes], elements); 11943 for r = 0 to regs-1 11944 D[d+r] = replicated_element; 11945#endif 11946 11947 bool success = false; 11948 11949 if (ConditionPassed (opcode)) 11950 { 11951 uint32_t ebytes; 11952 uint32_t elements; 11953 uint32_t regs; 11954 uint32_t alignment; 11955 uint32_t d; 11956 uint32_t n; 11957 uint32_t m; 11958 bool wback; 11959 bool register_index; 11960 11961 switch (encoding) 11962 { 11963 case eEncodingT1: 11964 case eEncodingA1: 11965 { 11966 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED; 11967 uint32_t size = Bits32 (opcode, 7, 6); 11968 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 11969 return false; 11970 11971 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2; 11972 ebytes = 1 << size; 11973 elements = 8 / ebytes; 11974 if (BitIsClear (opcode, 5)) 11975 regs = 1; 11976 else 11977 regs = 2; 11978 11979 //alignment = if a == �0� then 1 else ebytes; 11980 if (BitIsClear (opcode, 4)) 11981 alignment = 1; 11982 else 11983 alignment = ebytes; 11984 11985 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11986 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11987 n = Bits32 (opcode, 19, 16); 11988 m = Bits32 (opcode, 3, 0); 11989 11990 //wback = (m != 15); register_index = (m != 15 && m != 13); 11991 wback = (m != 15); 11992 register_index = ((m != 15) && (m != 13)); 11993 11994 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11995 if ((d + regs) > 32) 11996 return false; 11997 11998 if (n == 15) 11999 return false; 12000 } 12001 break; 12002 12003 default: 12004 return false; 12005 } 12006 12007 RegisterInfo base_reg; 12008 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12009 12010 uint32_t Rn = ReadCoreReg (n, &success); 12011 if (!success) 12012 return false; 12013 12014 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12015 addr_t address = Rn; 12016 if ((address % alignment) != 0) 12017 return false; 12018 12019 EmulateInstruction::Context context; 12020 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12021 if (wback) 12022 { 12023 uint32_t Rm = ReadCoreReg (m, &success); 12024 if (!success) 12025 return false; 12026 12027 uint32_t offset; 12028 if (register_index) 12029 offset = Rm; 12030 else 12031 offset = ebytes; 12032 12033 context.type = eContextAdjustBaseRegister; 12034 context.SetRegisterPlusOffset (base_reg, offset); 12035 12036 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12037 return false; 12038 } 12039 12040 // replicated_element = Replicate(MemU[address,ebytes], elements); 12041 12042 context.type = eContextRegisterLoad; 12043 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12044 if (!success) 12045 return false; 12046 12047 uint64_t replicated_element = 0; 12048 uint32_t esize = ebytes * 8; 12049 for (int e = 0; e < elements; ++e) 12050 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12051 12052 // for r = 0 to regs-1 12053 for (int r = 0; r < regs; ++r) 12054 { 12055 // D[d+r] = replicated_element; 12056 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12057 return false; 12058 } 12059 } 12060 return true; 12061} 12062 12063// B6.2.13 SUBS PC, LR and related instructions 12064//The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12065// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12066bool 12067EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12068{ 12069#if 0 12070 if ConditionPassed() then 12071 EncodingSpecificOperations(); 12072 if CurrentInstrSet() == InstrSet_ThumbEE then 12073 UNPREDICTABLE; 12074 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12075 case opcode of 12076 when �0000� result = R[n] AND operand2; // AND 12077 when �0001� result = R[n] EOR operand2; // EOR 12078 when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12079 when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12080 when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12081 when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12082 when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12083 when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12084 when �1100� result = R[n] OR operand2; // ORR 12085 when �1101� result = operand2; // MOV 12086 when �1110� result = R[n] AND NOT(operand2); // BIC 12087 when �1111� result = NOT(operand2); // MVN 12088 CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12089 BranchWritePC(result); 12090#endif 12091 12092 bool success = false; 12093 12094 if (ConditionPassed (opcode)) 12095 { 12096 uint32_t n; 12097 uint32_t m; 12098 uint32_t imm32; 12099 bool register_form; 12100 ARM_ShifterType shift_t; 12101 uint32_t shift_n; 12102 uint32_t code; 12103 12104 switch (encoding) 12105 { 12106 case eEncodingT1: 12107 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12108 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB 12109 n = 14; 12110 imm32 = Bits32 (opcode, 7, 0); 12111 register_form = false; 12112 code = 2; 12113 12114 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12115 if (InITBlock() && !LastInITBlock()) 12116 return false; 12117 12118 break; 12119 12120 case eEncodingA1: 12121 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12122 n = Bits32 (opcode, 19, 16); 12123 imm32 = ARMExpandImm (opcode); 12124 register_form = false; 12125 code = Bits32 (opcode, 24, 21); 12126 12127 break; 12128 12129 case eEncodingA2: 12130 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12131 n = Bits32 (opcode, 19, 16); 12132 m = Bits32 (opcode, 3, 0); 12133 register_form = true; 12134 12135 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12136 shift_n = DecodeImmShiftARM (opcode, shift_t); 12137 12138 break; 12139 12140 default: 12141 return false; 12142 } 12143 12144 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12145 uint32_t operand2; 12146 if (register_form) 12147 { 12148 uint32_t Rm = ReadCoreReg (m, &success); 12149 if (!success) 12150 return false; 12151 12152 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12153 if (!success) 12154 return false; 12155 } 12156 else 12157 { 12158 operand2 = imm32; 12159 } 12160 12161 uint32_t Rn = ReadCoreReg (n, &success); 12162 if (!success) 12163 return false; 12164 12165 AddWithCarryResult result; 12166 12167 // case opcode of 12168 switch (code) 12169 { 12170 case 0: // when �0000� 12171 // result = R[n] AND operand2; // AND 12172 result.result = Rn & operand2; 12173 break; 12174 12175 case 1: // when �0001� 12176 // result = R[n] EOR operand2; // EOR 12177 result.result = Rn ^ operand2; 12178 break; 12179 12180 case 2: // when �0010� 12181 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12182 result = AddWithCarry (Rn, ~(operand2), 1); 12183 break; 12184 12185 case 3: // when �0011� 12186 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12187 result = AddWithCarry (~(Rn), operand2, 1); 12188 break; 12189 12190 case 4: // when �0100� 12191 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12192 result = AddWithCarry (Rn, operand2, 0); 12193 break; 12194 12195 case 5: // when �0101� 12196 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12197 result = AddWithCarry (Rn, operand2, APSR_C); 12198 break; 12199 12200 case 6: // when �0110� 12201 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12202 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12203 break; 12204 12205 case 7: // when �0111� 12206 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12207 result = AddWithCarry (~(Rn), operand2, APSR_C); 12208 break; 12209 12210 case 10: // when �1100� 12211 // result = R[n] OR operand2; // ORR 12212 result.result = Rn | operand2; 12213 break; 12214 12215 case 11: // when �1101� 12216 // result = operand2; // MOV 12217 result.result = operand2; 12218 break; 12219 12220 case 12: // when �1110� 12221 // result = R[n] AND NOT(operand2); // BIC 12222 result.result = Rn & ~(operand2); 12223 break; 12224 12225 case 15: // when �1111� 12226 // result = NOT(operand2); // MVN 12227 result.result = ~(operand2); 12228 break; 12229 12230 default: 12231 return false; 12232 } 12233 // CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12234 12235 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12236 // the best. 12237 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12238 if (!success) 12239 return false; 12240 12241 CPSRWriteByInstr (spsr, 15, true); 12242 12243 // BranchWritePC(result); 12244 EmulateInstruction::Context context; 12245 context.type = eContextAdjustPC; 12246 context.SetImmediate (result.result); 12247 12248 BranchWritePC (context, result.result); 12249 } 12250 return true; 12251} 12252 12253EmulateInstructionARM::ARMOpcode* 12254EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12255{ 12256 static ARMOpcode 12257 g_arm_opcodes[] = 12258 { 12259 //---------------------------------------------------------------------- 12260 // Prologue instructions 12261 //---------------------------------------------------------------------- 12262 12263 // push register(s) 12264 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12265 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12266 12267 // set r7 to point to a stack offset 12268 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12269 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12270 // copy the stack pointer to ip 12271 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12272 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12273 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12274 12275 // adjust the stack pointer 12276 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12277 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12278 12279 // push one register 12280 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12281 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12282 12283 // vector push consecutive extension register(s) 12284 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12285 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12286 12287 //---------------------------------------------------------------------- 12288 // Epilogue instructions 12289 //---------------------------------------------------------------------- 12290 12291 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12292 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12293 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12294 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12295 12296 //---------------------------------------------------------------------- 12297 // Supervisor Call (previously Software Interrupt) 12298 //---------------------------------------------------------------------- 12299 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12300 12301 //---------------------------------------------------------------------- 12302 // Branch instructions 12303 //---------------------------------------------------------------------- 12304 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12305 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 12306 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12307 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12308 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12309 // for example, "bx lr" 12310 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12311 // bxj 12312 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12313 12314 //---------------------------------------------------------------------- 12315 // Data-processing instructions 12316 //---------------------------------------------------------------------- 12317 // adc (immediate) 12318 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12319 // adc (register) 12320 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12321 // add (immediate) 12322 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12323 // add (register) 12324 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12325 // add (register-shifted register) 12326 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12327 // adr 12328 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12329 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12330 // and (immediate) 12331 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12332 // and (register) 12333 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12334 // bic (immediate) 12335 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12336 // bic (register) 12337 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12338 // eor (immediate) 12339 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12340 // eor (register) 12341 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12342 // orr (immediate) 12343 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12344 // orr (register) 12345 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12346 // rsb (immediate) 12347 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12348 // rsb (register) 12349 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12350 // rsc (immediate) 12351 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12352 // rsc (register) 12353 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12354 // sbc (immediate) 12355 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12356 // sbc (register) 12357 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12358 // sub (immediate, ARM) 12359 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12360 // sub (sp minus immediate) 12361 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12362 // sub (register) 12363 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12364 // teq (immediate) 12365 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12366 // teq (register) 12367 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12368 // tst (immediate) 12369 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12370 // tst (register) 12371 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12372 12373 // mov (immediate) 12374 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12375 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12376 // mov (register) 12377 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12378 // mvn (immediate) 12379 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12380 // mvn (register) 12381 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12382 // cmn (immediate) 12383 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12384 // cmn (register) 12385 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12386 // cmp (immediate) 12387 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12388 // cmp (register) 12389 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12390 // asr (immediate) 12391 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12392 // asr (register) 12393 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12394 // lsl (immediate) 12395 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12396 // lsl (register) 12397 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12398 // lsr (immediate) 12399 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12400 // lsr (register) 12401 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12402 // rrx is a special case encoding of ror (immediate) 12403 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12404 // ror (immediate) 12405 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12406 // ror (register) 12407 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12408 // mul 12409 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12410 12411 // subs pc, lr and related instructions 12412 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12413 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12414 12415 //---------------------------------------------------------------------- 12416 // Load instructions 12417 //---------------------------------------------------------------------- 12418 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12419 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12420 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12421 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12422 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12423 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12424 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12425 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12426 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12427 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12428 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12429 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12430 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12431 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12432 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12433 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12434 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12435 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12436 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12437 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12438 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12439 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12440 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12441 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12442 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12443 12444 //---------------------------------------------------------------------- 12445 // Store instructions 12446 //---------------------------------------------------------------------- 12447 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12448 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12449 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12450 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12451 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12452 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12453 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12454 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12455 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12456 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12457 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12458 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12459 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12460 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12461 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12462 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12463 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12464 12465 //---------------------------------------------------------------------- 12466 // Other instructions 12467 //---------------------------------------------------------------------- 12468 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12469 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12470 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12471 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12472 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12473 12474 }; 12475 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 12476 12477 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12478 { 12479 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12480 (g_arm_opcodes[i].variants & arm_isa) != 0) 12481 return &g_arm_opcodes[i]; 12482 } 12483 return NULL; 12484} 12485 12486 12487EmulateInstructionARM::ARMOpcode* 12488EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12489{ 12490 12491 static ARMOpcode 12492 g_thumb_opcodes[] = 12493 { 12494 //---------------------------------------------------------------------- 12495 // Prologue instructions 12496 //---------------------------------------------------------------------- 12497 12498 // push register(s) 12499 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12500 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12501 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12502 12503 // set r7 to point to a stack offset 12504 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12505 // copy the stack pointer to r7 12506 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12507 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12508 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12509 12510 // PC-relative load into register (see also EmulateADDSPRm) 12511 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12512 12513 // adjust the stack pointer 12514 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12515 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12516 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12517 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12518 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12519 12520 // vector push consecutive extension register(s) 12521 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12522 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12523 12524 //---------------------------------------------------------------------- 12525 // Epilogue instructions 12526 //---------------------------------------------------------------------- 12527 12528 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12529 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12530 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12531 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12532 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12533 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12534 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12535 12536 //---------------------------------------------------------------------- 12537 // Supervisor Call (previously Software Interrupt) 12538 //---------------------------------------------------------------------- 12539 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12540 12541 //---------------------------------------------------------------------- 12542 // If Then makes up to four following instructions conditional. 12543 //---------------------------------------------------------------------- 12544 // The next 5 opcode _must_ come before the if then instruction 12545 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12546 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12547 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12548 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12549 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12550 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12551 12552 //---------------------------------------------------------------------- 12553 // Branch instructions 12554 //---------------------------------------------------------------------- 12555 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12556 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12557 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12558 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12559 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12560 // J1 == J2 == 1 12561 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12562 // J1 == J2 == 1 12563 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12564 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12565 // for example, "bx lr" 12566 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12567 // bxj 12568 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12569 // compare and branch 12570 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12571 // table branch byte 12572 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12573 // table branch halfword 12574 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12575 12576 //---------------------------------------------------------------------- 12577 // Data-processing instructions 12578 //---------------------------------------------------------------------- 12579 // adc (immediate) 12580 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12581 // adc (register) 12582 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12583 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12584 // add (register) 12585 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12586 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12587 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12588 // adr 12589 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12590 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12591 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12592 // and (immediate) 12593 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12594 // and (register) 12595 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12596 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12597 // bic (immediate) 12598 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12599 // bic (register) 12600 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12601 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12602 // eor (immediate) 12603 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12604 // eor (register) 12605 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12606 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12607 // orr (immediate) 12608 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12609 // orr (register) 12610 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12611 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12612 // rsb (immediate) 12613 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12614 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12615 // rsb (register) 12616 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12617 // sbc (immediate) 12618 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12619 // sbc (register) 12620 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12621 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12622 // add (immediate, Thumb) 12623 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12624 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12625 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12626 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12627 // sub (immediate, Thumb) 12628 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12629 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12630 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12631 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12632 // sub (sp minus immediate) 12633 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12634 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12635 // sub (register) 12636 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12637 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12638 // teq (immediate) 12639 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12640 // teq (register) 12641 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12642 // tst (immediate) 12643 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12644 // tst (register) 12645 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12646 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12647 12648 12649 // move from high register to high register 12650 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12651 // move from low register to low register 12652 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12653 // mov{s}<c>.w <Rd>, <Rm> 12654 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12655 // move immediate 12656 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12657 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12658 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12659 // mvn (immediate) 12660 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12661 // mvn (register) 12662 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12663 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12664 // cmn (immediate) 12665 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12666 // cmn (register) 12667 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12668 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12669 // cmp (immediate) 12670 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12671 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12672 // cmp (register) (Rn and Rm both from r0-r7) 12673 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12674 // cmp (register) (Rn and Rm not both from r0-r7) 12675 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12676 // asr (immediate) 12677 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12678 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12679 // asr (register) 12680 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12681 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12682 // lsl (immediate) 12683 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12684 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12685 // lsl (register) 12686 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12687 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12688 // lsr (immediate) 12689 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12690 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12691 // lsr (register) 12692 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12693 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12694 // rrx is a special case encoding of ror (immediate) 12695 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12696 // ror (immediate) 12697 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12698 // ror (register) 12699 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12700 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12701 // mul 12702 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12703 // mul 12704 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12705 12706 // subs pc, lr and related instructions 12707 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12708 12709 //---------------------------------------------------------------------- 12710 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12711 // otherwise the wrong instructions will be selected. 12712 //---------------------------------------------------------------------- 12713 12714 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12715 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12716 12717 //---------------------------------------------------------------------- 12718 // Load instructions 12719 //---------------------------------------------------------------------- 12720 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12721 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12722 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12723 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12724 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12725 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12726 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12727 // Thumb2 PC-relative load into register 12728 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12729 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12730 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12731 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12732 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12733 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12734 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12735 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12736 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12737 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12738 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12739 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12740 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12741 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12742 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12743 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12744 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12745 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12746 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12747 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12748 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12749 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12750 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12751 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12752 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12753 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12754 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12755 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12756 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12757 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12758 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12759 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12760 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12761 12762 //---------------------------------------------------------------------- 12763 // Store instructions 12764 //---------------------------------------------------------------------- 12765 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12766 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12767 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12768 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12769 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12770 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12771 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12772 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12773 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12774 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12775 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12776 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12777 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12778 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12779 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12780 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12781 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12782 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12783 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12784 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12785 { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12786 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12787 12788 //---------------------------------------------------------------------- 12789 // Other instructions 12790 //---------------------------------------------------------------------- 12791 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12792 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12793 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12794 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12795 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12796 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12797 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12798 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12799 }; 12800 12801 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 12802 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12803 { 12804 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12805 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12806 return &g_thumb_opcodes[i]; 12807 } 12808 return NULL; 12809} 12810 12811bool 12812EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12813{ 12814 m_arch = arch; 12815 m_arm_isa = 0; 12816 const char *arch_cstr = arch.GetArchitectureName (); 12817 if (arch_cstr) 12818 { 12819 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12820 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12821 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12822 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12823 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12824 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12825 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12826 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12827 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12828 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12829 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12830 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12831 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12832 } 12833 return m_arm_isa != 0; 12834} 12835 12836bool 12837EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12838{ 12839 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12840 { 12841 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12842 m_opcode_mode = eModeThumb; 12843 else 12844 { 12845 AddressClass addr_class = inst_addr.GetAddressClass(); 12846 12847 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 12848 m_opcode_mode = eModeARM; 12849 else if (addr_class == eAddressClassCodeAlternateISA) 12850 m_opcode_mode = eModeThumb; 12851 else 12852 return false; 12853 } 12854 if (m_opcode_mode == eModeThumb) 12855 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 12856 else 12857 m_opcode_cpsr = CPSR_MODE_USR; 12858 return true; 12859 } 12860 return false; 12861} 12862 12863bool 12864EmulateInstructionARM::ReadInstruction () 12865{ 12866 bool success = false; 12867 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 12868 if (success) 12869 { 12870 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 12871 if (success) 12872 { 12873 Context read_inst_context; 12874 read_inst_context.type = eContextReadOpcode; 12875 read_inst_context.SetNoArgs (); 12876 12877 if (m_opcode_cpsr & MASK_CPSR_T) 12878 { 12879 m_opcode_mode = eModeThumb; 12880 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 12881 12882 if (success) 12883 { 12884 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 12885 { 12886 m_opcode.SetOpcode16 (thumb_opcode); 12887 } 12888 else 12889 { 12890 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success)); 12891 } 12892 } 12893 } 12894 else 12895 { 12896 m_opcode_mode = eModeARM; 12897 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success)); 12898 } 12899 } 12900 } 12901 if (!success) 12902 { 12903 m_opcode_mode = eModeInvalid; 12904 m_addr = LLDB_INVALID_ADDRESS; 12905 } 12906 return success; 12907} 12908 12909uint32_t 12910EmulateInstructionARM::ArchVersion () 12911{ 12912 return m_arm_isa; 12913} 12914 12915bool 12916EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) 12917{ 12918 // If we are ignoring conditions, then always return true. 12919 // this allows us to iterate over disassembly code and still 12920 // emulate an instruction even if we don't have all the right 12921 // bits set in the CPSR register... 12922 if (m_ignore_conditions) 12923 return true; 12924 12925 if (is_conditional) 12926 *is_conditional = true; 12927 12928 const uint32_t cond = CurrentCond (opcode); 12929 12930 if (cond == UINT32_MAX) 12931 return false; 12932 12933 bool result = false; 12934 switch (UnsignedBits(cond, 3, 1)) 12935 { 12936 case 0: 12937 if (m_opcode_cpsr == 0) 12938 result = true; 12939 else 12940 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 12941 break; 12942 case 1: 12943 if (m_opcode_cpsr == 0) 12944 result = true; 12945 else 12946 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 12947 break; 12948 case 2: 12949 if (m_opcode_cpsr == 0) 12950 result = true; 12951 else 12952 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 12953 break; 12954 case 3: 12955 if (m_opcode_cpsr == 0) 12956 result = true; 12957 else 12958 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 12959 break; 12960 case 4: 12961 if (m_opcode_cpsr == 0) 12962 result = true; 12963 else 12964 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12965 break; 12966 case 5: 12967 if (m_opcode_cpsr == 0) 12968 result = true; 12969 else 12970 { 12971 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12972 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12973 result = n == v; 12974 } 12975 break; 12976 case 6: 12977 if (m_opcode_cpsr == 0) 12978 result = true; 12979 else 12980 { 12981 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12982 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12983 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12984 } 12985 break; 12986 case 7: 12987 // Always execute (cond == 0b1110, or the special 0b1111 which gives 12988 // opcodes different meanings, but always means execution happpens. 12989 if (is_conditional) 12990 *is_conditional = false; 12991 result = true; 12992 break; 12993 } 12994 12995 if (cond & 1) 12996 result = !result; 12997 return result; 12998} 12999 13000uint32_t 13001EmulateInstructionARM::CurrentCond (const uint32_t opcode) 13002{ 13003 switch (m_opcode_mode) 13004 { 13005 case eModeInvalid: 13006 break; 13007 13008 case eModeARM: 13009 return UnsignedBits(opcode, 31, 28); 13010 13011 case eModeThumb: 13012 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13013 // 'cond' field of the encoding. 13014 { 13015 const uint32_t byte_size = m_opcode.GetByteSize(); 13016 if (byte_size == 2) 13017 { 13018 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 13019 return Bits32(opcode, 11, 7); 13020 } 13021 else if (byte_size == 4) 13022 { 13023 if (Bits32(opcode, 31, 27) == 0x1e && 13024 Bits32(opcode, 15, 14) == 0x02 && 13025 Bits32(opcode, 12, 12) == 0x00 && 13026 Bits32(opcode, 25, 22) <= 0x0d) 13027 { 13028 return Bits32(opcode, 25, 22); 13029 } 13030 } 13031 else 13032 // We have an invalid thumb instruction, let's bail out. 13033 break; 13034 13035 return m_it_session.GetCond(); 13036 } 13037 } 13038 return UINT32_MAX; // Return invalid value 13039} 13040 13041bool 13042EmulateInstructionARM::InITBlock() 13043{ 13044 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13045} 13046 13047bool 13048EmulateInstructionARM::LastInITBlock() 13049{ 13050 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13051} 13052 13053bool 13054EmulateInstructionARM::BadMode (uint32_t mode) 13055{ 13056 13057 switch (mode) 13058 { 13059 case 16: return false; // '10000' 13060 case 17: return false; // '10001' 13061 case 18: return false; // '10010' 13062 case 19: return false; // '10011' 13063 case 22: return false; // '10110' 13064 case 23: return false; // '10111' 13065 case 27: return false; // '11011' 13066 case 31: return false; // '11111' 13067 default: return true; 13068 } 13069 return true; 13070} 13071 13072bool 13073EmulateInstructionARM::CurrentModeIsPrivileged () 13074{ 13075 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13076 13077 if (BadMode (mode)) 13078 return false; 13079 13080 if (mode == 16) 13081 return false; 13082 13083 return true; 13084} 13085 13086void 13087EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13088{ 13089 bool privileged = CurrentModeIsPrivileged(); 13090 13091 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13092 13093 if (BitIsSet (bytemask, 3)) 13094 { 13095 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13096 if (affect_execstate) 13097 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13098 } 13099 13100 if (BitIsSet (bytemask, 2)) 13101 { 13102 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13103 } 13104 13105 if (BitIsSet (bytemask, 1)) 13106 { 13107 if (affect_execstate) 13108 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13109 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13110 if (privileged) 13111 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13112 } 13113 13114 if (BitIsSet (bytemask, 0)) 13115 { 13116 if (privileged) 13117 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13118 if (affect_execstate) 13119 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13120 if (privileged) 13121 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13122 } 13123 13124 m_opcode_cpsr = tmp_cpsr; 13125} 13126 13127 13128bool 13129EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13130{ 13131 addr_t target; 13132 13133 // Check the current instruction set. 13134 if (CurrentInstrSet() == eModeARM) 13135 target = addr & 0xfffffffc; 13136 else 13137 target = addr & 0xfffffffe; 13138 13139 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13140 return false; 13141 13142 return true; 13143} 13144 13145// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13146bool 13147EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13148{ 13149 addr_t target; 13150 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13151 // we want to record it and issue a WriteRegister callback so the clients 13152 // can track the mode changes accordingly. 13153 bool cpsr_changed = false; 13154 13155 if (BitIsSet(addr, 0)) 13156 { 13157 if (CurrentInstrSet() != eModeThumb) 13158 { 13159 SelectInstrSet(eModeThumb); 13160 cpsr_changed = true; 13161 } 13162 target = addr & 0xfffffffe; 13163 context.SetISA (eModeThumb); 13164 } 13165 else if (BitIsClear(addr, 1)) 13166 { 13167 if (CurrentInstrSet() != eModeARM) 13168 { 13169 SelectInstrSet(eModeARM); 13170 cpsr_changed = true; 13171 } 13172 target = addr & 0xfffffffc; 13173 context.SetISA (eModeARM); 13174 } 13175 else 13176 return false; // address<1:0> == '10' => UNPREDICTABLE 13177 13178 if (cpsr_changed) 13179 { 13180 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13181 return false; 13182 } 13183 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13184 return false; 13185 13186 return true; 13187} 13188 13189// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13190bool 13191EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13192{ 13193 if (ArchVersion() >= ARMv5T) 13194 return BXWritePC(context, addr); 13195 else 13196 return BranchWritePC((const Context)context, addr); 13197} 13198 13199// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13200bool 13201EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13202{ 13203 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13204 return BXWritePC(context, addr); 13205 else 13206 return BranchWritePC((const Context)context, addr); 13207} 13208 13209EmulateInstructionARM::Mode 13210EmulateInstructionARM::CurrentInstrSet () 13211{ 13212 return m_opcode_mode; 13213} 13214 13215// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13216// ReadInstruction() is performed. This function has a side effect of updating 13217// the m_new_inst_cpsr member variable if necessary. 13218bool 13219EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13220{ 13221 m_new_inst_cpsr = m_opcode_cpsr; 13222 switch (arm_or_thumb) 13223 { 13224 default: 13225 return false; 13226 case eModeARM: 13227 // Clear the T bit. 13228 m_new_inst_cpsr &= ~MASK_CPSR_T; 13229 break; 13230 case eModeThumb: 13231 // Set the T bit. 13232 m_new_inst_cpsr |= MASK_CPSR_T; 13233 break; 13234 } 13235 return true; 13236} 13237 13238// This function returns TRUE if the processor currently provides support for 13239// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13240// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13241bool 13242EmulateInstructionARM::UnalignedSupport() 13243{ 13244 return (ArchVersion() >= ARMv7); 13245} 13246 13247// The main addition and subtraction instructions can produce status information 13248// about both unsigned carry and signed overflow conditions. This status 13249// information can be used to synthesize multi-word additions and subtractions. 13250EmulateInstructionARM::AddWithCarryResult 13251EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13252{ 13253 uint32_t result; 13254 uint8_t carry_out; 13255 uint8_t overflow; 13256 13257 uint64_t unsigned_sum = x + y + carry_in; 13258 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13259 13260 result = UnsignedBits(unsigned_sum, 31, 0); 13261// carry_out = (result == unsigned_sum ? 0 : 1); 13262 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13263 13264 if (carry_in) 13265 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13266 else 13267 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13268 13269 AddWithCarryResult res = { result, carry_out, overflow }; 13270 return res; 13271} 13272 13273uint32_t 13274EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13275{ 13276 uint32_t reg_kind, reg_num; 13277 switch (num) 13278 { 13279 case SP_REG: 13280 reg_kind = eRegisterKindGeneric; 13281 reg_num = LLDB_REGNUM_GENERIC_SP; 13282 break; 13283 case LR_REG: 13284 reg_kind = eRegisterKindGeneric; 13285 reg_num = LLDB_REGNUM_GENERIC_RA; 13286 break; 13287 case PC_REG: 13288 reg_kind = eRegisterKindGeneric; 13289 reg_num = LLDB_REGNUM_GENERIC_PC; 13290 break; 13291 default: 13292 if (num < SP_REG) 13293 { 13294 reg_kind = eRegisterKindDWARF; 13295 reg_num = dwarf_r0 + num; 13296 } 13297 else 13298 { 13299 //assert(0 && "Invalid register number"); 13300 *success = false; 13301 return UINT32_MAX; 13302 } 13303 break; 13304 } 13305 13306 // Read our register. 13307 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13308 13309 // When executing an ARM instruction , PC reads as the address of the current 13310 // instruction plus 8. 13311 // When executing a Thumb instruction , PC reads as the address of the current 13312 // instruction plus 4. 13313 if (num == 15) 13314 { 13315 if (CurrentInstrSet() == eModeARM) 13316 val += 8; 13317 else 13318 val += 4; 13319 } 13320 13321 return val; 13322} 13323 13324// Write the result to the ARM core register Rd, and optionally update the 13325// condition flags based on the result. 13326// 13327// This helper method tries to encapsulate the following pseudocode from the 13328// ARM Architecture Reference Manual: 13329// 13330// if d == 15 then // Can only occur for encoding A1 13331// ALUWritePC(result); // setflags is always FALSE here 13332// else 13333// R[d] = result; 13334// if setflags then 13335// APSR.N = result<31>; 13336// APSR.Z = IsZeroBit(result); 13337// APSR.C = carry; 13338// // APSR.V unchanged 13339// 13340// In the above case, the API client does not pass in the overflow arg, which 13341// defaults to ~0u. 13342bool 13343EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13344 const uint32_t result, 13345 const uint32_t Rd, 13346 bool setflags, 13347 const uint32_t carry, 13348 const uint32_t overflow) 13349{ 13350 if (Rd == 15) 13351 { 13352 if (!ALUWritePC (context, result)) 13353 return false; 13354 } 13355 else 13356 { 13357 uint32_t reg_kind, reg_num; 13358 switch (Rd) 13359 { 13360 case SP_REG: 13361 reg_kind = eRegisterKindGeneric; 13362 reg_num = LLDB_REGNUM_GENERIC_SP; 13363 break; 13364 case LR_REG: 13365 reg_kind = eRegisterKindGeneric; 13366 reg_num = LLDB_REGNUM_GENERIC_RA; 13367 break; 13368 default: 13369 reg_kind = eRegisterKindDWARF; 13370 reg_num = dwarf_r0 + Rd; 13371 } 13372 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13373 return false; 13374 if (setflags) 13375 return WriteFlags (context, result, carry, overflow); 13376 } 13377 return true; 13378} 13379 13380// This helper method tries to encapsulate the following pseudocode from the 13381// ARM Architecture Reference Manual: 13382// 13383// APSR.N = result<31>; 13384// APSR.Z = IsZeroBit(result); 13385// APSR.C = carry; 13386// APSR.V = overflow 13387// 13388// Default arguments can be specified for carry and overflow parameters, which means 13389// not to update the respective flags. 13390bool 13391EmulateInstructionARM::WriteFlags (Context &context, 13392 const uint32_t result, 13393 const uint32_t carry, 13394 const uint32_t overflow) 13395{ 13396 m_new_inst_cpsr = m_opcode_cpsr; 13397 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13398 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13399 if (carry != ~0u) 13400 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13401 if (overflow != ~0u) 13402 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13403 if (m_new_inst_cpsr != m_opcode_cpsr) 13404 { 13405 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13406 return false; 13407 } 13408 return true; 13409} 13410 13411bool 13412EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13413{ 13414 // Advance the ITSTATE bits to their values for the next instruction. 13415 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13416 m_it_session.ITAdvance(); 13417 13418 ARMOpcode *opcode_data = NULL; 13419 13420 if (m_opcode_mode == eModeThumb) 13421 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13422 else if (m_opcode_mode == eModeARM) 13423 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13424 13425 if (opcode_data == NULL) 13426 return false; 13427 13428 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13429 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13430 13431 bool success = false; 13432 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13433 { 13434 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13435 dwarf_cpsr, 13436 0, 13437 &success); 13438 } 13439 13440 // Only return false if we are unable to read the CPSR if we care about conditions 13441 if (success == false && m_ignore_conditions == false) 13442 return false; 13443 13444 uint32_t orig_pc_value = 0; 13445 if (auto_advance_pc) 13446 { 13447 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13448 if (!success) 13449 return false; 13450 } 13451 13452 // Call the Emulate... function. 13453 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13454 if (!success) 13455 return false; 13456 13457 if (auto_advance_pc) 13458 { 13459 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13460 if (!success) 13461 return false; 13462 13463 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13464 { 13465 if (opcode_data->size == eSize32) 13466 after_pc_value += 4; 13467 else if (opcode_data->size == eSize16) 13468 after_pc_value += 2; 13469 13470 EmulateInstruction::Context context; 13471 context.type = eContextAdvancePC; 13472 context.SetNoArgs(); 13473 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13474 return false; 13475 13476 } 13477 } 13478 return true; 13479} 13480 13481bool 13482EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13483{ 13484 if (!test_data) 13485 { 13486 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13487 return false; 13488 } 13489 13490 static ConstString opcode_key ("opcode"); 13491 static ConstString before_key ("before_state"); 13492 static ConstString after_key ("after_state"); 13493 13494 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13495 13496 uint32_t test_opcode; 13497 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13498 { 13499 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13500 return false; 13501 } 13502 test_opcode = value_sp->GetUInt64Value (); 13503 13504 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13505 { 13506 m_opcode_mode = eModeARM; 13507 m_opcode.SetOpcode32 (test_opcode); 13508 } 13509 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13510 { 13511 m_opcode_mode = eModeThumb; 13512 if (test_opcode < 0x10000) 13513 m_opcode.SetOpcode16 (test_opcode); 13514 else 13515 m_opcode.SetOpcode32 (test_opcode); 13516 13517 } 13518 else 13519 { 13520 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13521 return false; 13522 } 13523 13524 EmulationStateARM before_state; 13525 EmulationStateARM after_state; 13526 13527 value_sp = test_data->GetValueForKey (before_key); 13528 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13529 { 13530 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13531 return false; 13532 } 13533 13534 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13535 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13536 { 13537 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13538 return false; 13539 } 13540 13541 value_sp = test_data->GetValueForKey (after_key); 13542 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13543 { 13544 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13545 return false; 13546 } 13547 13548 state_dictionary = value_sp->GetAsDictionary (); 13549 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13550 { 13551 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13552 return false; 13553 } 13554 13555 SetBaton ((void *) &before_state); 13556 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13557 &EmulationStateARM::WritePseudoMemory, 13558 &EmulationStateARM::ReadPseudoRegister, 13559 &EmulationStateARM::WritePseudoRegister); 13560 13561 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13562 if (!success) 13563 { 13564 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13565 return false; 13566 } 13567 13568 success = before_state.CompareState (after_state); 13569 if (!success) 13570 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13571 13572 return success; 13573} 13574// 13575// 13576//const char * 13577//EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13578//{ 13579// if (reg_kind == eRegisterKindGeneric) 13580// { 13581// switch (reg_num) 13582// { 13583// case LLDB_REGNUM_GENERIC_PC: return "pc"; 13584// case LLDB_REGNUM_GENERIC_SP: return "sp"; 13585// case LLDB_REGNUM_GENERIC_FP: return "fp"; 13586// case LLDB_REGNUM_GENERIC_RA: return "lr"; 13587// case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13588// default: return NULL; 13589// } 13590// } 13591// else if (reg_kind == eRegisterKindDWARF) 13592// { 13593// return GetARMDWARFRegisterName (reg_num); 13594// } 13595// return NULL; 13596//} 13597// 13598bool 13599EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13600{ 13601 unwind_plan.Clear(); 13602 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13603 13604 UnwindPlan::RowSP row(new UnwindPlan::Row); 13605 13606 // Our previous Call Frame Address is the stack pointer 13607 row->SetCFARegister (dwarf_sp); 13608 13609 // Our previous PC is in the LR 13610 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true); 13611 unwind_plan.AppendRow (row); 13612 13613 // All other registers are the same. 13614 13615 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13616 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 13617 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 13618 return true; 13619} 13620