EmulateInstructionARM.cpp revision 81a96aa6242f7b559770f5dc62316253cb8cb0d4
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_32 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_32(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 177const char * 178EmulateInstructionARM::GetPluginNameStatic () 179{ 180 return "lldb.emulate-instruction.arm"; 181} 182 183const char * 184EmulateInstructionARM::GetPluginDescriptionStatic () 185{ 186 return "Emulate instructions for the ARM architecture."; 187} 188 189EmulateInstruction * 190EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) 191{ 192 if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type)) 193 { 194 if (arch.GetTriple().getArch() == llvm::Triple::arm) 195 { 196 STD_UNIQUE_PTR(EmulateInstructionARM) emulate_insn_ap (new EmulateInstructionARM (arch)); 197 198 if (emulate_insn_ap.get()) 199 return emulate_insn_ap.release(); 200 } 201 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 202 { 203 STD_UNIQUE_PTR(EmulateInstructionARM) emulate_insn_ap (new EmulateInstructionARM (arch)); 204 205 if (emulate_insn_ap.get()) 206 return emulate_insn_ap.release(); 207 } 208 } 209 210 return NULL; 211} 212 213bool 214EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch) 215{ 216 if (arch.GetTriple().getArch () == llvm::Triple::arm) 217 return true; 218 else if (arch.GetTriple().getArch () == llvm::Triple::thumb) 219 return true; 220 221 return false; 222} 223 224// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 225bool 226EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 227{ 228 EmulateInstruction::Context context; 229 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 230 context.SetNoArgs (); 231 232 uint32_t random_data = rand (); 233 const uint32_t addr_byte_size = GetAddressByteSize(); 234 235 if (!MemAWrite (context, address, random_data, addr_byte_size)) 236 return false; 237 238 return true; 239} 240 241// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 242bool 243EmulateInstructionARM::WriteBits32Unknown (int n) 244{ 245 EmulateInstruction::Context context; 246 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 247 context.SetNoArgs (); 248 249 bool success; 250 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 251 252 if (!success) 253 return false; 254 255 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 256 return false; 257 258 return true; 259} 260 261bool 262EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo ®_info) 263{ 264 if (reg_kind == eRegisterKindGeneric) 265 { 266 switch (reg_num) 267 { 268 case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break; 269 case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break; 270 case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break; 271 case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break; 272 case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break; 273 default: return false; 274 } 275 } 276 277 if (reg_kind == eRegisterKindDWARF) 278 return GetARMDWARFRegisterInfo(reg_num, reg_info); 279 return false; 280} 281 282uint32_t 283EmulateInstructionARM::GetFramePointerRegisterNumber () const 284{ 285 if (m_opcode_mode == eModeThumb) 286 { 287 switch (m_arch.GetTriple().getOS()) 288 { 289 case llvm::Triple::Darwin: 290 case llvm::Triple::MacOSX: 291 case llvm::Triple::IOS: 292 return 7; 293 default: 294 break; 295 } 296 } 297 return 11; 298} 299 300uint32_t 301EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 302{ 303 if (m_opcode_mode == eModeThumb) 304 { 305 switch (m_arch.GetTriple().getOS()) 306 { 307 case llvm::Triple::Darwin: 308 case llvm::Triple::MacOSX: 309 case llvm::Triple::IOS: 310 return dwarf_r7; 311 default: 312 break; 313 } 314 } 315 return dwarf_r11; 316} 317 318// Push Multiple Registers stores multiple registers to the stack, storing to 319// consecutive memory locations ending just below the address in SP, and updates 320// SP to point to the start of the stored data. 321bool 322EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 323{ 324#if 0 325 // ARM pseudo code... 326 if (ConditionPassed()) 327 { 328 EncodingSpecificOperations(); 329 NullCheckIfThumbEE(13); 330 address = SP - 4*BitCount(registers); 331 332 for (i = 0 to 14) 333 { 334 if (registers<i> == '1') 335 { 336 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 337 MemA[address,4] = bits(32) UNKNOWN; 338 else 339 MemA[address,4] = R[i]; 340 address = address + 4; 341 } 342 } 343 344 if (registers<15> == '1') // Only possible for encoding A1 or A2 345 MemA[address,4] = PCStoreValue(); 346 347 SP = SP - 4*BitCount(registers); 348 } 349#endif 350 351 bool conditional = false; 352 bool success = false; 353 if (ConditionPassed(opcode, &conditional)) 354 { 355 const uint32_t addr_byte_size = GetAddressByteSize(); 356 const addr_t sp = ReadCoreReg (SP_REG, &success); 357 if (!success) 358 return false; 359 uint32_t registers = 0; 360 uint32_t Rt; // the source register 361 switch (encoding) { 362 case eEncodingT1: 363 registers = Bits32(opcode, 7, 0); 364 // The M bit represents LR. 365 if (Bit32(opcode, 8)) 366 registers |= (1u << 14); 367 // if BitCount(registers) < 1 then UNPREDICTABLE; 368 if (BitCount(registers) < 1) 369 return false; 370 break; 371 case eEncodingT2: 372 // Ignore bits 15 & 13. 373 registers = Bits32(opcode, 15, 0) & ~0xa000; 374 // if BitCount(registers) < 2 then UNPREDICTABLE; 375 if (BitCount(registers) < 2) 376 return false; 377 break; 378 case eEncodingT3: 379 Rt = Bits32(opcode, 15, 12); 380 // if BadReg(t) then UNPREDICTABLE; 381 if (BadReg(Rt)) 382 return false; 383 registers = (1u << Rt); 384 break; 385 case eEncodingA1: 386 registers = Bits32(opcode, 15, 0); 387 // Instead of return false, let's handle the following case as well, 388 // which amounts to pushing one reg onto the full descending stacks. 389 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 390 break; 391 case eEncodingA2: 392 Rt = Bits32(opcode, 15, 12); 393 // if t == 13 then UNPREDICTABLE; 394 if (Rt == dwarf_sp) 395 return false; 396 registers = (1u << Rt); 397 break; 398 default: 399 return false; 400 } 401 addr_t sp_offset = addr_byte_size * BitCount (registers); 402 addr_t addr = sp - sp_offset; 403 uint32_t i; 404 405 EmulateInstruction::Context context; 406 if (conditional) 407 context.type = EmulateInstruction::eContextRegisterStore; 408 else 409 context.type = EmulateInstruction::eContextPushRegisterOnStack; 410 RegisterInfo reg_info; 411 RegisterInfo sp_reg; 412 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 413 for (i=0; i<15; ++i) 414 { 415 if (BitIsSet (registers, i)) 416 { 417 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 418 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 419 uint32_t reg_value = ReadCoreReg(i, &success); 420 if (!success) 421 return false; 422 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 423 return false; 424 addr += addr_byte_size; 425 } 426 } 427 428 if (BitIsSet (registers, 15)) 429 { 430 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 431 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 432 const uint32_t pc = ReadCoreReg(PC_REG, &success); 433 if (!success) 434 return false; 435 if (!MemAWrite (context, addr, pc, addr_byte_size)) 436 return false; 437 } 438 439 context.type = EmulateInstruction::eContextAdjustStackPointer; 440 context.SetImmediateSigned (-sp_offset); 441 442 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 443 return false; 444 } 445 return true; 446} 447 448// Pop Multiple Registers loads multiple registers from the stack, loading from 449// consecutive memory locations staring at the address in SP, and updates 450// SP to point just above the loaded data. 451bool 452EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 453{ 454#if 0 455 // ARM pseudo code... 456 if (ConditionPassed()) 457 { 458 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 459 address = SP; 460 for i = 0 to 14 461 if registers<i> == '1' then 462 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 463 if registers<15> == '1' then 464 if UnalignedAllowed then 465 LoadWritePC(MemU[address,4]); 466 else 467 LoadWritePC(MemA[address,4]); 468 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 469 if registers<13> == '1' then SP = bits(32) UNKNOWN; 470 } 471#endif 472 473 bool success = false; 474 475 bool conditional = false; 476 if (ConditionPassed(opcode, &conditional)) 477 { 478 const uint32_t addr_byte_size = GetAddressByteSize(); 479 const addr_t sp = ReadCoreReg (SP_REG, &success); 480 if (!success) 481 return false; 482 uint32_t registers = 0; 483 uint32_t Rt; // the destination register 484 switch (encoding) { 485 case eEncodingT1: 486 registers = Bits32(opcode, 7, 0); 487 // The P bit represents PC. 488 if (Bit32(opcode, 8)) 489 registers |= (1u << 15); 490 // if BitCount(registers) < 1 then UNPREDICTABLE; 491 if (BitCount(registers) < 1) 492 return false; 493 break; 494 case eEncodingT2: 495 // Ignore bit 13. 496 registers = Bits32(opcode, 15, 0) & ~0x2000; 497 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 498 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 499 return false; 500 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 501 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 502 return false; 503 break; 504 case eEncodingT3: 505 Rt = Bits32(opcode, 15, 12); 506 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 507 if (Rt == 13) 508 return false; 509 if (Rt == 15 && InITBlock() && !LastInITBlock()) 510 return false; 511 registers = (1u << Rt); 512 break; 513 case eEncodingA1: 514 registers = Bits32(opcode, 15, 0); 515 // Instead of return false, let's handle the following case as well, 516 // which amounts to popping one reg from the full descending stacks. 517 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 518 519 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 520 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 521 return false; 522 break; 523 case eEncodingA2: 524 Rt = Bits32(opcode, 15, 12); 525 // if t == 13 then UNPREDICTABLE; 526 if (Rt == dwarf_sp) 527 return false; 528 registers = (1u << Rt); 529 break; 530 default: 531 return false; 532 } 533 addr_t sp_offset = addr_byte_size * BitCount (registers); 534 addr_t addr = sp; 535 uint32_t i, data; 536 537 EmulateInstruction::Context context; 538 if (conditional) 539 context.type = EmulateInstruction::eContextRegisterLoad; 540 else 541 context.type = EmulateInstruction::eContextPopRegisterOffStack; 542 543 RegisterInfo sp_reg; 544 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 545 546 for (i=0; i<15; ++i) 547 { 548 if (BitIsSet (registers, i)) 549 { 550 context.SetRegisterPlusOffset (sp_reg, addr - sp); 551 data = MemARead(context, addr, 4, 0, &success); 552 if (!success) 553 return false; 554 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 555 return false; 556 addr += addr_byte_size; 557 } 558 } 559 560 if (BitIsSet (registers, 15)) 561 { 562 context.SetRegisterPlusOffset (sp_reg, addr - sp); 563 data = MemARead(context, addr, 4, 0, &success); 564 if (!success) 565 return false; 566 // In ARMv5T and above, this is an interworking branch. 567 if (!LoadWritePC(context, data)) 568 return false; 569 //addr += addr_byte_size; 570 } 571 572 context.type = EmulateInstruction::eContextAdjustStackPointer; 573 context.SetImmediateSigned (sp_offset); 574 575 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 576 return false; 577 } 578 return true; 579} 580 581// Set r7 or ip to point to saved value residing within the stack. 582// ADD (SP plus immediate) 583bool 584EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 585{ 586#if 0 587 // ARM pseudo code... 588 if (ConditionPassed()) 589 { 590 EncodingSpecificOperations(); 591 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 592 if d == 15 then 593 ALUWritePC(result); // setflags is always FALSE here 594 else 595 R[d] = result; 596 if setflags then 597 APSR.N = result<31>; 598 APSR.Z = IsZeroBit(result); 599 APSR.C = carry; 600 APSR.V = overflow; 601 } 602#endif 603 604 bool success = false; 605 606 if (ConditionPassed(opcode)) 607 { 608 const addr_t sp = ReadCoreReg (SP_REG, &success); 609 if (!success) 610 return false; 611 uint32_t Rd; // the destination register 612 uint32_t imm32; 613 switch (encoding) { 614 case eEncodingT1: 615 Rd = 7; 616 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 617 break; 618 case eEncodingA1: 619 Rd = Bits32(opcode, 15, 12); 620 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 621 break; 622 default: 623 return false; 624 } 625 addr_t sp_offset = imm32; 626 addr_t addr = sp + sp_offset; // a pointer to the stack area 627 628 EmulateInstruction::Context context; 629 context.type = eContextSetFramePointer; 630 RegisterInfo sp_reg; 631 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 632 context.SetRegisterPlusOffset (sp_reg, sp_offset); 633 634 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 635 return false; 636 } 637 return true; 638} 639 640// Set r7 or ip to the current stack pointer. 641// MOV (register) 642bool 643EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 644{ 645#if 0 646 // ARM pseudo code... 647 if (ConditionPassed()) 648 { 649 EncodingSpecificOperations(); 650 result = R[m]; 651 if d == 15 then 652 ALUWritePC(result); // setflags is always FALSE here 653 else 654 R[d] = result; 655 if setflags then 656 APSR.N = result<31>; 657 APSR.Z = IsZeroBit(result); 658 // APSR.C unchanged 659 // APSR.V unchanged 660 } 661#endif 662 663 bool success = false; 664 665 if (ConditionPassed(opcode)) 666 { 667 const addr_t sp = ReadCoreReg (SP_REG, &success); 668 if (!success) 669 return false; 670 uint32_t Rd; // the destination register 671 switch (encoding) { 672 case eEncodingT1: 673 Rd = 7; 674 break; 675 case eEncodingA1: 676 Rd = 12; 677 break; 678 default: 679 return false; 680 } 681 682 EmulateInstruction::Context context; 683 if (Rd == GetFramePointerRegisterNumber()) 684 context.type = EmulateInstruction::eContextSetFramePointer; 685 else 686 context.type = EmulateInstruction::eContextRegisterPlusOffset; 687 RegisterInfo sp_reg; 688 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 689 context.SetRegisterPlusOffset (sp_reg, 0); 690 691 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 692 return false; 693 } 694 return true; 695} 696 697// Move from high register (r8-r15) to low register (r0-r7). 698// MOV (register) 699bool 700EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 701{ 702 return EmulateMOVRdRm (opcode, encoding); 703} 704 705// Move from register to register. 706// MOV (register) 707bool 708EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 709{ 710#if 0 711 // ARM pseudo code... 712 if (ConditionPassed()) 713 { 714 EncodingSpecificOperations(); 715 result = R[m]; 716 if d == 15 then 717 ALUWritePC(result); // setflags is always FALSE here 718 else 719 R[d] = result; 720 if setflags then 721 APSR.N = result<31>; 722 APSR.Z = IsZeroBit(result); 723 // APSR.C unchanged 724 // APSR.V unchanged 725 } 726#endif 727 728 bool success = false; 729 730 if (ConditionPassed(opcode)) 731 { 732 uint32_t Rm; // the source register 733 uint32_t Rd; // the destination register 734 bool setflags; 735 switch (encoding) { 736 case eEncodingT1: 737 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 738 Rm = Bits32(opcode, 6, 3); 739 setflags = false; 740 if (Rd == 15 && InITBlock() && !LastInITBlock()) 741 return false; 742 break; 743 case eEncodingT2: 744 Rd = Bits32(opcode, 2, 0); 745 Rm = Bits32(opcode, 5, 3); 746 setflags = true; 747 if (InITBlock()) 748 return false; 749 break; 750 case eEncodingT3: 751 Rd = Bits32(opcode, 11, 8); 752 Rm = Bits32(opcode, 3, 0); 753 setflags = BitIsSet(opcode, 20); 754 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 755 if (setflags && (BadReg(Rd) || BadReg(Rm))) 756 return false; 757 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 758 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 759 return false; 760 break; 761 case eEncodingA1: 762 Rd = Bits32(opcode, 15, 12); 763 Rm = Bits32(opcode, 3, 0); 764 setflags = BitIsSet(opcode, 20); 765 766 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 767 if (Rd == 15 && setflags) 768 return EmulateSUBSPcLrEtc (opcode, encoding); 769 break; 770 default: 771 return false; 772 } 773 uint32_t result = ReadCoreReg(Rm, &success); 774 if (!success) 775 return false; 776 777 // The context specifies that Rm is to be moved into Rd. 778 EmulateInstruction::Context context; 779 context.type = EmulateInstruction::eContextRegisterLoad; 780 RegisterInfo dwarf_reg; 781 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 782 context.SetRegister (dwarf_reg); 783 784 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 785 return false; 786 } 787 return true; 788} 789 790// Move (immediate) writes an immediate value to the destination register. It 791// can optionally update the condition flags based on the value. 792// MOV (immediate) 793bool 794EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 795{ 796#if 0 797 // ARM pseudo code... 798 if (ConditionPassed()) 799 { 800 EncodingSpecificOperations(); 801 result = imm32; 802 if d == 15 then // Can only occur for ARM encoding 803 ALUWritePC(result); // setflags is always FALSE here 804 else 805 R[d] = result; 806 if setflags then 807 APSR.N = result<31>; 808 APSR.Z = IsZeroBit(result); 809 APSR.C = carry; 810 // APSR.V unchanged 811 } 812#endif 813 814 if (ConditionPassed(opcode)) 815 { 816 uint32_t Rd; // the destination register 817 uint32_t imm32; // the immediate value to be written to Rd 818 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 819 // for setflags == false, this value is a don't care 820 // initialized to 0 to silence the static analyzer 821 bool setflags; 822 switch (encoding) { 823 case eEncodingT1: 824 Rd = Bits32(opcode, 10, 8); 825 setflags = !InITBlock(); 826 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 827 carry = APSR_C; 828 829 break; 830 831 case eEncodingT2: 832 Rd = Bits32(opcode, 11, 8); 833 setflags = BitIsSet(opcode, 20); 834 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 835 if (BadReg(Rd)) 836 return false; 837 838 break; 839 840 case eEncodingT3: 841 { 842 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 843 Rd = Bits32 (opcode, 11, 8); 844 setflags = false; 845 uint32_t imm4 = Bits32 (opcode, 19, 16); 846 uint32_t imm3 = Bits32 (opcode, 14, 12); 847 uint32_t i = Bit32 (opcode, 26); 848 uint32_t imm8 = Bits32 (opcode, 7, 0); 849 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 850 851 // if BadReg(d) then UNPREDICTABLE; 852 if (BadReg (Rd)) 853 return false; 854 } 855 break; 856 857 case eEncodingA1: 858 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 859 Rd = Bits32 (opcode, 15, 12); 860 setflags = BitIsSet (opcode, 20); 861 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 862 863 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 864 if ((Rd == 15) && setflags) 865 return EmulateSUBSPcLrEtc (opcode, encoding); 866 867 break; 868 869 case eEncodingA2: 870 { 871 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 872 Rd = Bits32 (opcode, 15, 12); 873 setflags = false; 874 uint32_t imm4 = Bits32 (opcode, 19, 16); 875 uint32_t imm12 = Bits32 (opcode, 11, 0); 876 imm32 = (imm4 << 12) | imm12; 877 878 // if d == 15 then UNPREDICTABLE; 879 if (Rd == 15) 880 return false; 881 } 882 break; 883 884 default: 885 return false; 886 } 887 uint32_t result = imm32; 888 889 // The context specifies that an immediate is to be moved into Rd. 890 EmulateInstruction::Context context; 891 context.type = EmulateInstruction::eContextImmediate; 892 context.SetNoArgs (); 893 894 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 895 return false; 896 } 897 return true; 898} 899 900// MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 901// register. These 32 bits do not depend on whether the source register values are considered to be signed values or 902// unsigned values. 903// 904// Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 905// limited to only a few forms of the instruction. 906bool 907EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 908{ 909#if 0 910 if ConditionPassed() then 911 EncodingSpecificOperations(); 912 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 913 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 914 result = operand1 * operand2; 915 R[d] = result<31:0>; 916 if setflags then 917 APSR.N = result<31>; 918 APSR.Z = IsZeroBit(result); 919 if ArchVersion() == 4 then 920 APSR.C = bit UNKNOWN; 921 // else APSR.C unchanged 922 // APSR.V always unchanged 923#endif 924 925 if (ConditionPassed(opcode)) 926 { 927 uint32_t d; 928 uint32_t n; 929 uint32_t m; 930 bool setflags; 931 932 // EncodingSpecificOperations(); 933 switch (encoding) 934 { 935 case eEncodingT1: 936 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 937 d = Bits32 (opcode, 2, 0); 938 n = Bits32 (opcode, 5, 3); 939 m = Bits32 (opcode, 2, 0); 940 setflags = !InITBlock(); 941 942 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 943 if ((ArchVersion() < ARMv6) && (d == n)) 944 return false; 945 946 break; 947 948 case eEncodingT2: 949 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 950 d = Bits32 (opcode, 11, 8); 951 n = Bits32 (opcode, 19, 16); 952 m = Bits32 (opcode, 3, 0); 953 setflags = false; 954 955 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 956 if (BadReg (d) || BadReg (n) || BadReg (m)) 957 return false; 958 959 break; 960 961 case eEncodingA1: 962 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 963 d = Bits32 (opcode, 19, 16); 964 n = Bits32 (opcode, 3, 0); 965 m = Bits32 (opcode, 11, 8); 966 setflags = BitIsSet (opcode, 20); 967 968 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 969 if ((d == 15) || (n == 15) || (m == 15)) 970 return false; 971 972 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 973 if ((ArchVersion() < ARMv6) && (d == n)) 974 return false; 975 976 break; 977 978 default: 979 return false; 980 } 981 982 bool success = false; 983 984 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 985 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 986 if (!success) 987 return false; 988 989 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 990 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 991 if (!success) 992 return false; 993 994 // result = operand1 * operand2; 995 uint64_t result = operand1 * operand2; 996 997 // R[d] = result<31:0>; 998 RegisterInfo op1_reg; 999 RegisterInfo op2_reg; 1000 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1001 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1002 1003 EmulateInstruction::Context context; 1004 context.type = eContextArithmetic; 1005 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 1006 1007 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 1008 return false; 1009 1010 // if setflags then 1011 if (setflags) 1012 { 1013 // APSR.N = result<31>; 1014 // APSR.Z = IsZeroBit(result); 1015 m_new_inst_cpsr = m_opcode_cpsr; 1016 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 1017 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1018 if (m_new_inst_cpsr != m_opcode_cpsr) 1019 { 1020 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1021 return false; 1022 } 1023 1024 // if ArchVersion() == 4 then 1025 // APSR.C = bit UNKNOWN; 1026 } 1027 } 1028 return true; 1029} 1030 1031// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1032// It can optionally update the condition flags based on the value. 1033bool 1034EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1035{ 1036#if 0 1037 // ARM pseudo code... 1038 if (ConditionPassed()) 1039 { 1040 EncodingSpecificOperations(); 1041 result = NOT(imm32); 1042 if d == 15 then // Can only occur for ARM encoding 1043 ALUWritePC(result); // setflags is always FALSE here 1044 else 1045 R[d] = result; 1046 if setflags then 1047 APSR.N = result<31>; 1048 APSR.Z = IsZeroBit(result); 1049 APSR.C = carry; 1050 // APSR.V unchanged 1051 } 1052#endif 1053 1054 if (ConditionPassed(opcode)) 1055 { 1056 uint32_t Rd; // the destination register 1057 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1058 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1059 bool setflags; 1060 switch (encoding) { 1061 case eEncodingT1: 1062 Rd = Bits32(opcode, 11, 8); 1063 setflags = BitIsSet(opcode, 20); 1064 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1065 break; 1066 case eEncodingA1: 1067 Rd = Bits32(opcode, 15, 12); 1068 setflags = BitIsSet(opcode, 20); 1069 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1070 1071 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1072 if (Rd == 15 && setflags) 1073 return EmulateSUBSPcLrEtc (opcode, encoding); 1074 break; 1075 default: 1076 return false; 1077 } 1078 uint32_t result = ~imm32; 1079 1080 // The context specifies that an immediate is to be moved into Rd. 1081 EmulateInstruction::Context context; 1082 context.type = EmulateInstruction::eContextImmediate; 1083 context.SetNoArgs (); 1084 1085 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1086 return false; 1087 } 1088 return true; 1089} 1090 1091// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1092// It can optionally update the condition flags based on the result. 1093bool 1094EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1095{ 1096#if 0 1097 // ARM pseudo code... 1098 if (ConditionPassed()) 1099 { 1100 EncodingSpecificOperations(); 1101 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1102 result = NOT(shifted); 1103 if d == 15 then // Can only occur for ARM encoding 1104 ALUWritePC(result); // setflags is always FALSE here 1105 else 1106 R[d] = result; 1107 if setflags then 1108 APSR.N = result<31>; 1109 APSR.Z = IsZeroBit(result); 1110 APSR.C = carry; 1111 // APSR.V unchanged 1112 } 1113#endif 1114 1115 if (ConditionPassed(opcode)) 1116 { 1117 uint32_t Rm; // the source register 1118 uint32_t Rd; // the destination register 1119 ARM_ShifterType shift_t; 1120 uint32_t shift_n; // the shift applied to the value read from Rm 1121 bool setflags; 1122 uint32_t carry; // the carry bit after the shift operation 1123 switch (encoding) { 1124 case eEncodingT1: 1125 Rd = Bits32(opcode, 2, 0); 1126 Rm = Bits32(opcode, 5, 3); 1127 setflags = !InITBlock(); 1128 shift_t = SRType_LSL; 1129 shift_n = 0; 1130 if (InITBlock()) 1131 return false; 1132 break; 1133 case eEncodingT2: 1134 Rd = Bits32(opcode, 11, 8); 1135 Rm = Bits32(opcode, 3, 0); 1136 setflags = BitIsSet(opcode, 20); 1137 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1138 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1139 if (BadReg(Rd) || BadReg(Rm)) 1140 return false; 1141 break; 1142 case eEncodingA1: 1143 Rd = Bits32(opcode, 15, 12); 1144 Rm = Bits32(opcode, 3, 0); 1145 setflags = BitIsSet(opcode, 20); 1146 shift_n = DecodeImmShiftARM(opcode, shift_t); 1147 break; 1148 default: 1149 return false; 1150 } 1151 bool success = false; 1152 uint32_t value = ReadCoreReg(Rm, &success); 1153 if (!success) 1154 return false; 1155 1156 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1157 if (!success) 1158 return false; 1159 uint32_t result = ~shifted; 1160 1161 // The context specifies that an immediate is to be moved into Rd. 1162 EmulateInstruction::Context context; 1163 context.type = EmulateInstruction::eContextImmediate; 1164 context.SetNoArgs (); 1165 1166 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1167 return false; 1168 } 1169 return true; 1170} 1171 1172// PC relative immediate load into register, possibly followed by ADD (SP plus register). 1173// LDR (literal) 1174bool 1175EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1176{ 1177#if 0 1178 // ARM pseudo code... 1179 if (ConditionPassed()) 1180 { 1181 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1182 base = Align(PC,4); 1183 address = if add then (base + imm32) else (base - imm32); 1184 data = MemU[address,4]; 1185 if t == 15 then 1186 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1187 elsif UnalignedSupport() || address<1:0> = '00' then 1188 R[t] = data; 1189 else // Can only apply before ARMv7 1190 if CurrentInstrSet() == InstrSet_ARM then 1191 R[t] = ROR(data, 8*UInt(address<1:0>)); 1192 else 1193 R[t] = bits(32) UNKNOWN; 1194 } 1195#endif 1196 1197 if (ConditionPassed(opcode)) 1198 { 1199 bool success = false; 1200 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1201 if (!success) 1202 return false; 1203 1204 // PC relative immediate load context 1205 EmulateInstruction::Context context; 1206 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1207 RegisterInfo pc_reg; 1208 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1209 context.SetRegisterPlusOffset (pc_reg, 0); 1210 1211 uint32_t Rt; // the destination register 1212 uint32_t imm32; // immediate offset from the PC 1213 bool add; // +imm32 or -imm32? 1214 addr_t base; // the base address 1215 addr_t address; // the PC relative address 1216 uint32_t data; // the literal data value from the PC relative load 1217 switch (encoding) { 1218 case eEncodingT1: 1219 Rt = Bits32(opcode, 10, 8); 1220 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1221 add = true; 1222 break; 1223 case eEncodingT2: 1224 Rt = Bits32(opcode, 15, 12); 1225 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1226 add = BitIsSet(opcode, 23); 1227 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1228 return false; 1229 break; 1230 default: 1231 return false; 1232 } 1233 1234 base = Align(pc, 4); 1235 if (add) 1236 address = base + imm32; 1237 else 1238 address = base - imm32; 1239 1240 context.SetRegisterPlusOffset(pc_reg, address - base); 1241 data = MemURead(context, address, 4, 0, &success); 1242 if (!success) 1243 return false; 1244 1245 if (Rt == 15) 1246 { 1247 if (Bits32(address, 1, 0) == 0) 1248 { 1249 // In ARMv5T and above, this is an interworking branch. 1250 if (!LoadWritePC(context, data)) 1251 return false; 1252 } 1253 else 1254 return false; 1255 } 1256 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1257 { 1258 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1259 return false; 1260 } 1261 else // We don't handle ARM for now. 1262 return false; 1263 1264 } 1265 return true; 1266} 1267 1268// An add operation to adjust the SP. 1269// ADD (SP plus immediate) 1270bool 1271EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1272{ 1273#if 0 1274 // ARM pseudo code... 1275 if (ConditionPassed()) 1276 { 1277 EncodingSpecificOperations(); 1278 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1279 if d == 15 then // Can only occur for ARM encoding 1280 ALUWritePC(result); // setflags is always FALSE here 1281 else 1282 R[d] = result; 1283 if setflags then 1284 APSR.N = result<31>; 1285 APSR.Z = IsZeroBit(result); 1286 APSR.C = carry; 1287 APSR.V = overflow; 1288 } 1289#endif 1290 1291 bool success = false; 1292 1293 if (ConditionPassed(opcode)) 1294 { 1295 const addr_t sp = ReadCoreReg (SP_REG, &success); 1296 if (!success) 1297 return false; 1298 uint32_t imm32; // the immediate operand 1299 uint32_t d; 1300 //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1 1301 switch (encoding) 1302 { 1303 case eEncodingT1: 1304 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1305 d = Bits32 (opcode, 10, 8); 1306 imm32 = (Bits32 (opcode, 7, 0) << 2); 1307 1308 break; 1309 1310 case eEncodingT2: 1311 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1312 d = 13; 1313 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1314 1315 break; 1316 1317 default: 1318 return false; 1319 } 1320 addr_t sp_offset = imm32; 1321 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1322 1323 EmulateInstruction::Context context; 1324 context.type = EmulateInstruction::eContextAdjustStackPointer; 1325 RegisterInfo sp_reg; 1326 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1327 context.SetRegisterPlusOffset (sp_reg, sp_offset); 1328 1329 if (d == 15) 1330 { 1331 if (!ALUWritePC (context, addr)) 1332 return false; 1333 } 1334 else 1335 { 1336 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr)) 1337 return false; 1338 1339 // Add this back if/when support eEncodingT3 eEncodingA1 1340 //if (setflags) 1341 //{ 1342 // APSR.N = result<31>; 1343 // APSR.Z = IsZeroBit(result); 1344 // APSR.C = carry; 1345 // APSR.V = overflow; 1346 //} 1347 } 1348 } 1349 return true; 1350} 1351 1352// An add operation to adjust the SP. 1353// ADD (SP plus register) 1354bool 1355EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1356{ 1357#if 0 1358 // ARM pseudo code... 1359 if (ConditionPassed()) 1360 { 1361 EncodingSpecificOperations(); 1362 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1363 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1364 if d == 15 then 1365 ALUWritePC(result); // setflags is always FALSE here 1366 else 1367 R[d] = result; 1368 if setflags then 1369 APSR.N = result<31>; 1370 APSR.Z = IsZeroBit(result); 1371 APSR.C = carry; 1372 APSR.V = overflow; 1373 } 1374#endif 1375 1376 bool success = false; 1377 1378 if (ConditionPassed(opcode)) 1379 { 1380 const addr_t sp = ReadCoreReg (SP_REG, &success); 1381 if (!success) 1382 return false; 1383 uint32_t Rm; // the second operand 1384 switch (encoding) { 1385 case eEncodingT2: 1386 Rm = Bits32(opcode, 6, 3); 1387 break; 1388 default: 1389 return false; 1390 } 1391 int32_t reg_value = ReadCoreReg(Rm, &success); 1392 if (!success) 1393 return false; 1394 1395 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1396 1397 EmulateInstruction::Context context; 1398 context.type = eContextArithmetic; 1399 RegisterInfo sp_reg; 1400 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1401 1402 RegisterInfo other_reg; 1403 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1404 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1405 1406 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1407 return false; 1408 } 1409 return true; 1410} 1411 1412// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1413// at a PC-relative address, and changes instruction set from ARM to Thumb, or 1414// from Thumb to ARM. 1415// BLX (immediate) 1416bool 1417EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1418{ 1419#if 0 1420 // ARM pseudo code... 1421 if (ConditionPassed()) 1422 { 1423 EncodingSpecificOperations(); 1424 if CurrentInstrSet() == InstrSet_ARM then 1425 LR = PC - 4; 1426 else 1427 LR = PC<31:1> : '1'; 1428 if targetInstrSet == InstrSet_ARM then 1429 targetAddress = Align(PC,4) + imm32; 1430 else 1431 targetAddress = PC + imm32; 1432 SelectInstrSet(targetInstrSet); 1433 BranchWritePC(targetAddress); 1434 } 1435#endif 1436 1437 bool success = true; 1438 1439 if (ConditionPassed(opcode)) 1440 { 1441 EmulateInstruction::Context context; 1442 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1443 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1444 if (!success) 1445 return false; 1446 addr_t lr; // next instruction address 1447 addr_t target; // target address 1448 int32_t imm32; // PC-relative offset 1449 switch (encoding) { 1450 case eEncodingT1: 1451 { 1452 lr = pc | 1u; // return address 1453 uint32_t S = Bit32(opcode, 26); 1454 uint32_t imm10 = Bits32(opcode, 25, 16); 1455 uint32_t J1 = Bit32(opcode, 13); 1456 uint32_t J2 = Bit32(opcode, 11); 1457 uint32_t imm11 = Bits32(opcode, 10, 0); 1458 uint32_t I1 = !(J1 ^ S); 1459 uint32_t I2 = !(J2 ^ S); 1460 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1461 imm32 = llvm::SignExtend32<25>(imm25); 1462 target = pc + imm32; 1463 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1464 if (InITBlock() && !LastInITBlock()) 1465 return false; 1466 break; 1467 } 1468 case eEncodingT2: 1469 { 1470 lr = pc | 1u; // return address 1471 uint32_t S = Bit32(opcode, 26); 1472 uint32_t imm10H = Bits32(opcode, 25, 16); 1473 uint32_t J1 = Bit32(opcode, 13); 1474 uint32_t J2 = Bit32(opcode, 11); 1475 uint32_t imm10L = Bits32(opcode, 10, 1); 1476 uint32_t I1 = !(J1 ^ S); 1477 uint32_t I2 = !(J2 ^ S); 1478 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1479 imm32 = llvm::SignExtend32<25>(imm25); 1480 target = Align(pc, 4) + imm32; 1481 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1482 if (InITBlock() && !LastInITBlock()) 1483 return false; 1484 break; 1485 } 1486 case eEncodingA1: 1487 lr = pc - 4; // return address 1488 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1489 target = Align(pc, 4) + imm32; 1490 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1491 break; 1492 case eEncodingA2: 1493 lr = pc - 4; // return address 1494 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1495 target = pc + imm32; 1496 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1497 break; 1498 default: 1499 return false; 1500 } 1501 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1502 return false; 1503 if (!BranchWritePC(context, target)) 1504 return false; 1505 } 1506 return true; 1507} 1508 1509// Branch with Link and Exchange (register) calls a subroutine at an address and 1510// instruction set specified by a register. 1511// BLX (register) 1512bool 1513EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1514{ 1515#if 0 1516 // ARM pseudo code... 1517 if (ConditionPassed()) 1518 { 1519 EncodingSpecificOperations(); 1520 target = R[m]; 1521 if CurrentInstrSet() == InstrSet_ARM then 1522 next_instr_addr = PC - 4; 1523 LR = next_instr_addr; 1524 else 1525 next_instr_addr = PC - 2; 1526 LR = next_instr_addr<31:1> : '1'; 1527 BXWritePC(target); 1528 } 1529#endif 1530 1531 bool success = false; 1532 1533 if (ConditionPassed(opcode)) 1534 { 1535 EmulateInstruction::Context context; 1536 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1537 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1538 addr_t lr; // next instruction address 1539 if (!success) 1540 return false; 1541 uint32_t Rm; // the register with the target address 1542 switch (encoding) { 1543 case eEncodingT1: 1544 lr = (pc - 2) | 1u; // return address 1545 Rm = Bits32(opcode, 6, 3); 1546 // if m == 15 then UNPREDICTABLE; 1547 if (Rm == 15) 1548 return false; 1549 if (InITBlock() && !LastInITBlock()) 1550 return false; 1551 break; 1552 case eEncodingA1: 1553 lr = pc - 4; // return address 1554 Rm = Bits32(opcode, 3, 0); 1555 // if m == 15 then UNPREDICTABLE; 1556 if (Rm == 15) 1557 return false; 1558 break; 1559 default: 1560 return false; 1561 } 1562 addr_t target = ReadCoreReg (Rm, &success); 1563 if (!success) 1564 return false; 1565 RegisterInfo dwarf_reg; 1566 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1567 context.SetRegister (dwarf_reg); 1568 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1569 return false; 1570 if (!BXWritePC(context, target)) 1571 return false; 1572 } 1573 return true; 1574} 1575 1576// Branch and Exchange causes a branch to an address and instruction set specified by a register. 1577bool 1578EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1579{ 1580#if 0 1581 // ARM pseudo code... 1582 if (ConditionPassed()) 1583 { 1584 EncodingSpecificOperations(); 1585 BXWritePC(R[m]); 1586 } 1587#endif 1588 1589 if (ConditionPassed(opcode)) 1590 { 1591 EmulateInstruction::Context context; 1592 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1593 uint32_t Rm; // the register with the target address 1594 switch (encoding) { 1595 case eEncodingT1: 1596 Rm = Bits32(opcode, 6, 3); 1597 if (InITBlock() && !LastInITBlock()) 1598 return false; 1599 break; 1600 case eEncodingA1: 1601 Rm = Bits32(opcode, 3, 0); 1602 break; 1603 default: 1604 return false; 1605 } 1606 bool success = false; 1607 addr_t target = ReadCoreReg (Rm, &success); 1608 if (!success) 1609 return false; 1610 1611 RegisterInfo dwarf_reg; 1612 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1613 context.SetRegister (dwarf_reg); 1614 if (!BXWritePC(context, target)) 1615 return false; 1616 } 1617 return true; 1618} 1619 1620// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1621// address and instruction set specified by a register as though it were a BX instruction. 1622// 1623// TODO: Emulate Jazelle architecture? 1624// We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1625bool 1626EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1627{ 1628#if 0 1629 // ARM pseudo code... 1630 if (ConditionPassed()) 1631 { 1632 EncodingSpecificOperations(); 1633 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1634 BXWritePC(R[m]); 1635 else 1636 if JazelleAcceptsExecution() then 1637 SwitchToJazelleExecution(); 1638 else 1639 SUBARCHITECTURE_DEFINED handler call; 1640 } 1641#endif 1642 1643 if (ConditionPassed(opcode)) 1644 { 1645 EmulateInstruction::Context context; 1646 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1647 uint32_t Rm; // the register with the target address 1648 switch (encoding) { 1649 case eEncodingT1: 1650 Rm = Bits32(opcode, 19, 16); 1651 if (BadReg(Rm)) 1652 return false; 1653 if (InITBlock() && !LastInITBlock()) 1654 return false; 1655 break; 1656 case eEncodingA1: 1657 Rm = Bits32(opcode, 3, 0); 1658 if (Rm == 15) 1659 return false; 1660 break; 1661 default: 1662 return false; 1663 } 1664 bool success = false; 1665 addr_t target = ReadCoreReg (Rm, &success); 1666 if (!success) 1667 return false; 1668 1669 RegisterInfo dwarf_reg; 1670 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1671 context.SetRegister (dwarf_reg); 1672 if (!BXWritePC(context, target)) 1673 return false; 1674 } 1675 return true; 1676} 1677 1678// Set r7 to point to some ip offset. 1679// SUB (immediate) 1680bool 1681EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1682{ 1683#if 0 1684 // ARM pseudo code... 1685 if (ConditionPassed()) 1686 { 1687 EncodingSpecificOperations(); 1688 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1689 if d == 15 then // Can only occur for ARM encoding 1690 ALUWritePC(result); // setflags is always FALSE here 1691 else 1692 R[d] = result; 1693 if setflags then 1694 APSR.N = result<31>; 1695 APSR.Z = IsZeroBit(result); 1696 APSR.C = carry; 1697 APSR.V = overflow; 1698 } 1699#endif 1700 1701 if (ConditionPassed(opcode)) 1702 { 1703 bool success = false; 1704 const addr_t ip = ReadCoreReg (12, &success); 1705 if (!success) 1706 return false; 1707 uint32_t imm32; 1708 switch (encoding) { 1709 case eEncodingA1: 1710 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1711 break; 1712 default: 1713 return false; 1714 } 1715 addr_t ip_offset = imm32; 1716 addr_t addr = ip - ip_offset; // the adjusted ip value 1717 1718 EmulateInstruction::Context context; 1719 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1720 RegisterInfo dwarf_reg; 1721 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1722 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1723 1724 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1725 return false; 1726 } 1727 return true; 1728} 1729 1730// Set ip to point to some stack offset. 1731// SUB (SP minus immediate) 1732bool 1733EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1734{ 1735#if 0 1736 // ARM pseudo code... 1737 if (ConditionPassed()) 1738 { 1739 EncodingSpecificOperations(); 1740 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1741 if d == 15 then // Can only occur for ARM encoding 1742 ALUWritePC(result); // setflags is always FALSE here 1743 else 1744 R[d] = result; 1745 if setflags then 1746 APSR.N = result<31>; 1747 APSR.Z = IsZeroBit(result); 1748 APSR.C = carry; 1749 APSR.V = overflow; 1750 } 1751#endif 1752 1753 if (ConditionPassed(opcode)) 1754 { 1755 bool success = false; 1756 const addr_t sp = ReadCoreReg (SP_REG, &success); 1757 if (!success) 1758 return false; 1759 uint32_t imm32; 1760 switch (encoding) { 1761 case eEncodingA1: 1762 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1763 break; 1764 default: 1765 return false; 1766 } 1767 addr_t sp_offset = imm32; 1768 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1769 1770 EmulateInstruction::Context context; 1771 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1772 RegisterInfo dwarf_reg; 1773 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1774 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1775 1776 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1777 return false; 1778 } 1779 return true; 1780} 1781 1782// This instruction subtracts an immediate value from the SP value, and writes 1783// the result to the destination register. 1784// 1785// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1786bool 1787EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1788{ 1789#if 0 1790 // ARM pseudo code... 1791 if (ConditionPassed()) 1792 { 1793 EncodingSpecificOperations(); 1794 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1795 if d == 15 then // Can only occur for ARM encoding 1796 ALUWritePC(result); // setflags is always FALSE here 1797 else 1798 R[d] = result; 1799 if setflags then 1800 APSR.N = result<31>; 1801 APSR.Z = IsZeroBit(result); 1802 APSR.C = carry; 1803 APSR.V = overflow; 1804 } 1805#endif 1806 1807 bool success = false; 1808 if (ConditionPassed(opcode)) 1809 { 1810 const addr_t sp = ReadCoreReg (SP_REG, &success); 1811 if (!success) 1812 return false; 1813 1814 uint32_t Rd; 1815 bool setflags; 1816 uint32_t imm32; 1817 switch (encoding) { 1818 case eEncodingT1: 1819 Rd = 13; 1820 setflags = false; 1821 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1822 break; 1823 case eEncodingT2: 1824 Rd = Bits32(opcode, 11, 8); 1825 setflags = BitIsSet(opcode, 20); 1826 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1827 if (Rd == 15 && setflags) 1828 return EmulateCMPImm(opcode, eEncodingT2); 1829 if (Rd == 15 && !setflags) 1830 return false; 1831 break; 1832 case eEncodingT3: 1833 Rd = Bits32(opcode, 11, 8); 1834 setflags = false; 1835 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1836 if (Rd == 15) 1837 return false; 1838 break; 1839 case eEncodingA1: 1840 Rd = Bits32(opcode, 15, 12); 1841 setflags = BitIsSet(opcode, 20); 1842 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1843 1844 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1845 if (Rd == 15 && setflags) 1846 return EmulateSUBSPcLrEtc (opcode, encoding); 1847 break; 1848 default: 1849 return false; 1850 } 1851 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1852 1853 EmulateInstruction::Context context; 1854 if (Rd == 13) 1855 { 1856 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1857 // value gets passed down to context.SetImmediateSigned. 1858 context.type = EmulateInstruction::eContextAdjustStackPointer; 1859 context.SetImmediateSigned (-imm64); // the stack pointer offset 1860 } 1861 else 1862 { 1863 context.type = EmulateInstruction::eContextImmediate; 1864 context.SetNoArgs (); 1865 } 1866 1867 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1868 return false; 1869 } 1870 return true; 1871} 1872 1873// A store operation to the stack that also updates the SP. 1874bool 1875EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1876{ 1877#if 0 1878 // ARM pseudo code... 1879 if (ConditionPassed()) 1880 { 1881 EncodingSpecificOperations(); 1882 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1883 address = if index then offset_addr else R[n]; 1884 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1885 if wback then R[n] = offset_addr; 1886 } 1887#endif 1888 1889 bool conditional = false; 1890 bool success = false; 1891 if (ConditionPassed(opcode, &conditional)) 1892 { 1893 const uint32_t addr_byte_size = GetAddressByteSize(); 1894 const addr_t sp = ReadCoreReg (SP_REG, &success); 1895 if (!success) 1896 return false; 1897 uint32_t Rt; // the source register 1898 uint32_t imm12; 1899 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1900 1901 bool index; 1902 bool add; 1903 bool wback; 1904 switch (encoding) { 1905 case eEncodingA1: 1906 Rt = Bits32(opcode, 15, 12); 1907 imm12 = Bits32(opcode, 11, 0); 1908 Rn = Bits32 (opcode, 19, 16); 1909 1910 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1911 return false; 1912 1913 index = BitIsSet (opcode, 24); 1914 add = BitIsSet (opcode, 23); 1915 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1916 1917 if (wback && ((Rn == 15) || (Rn == Rt))) 1918 return false; 1919 break; 1920 default: 1921 return false; 1922 } 1923 addr_t offset_addr; 1924 if (add) 1925 offset_addr = sp + imm12; 1926 else 1927 offset_addr = sp - imm12; 1928 1929 addr_t addr; 1930 if (index) 1931 addr = offset_addr; 1932 else 1933 addr = sp; 1934 1935 EmulateInstruction::Context context; 1936 if (conditional) 1937 context.type = EmulateInstruction::eContextRegisterStore; 1938 else 1939 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1940 RegisterInfo sp_reg; 1941 RegisterInfo dwarf_reg; 1942 1943 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1944 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 1945 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 1946 if (Rt != 15) 1947 { 1948 uint32_t reg_value = ReadCoreReg(Rt, &success); 1949 if (!success) 1950 return false; 1951 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1952 return false; 1953 } 1954 else 1955 { 1956 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1957 if (!success) 1958 return false; 1959 if (!MemUWrite (context, addr, pc, addr_byte_size)) 1960 return false; 1961 } 1962 1963 1964 if (wback) 1965 { 1966 context.type = EmulateInstruction::eContextAdjustStackPointer; 1967 context.SetImmediateSigned (addr - sp); 1968 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 1969 return false; 1970 } 1971 } 1972 return true; 1973} 1974 1975// Vector Push stores multiple extension registers to the stack. 1976// It also updates SP to point to the start of the stored data. 1977bool 1978EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 1979{ 1980#if 0 1981 // ARM pseudo code... 1982 if (ConditionPassed()) 1983 { 1984 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1985 address = SP - imm32; 1986 SP = SP - imm32; 1987 if single_regs then 1988 for r = 0 to regs-1 1989 MemA[address,4] = S[d+r]; address = address+4; 1990 else 1991 for r = 0 to regs-1 1992 // Store as two word-aligned words in the correct order for current endianness. 1993 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1994 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1995 address = address+8; 1996 } 1997#endif 1998 1999 bool success = false; 2000 bool conditional = false; 2001 if (ConditionPassed(opcode, &conditional)) 2002 { 2003 const uint32_t addr_byte_size = GetAddressByteSize(); 2004 const addr_t sp = ReadCoreReg (SP_REG, &success); 2005 if (!success) 2006 return false; 2007 bool single_regs; 2008 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2009 uint32_t imm32; // stack offset 2010 uint32_t regs; // number of registers 2011 switch (encoding) { 2012 case eEncodingT1: 2013 case eEncodingA1: 2014 single_regs = false; 2015 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2016 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2017 // If UInt(imm8) is odd, see "FSTMX". 2018 regs = Bits32(opcode, 7, 0) / 2; 2019 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2020 if (regs == 0 || regs > 16 || (d + regs) > 32) 2021 return false; 2022 break; 2023 case eEncodingT2: 2024 case eEncodingA2: 2025 single_regs = true; 2026 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2027 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2028 regs = Bits32(opcode, 7, 0); 2029 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2030 if (regs == 0 || regs > 16 || (d + regs) > 32) 2031 return false; 2032 break; 2033 default: 2034 return false; 2035 } 2036 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2037 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2038 addr_t sp_offset = imm32; 2039 addr_t addr = sp - sp_offset; 2040 uint32_t i; 2041 2042 EmulateInstruction::Context context; 2043 if (conditional) 2044 context.type = EmulateInstruction::eContextRegisterStore; 2045 else 2046 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2047 RegisterInfo dwarf_reg; 2048 RegisterInfo sp_reg; 2049 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2050 for (i=0; i<regs; ++i) 2051 { 2052 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2053 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2054 // uint64_t to accommodate 64-bit registers. 2055 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2056 if (!success) 2057 return false; 2058 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2059 return false; 2060 addr += reg_byte_size; 2061 } 2062 2063 context.type = EmulateInstruction::eContextAdjustStackPointer; 2064 context.SetImmediateSigned (-sp_offset); 2065 2066 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2067 return false; 2068 } 2069 return true; 2070} 2071 2072// Vector Pop loads multiple extension registers from the stack. 2073// It also updates SP to point just above the loaded data. 2074bool 2075EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2076{ 2077#if 0 2078 // ARM pseudo code... 2079 if (ConditionPassed()) 2080 { 2081 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2082 address = SP; 2083 SP = SP + imm32; 2084 if single_regs then 2085 for r = 0 to regs-1 2086 S[d+r] = MemA[address,4]; address = address+4; 2087 else 2088 for r = 0 to regs-1 2089 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2090 // Combine the word-aligned words in the correct order for current endianness. 2091 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2092 } 2093#endif 2094 2095 bool success = false; 2096 bool conditional = false; 2097 if (ConditionPassed(opcode, &conditional)) 2098 { 2099 const uint32_t addr_byte_size = GetAddressByteSize(); 2100 const addr_t sp = ReadCoreReg (SP_REG, &success); 2101 if (!success) 2102 return false; 2103 bool single_regs; 2104 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2105 uint32_t imm32; // stack offset 2106 uint32_t regs; // number of registers 2107 switch (encoding) { 2108 case eEncodingT1: 2109 case eEncodingA1: 2110 single_regs = false; 2111 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2112 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2113 // If UInt(imm8) is odd, see "FLDMX". 2114 regs = Bits32(opcode, 7, 0) / 2; 2115 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2116 if (regs == 0 || regs > 16 || (d + regs) > 32) 2117 return false; 2118 break; 2119 case eEncodingT2: 2120 case eEncodingA2: 2121 single_regs = true; 2122 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2123 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2124 regs = Bits32(opcode, 7, 0); 2125 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2126 if (regs == 0 || regs > 16 || (d + regs) > 32) 2127 return false; 2128 break; 2129 default: 2130 return false; 2131 } 2132 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2133 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2134 addr_t sp_offset = imm32; 2135 addr_t addr = sp; 2136 uint32_t i; 2137 uint64_t data; // uint64_t to accomodate 64-bit registers. 2138 2139 EmulateInstruction::Context context; 2140 if (conditional) 2141 context.type = EmulateInstruction::eContextRegisterLoad; 2142 else 2143 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2144 RegisterInfo dwarf_reg; 2145 RegisterInfo sp_reg; 2146 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2147 for (i=0; i<regs; ++i) 2148 { 2149 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2150 context.SetRegisterPlusOffset (sp_reg, addr - sp); 2151 data = MemARead(context, addr, reg_byte_size, 0, &success); 2152 if (!success) 2153 return false; 2154 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2155 return false; 2156 addr += reg_byte_size; 2157 } 2158 2159 context.type = EmulateInstruction::eContextAdjustStackPointer; 2160 context.SetImmediateSigned (sp_offset); 2161 2162 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2163 return false; 2164 } 2165 return true; 2166} 2167 2168// SVC (previously SWI) 2169bool 2170EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2171{ 2172#if 0 2173 // ARM pseudo code... 2174 if (ConditionPassed()) 2175 { 2176 EncodingSpecificOperations(); 2177 CallSupervisor(); 2178 } 2179#endif 2180 2181 bool success = false; 2182 2183 if (ConditionPassed(opcode)) 2184 { 2185 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2186 addr_t lr; // next instruction address 2187 if (!success) 2188 return false; 2189 uint32_t imm32; // the immediate constant 2190 uint32_t mode; // ARM or Thumb mode 2191 switch (encoding) { 2192 case eEncodingT1: 2193 lr = (pc + 2) | 1u; // return address 2194 imm32 = Bits32(opcode, 7, 0); 2195 mode = eModeThumb; 2196 break; 2197 case eEncodingA1: 2198 lr = pc + 4; // return address 2199 imm32 = Bits32(opcode, 23, 0); 2200 mode = eModeARM; 2201 break; 2202 default: 2203 return false; 2204 } 2205 2206 EmulateInstruction::Context context; 2207 context.type = EmulateInstruction::eContextSupervisorCall; 2208 context.SetISAAndImmediate (mode, imm32); 2209 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2210 return false; 2211 } 2212 return true; 2213} 2214 2215// If Then makes up to four following instructions (the IT block) conditional. 2216bool 2217EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2218{ 2219#if 0 2220 // ARM pseudo code... 2221 EncodingSpecificOperations(); 2222 ITSTATE.IT<7:0> = firstcond:mask; 2223#endif 2224 2225 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2226 return true; 2227} 2228 2229bool 2230EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2231{ 2232 // NOP, nothing to do... 2233 return true; 2234} 2235 2236// Branch causes a branch to a target address. 2237bool 2238EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2239{ 2240#if 0 2241 // ARM pseudo code... 2242 if (ConditionPassed()) 2243 { 2244 EncodingSpecificOperations(); 2245 BranchWritePC(PC + imm32); 2246 } 2247#endif 2248 2249 bool success = false; 2250 2251 if (ConditionPassed(opcode)) 2252 { 2253 EmulateInstruction::Context context; 2254 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2255 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2256 if (!success) 2257 return false; 2258 addr_t target; // target address 2259 int32_t imm32; // PC-relative offset 2260 switch (encoding) { 2261 case eEncodingT1: 2262 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2263 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2264 target = pc + imm32; 2265 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2266 break; 2267 case eEncodingT2: 2268 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2269 target = pc + imm32; 2270 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2271 break; 2272 case eEncodingT3: 2273 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2274 { 2275 uint32_t S = Bit32(opcode, 26); 2276 uint32_t imm6 = Bits32(opcode, 21, 16); 2277 uint32_t J1 = Bit32(opcode, 13); 2278 uint32_t J2 = Bit32(opcode, 11); 2279 uint32_t imm11 = Bits32(opcode, 10, 0); 2280 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2281 imm32 = llvm::SignExtend32<21>(imm21); 2282 target = pc + imm32; 2283 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2284 break; 2285 } 2286 case eEncodingT4: 2287 { 2288 uint32_t S = Bit32(opcode, 26); 2289 uint32_t imm10 = Bits32(opcode, 25, 16); 2290 uint32_t J1 = Bit32(opcode, 13); 2291 uint32_t J2 = Bit32(opcode, 11); 2292 uint32_t imm11 = Bits32(opcode, 10, 0); 2293 uint32_t I1 = !(J1 ^ S); 2294 uint32_t I2 = !(J2 ^ S); 2295 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2296 imm32 = llvm::SignExtend32<25>(imm25); 2297 target = pc + imm32; 2298 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2299 break; 2300 } 2301 case eEncodingA1: 2302 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2303 target = pc + imm32; 2304 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2305 break; 2306 default: 2307 return false; 2308 } 2309 if (!BranchWritePC(context, target)) 2310 return false; 2311 } 2312 return true; 2313} 2314 2315// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2316// zero and conditionally branch forward a constant value. They do not affect the condition flags. 2317// CBNZ, CBZ 2318bool 2319EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2320{ 2321#if 0 2322 // ARM pseudo code... 2323 EncodingSpecificOperations(); 2324 if nonzero ^ IsZero(R[n]) then 2325 BranchWritePC(PC + imm32); 2326#endif 2327 2328 bool success = false; 2329 2330 // Read the register value from the operand register Rn. 2331 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2332 if (!success) 2333 return false; 2334 2335 EmulateInstruction::Context context; 2336 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2337 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2338 if (!success) 2339 return false; 2340 2341 addr_t target; // target address 2342 uint32_t imm32; // PC-relative offset to branch forward 2343 bool nonzero; 2344 switch (encoding) { 2345 case eEncodingT1: 2346 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2347 nonzero = BitIsSet(opcode, 11); 2348 target = pc + imm32; 2349 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2350 break; 2351 default: 2352 return false; 2353 } 2354 if (nonzero ^ (reg_val == 0)) 2355 if (!BranchWritePC(context, target)) 2356 return false; 2357 2358 return true; 2359} 2360 2361// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2362// A base register provides a pointer to the table, and a second register supplies an index into the table. 2363// The branch length is twice the value of the byte returned from the table. 2364// 2365// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2366// A base register provides a pointer to the table, and a second register supplies an index into the table. 2367// The branch length is twice the value of the halfword returned from the table. 2368// TBB, TBH 2369bool 2370EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2371{ 2372#if 0 2373 // ARM pseudo code... 2374 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2375 if is_tbh then 2376 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2377 else 2378 halfwords = UInt(MemU[R[n]+R[m], 1]); 2379 BranchWritePC(PC + 2*halfwords); 2380#endif 2381 2382 bool success = false; 2383 2384 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2385 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2386 bool is_tbh; // true if table branch halfword 2387 switch (encoding) { 2388 case eEncodingT1: 2389 Rn = Bits32(opcode, 19, 16); 2390 Rm = Bits32(opcode, 3, 0); 2391 is_tbh = BitIsSet(opcode, 4); 2392 if (Rn == 13 || BadReg(Rm)) 2393 return false; 2394 if (InITBlock() && !LastInITBlock()) 2395 return false; 2396 break; 2397 default: 2398 return false; 2399 } 2400 2401 // Read the address of the table from the operand register Rn. 2402 // The PC can be used, in which case the table immediately follows this instruction. 2403 uint32_t base = ReadCoreReg(Rm, &success); 2404 if (!success) 2405 return false; 2406 2407 // the table index 2408 uint32_t index = ReadCoreReg(Rm, &success); 2409 if (!success) 2410 return false; 2411 2412 // the offsetted table address 2413 addr_t addr = base + (is_tbh ? index*2 : index); 2414 2415 // PC-relative offset to branch forward 2416 EmulateInstruction::Context context; 2417 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2418 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2419 if (!success) 2420 return false; 2421 2422 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2423 if (!success) 2424 return false; 2425 2426 // target address 2427 addr_t target = pc + offset; 2428 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2429 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2430 2431 if (!BranchWritePC(context, target)) 2432 return false; 2433 2434 return true; 2435} 2436 2437// This instruction adds an immediate value to a register value, and writes the result to the destination register. 2438// It can optionally update the condition flags based on the result. 2439bool 2440EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2441{ 2442#if 0 2443 if ConditionPassed() then 2444 EncodingSpecificOperations(); 2445 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2446 R[d] = result; 2447 if setflags then 2448 APSR.N = result<31>; 2449 APSR.Z = IsZeroBit(result); 2450 APSR.C = carry; 2451 APSR.V = overflow; 2452#endif 2453 2454 bool success = false; 2455 2456 if (ConditionPassed(opcode)) 2457 { 2458 uint32_t d; 2459 uint32_t n; 2460 bool setflags; 2461 uint32_t imm32; 2462 uint32_t carry_out; 2463 2464 //EncodingSpecificOperations(); 2465 switch (encoding) 2466 { 2467 case eEncodingT1: 2468 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2469 d = Bits32 (opcode, 2, 0); 2470 n = Bits32 (opcode, 5, 3); 2471 setflags = !InITBlock(); 2472 imm32 = Bits32 (opcode, 8,6); 2473 2474 break; 2475 2476 case eEncodingT2: 2477 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2478 d = Bits32 (opcode, 10, 8); 2479 n = Bits32 (opcode, 10, 8); 2480 setflags = !InITBlock(); 2481 imm32 = Bits32 (opcode, 7, 0); 2482 2483 break; 2484 2485 case eEncodingT3: 2486 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2487 // if Rn == '1101' then SEE ADD (SP plus immediate); 2488 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2489 d = Bits32 (opcode, 11, 8); 2490 n = Bits32 (opcode, 19, 16); 2491 setflags = BitIsSet (opcode, 20); 2492 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2493 2494 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2495 if (BadReg (d) || (n == 15)) 2496 return false; 2497 2498 break; 2499 2500 case eEncodingT4: 2501 { 2502 // if Rn == '1111' then SEE ADR; 2503 // if Rn == '1101' then SEE ADD (SP plus immediate); 2504 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2505 d = Bits32 (opcode, 11, 8); 2506 n = Bits32 (opcode, 19, 16); 2507 setflags = false; 2508 uint32_t i = Bit32 (opcode, 26); 2509 uint32_t imm3 = Bits32 (opcode, 14, 12); 2510 uint32_t imm8 = Bits32 (opcode, 7, 0); 2511 imm32 = (i << 11) | (imm3 << 8) | imm8; 2512 2513 // if BadReg(d) then UNPREDICTABLE; 2514 if (BadReg (d)) 2515 return false; 2516 2517 break; 2518 } 2519 default: 2520 return false; 2521 } 2522 2523 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2524 if (!success) 2525 return false; 2526 2527 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2528 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2529 2530 RegisterInfo reg_n; 2531 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2532 2533 EmulateInstruction::Context context; 2534 context.type = eContextArithmetic; 2535 context.SetRegisterPlusOffset (reg_n, imm32); 2536 2537 //R[d] = result; 2538 //if setflags then 2539 //APSR.N = result<31>; 2540 //APSR.Z = IsZeroBit(result); 2541 //APSR.C = carry; 2542 //APSR.V = overflow; 2543 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2544 return false; 2545 2546 } 2547 return true; 2548} 2549 2550// This instruction adds an immediate value to a register value, and writes the result to the destination 2551// register. It can optionally update the condition flags based on the result. 2552bool 2553EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2554{ 2555#if 0 2556 // ARM pseudo code... 2557 if ConditionPassed() then 2558 EncodingSpecificOperations(); 2559 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2560 if d == 15 then 2561 ALUWritePC(result); // setflags is always FALSE here 2562 else 2563 R[d] = result; 2564 if setflags then 2565 APSR.N = result<31>; 2566 APSR.Z = IsZeroBit(result); 2567 APSR.C = carry; 2568 APSR.V = overflow; 2569#endif 2570 2571 bool success = false; 2572 2573 if (ConditionPassed(opcode)) 2574 { 2575 uint32_t Rd, Rn; 2576 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2577 bool setflags; 2578 switch (encoding) 2579 { 2580 case eEncodingA1: 2581 Rd = Bits32(opcode, 15, 12); 2582 Rn = Bits32(opcode, 19, 16); 2583 setflags = BitIsSet(opcode, 20); 2584 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2585 break; 2586 default: 2587 return false; 2588 } 2589 2590 // Read the first operand. 2591 uint32_t val1 = ReadCoreReg(Rn, &success); 2592 if (!success) 2593 return false; 2594 2595 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2596 2597 EmulateInstruction::Context context; 2598 context.type = eContextArithmetic; 2599 RegisterInfo dwarf_reg; 2600 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2601 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2602 2603 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2604 return false; 2605 } 2606 return true; 2607} 2608 2609// This instruction adds a register value and an optionally-shifted register value, and writes the result 2610// to the destination register. It can optionally update the condition flags based on the result. 2611bool 2612EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2613{ 2614#if 0 2615 // ARM pseudo code... 2616 if ConditionPassed() then 2617 EncodingSpecificOperations(); 2618 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2619 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2620 if d == 15 then 2621 ALUWritePC(result); // setflags is always FALSE here 2622 else 2623 R[d] = result; 2624 if setflags then 2625 APSR.N = result<31>; 2626 APSR.Z = IsZeroBit(result); 2627 APSR.C = carry; 2628 APSR.V = overflow; 2629#endif 2630 2631 bool success = false; 2632 2633 if (ConditionPassed(opcode)) 2634 { 2635 uint32_t Rd, Rn, Rm; 2636 ARM_ShifterType shift_t; 2637 uint32_t shift_n; // the shift applied to the value read from Rm 2638 bool setflags; 2639 switch (encoding) 2640 { 2641 case eEncodingT1: 2642 Rd = Bits32(opcode, 2, 0); 2643 Rn = Bits32(opcode, 5, 3); 2644 Rm = Bits32(opcode, 8, 6); 2645 setflags = !InITBlock(); 2646 shift_t = SRType_LSL; 2647 shift_n = 0; 2648 break; 2649 case eEncodingT2: 2650 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2651 Rm = Bits32(opcode, 6, 3); 2652 setflags = false; 2653 shift_t = SRType_LSL; 2654 shift_n = 0; 2655 if (Rn == 15 && Rm == 15) 2656 return false; 2657 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2658 return false; 2659 break; 2660 case eEncodingA1: 2661 Rd = Bits32(opcode, 15, 12); 2662 Rn = Bits32(opcode, 19, 16); 2663 Rm = Bits32(opcode, 3, 0); 2664 setflags = BitIsSet(opcode, 20); 2665 shift_n = DecodeImmShiftARM(opcode, shift_t); 2666 break; 2667 default: 2668 return false; 2669 } 2670 2671 // Read the first operand. 2672 uint32_t val1 = ReadCoreReg(Rn, &success); 2673 if (!success) 2674 return false; 2675 2676 // Read the second operand. 2677 uint32_t val2 = ReadCoreReg(Rm, &success); 2678 if (!success) 2679 return false; 2680 2681 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2682 if (!success) 2683 return false; 2684 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2685 2686 EmulateInstruction::Context context; 2687 context.type = eContextArithmetic; 2688 RegisterInfo op1_reg; 2689 RegisterInfo op2_reg; 2690 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2691 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2692 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2693 2694 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2695 return false; 2696 } 2697 return true; 2698} 2699 2700// Compare Negative (immediate) adds a register value and an immediate value. 2701// It updates the condition flags based on the result, and discards the result. 2702bool 2703EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2704{ 2705#if 0 2706 // ARM pseudo code... 2707 if ConditionPassed() then 2708 EncodingSpecificOperations(); 2709 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2710 APSR.N = result<31>; 2711 APSR.Z = IsZeroBit(result); 2712 APSR.C = carry; 2713 APSR.V = overflow; 2714#endif 2715 2716 bool success = false; 2717 2718 uint32_t Rn; // the first operand 2719 uint32_t imm32; // the immediate value to be compared with 2720 switch (encoding) { 2721 case eEncodingT1: 2722 Rn = Bits32(opcode, 19, 16); 2723 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2724 if (Rn == 15) 2725 return false; 2726 break; 2727 case eEncodingA1: 2728 Rn = Bits32(opcode, 19, 16); 2729 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2730 break; 2731 default: 2732 return false; 2733 } 2734 // Read the register value from the operand register Rn. 2735 uint32_t reg_val = ReadCoreReg(Rn, &success); 2736 if (!success) 2737 return false; 2738 2739 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2740 2741 EmulateInstruction::Context context; 2742 context.type = EmulateInstruction::eContextImmediate; 2743 context.SetNoArgs (); 2744 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2745 return false; 2746 2747 return true; 2748} 2749 2750// Compare Negative (register) adds a register value and an optionally-shifted register value. 2751// It updates the condition flags based on the result, and discards the result. 2752bool 2753EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2754{ 2755#if 0 2756 // ARM pseudo code... 2757 if ConditionPassed() then 2758 EncodingSpecificOperations(); 2759 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2760 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2761 APSR.N = result<31>; 2762 APSR.Z = IsZeroBit(result); 2763 APSR.C = carry; 2764 APSR.V = overflow; 2765#endif 2766 2767 bool success = false; 2768 2769 uint32_t Rn; // the first operand 2770 uint32_t Rm; // the second operand 2771 ARM_ShifterType shift_t; 2772 uint32_t shift_n; // the shift applied to the value read from Rm 2773 switch (encoding) { 2774 case eEncodingT1: 2775 Rn = Bits32(opcode, 2, 0); 2776 Rm = Bits32(opcode, 5, 3); 2777 shift_t = SRType_LSL; 2778 shift_n = 0; 2779 break; 2780 case eEncodingT2: 2781 Rn = Bits32(opcode, 19, 16); 2782 Rm = Bits32(opcode, 3, 0); 2783 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2784 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2785 if (Rn == 15 || BadReg(Rm)) 2786 return false; 2787 break; 2788 case eEncodingA1: 2789 Rn = Bits32(opcode, 19, 16); 2790 Rm = Bits32(opcode, 3, 0); 2791 shift_n = DecodeImmShiftARM(opcode, shift_t); 2792 break; 2793 default: 2794 return false; 2795 } 2796 // Read the register value from register Rn. 2797 uint32_t val1 = ReadCoreReg(Rn, &success); 2798 if (!success) 2799 return false; 2800 2801 // Read the register value from register Rm. 2802 uint32_t val2 = ReadCoreReg(Rm, &success); 2803 if (!success) 2804 return false; 2805 2806 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2807 if (!success) 2808 return false; 2809 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2810 2811 EmulateInstruction::Context context; 2812 context.type = EmulateInstruction::eContextImmediate; 2813 context.SetNoArgs(); 2814 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2815 return false; 2816 2817 return true; 2818} 2819 2820// Compare (immediate) subtracts an immediate value from a register value. 2821// It updates the condition flags based on the result, and discards the result. 2822bool 2823EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2824{ 2825#if 0 2826 // ARM pseudo code... 2827 if ConditionPassed() then 2828 EncodingSpecificOperations(); 2829 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2830 APSR.N = result<31>; 2831 APSR.Z = IsZeroBit(result); 2832 APSR.C = carry; 2833 APSR.V = overflow; 2834#endif 2835 2836 bool success = false; 2837 2838 uint32_t Rn; // the first operand 2839 uint32_t imm32; // the immediate value to be compared with 2840 switch (encoding) { 2841 case eEncodingT1: 2842 Rn = Bits32(opcode, 10, 8); 2843 imm32 = Bits32(opcode, 7, 0); 2844 break; 2845 case eEncodingT2: 2846 Rn = Bits32(opcode, 19, 16); 2847 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2848 if (Rn == 15) 2849 return false; 2850 break; 2851 case eEncodingA1: 2852 Rn = Bits32(opcode, 19, 16); 2853 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2854 break; 2855 default: 2856 return false; 2857 } 2858 // Read the register value from the operand register Rn. 2859 uint32_t reg_val = ReadCoreReg(Rn, &success); 2860 if (!success) 2861 return false; 2862 2863 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2864 2865 EmulateInstruction::Context context; 2866 context.type = EmulateInstruction::eContextImmediate; 2867 context.SetNoArgs (); 2868 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2869 return false; 2870 2871 return true; 2872} 2873 2874// Compare (register) subtracts an optionally-shifted register value from a register value. 2875// It updates the condition flags based on the result, and discards the result. 2876bool 2877EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2878{ 2879#if 0 2880 // ARM pseudo code... 2881 if ConditionPassed() then 2882 EncodingSpecificOperations(); 2883 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2884 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2885 APSR.N = result<31>; 2886 APSR.Z = IsZeroBit(result); 2887 APSR.C = carry; 2888 APSR.V = overflow; 2889#endif 2890 2891 bool success = false; 2892 2893 uint32_t Rn; // the first operand 2894 uint32_t Rm; // the second operand 2895 ARM_ShifterType shift_t; 2896 uint32_t shift_n; // the shift applied to the value read from Rm 2897 switch (encoding) { 2898 case eEncodingT1: 2899 Rn = Bits32(opcode, 2, 0); 2900 Rm = Bits32(opcode, 5, 3); 2901 shift_t = SRType_LSL; 2902 shift_n = 0; 2903 break; 2904 case eEncodingT2: 2905 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2906 Rm = Bits32(opcode, 6, 3); 2907 shift_t = SRType_LSL; 2908 shift_n = 0; 2909 if (Rn < 8 && Rm < 8) 2910 return false; 2911 if (Rn == 15 || Rm == 15) 2912 return false; 2913 break; 2914 case eEncodingA1: 2915 Rn = Bits32(opcode, 19, 16); 2916 Rm = Bits32(opcode, 3, 0); 2917 shift_n = DecodeImmShiftARM(opcode, shift_t); 2918 break; 2919 default: 2920 return false; 2921 } 2922 // Read the register value from register Rn. 2923 uint32_t val1 = ReadCoreReg(Rn, &success); 2924 if (!success) 2925 return false; 2926 2927 // Read the register value from register Rm. 2928 uint32_t val2 = ReadCoreReg(Rm, &success); 2929 if (!success) 2930 return false; 2931 2932 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2933 if (!success) 2934 return false; 2935 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 2936 2937 EmulateInstruction::Context context; 2938 context.type = EmulateInstruction::eContextImmediate; 2939 context.SetNoArgs(); 2940 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2941 return false; 2942 2943 return true; 2944} 2945 2946// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2947// shifting in copies of its sign bit, and writes the result to the destination register. It can 2948// optionally update the condition flags based on the result. 2949bool 2950EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 2951{ 2952#if 0 2953 // ARM pseudo code... 2954 if ConditionPassed() then 2955 EncodingSpecificOperations(); 2956 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2957 if d == 15 then // Can only occur for ARM encoding 2958 ALUWritePC(result); // setflags is always FALSE here 2959 else 2960 R[d] = result; 2961 if setflags then 2962 APSR.N = result<31>; 2963 APSR.Z = IsZeroBit(result); 2964 APSR.C = carry; 2965 // APSR.V unchanged 2966#endif 2967 2968 return EmulateShiftImm (opcode, encoding, SRType_ASR); 2969} 2970 2971// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 2972// shifting in copies of its sign bit, and writes the result to the destination register. 2973// The variable number of bits is read from the bottom byte of a register. It can optionally update 2974// the condition flags based on the result. 2975bool 2976EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 2977{ 2978#if 0 2979 // ARM pseudo code... 2980 if ConditionPassed() then 2981 EncodingSpecificOperations(); 2982 shift_n = UInt(R[m]<7:0>); 2983 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2984 R[d] = result; 2985 if setflags then 2986 APSR.N = result<31>; 2987 APSR.Z = IsZeroBit(result); 2988 APSR.C = carry; 2989 // APSR.V unchanged 2990#endif 2991 2992 return EmulateShiftReg (opcode, encoding, SRType_ASR); 2993} 2994 2995// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 2996// shifting in zeros, and writes the result to the destination register. It can optionally 2997// update the condition flags based on the result. 2998bool 2999EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 3000{ 3001#if 0 3002 // ARM pseudo code... 3003 if ConditionPassed() then 3004 EncodingSpecificOperations(); 3005 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3006 if d == 15 then // Can only occur for ARM encoding 3007 ALUWritePC(result); // setflags is always FALSE here 3008 else 3009 R[d] = result; 3010 if setflags then 3011 APSR.N = result<31>; 3012 APSR.Z = IsZeroBit(result); 3013 APSR.C = carry; 3014 // APSR.V unchanged 3015#endif 3016 3017 return EmulateShiftImm (opcode, encoding, SRType_LSL); 3018} 3019 3020// Logical Shift Left (register) shifts a register value left by a variable number of bits, 3021// shifting in zeros, and writes the result to the destination register. The variable number 3022// of bits is read from the bottom byte of a register. It can optionally update the condition 3023// flags based on the result. 3024bool 3025EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 3026{ 3027#if 0 3028 // ARM pseudo code... 3029 if ConditionPassed() then 3030 EncodingSpecificOperations(); 3031 shift_n = UInt(R[m]<7:0>); 3032 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3033 R[d] = result; 3034 if setflags then 3035 APSR.N = result<31>; 3036 APSR.Z = IsZeroBit(result); 3037 APSR.C = carry; 3038 // APSR.V unchanged 3039#endif 3040 3041 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3042} 3043 3044// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3045// shifting in zeros, and writes the result to the destination register. It can optionally 3046// update the condition flags based on the result. 3047bool 3048EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3049{ 3050#if 0 3051 // ARM pseudo code... 3052 if ConditionPassed() then 3053 EncodingSpecificOperations(); 3054 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3055 if d == 15 then // Can only occur for ARM encoding 3056 ALUWritePC(result); // setflags is always FALSE here 3057 else 3058 R[d] = result; 3059 if setflags then 3060 APSR.N = result<31>; 3061 APSR.Z = IsZeroBit(result); 3062 APSR.C = carry; 3063 // APSR.V unchanged 3064#endif 3065 3066 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3067} 3068 3069// Logical Shift Right (register) shifts a register value right by a variable number of bits, 3070// shifting in zeros, and writes the result to the destination register. The variable number 3071// of bits is read from the bottom byte of a register. It can optionally update the condition 3072// flags based on the result. 3073bool 3074EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3075{ 3076#if 0 3077 // ARM pseudo code... 3078 if ConditionPassed() then 3079 EncodingSpecificOperations(); 3080 shift_n = UInt(R[m]<7:0>); 3081 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3082 R[d] = result; 3083 if setflags then 3084 APSR.N = result<31>; 3085 APSR.Z = IsZeroBit(result); 3086 APSR.C = carry; 3087 // APSR.V unchanged 3088#endif 3089 3090 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3091} 3092 3093// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3094// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3095// It can optionally update the condition flags based on the result. 3096bool 3097EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3098{ 3099#if 0 3100 // ARM pseudo code... 3101 if ConditionPassed() then 3102 EncodingSpecificOperations(); 3103 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3104 if d == 15 then // Can only occur for ARM encoding 3105 ALUWritePC(result); // setflags is always FALSE here 3106 else 3107 R[d] = result; 3108 if setflags then 3109 APSR.N = result<31>; 3110 APSR.Z = IsZeroBit(result); 3111 APSR.C = carry; 3112 // APSR.V unchanged 3113#endif 3114 3115 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3116} 3117 3118// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3119// The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3120// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3121// flags based on the result. 3122bool 3123EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3124{ 3125#if 0 3126 // ARM pseudo code... 3127 if ConditionPassed() then 3128 EncodingSpecificOperations(); 3129 shift_n = UInt(R[m]<7:0>); 3130 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3131 R[d] = result; 3132 if setflags then 3133 APSR.N = result<31>; 3134 APSR.Z = IsZeroBit(result); 3135 APSR.C = carry; 3136 // APSR.V unchanged 3137#endif 3138 3139 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3140} 3141 3142// Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3143// with the carry flag shifted into bit [31]. 3144// 3145// RRX can optionally update the condition flags based on the result. 3146// In that case, bit [0] is shifted into the carry flag. 3147bool 3148EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3149{ 3150#if 0 3151 // ARM pseudo code... 3152 if ConditionPassed() then 3153 EncodingSpecificOperations(); 3154 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3155 if d == 15 then // Can only occur for ARM encoding 3156 ALUWritePC(result); // setflags is always FALSE here 3157 else 3158 R[d] = result; 3159 if setflags then 3160 APSR.N = result<31>; 3161 APSR.Z = IsZeroBit(result); 3162 APSR.C = carry; 3163 // APSR.V unchanged 3164#endif 3165 3166 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3167} 3168 3169bool 3170EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3171{ 3172// assert(shift_type == SRType_ASR 3173// || shift_type == SRType_LSL 3174// || shift_type == SRType_LSR 3175// || shift_type == SRType_ROR 3176// || shift_type == SRType_RRX); 3177 3178 bool success = false; 3179 3180 if (ConditionPassed(opcode)) 3181 { 3182 uint32_t Rd; // the destination register 3183 uint32_t Rm; // the first operand register 3184 uint32_t imm5; // encoding for the shift amount 3185 uint32_t carry; // the carry bit after the shift operation 3186 bool setflags; 3187 3188 // Special case handling! 3189 // A8.6.139 ROR (immediate) -- Encoding T1 3190 ARMEncoding use_encoding = encoding; 3191 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3192 { 3193 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3194 // have the same decoding of bit fields as the other Thumb2 shift operations. 3195 use_encoding = eEncodingT2; 3196 } 3197 3198 switch (use_encoding) { 3199 case eEncodingT1: 3200 // Due to the above special case handling! 3201 if (shift_type == SRType_ROR) 3202 return false; 3203 3204 Rd = Bits32(opcode, 2, 0); 3205 Rm = Bits32(opcode, 5, 3); 3206 setflags = !InITBlock(); 3207 imm5 = Bits32(opcode, 10, 6); 3208 break; 3209 case eEncodingT2: 3210 // A8.6.141 RRX 3211 // There's no imm form of RRX instructions. 3212 if (shift_type == SRType_RRX) 3213 return false; 3214 3215 Rd = Bits32(opcode, 11, 8); 3216 Rm = Bits32(opcode, 3, 0); 3217 setflags = BitIsSet(opcode, 20); 3218 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3219 if (BadReg(Rd) || BadReg(Rm)) 3220 return false; 3221 break; 3222 case eEncodingA1: 3223 Rd = Bits32(opcode, 15, 12); 3224 Rm = Bits32(opcode, 3, 0); 3225 setflags = BitIsSet(opcode, 20); 3226 imm5 = Bits32(opcode, 11, 7); 3227 break; 3228 default: 3229 return false; 3230 } 3231 3232 // A8.6.139 ROR (immediate) 3233 if (shift_type == SRType_ROR && imm5 == 0) 3234 shift_type = SRType_RRX; 3235 3236 // Get the first operand. 3237 uint32_t value = ReadCoreReg (Rm, &success); 3238 if (!success) 3239 return false; 3240 3241 // Decode the shift amount if not RRX. 3242 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3243 3244 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3245 if (!success) 3246 return false; 3247 3248 // The context specifies that an immediate is to be moved into Rd. 3249 EmulateInstruction::Context context; 3250 context.type = EmulateInstruction::eContextImmediate; 3251 context.SetNoArgs (); 3252 3253 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3254 return false; 3255 } 3256 return true; 3257} 3258 3259bool 3260EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3261{ 3262 // assert(shift_type == SRType_ASR 3263 // || shift_type == SRType_LSL 3264 // || shift_type == SRType_LSR 3265 // || shift_type == SRType_ROR); 3266 3267 bool success = false; 3268 3269 if (ConditionPassed(opcode)) 3270 { 3271 uint32_t Rd; // the destination register 3272 uint32_t Rn; // the first operand register 3273 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3274 uint32_t carry; // the carry bit after the shift operation 3275 bool setflags; 3276 switch (encoding) { 3277 case eEncodingT1: 3278 Rd = Bits32(opcode, 2, 0); 3279 Rn = Rd; 3280 Rm = Bits32(opcode, 5, 3); 3281 setflags = !InITBlock(); 3282 break; 3283 case eEncodingT2: 3284 Rd = Bits32(opcode, 11, 8); 3285 Rn = Bits32(opcode, 19, 16); 3286 Rm = Bits32(opcode, 3, 0); 3287 setflags = BitIsSet(opcode, 20); 3288 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3289 return false; 3290 break; 3291 case eEncodingA1: 3292 Rd = Bits32(opcode, 15, 12); 3293 Rn = Bits32(opcode, 3, 0); 3294 Rm = Bits32(opcode, 11, 8); 3295 setflags = BitIsSet(opcode, 20); 3296 if (Rd == 15 || Rn == 15 || Rm == 15) 3297 return false; 3298 break; 3299 default: 3300 return false; 3301 } 3302 3303 // Get the first operand. 3304 uint32_t value = ReadCoreReg (Rn, &success); 3305 if (!success) 3306 return false; 3307 // Get the Rm register content. 3308 uint32_t val = ReadCoreReg (Rm, &success); 3309 if (!success) 3310 return false; 3311 3312 // Get the shift amount. 3313 uint32_t amt = Bits32(val, 7, 0); 3314 3315 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3316 if (!success) 3317 return false; 3318 3319 // The context specifies that an immediate is to be moved into Rd. 3320 EmulateInstruction::Context context; 3321 context.type = EmulateInstruction::eContextImmediate; 3322 context.SetNoArgs (); 3323 3324 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3325 return false; 3326 } 3327 return true; 3328} 3329 3330// LDM loads multiple registers from consecutive memory locations, using an 3331// address from a base register. Optionally the address just above the highest of those locations 3332// can be written back to the base register. 3333bool 3334EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3335{ 3336#if 0 3337 // ARM pseudo code... 3338 if ConditionPassed() 3339 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3340 address = R[n]; 3341 3342 for i = 0 to 14 3343 if registers<i> == '1' then 3344 R[i] = MemA[address, 4]; address = address + 4; 3345 if registers<15> == '1' then 3346 LoadWritePC (MemA[address, 4]); 3347 3348 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3349 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3350 3351#endif 3352 3353 bool success = false; 3354 bool conditional = false; 3355 if (ConditionPassed(opcode, &conditional)) 3356 { 3357 uint32_t n; 3358 uint32_t registers = 0; 3359 bool wback; 3360 const uint32_t addr_byte_size = GetAddressByteSize(); 3361 switch (encoding) 3362 { 3363 case eEncodingT1: 3364 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3365 n = Bits32 (opcode, 10, 8); 3366 registers = Bits32 (opcode, 7, 0); 3367 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3368 wback = BitIsClear (registers, n); 3369 // if BitCount(registers) < 1 then UNPREDICTABLE; 3370 if (BitCount(registers) < 1) 3371 return false; 3372 break; 3373 case eEncodingT2: 3374 // if W == '1' && Rn == '1101' then SEE POP; 3375 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3376 n = Bits32 (opcode, 19, 16); 3377 registers = Bits32 (opcode, 15, 0); 3378 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3379 wback = BitIsSet (opcode, 21); 3380 3381 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3382 if ((n == 15) 3383 || (BitCount (registers) < 2) 3384 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3385 return false; 3386 3387 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3388 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3389 return false; 3390 3391 // if wback && registers<n> == '1' then UNPREDICTABLE; 3392 if (wback 3393 && BitIsSet (registers, n)) 3394 return false; 3395 break; 3396 3397 case eEncodingA1: 3398 n = Bits32 (opcode, 19, 16); 3399 registers = Bits32 (opcode, 15, 0); 3400 wback = BitIsSet (opcode, 21); 3401 if ((n == 15) 3402 || (BitCount (registers) < 1)) 3403 return false; 3404 break; 3405 default: 3406 return false; 3407 } 3408 3409 int32_t offset = 0; 3410 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3411 if (!success) 3412 return false; 3413 3414 EmulateInstruction::Context context; 3415 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3416 RegisterInfo dwarf_reg; 3417 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3418 context.SetRegisterPlusOffset (dwarf_reg, offset); 3419 3420 for (int i = 0; i < 14; ++i) 3421 { 3422 if (BitIsSet (registers, i)) 3423 { 3424 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3425 context.SetRegisterPlusOffset (dwarf_reg, offset); 3426 if (wback && (n == 13)) // Pop Instruction 3427 { 3428 if (conditional) 3429 context.type = EmulateInstruction::eContextRegisterLoad; 3430 else 3431 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3432 } 3433 3434 // R[i] = MemA [address, 4]; address = address + 4; 3435 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3436 if (!success) 3437 return false; 3438 3439 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3440 return false; 3441 3442 offset += addr_byte_size; 3443 } 3444 } 3445 3446 if (BitIsSet (registers, 15)) 3447 { 3448 //LoadWritePC (MemA [address, 4]); 3449 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3450 context.SetRegisterPlusOffset (dwarf_reg, offset); 3451 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3452 if (!success) 3453 return false; 3454 // In ARMv5T and above, this is an interworking branch. 3455 if (!LoadWritePC(context, data)) 3456 return false; 3457 } 3458 3459 if (wback && BitIsClear (registers, n)) 3460 { 3461 // R[n] = R[n] + 4 * BitCount (registers) 3462 int32_t offset = addr_byte_size * BitCount (registers); 3463 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3464 context.SetRegisterPlusOffset (dwarf_reg, offset); 3465 3466 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3467 return false; 3468 } 3469 if (wback && BitIsSet (registers, n)) 3470 // R[n] bits(32) UNKNOWN; 3471 return WriteBits32Unknown (n); 3472 } 3473 return true; 3474} 3475 3476// LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3477// The consecutive memory locations end at this address and the address just below the lowest of those locations 3478// can optionally be written back to the base register. 3479bool 3480EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3481{ 3482#if 0 3483 // ARM pseudo code... 3484 if ConditionPassed() then 3485 EncodingSpecificOperations(); 3486 address = R[n] - 4*BitCount(registers) + 4; 3487 3488 for i = 0 to 14 3489 if registers<i> == '1' then 3490 R[i] = MemA[address,4]; address = address + 4; 3491 3492 if registers<15> == '1' then 3493 LoadWritePC(MemA[address,4]); 3494 3495 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3496 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3497#endif 3498 3499 bool success = false; 3500 3501 if (ConditionPassed(opcode)) 3502 { 3503 uint32_t n; 3504 uint32_t registers = 0; 3505 bool wback; 3506 const uint32_t addr_byte_size = GetAddressByteSize(); 3507 3508 // EncodingSpecificOperations(); 3509 switch (encoding) 3510 { 3511 case eEncodingA1: 3512 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3513 n = Bits32 (opcode, 19, 16); 3514 registers = Bits32 (opcode, 15, 0); 3515 wback = BitIsSet (opcode, 21); 3516 3517 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3518 if ((n == 15) || (BitCount (registers) < 1)) 3519 return false; 3520 3521 break; 3522 3523 default: 3524 return false; 3525 } 3526 // address = R[n] - 4*BitCount(registers) + 4; 3527 3528 int32_t offset = 0; 3529 addr_t Rn = ReadCoreReg (n, &success); 3530 3531 if (!success) 3532 return false; 3533 3534 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3535 3536 EmulateInstruction::Context context; 3537 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3538 RegisterInfo dwarf_reg; 3539 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3540 context.SetRegisterPlusOffset (dwarf_reg, offset); 3541 3542 // for i = 0 to 14 3543 for (int i = 0; i < 14; ++i) 3544 { 3545 // if registers<i> == '1' then 3546 if (BitIsSet (registers, i)) 3547 { 3548 // R[i] = MemA[address,4]; address = address + 4; 3549 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3550 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3551 if (!success) 3552 return false; 3553 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3554 return false; 3555 offset += addr_byte_size; 3556 } 3557 } 3558 3559 // if registers<15> == '1' then 3560 // LoadWritePC(MemA[address,4]); 3561 if (BitIsSet (registers, 15)) 3562 { 3563 context.SetRegisterPlusOffset (dwarf_reg, offset); 3564 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3565 if (!success) 3566 return false; 3567 // In ARMv5T and above, this is an interworking branch. 3568 if (!LoadWritePC(context, data)) 3569 return false; 3570 } 3571 3572 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3573 if (wback && BitIsClear (registers, n)) 3574 { 3575 if (!success) 3576 return false; 3577 3578 offset = (addr_byte_size * BitCount (registers)) * -1; 3579 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3580 context.SetImmediateSigned (offset); 3581 addr_t addr = Rn + offset; 3582 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3583 return false; 3584 } 3585 3586 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3587 if (wback && BitIsSet (registers, n)) 3588 return WriteBits32Unknown (n); 3589 } 3590 return true; 3591} 3592 3593// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3594// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3595// be optionally written back to the base register. 3596bool 3597EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3598{ 3599#if 0 3600 // ARM pseudo code... 3601 if ConditionPassed() then 3602 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3603 address = R[n] - 4*BitCount(registers); 3604 3605 for i = 0 to 14 3606 if registers<i> == '1' then 3607 R[i] = MemA[address,4]; address = address + 4; 3608 if registers<15> == '1' then 3609 LoadWritePC(MemA[address,4]); 3610 3611 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3612 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3613#endif 3614 3615 bool success = false; 3616 3617 if (ConditionPassed(opcode)) 3618 { 3619 uint32_t n; 3620 uint32_t registers = 0; 3621 bool wback; 3622 const uint32_t addr_byte_size = GetAddressByteSize(); 3623 switch (encoding) 3624 { 3625 case eEncodingT1: 3626 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3627 n = Bits32 (opcode, 19, 16); 3628 registers = Bits32 (opcode, 15, 0); 3629 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3630 wback = BitIsSet (opcode, 21); 3631 3632 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3633 if ((n == 15) 3634 || (BitCount (registers) < 2) 3635 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3636 return false; 3637 3638 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3639 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3640 return false; 3641 3642 // if wback && registers<n> == '1' then UNPREDICTABLE; 3643 if (wback && BitIsSet (registers, n)) 3644 return false; 3645 3646 break; 3647 3648 case eEncodingA1: 3649 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3650 n = Bits32 (opcode, 19, 16); 3651 registers = Bits32 (opcode, 15, 0); 3652 wback = BitIsSet (opcode, 21); 3653 3654 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3655 if ((n == 15) || (BitCount (registers) < 1)) 3656 return false; 3657 3658 break; 3659 3660 default: 3661 return false; 3662 } 3663 3664 // address = R[n] - 4*BitCount(registers); 3665 3666 int32_t offset = 0; 3667 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3668 3669 if (!success) 3670 return false; 3671 3672 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3673 EmulateInstruction::Context context; 3674 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3675 RegisterInfo dwarf_reg; 3676 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3677 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3678 3679 for (int i = 0; i < 14; ++i) 3680 { 3681 if (BitIsSet (registers, i)) 3682 { 3683 // R[i] = MemA[address,4]; address = address + 4; 3684 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3685 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3686 if (!success) 3687 return false; 3688 3689 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3690 return false; 3691 3692 offset += addr_byte_size; 3693 } 3694 } 3695 3696 // if registers<15> == '1' then 3697 // LoadWritePC(MemA[address,4]); 3698 if (BitIsSet (registers, 15)) 3699 { 3700 context.SetRegisterPlusOffset (dwarf_reg, offset); 3701 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3702 if (!success) 3703 return false; 3704 // In ARMv5T and above, this is an interworking branch. 3705 if (!LoadWritePC(context, data)) 3706 return false; 3707 } 3708 3709 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3710 if (wback && BitIsClear (registers, n)) 3711 { 3712 if (!success) 3713 return false; 3714 3715 offset = (addr_byte_size * BitCount (registers)) * -1; 3716 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3717 context.SetImmediateSigned (offset); 3718 addr_t addr = Rn + offset; 3719 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3720 return false; 3721 } 3722 3723 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3724 if (wback && BitIsSet (registers, n)) 3725 return WriteBits32Unknown (n); 3726 } 3727 return true; 3728} 3729 3730// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3731// consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3732// optinoally be written back to the base register. 3733bool 3734EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3735{ 3736#if 0 3737 if ConditionPassed() then 3738 EncodingSpecificOperations(); 3739 address = R[n] + 4; 3740 3741 for i = 0 to 14 3742 if registers<i> == '1' then 3743 R[i] = MemA[address,4]; address = address + 4; 3744 if registers<15> == '1' then 3745 LoadWritePC(MemA[address,4]); 3746 3747 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3748 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3749#endif 3750 3751 bool success = false; 3752 3753 if (ConditionPassed(opcode)) 3754 { 3755 uint32_t n; 3756 uint32_t registers = 0; 3757 bool wback; 3758 const uint32_t addr_byte_size = GetAddressByteSize(); 3759 switch (encoding) 3760 { 3761 case eEncodingA1: 3762 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3763 n = Bits32 (opcode, 19, 16); 3764 registers = Bits32 (opcode, 15, 0); 3765 wback = BitIsSet (opcode, 21); 3766 3767 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3768 if ((n == 15) || (BitCount (registers) < 1)) 3769 return false; 3770 3771 break; 3772 default: 3773 return false; 3774 } 3775 // address = R[n] + 4; 3776 3777 int32_t offset = 0; 3778 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3779 3780 if (!success) 3781 return false; 3782 3783 addr_t address = Rn + addr_byte_size; 3784 3785 EmulateInstruction::Context context; 3786 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3787 RegisterInfo dwarf_reg; 3788 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3789 context.SetRegisterPlusOffset (dwarf_reg, offset); 3790 3791 for (int i = 0; i < 14; ++i) 3792 { 3793 if (BitIsSet (registers, i)) 3794 { 3795 // R[i] = MemA[address,4]; address = address + 4; 3796 3797 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3798 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3799 if (!success) 3800 return false; 3801 3802 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3803 return false; 3804 3805 offset += addr_byte_size; 3806 } 3807 } 3808 3809 // if registers<15> == '1' then 3810 // LoadWritePC(MemA[address,4]); 3811 if (BitIsSet (registers, 15)) 3812 { 3813 context.SetRegisterPlusOffset (dwarf_reg, offset); 3814 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3815 if (!success) 3816 return false; 3817 // In ARMv5T and above, this is an interworking branch. 3818 if (!LoadWritePC(context, data)) 3819 return false; 3820 } 3821 3822 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3823 if (wback && BitIsClear (registers, n)) 3824 { 3825 if (!success) 3826 return false; 3827 3828 offset = addr_byte_size * BitCount (registers); 3829 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3830 context.SetImmediateSigned (offset); 3831 addr_t addr = Rn + offset; 3832 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3833 return false; 3834 } 3835 3836 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3837 if (wback && BitIsSet (registers, n)) 3838 return WriteBits32Unknown (n); 3839 } 3840 return true; 3841} 3842 3843// Load Register (immediate) calculates an address from a base register value and 3844// an immediate offset, loads a word from memory, and writes to a register. 3845// LDR (immediate, Thumb) 3846bool 3847EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3848{ 3849#if 0 3850 // ARM pseudo code... 3851 if (ConditionPassed()) 3852 { 3853 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3854 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3855 address = if index then offset_addr else R[n]; 3856 data = MemU[address,4]; 3857 if wback then R[n] = offset_addr; 3858 if t == 15 then 3859 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3860 elsif UnalignedSupport() || address<1:0> = '00' then 3861 R[t] = data; 3862 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3863 } 3864#endif 3865 3866 bool success = false; 3867 3868 if (ConditionPassed(opcode)) 3869 { 3870 uint32_t Rt; // the destination register 3871 uint32_t Rn; // the base register 3872 uint32_t imm32; // the immediate offset used to form the address 3873 addr_t offset_addr; // the offset address 3874 addr_t address; // the calculated address 3875 uint32_t data; // the literal data value from memory load 3876 bool add, index, wback; 3877 switch (encoding) { 3878 case eEncodingT1: 3879 Rt = Bits32(opcode, 2, 0); 3880 Rn = Bits32(opcode, 5, 3); 3881 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3882 // index = TRUE; add = TRUE; wback = FALSE 3883 add = true; 3884 index = true; 3885 wback = false; 3886 3887 break; 3888 3889 case eEncodingT2: 3890 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3891 Rt = Bits32 (opcode, 10, 8); 3892 Rn = 13; 3893 imm32 = Bits32 (opcode, 7, 0) << 2; 3894 3895 // index = TRUE; add = TRUE; wback = FALSE; 3896 index = true; 3897 add = true; 3898 wback = false; 3899 3900 break; 3901 3902 case eEncodingT3: 3903 // if Rn == '1111' then SEE LDR (literal); 3904 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3905 Rt = Bits32 (opcode, 15, 12); 3906 Rn = Bits32 (opcode, 19, 16); 3907 imm32 = Bits32 (opcode, 11, 0); 3908 3909 // index = TRUE; add = TRUE; wback = FALSE; 3910 index = true; 3911 add = true; 3912 wback = false; 3913 3914 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3915 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3916 return false; 3917 3918 break; 3919 3920 case eEncodingT4: 3921 // if Rn == '1111' then SEE LDR (literal); 3922 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3923 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3924 // if P == '0' && W == '0' then UNDEFINED; 3925 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3926 return false; 3927 3928 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3929 Rt = Bits32 (opcode, 15, 12); 3930 Rn = Bits32 (opcode, 19, 16); 3931 imm32 = Bits32 (opcode, 7, 0); 3932 3933 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3934 index = BitIsSet (opcode, 10); 3935 add = BitIsSet (opcode, 9); 3936 wback = BitIsSet (opcode, 8); 3937 3938 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3939 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3940 return false; 3941 3942 break; 3943 3944 default: 3945 return false; 3946 } 3947 uint32_t base = ReadCoreReg (Rn, &success); 3948 if (!success) 3949 return false; 3950 if (add) 3951 offset_addr = base + imm32; 3952 else 3953 offset_addr = base - imm32; 3954 3955 address = (index ? offset_addr : base); 3956 3957 RegisterInfo base_reg; 3958 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 3959 if (wback) 3960 { 3961 EmulateInstruction::Context ctx; 3962 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 3963 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3964 3965 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3966 return false; 3967 } 3968 3969 // Prepare to write to the Rt register. 3970 EmulateInstruction::Context context; 3971 context.type = EmulateInstruction::eContextRegisterLoad; 3972 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3973 3974 // Read memory from the address. 3975 data = MemURead(context, address, 4, 0, &success); 3976 if (!success) 3977 return false; 3978 3979 if (Rt == 15) 3980 { 3981 if (Bits32(address, 1, 0) == 0) 3982 { 3983 if (!LoadWritePC(context, data)) 3984 return false; 3985 } 3986 else 3987 return false; 3988 } 3989 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3990 { 3991 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3992 return false; 3993 } 3994 else 3995 WriteBits32Unknown (Rt); 3996 } 3997 return true; 3998} 3999 4000// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 4001// from a base register. The consecutive memory locations start at this address, and teh address just above the last 4002// of those locations can optionally be written back to the base register. 4003bool 4004EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 4005{ 4006#if 0 4007 if ConditionPassed() then 4008 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4009 address = R[n]; 4010 4011 for i = 0 to 14 4012 if registers<i> == '1' then 4013 if i == n && wback && i != LowestSetBit(registers) then 4014 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4015 else 4016 MemA[address,4] = R[i]; 4017 address = address + 4; 4018 4019 if registers<15> == '1' then // Only possible for encoding A1 4020 MemA[address,4] = PCStoreValue(); 4021 if wback then R[n] = R[n] + 4*BitCount(registers); 4022#endif 4023 4024 bool success = false; 4025 4026 if (ConditionPassed(opcode)) 4027 { 4028 uint32_t n; 4029 uint32_t registers = 0; 4030 bool wback; 4031 const uint32_t addr_byte_size = GetAddressByteSize(); 4032 4033 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4034 switch (encoding) 4035 { 4036 case eEncodingT1: 4037 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4038 n = Bits32 (opcode, 10, 8); 4039 registers = Bits32 (opcode, 7, 0); 4040 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4041 wback = true; 4042 4043 // if BitCount(registers) < 1 then UNPREDICTABLE; 4044 if (BitCount (registers) < 1) 4045 return false; 4046 4047 break; 4048 4049 case eEncodingT2: 4050 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4051 n = Bits32 (opcode, 19, 16); 4052 registers = Bits32 (opcode, 15, 0); 4053 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4054 wback = BitIsSet (opcode, 21); 4055 4056 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4057 if ((n == 15) || (BitCount (registers) < 2)) 4058 return false; 4059 4060 // if wback && registers<n> == '1' then UNPREDICTABLE; 4061 if (wback && BitIsSet (registers, n)) 4062 return false; 4063 4064 break; 4065 4066 case eEncodingA1: 4067 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4068 n = Bits32 (opcode, 19, 16); 4069 registers = Bits32 (opcode, 15, 0); 4070 wback = BitIsSet (opcode, 21); 4071 4072 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4073 if ((n == 15) || (BitCount (registers) < 1)) 4074 return false; 4075 4076 break; 4077 4078 default: 4079 return false; 4080 } 4081 4082 // address = R[n]; 4083 int32_t offset = 0; 4084 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4085 if (!success) 4086 return false; 4087 4088 EmulateInstruction::Context context; 4089 context.type = EmulateInstruction::eContextRegisterStore; 4090 RegisterInfo base_reg; 4091 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4092 4093 // for i = 0 to 14 4094 int lowest_set_bit = 14; 4095 for (int i = 0; i < 14; ++i) 4096 { 4097 // if registers<i> == '1' then 4098 if (BitIsSet (registers, i)) 4099 { 4100 if (i < lowest_set_bit) 4101 lowest_set_bit = i; 4102 // if i == n && wback && i != LowestSetBit(registers) then 4103 if ((i == n) && wback && (i != lowest_set_bit)) 4104 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4105 WriteBits32UnknownToMemory (address + offset); 4106 else 4107 { 4108 // MemA[address,4] = R[i]; 4109 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4110 if (!success) 4111 return false; 4112 4113 RegisterInfo data_reg; 4114 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4115 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4116 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4117 return false; 4118 } 4119 4120 // address = address + 4; 4121 offset += addr_byte_size; 4122 } 4123 } 4124 4125 // if registers<15> == '1' then // Only possible for encoding A1 4126 // MemA[address,4] = PCStoreValue(); 4127 if (BitIsSet (registers, 15)) 4128 { 4129 RegisterInfo pc_reg; 4130 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4131 context.SetRegisterPlusOffset (pc_reg, 8); 4132 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4133 if (!success) 4134 return false; 4135 4136 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4137 return false; 4138 } 4139 4140 // if wback then R[n] = R[n] + 4*BitCount(registers); 4141 if (wback) 4142 { 4143 offset = addr_byte_size * BitCount (registers); 4144 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4145 context.SetImmediateSigned (offset); 4146 addr_t data = address + offset; 4147 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4148 return false; 4149 } 4150 } 4151 return true; 4152} 4153 4154// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4155// from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4156// of those locations can optionally be written back to the base register. 4157bool 4158EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4159{ 4160#if 0 4161 if ConditionPassed() then 4162 EncodingSpecificOperations(); 4163 address = R[n] - 4*BitCount(registers) + 4; 4164 4165 for i = 0 to 14 4166 if registers<i> == '1' then 4167 if i == n && wback && i != LowestSetBit(registers) then 4168 MemA[address,4] = bits(32) UNKNOWN; 4169 else 4170 MemA[address,4] = R[i]; 4171 address = address + 4; 4172 4173 if registers<15> == '1' then 4174 MemA[address,4] = PCStoreValue(); 4175 4176 if wback then R[n] = R[n] - 4*BitCount(registers); 4177#endif 4178 4179 bool success = false; 4180 4181 if (ConditionPassed(opcode)) 4182 { 4183 uint32_t n; 4184 uint32_t registers = 0; 4185 bool wback; 4186 const uint32_t addr_byte_size = GetAddressByteSize(); 4187 4188 // EncodingSpecificOperations(); 4189 switch (encoding) 4190 { 4191 case eEncodingA1: 4192 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4193 n = Bits32 (opcode, 19, 16); 4194 registers = Bits32 (opcode, 15, 0); 4195 wback = BitIsSet (opcode, 21); 4196 4197 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4198 if ((n == 15) || (BitCount (registers) < 1)) 4199 return false; 4200 break; 4201 default: 4202 return false; 4203 } 4204 4205 // address = R[n] - 4*BitCount(registers) + 4; 4206 int32_t offset = 0; 4207 addr_t Rn = ReadCoreReg (n, &success); 4208 if (!success) 4209 return false; 4210 4211 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4212 4213 EmulateInstruction::Context context; 4214 context.type = EmulateInstruction::eContextRegisterStore; 4215 RegisterInfo base_reg; 4216 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4217 4218 // for i = 0 to 14 4219 int lowest_bit_set = 14; 4220 for (int i = 0; i < 14; ++i) 4221 { 4222 // if registers<i> == '1' then 4223 if (BitIsSet (registers, i)) 4224 { 4225 if (i < lowest_bit_set) 4226 lowest_bit_set = i; 4227 //if i == n && wback && i != LowestSetBit(registers) then 4228 if ((i == n) && wback && (i != lowest_bit_set)) 4229 // MemA[address,4] = bits(32) UNKNOWN; 4230 WriteBits32UnknownToMemory (address + offset); 4231 else 4232 { 4233 // MemA[address,4] = R[i]; 4234 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4235 if (!success) 4236 return false; 4237 4238 RegisterInfo data_reg; 4239 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4240 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4241 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4242 return false; 4243 } 4244 4245 // address = address + 4; 4246 offset += addr_byte_size; 4247 } 4248 } 4249 4250 // if registers<15> == '1' then 4251 // MemA[address,4] = PCStoreValue(); 4252 if (BitIsSet (registers, 15)) 4253 { 4254 RegisterInfo pc_reg; 4255 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4256 context.SetRegisterPlusOffset (pc_reg, 8); 4257 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4258 if (!success) 4259 return false; 4260 4261 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4262 return false; 4263 } 4264 4265 // if wback then R[n] = R[n] - 4*BitCount(registers); 4266 if (wback) 4267 { 4268 offset = (addr_byte_size * BitCount (registers)) * -1; 4269 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4270 context.SetImmediateSigned (offset); 4271 addr_t data = Rn + offset; 4272 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4273 return false; 4274 } 4275 } 4276 return true; 4277} 4278 4279// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4280// from a base register. The consecutive memory locations end just below this address, and the address of the first of 4281// those locations can optionally be written back to the base register. 4282bool 4283EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4284{ 4285#if 0 4286 if ConditionPassed() then 4287 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4288 address = R[n] - 4*BitCount(registers); 4289 4290 for i = 0 to 14 4291 if registers<i> == '1' then 4292 if i == n && wback && i != LowestSetBit(registers) then 4293 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4294 else 4295 MemA[address,4] = R[i]; 4296 address = address + 4; 4297 4298 if registers<15> == '1' then // Only possible for encoding A1 4299 MemA[address,4] = PCStoreValue(); 4300 4301 if wback then R[n] = R[n] - 4*BitCount(registers); 4302#endif 4303 4304 4305 bool success = false; 4306 4307 if (ConditionPassed(opcode)) 4308 { 4309 uint32_t n; 4310 uint32_t registers = 0; 4311 bool wback; 4312 const uint32_t addr_byte_size = GetAddressByteSize(); 4313 4314 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4315 switch (encoding) 4316 { 4317 case eEncodingT1: 4318 // if W == '1' && Rn == '1101' then SEE PUSH; 4319 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4320 { 4321 // See PUSH 4322 } 4323 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4324 n = Bits32 (opcode, 19, 16); 4325 registers = Bits32 (opcode, 15, 0); 4326 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4327 wback = BitIsSet (opcode, 21); 4328 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4329 if ((n == 15) || BitCount (registers) < 2) 4330 return false; 4331 // if wback && registers<n> == '1' then UNPREDICTABLE; 4332 if (wback && BitIsSet (registers, n)) 4333 return false; 4334 break; 4335 4336 case eEncodingA1: 4337 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH; 4338 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4339 { 4340 // See Push 4341 } 4342 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4343 n = Bits32 (opcode, 19, 16); 4344 registers = Bits32 (opcode, 15, 0); 4345 wback = BitIsSet (opcode, 21); 4346 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4347 if ((n == 15) || BitCount (registers) < 1) 4348 return false; 4349 break; 4350 4351 default: 4352 return false; 4353 } 4354 4355 // address = R[n] - 4*BitCount(registers); 4356 4357 int32_t offset = 0; 4358 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4359 if (!success) 4360 return false; 4361 4362 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4363 4364 EmulateInstruction::Context context; 4365 context.type = EmulateInstruction::eContextRegisterStore; 4366 RegisterInfo base_reg; 4367 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4368 4369 // for i = 0 to 14 4370 uint32_t lowest_set_bit = 14; 4371 for (int i = 0; i < 14; ++i) 4372 { 4373 // if registers<i> == '1' then 4374 if (BitIsSet (registers, i)) 4375 { 4376 if (i < lowest_set_bit) 4377 lowest_set_bit = i; 4378 // if i == n && wback && i != LowestSetBit(registers) then 4379 if ((i == n) && wback && (i != lowest_set_bit)) 4380 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4381 WriteBits32UnknownToMemory (address + offset); 4382 else 4383 { 4384 // MemA[address,4] = R[i]; 4385 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4386 if (!success) 4387 return false; 4388 4389 RegisterInfo data_reg; 4390 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4391 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4392 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4393 return false; 4394 } 4395 4396 // address = address + 4; 4397 offset += addr_byte_size; 4398 } 4399 } 4400 4401 // if registers<15> == '1' then // Only possible for encoding A1 4402 // MemA[address,4] = PCStoreValue(); 4403 if (BitIsSet (registers, 15)) 4404 { 4405 RegisterInfo pc_reg; 4406 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4407 context.SetRegisterPlusOffset (pc_reg, 8); 4408 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4409 if (!success) 4410 return false; 4411 4412 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4413 return false; 4414 } 4415 4416 // if wback then R[n] = R[n] - 4*BitCount(registers); 4417 if (wback) 4418 { 4419 offset = (addr_byte_size * BitCount (registers)) * -1; 4420 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4421 context.SetImmediateSigned (offset); 4422 addr_t data = Rn + offset; 4423 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4424 return false; 4425 } 4426 } 4427 return true; 4428} 4429 4430// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4431// from a base register. The consecutive memory locations start just above this address, and the address of the last 4432// of those locations can optionally be written back to the base register. 4433bool 4434EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4435{ 4436#if 0 4437 if ConditionPassed() then 4438 EncodingSpecificOperations(); 4439 address = R[n] + 4; 4440 4441 for i = 0 to 14 4442 if registers<i> == '1' then 4443 if i == n && wback && i != LowestSetBit(registers) then 4444 MemA[address,4] = bits(32) UNKNOWN; 4445 else 4446 MemA[address,4] = R[i]; 4447 address = address + 4; 4448 4449 if registers<15> == '1' then 4450 MemA[address,4] = PCStoreValue(); 4451 4452 if wback then R[n] = R[n] + 4*BitCount(registers); 4453#endif 4454 4455 bool success = false; 4456 4457 if (ConditionPassed(opcode)) 4458 { 4459 uint32_t n; 4460 uint32_t registers = 0; 4461 bool wback; 4462 const uint32_t addr_byte_size = GetAddressByteSize(); 4463 4464 // EncodingSpecificOperations(); 4465 switch (encoding) 4466 { 4467 case eEncodingA1: 4468 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4469 n = Bits32 (opcode, 19, 16); 4470 registers = Bits32 (opcode, 15, 0); 4471 wback = BitIsSet (opcode, 21); 4472 4473 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4474 if ((n == 15) && (BitCount (registers) < 1)) 4475 return false; 4476 break; 4477 default: 4478 return false; 4479 } 4480 // address = R[n] + 4; 4481 4482 int32_t offset = 0; 4483 addr_t Rn = ReadCoreReg (n, &success); 4484 if (!success) 4485 return false; 4486 4487 addr_t address = Rn + addr_byte_size; 4488 4489 EmulateInstruction::Context context; 4490 context.type = EmulateInstruction::eContextRegisterStore; 4491 RegisterInfo base_reg; 4492 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4493 4494 uint32_t lowest_set_bit = 14; 4495 // for i = 0 to 14 4496 for (int i = 0; i < 14; ++i) 4497 { 4498 // if registers<i> == '1' then 4499 if (BitIsSet (registers, i)) 4500 { 4501 if (i < lowest_set_bit) 4502 lowest_set_bit = i; 4503 // if i == n && wback && i != LowestSetBit(registers) then 4504 if ((i == n) && wback && (i != lowest_set_bit)) 4505 // MemA[address,4] = bits(32) UNKNOWN; 4506 WriteBits32UnknownToMemory (address + offset); 4507 // else 4508 else 4509 { 4510 // MemA[address,4] = R[i]; 4511 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4512 if (!success) 4513 return false; 4514 4515 RegisterInfo data_reg; 4516 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4517 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4518 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4519 return false; 4520 } 4521 4522 // address = address + 4; 4523 offset += addr_byte_size; 4524 } 4525 } 4526 4527 // if registers<15> == '1' then 4528 // MemA[address,4] = PCStoreValue(); 4529 if (BitIsSet (registers, 15)) 4530 { 4531 RegisterInfo pc_reg; 4532 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4533 context.SetRegisterPlusOffset (pc_reg, 8); 4534 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4535 if (!success) 4536 return false; 4537 4538 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4539 return false; 4540 } 4541 4542 // if wback then R[n] = R[n] + 4*BitCount(registers); 4543 if (wback) 4544 { 4545 offset = addr_byte_size * BitCount (registers); 4546 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4547 context.SetImmediateSigned (offset); 4548 addr_t data = Rn + offset; 4549 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4550 return false; 4551 } 4552 } 4553 return true; 4554} 4555 4556// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 4557// from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4558bool 4559EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4560{ 4561#if 0 4562 if ConditionPassed() then 4563 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4564 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4565 address = if index then offset_addr else R[n]; 4566 if UnalignedSupport() || address<1:0> == '00' then 4567 MemU[address,4] = R[t]; 4568 else // Can only occur before ARMv7 4569 MemU[address,4] = bits(32) UNKNOWN; 4570 if wback then R[n] = offset_addr; 4571#endif 4572 4573 bool success = false; 4574 4575 if (ConditionPassed(opcode)) 4576 { 4577 const uint32_t addr_byte_size = GetAddressByteSize(); 4578 4579 uint32_t t; 4580 uint32_t n; 4581 uint32_t imm32; 4582 bool index; 4583 bool add; 4584 bool wback; 4585 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4586 switch (encoding) 4587 { 4588 case eEncodingT1: 4589 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4590 t = Bits32 (opcode, 2, 0); 4591 n = Bits32 (opcode, 5, 3); 4592 imm32 = Bits32 (opcode, 10, 6) << 2; 4593 4594 // index = TRUE; add = TRUE; wback = FALSE; 4595 index = true; 4596 add = false; 4597 wback = false; 4598 break; 4599 4600 case eEncodingT2: 4601 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4602 t = Bits32 (opcode, 10, 8); 4603 n = 13; 4604 imm32 = Bits32 (opcode, 7, 0) << 2; 4605 4606 // index = TRUE; add = TRUE; wback = FALSE; 4607 index = true; 4608 add = true; 4609 wback = false; 4610 break; 4611 4612 case eEncodingT3: 4613 // if Rn == '1111' then UNDEFINED; 4614 if (Bits32 (opcode, 19, 16) == 15) 4615 return false; 4616 4617 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4618 t = Bits32 (opcode, 15, 12); 4619 n = Bits32 (opcode, 19, 16); 4620 imm32 = Bits32 (opcode, 11, 0); 4621 4622 // index = TRUE; add = TRUE; wback = FALSE; 4623 index = true; 4624 add = true; 4625 wback = false; 4626 4627 // if t == 15 then UNPREDICTABLE; 4628 if (t == 15) 4629 return false; 4630 break; 4631 4632 case eEncodingT4: 4633 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4634 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4635 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4636 if ((Bits32 (opcode, 19, 16) == 15) 4637 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4638 return false; 4639 4640 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4641 t = Bits32 (opcode, 15, 12); 4642 n = Bits32 (opcode, 19, 16); 4643 imm32 = Bits32 (opcode, 7, 0); 4644 4645 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4646 index = BitIsSet (opcode, 10); 4647 add = BitIsSet (opcode, 9); 4648 wback = BitIsSet (opcode, 8); 4649 4650 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4651 if ((t == 15) || (wback && (n == t))) 4652 return false; 4653 break; 4654 4655 default: 4656 return false; 4657 } 4658 4659 addr_t offset_addr; 4660 addr_t address; 4661 4662 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4663 uint32_t base_address = ReadCoreReg (n, &success); 4664 if (!success) 4665 return false; 4666 4667 if (add) 4668 offset_addr = base_address + imm32; 4669 else 4670 offset_addr = base_address - imm32; 4671 4672 // address = if index then offset_addr else R[n]; 4673 if (index) 4674 address = offset_addr; 4675 else 4676 address = base_address; 4677 4678 EmulateInstruction::Context context; 4679 context.type = eContextRegisterStore; 4680 RegisterInfo base_reg; 4681 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4682 4683 // if UnalignedSupport() || address<1:0> == '00' then 4684 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4685 { 4686 // MemU[address,4] = R[t]; 4687 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4688 if (!success) 4689 return false; 4690 4691 RegisterInfo data_reg; 4692 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4693 int32_t offset = address - base_address; 4694 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4695 if (!MemUWrite (context, address, data, addr_byte_size)) 4696 return false; 4697 } 4698 else 4699 { 4700 // MemU[address,4] = bits(32) UNKNOWN; 4701 WriteBits32UnknownToMemory (address); 4702 } 4703 4704 // if wback then R[n] = offset_addr; 4705 if (wback) 4706 { 4707 context.type = eContextRegisterLoad; 4708 context.SetAddress (offset_addr); 4709 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4710 return false; 4711 } 4712 } 4713 return true; 4714} 4715 4716// STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4717// word from a register to memory. The offset register value can optionally be shifted. 4718bool 4719EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4720{ 4721#if 0 4722 if ConditionPassed() then 4723 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4724 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4725 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4726 address = if index then offset_addr else R[n]; 4727 if t == 15 then // Only possible for encoding A1 4728 data = PCStoreValue(); 4729 else 4730 data = R[t]; 4731 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4732 MemU[address,4] = data; 4733 else // Can only occur before ARMv7 4734 MemU[address,4] = bits(32) UNKNOWN; 4735 if wback then R[n] = offset_addr; 4736#endif 4737 4738 bool success = false; 4739 4740 if (ConditionPassed(opcode)) 4741 { 4742 const uint32_t addr_byte_size = GetAddressByteSize(); 4743 4744 uint32_t t; 4745 uint32_t n; 4746 uint32_t m; 4747 ARM_ShifterType shift_t; 4748 uint32_t shift_n; 4749 bool index; 4750 bool add; 4751 bool wback; 4752 4753 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4754 switch (encoding) 4755 { 4756 case eEncodingT1: 4757 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4758 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4759 t = Bits32 (opcode, 2, 0); 4760 n = Bits32 (opcode, 5, 3); 4761 m = Bits32 (opcode, 8, 6); 4762 4763 // index = TRUE; add = TRUE; wback = FALSE; 4764 index = true; 4765 add = true; 4766 wback = false; 4767 4768 // (shift_t, shift_n) = (SRType_LSL, 0); 4769 shift_t = SRType_LSL; 4770 shift_n = 0; 4771 break; 4772 4773 case eEncodingT2: 4774 // if Rn == '1111' then UNDEFINED; 4775 if (Bits32 (opcode, 19, 16) == 15) 4776 return false; 4777 4778 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4779 t = Bits32 (opcode, 15, 12); 4780 n = Bits32 (opcode, 19, 16); 4781 m = Bits32 (opcode, 3, 0); 4782 4783 // index = TRUE; add = TRUE; wback = FALSE; 4784 index = true; 4785 add = true; 4786 wback = false; 4787 4788 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4789 shift_t = SRType_LSL; 4790 shift_n = Bits32 (opcode, 5, 4); 4791 4792 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4793 if ((t == 15) || (BadReg (m))) 4794 return false; 4795 break; 4796 4797 case eEncodingA1: 4798 { 4799 // if P == '0' && W == '1' then SEE STRT; 4800 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4801 t = Bits32 (opcode, 15, 12); 4802 n = Bits32 (opcode, 19, 16); 4803 m = Bits32 (opcode, 3, 0); 4804 4805 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4806 index = BitIsSet (opcode, 24); 4807 add = BitIsSet (opcode, 23); 4808 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4809 4810 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4811 uint32_t typ = Bits32 (opcode, 6, 5); 4812 uint32_t imm5 = Bits32 (opcode, 11, 7); 4813 shift_n = DecodeImmShift(typ, imm5, shift_t); 4814 4815 // if m == 15 then UNPREDICTABLE; 4816 if (m == 15) 4817 return false; 4818 4819 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4820 if (wback && ((n == 15) || (n == t))) 4821 return false; 4822 4823 break; 4824 } 4825 default: 4826 return false; 4827 } 4828 4829 addr_t offset_addr; 4830 addr_t address; 4831 int32_t offset = 0; 4832 4833 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4834 if (!success) 4835 return false; 4836 4837 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4838 if (!success) 4839 return false; 4840 4841 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4842 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4843 if (!success) 4844 return false; 4845 4846 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4847 if (add) 4848 offset_addr = base_address + offset; 4849 else 4850 offset_addr = base_address - offset; 4851 4852 // address = if index then offset_addr else R[n]; 4853 if (index) 4854 address = offset_addr; 4855 else 4856 address = base_address; 4857 4858 uint32_t data; 4859 // if t == 15 then // Only possible for encoding A1 4860 if (t == 15) 4861 // data = PCStoreValue(); 4862 data = ReadCoreReg (PC_REG, &success); 4863 else 4864 // data = R[t]; 4865 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4866 4867 if (!success) 4868 return false; 4869 4870 EmulateInstruction::Context context; 4871 context.type = eContextRegisterStore; 4872 4873 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4874 if (UnalignedSupport () 4875 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4876 || CurrentInstrSet() == eModeARM) 4877 { 4878 // MemU[address,4] = data; 4879 4880 RegisterInfo base_reg; 4881 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4882 4883 RegisterInfo data_reg; 4884 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4885 4886 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4887 if (!MemUWrite (context, address, data, addr_byte_size)) 4888 return false; 4889 4890 } 4891 else 4892 // MemU[address,4] = bits(32) UNKNOWN; 4893 WriteBits32UnknownToMemory (address); 4894 4895 // if wback then R[n] = offset_addr; 4896 if (wback) 4897 { 4898 context.type = eContextRegisterLoad; 4899 context.SetAddress (offset_addr); 4900 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4901 return false; 4902 } 4903 4904 } 4905 return true; 4906} 4907 4908bool 4909EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 4910{ 4911#if 0 4912 if ConditionPassed() then 4913 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4914 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4915 address = if index then offset_addr else R[n]; 4916 MemU[address,1] = R[t]<7:0>; 4917 if wback then R[n] = offset_addr; 4918#endif 4919 4920 4921 bool success = false; 4922 4923 if (ConditionPassed(opcode)) 4924 { 4925 uint32_t t; 4926 uint32_t n; 4927 uint32_t imm32; 4928 bool index; 4929 bool add; 4930 bool wback; 4931 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4932 switch (encoding) 4933 { 4934 case eEncodingT1: 4935 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4936 t = Bits32 (opcode, 2, 0); 4937 n = Bits32 (opcode, 5, 3); 4938 imm32 = Bits32 (opcode, 10, 6); 4939 4940 // index = TRUE; add = TRUE; wback = FALSE; 4941 index = true; 4942 add = true; 4943 wback = false; 4944 break; 4945 4946 case eEncodingT2: 4947 // if Rn == '1111' then UNDEFINED; 4948 if (Bits32 (opcode, 19, 16) == 15) 4949 return false; 4950 4951 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4952 t = Bits32 (opcode, 15, 12); 4953 n = Bits32 (opcode, 19, 16); 4954 imm32 = Bits32 (opcode, 11, 0); 4955 4956 // index = TRUE; add = TRUE; wback = FALSE; 4957 index = true; 4958 add = true; 4959 wback = false; 4960 4961 // if BadReg(t) then UNPREDICTABLE; 4962 if (BadReg (t)) 4963 return false; 4964 break; 4965 4966 case eEncodingT3: 4967 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 4968 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4969 if (Bits32 (opcode, 19, 16) == 15) 4970 return false; 4971 4972 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4973 t = Bits32 (opcode, 15, 12); 4974 n = Bits32 (opcode, 19, 16); 4975 imm32 = Bits32 (opcode, 7, 0); 4976 4977 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4978 index = BitIsSet (opcode, 10); 4979 add = BitIsSet (opcode, 9); 4980 wback = BitIsSet (opcode, 8); 4981 4982 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 4983 if ((BadReg (t)) || (wback && (n == t))) 4984 return false; 4985 break; 4986 4987 default: 4988 return false; 4989 } 4990 4991 addr_t offset_addr; 4992 addr_t address; 4993 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4994 if (!success) 4995 return false; 4996 4997 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4998 if (add) 4999 offset_addr = base_address + imm32; 5000 else 5001 offset_addr = base_address - imm32; 5002 5003 // address = if index then offset_addr else R[n]; 5004 if (index) 5005 address = offset_addr; 5006 else 5007 address = base_address; 5008 5009 // MemU[address,1] = R[t]<7:0> 5010 RegisterInfo base_reg; 5011 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5012 5013 RegisterInfo data_reg; 5014 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5015 5016 EmulateInstruction::Context context; 5017 context.type = eContextRegisterStore; 5018 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5019 5020 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5021 if (!success) 5022 return false; 5023 5024 data = Bits32 (data, 7, 0); 5025 5026 if (!MemUWrite (context, address, data, 1)) 5027 return false; 5028 5029 // if wback then R[n] = offset_addr; 5030 if (wback) 5031 { 5032 context.type = eContextRegisterLoad; 5033 context.SetAddress (offset_addr); 5034 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5035 return false; 5036 } 5037 5038 } 5039 5040 return true; 5041} 5042 5043// STRH (register) calculates an address from a base register value and an offset register value, and stores a 5044// halfword from a register to memory. The offset register alue can be shifted left by 0, 1, 2, or 3 bits. 5045bool 5046EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5047{ 5048#if 0 5049 if ConditionPassed() then 5050 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5051 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5052 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5053 address = if index then offset_addr else R[n]; 5054 if UnalignedSupport() || address<0> == '0' then 5055 MemU[address,2] = R[t]<15:0>; 5056 else // Can only occur before ARMv7 5057 MemU[address,2] = bits(16) UNKNOWN; 5058 if wback then R[n] = offset_addr; 5059#endif 5060 5061 bool success = false; 5062 5063 if (ConditionPassed(opcode)) 5064 { 5065 uint32_t t; 5066 uint32_t n; 5067 uint32_t m; 5068 bool index; 5069 bool add; 5070 bool wback; 5071 ARM_ShifterType shift_t; 5072 uint32_t shift_n; 5073 5074 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5075 switch (encoding) 5076 { 5077 case eEncodingT1: 5078 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5079 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5080 t = Bits32 (opcode, 2, 0); 5081 n = Bits32 (opcode, 5, 3); 5082 m = Bits32 (opcode, 8, 6); 5083 5084 // index = TRUE; add = TRUE; wback = FALSE; 5085 index = true; 5086 add = true; 5087 wback = false; 5088 5089 // (shift_t, shift_n) = (SRType_LSL, 0); 5090 shift_t = SRType_LSL; 5091 shift_n = 0; 5092 5093 break; 5094 5095 case eEncodingT2: 5096 // if Rn == '1111' then UNDEFINED; 5097 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5098 t = Bits32 (opcode, 15, 12); 5099 n = Bits32 (opcode, 19, 16); 5100 m = Bits32 (opcode, 3, 0); 5101 if (n == 15) 5102 return false; 5103 5104 // index = TRUE; add = TRUE; wback = FALSE; 5105 index = true; 5106 add = true; 5107 wback = false; 5108 5109 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5110 shift_t = SRType_LSL; 5111 shift_n = Bits32 (opcode, 5, 4); 5112 5113 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5114 if (BadReg (t) || BadReg (m)) 5115 return false; 5116 5117 break; 5118 5119 case eEncodingA1: 5120 // if P == '0' && W == '1' then SEE STRHT; 5121 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5122 t = Bits32 (opcode, 15, 12); 5123 n = Bits32 (opcode, 19, 16); 5124 m = Bits32 (opcode, 3, 0); 5125 5126 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5127 index = BitIsSet (opcode, 24); 5128 add = BitIsSet (opcode, 23); 5129 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5130 5131 // (shift_t, shift_n) = (SRType_LSL, 0); 5132 shift_t = SRType_LSL; 5133 shift_n = 0; 5134 5135 // if t == 15 || m == 15 then UNPREDICTABLE; 5136 if ((t == 15) || (m == 15)) 5137 return false; 5138 5139 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5140 if (wback && ((n == 15) || (n == t))) 5141 return false; 5142 5143 break; 5144 5145 default: 5146 return false; 5147 } 5148 5149 uint32_t Rm = ReadCoreReg (m, &success); 5150 if (!success) 5151 return false; 5152 5153 uint32_t Rn = ReadCoreReg (n, &success); 5154 if (!success) 5155 return false; 5156 5157 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5158 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5159 if (!success) 5160 return false; 5161 5162 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5163 addr_t offset_addr; 5164 if (add) 5165 offset_addr = Rn + offset; 5166 else 5167 offset_addr = Rn - offset; 5168 5169 // address = if index then offset_addr else R[n]; 5170 addr_t address; 5171 if (index) 5172 address = offset_addr; 5173 else 5174 address = Rn; 5175 5176 EmulateInstruction::Context context; 5177 context.type = eContextRegisterStore; 5178 RegisterInfo base_reg; 5179 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5180 RegisterInfo offset_reg; 5181 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5182 5183 // if UnalignedSupport() || address<0> == '0' then 5184 if (UnalignedSupport() || BitIsClear (address, 0)) 5185 { 5186 // MemU[address,2] = R[t]<15:0>; 5187 uint32_t Rt = ReadCoreReg (t, &success); 5188 if (!success) 5189 return false; 5190 5191 EmulateInstruction::Context context; 5192 context.type = eContextRegisterStore; 5193 RegisterInfo base_reg; 5194 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5195 RegisterInfo offset_reg; 5196 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5197 RegisterInfo data_reg; 5198 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5199 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5200 5201 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5202 return false; 5203 } 5204 else // Can only occur before ARMv7 5205 { 5206 // MemU[address,2] = bits(16) UNKNOWN; 5207 } 5208 5209 // if wback then R[n] = offset_addr; 5210 if (wback) 5211 { 5212 context.type = eContextAdjustBaseRegister; 5213 context.SetAddress (offset_addr); 5214 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5215 return false; 5216 } 5217 } 5218 5219 return true; 5220} 5221 5222// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5223// and writes the result to the destination register. It can optionally update the condition flags 5224// based on the result. 5225bool 5226EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5227{ 5228#if 0 5229 // ARM pseudo code... 5230 if ConditionPassed() then 5231 EncodingSpecificOperations(); 5232 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5233 if d == 15 then // Can only occur for ARM encoding 5234 ALUWritePC(result); // setflags is always FALSE here 5235 else 5236 R[d] = result; 5237 if setflags then 5238 APSR.N = result<31>; 5239 APSR.Z = IsZeroBit(result); 5240 APSR.C = carry; 5241 APSR.V = overflow; 5242#endif 5243 5244 bool success = false; 5245 5246 if (ConditionPassed(opcode)) 5247 { 5248 uint32_t Rd, Rn; 5249 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5250 bool setflags; 5251 switch (encoding) 5252 { 5253 case eEncodingT1: 5254 Rd = Bits32(opcode, 11, 8); 5255 Rn = Bits32(opcode, 19, 16); 5256 setflags = BitIsSet(opcode, 20); 5257 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5258 if (BadReg(Rd) || BadReg(Rn)) 5259 return false; 5260 break; 5261 case eEncodingA1: 5262 Rd = Bits32(opcode, 15, 12); 5263 Rn = Bits32(opcode, 19, 16); 5264 setflags = BitIsSet(opcode, 20); 5265 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5266 5267 if (Rd == 15 && setflags) 5268 return EmulateSUBSPcLrEtc (opcode, encoding); 5269 break; 5270 default: 5271 return false; 5272 } 5273 5274 // Read the first operand. 5275 int32_t val1 = ReadCoreReg(Rn, &success); 5276 if (!success) 5277 return false; 5278 5279 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5280 5281 EmulateInstruction::Context context; 5282 context.type = EmulateInstruction::eContextImmediate; 5283 context.SetNoArgs (); 5284 5285 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5286 return false; 5287 } 5288 return true; 5289} 5290 5291// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5292// register value, and writes the result to the destination register. It can optionally update the 5293// condition flags based on the result. 5294bool 5295EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5296{ 5297#if 0 5298 // ARM pseudo code... 5299 if ConditionPassed() then 5300 EncodingSpecificOperations(); 5301 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5302 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5303 if d == 15 then // Can only occur for ARM encoding 5304 ALUWritePC(result); // setflags is always FALSE here 5305 else 5306 R[d] = result; 5307 if setflags then 5308 APSR.N = result<31>; 5309 APSR.Z = IsZeroBit(result); 5310 APSR.C = carry; 5311 APSR.V = overflow; 5312#endif 5313 5314 bool success = false; 5315 5316 if (ConditionPassed(opcode)) 5317 { 5318 uint32_t Rd, Rn, Rm; 5319 ARM_ShifterType shift_t; 5320 uint32_t shift_n; // the shift applied to the value read from Rm 5321 bool setflags; 5322 switch (encoding) 5323 { 5324 case eEncodingT1: 5325 Rd = Rn = Bits32(opcode, 2, 0); 5326 Rm = Bits32(opcode, 5, 3); 5327 setflags = !InITBlock(); 5328 shift_t = SRType_LSL; 5329 shift_n = 0; 5330 break; 5331 case eEncodingT2: 5332 Rd = Bits32(opcode, 11, 8); 5333 Rn = Bits32(opcode, 19, 16); 5334 Rm = Bits32(opcode, 3, 0); 5335 setflags = BitIsSet(opcode, 20); 5336 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5337 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5338 return false; 5339 break; 5340 case eEncodingA1: 5341 Rd = Bits32(opcode, 15, 12); 5342 Rn = Bits32(opcode, 19, 16); 5343 Rm = Bits32(opcode, 3, 0); 5344 setflags = BitIsSet(opcode, 20); 5345 shift_n = DecodeImmShiftARM(opcode, shift_t); 5346 5347 if (Rd == 15 && setflags) 5348 return EmulateSUBSPcLrEtc (opcode, encoding); 5349 break; 5350 default: 5351 return false; 5352 } 5353 5354 // Read the first operand. 5355 int32_t val1 = ReadCoreReg(Rn, &success); 5356 if (!success) 5357 return false; 5358 5359 // Read the second operand. 5360 int32_t val2 = ReadCoreReg(Rm, &success); 5361 if (!success) 5362 return false; 5363 5364 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5365 if (!success) 5366 return false; 5367 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5368 5369 EmulateInstruction::Context context; 5370 context.type = EmulateInstruction::eContextImmediate; 5371 context.SetNoArgs (); 5372 5373 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5374 return false; 5375 } 5376 return true; 5377} 5378 5379// This instruction adds an immediate value to the PC value to form a PC-relative address, 5380// and writes the result to the destination register. 5381bool 5382EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5383{ 5384#if 0 5385 // ARM pseudo code... 5386 if ConditionPassed() then 5387 EncodingSpecificOperations(); 5388 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5389 if d == 15 then // Can only occur for ARM encodings 5390 ALUWritePC(result); 5391 else 5392 R[d] = result; 5393#endif 5394 5395 bool success = false; 5396 5397 if (ConditionPassed(opcode)) 5398 { 5399 uint32_t Rd; 5400 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5401 bool add; 5402 switch (encoding) 5403 { 5404 case eEncodingT1: 5405 Rd = Bits32(opcode, 10, 8); 5406 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5407 add = true; 5408 break; 5409 case eEncodingT2: 5410 case eEncodingT3: 5411 Rd = Bits32(opcode, 11, 8); 5412 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5413 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5414 if (BadReg(Rd)) 5415 return false; 5416 break; 5417 case eEncodingA1: 5418 case eEncodingA2: 5419 Rd = Bits32(opcode, 15, 12); 5420 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5421 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5422 break; 5423 default: 5424 return false; 5425 } 5426 5427 // Read the PC value. 5428 uint32_t pc = ReadCoreReg(PC_REG, &success); 5429 if (!success) 5430 return false; 5431 5432 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5433 5434 EmulateInstruction::Context context; 5435 context.type = EmulateInstruction::eContextImmediate; 5436 context.SetNoArgs (); 5437 5438 if (!WriteCoreReg(context, result, Rd)) 5439 return false; 5440 } 5441 return true; 5442} 5443 5444// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5445// to the destination register. It can optionally update the condition flags based on the result. 5446bool 5447EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5448{ 5449#if 0 5450 // ARM pseudo code... 5451 if ConditionPassed() then 5452 EncodingSpecificOperations(); 5453 result = R[n] AND imm32; 5454 if d == 15 then // Can only occur for ARM encoding 5455 ALUWritePC(result); // setflags is always FALSE here 5456 else 5457 R[d] = result; 5458 if setflags then 5459 APSR.N = result<31>; 5460 APSR.Z = IsZeroBit(result); 5461 APSR.C = carry; 5462 // APSR.V unchanged 5463#endif 5464 5465 bool success = false; 5466 5467 if (ConditionPassed(opcode)) 5468 { 5469 uint32_t Rd, Rn; 5470 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5471 bool setflags; 5472 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5473 switch (encoding) 5474 { 5475 case eEncodingT1: 5476 Rd = Bits32(opcode, 11, 8); 5477 Rn = Bits32(opcode, 19, 16); 5478 setflags = BitIsSet(opcode, 20); 5479 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5480 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5481 if (Rd == 15 && setflags) 5482 return EmulateTSTImm(opcode, eEncodingT1); 5483 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5484 return false; 5485 break; 5486 case eEncodingA1: 5487 Rd = Bits32(opcode, 15, 12); 5488 Rn = Bits32(opcode, 19, 16); 5489 setflags = BitIsSet(opcode, 20); 5490 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5491 5492 if (Rd == 15 && setflags) 5493 return EmulateSUBSPcLrEtc (opcode, encoding); 5494 break; 5495 default: 5496 return false; 5497 } 5498 5499 // Read the first operand. 5500 uint32_t val1 = ReadCoreReg(Rn, &success); 5501 if (!success) 5502 return false; 5503 5504 uint32_t result = val1 & imm32; 5505 5506 EmulateInstruction::Context context; 5507 context.type = EmulateInstruction::eContextImmediate; 5508 context.SetNoArgs (); 5509 5510 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5511 return false; 5512 } 5513 return true; 5514} 5515 5516// This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5517// and writes the result to the destination register. It can optionally update the condition flags 5518// based on the result. 5519bool 5520EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5521{ 5522#if 0 5523 // ARM pseudo code... 5524 if ConditionPassed() then 5525 EncodingSpecificOperations(); 5526 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5527 result = R[n] AND shifted; 5528 if d == 15 then // Can only occur for ARM encoding 5529 ALUWritePC(result); // setflags is always FALSE here 5530 else 5531 R[d] = result; 5532 if setflags then 5533 APSR.N = result<31>; 5534 APSR.Z = IsZeroBit(result); 5535 APSR.C = carry; 5536 // APSR.V unchanged 5537#endif 5538 5539 bool success = false; 5540 5541 if (ConditionPassed(opcode)) 5542 { 5543 uint32_t Rd, Rn, Rm; 5544 ARM_ShifterType shift_t; 5545 uint32_t shift_n; // the shift applied to the value read from Rm 5546 bool setflags; 5547 uint32_t carry; 5548 switch (encoding) 5549 { 5550 case eEncodingT1: 5551 Rd = Rn = Bits32(opcode, 2, 0); 5552 Rm = Bits32(opcode, 5, 3); 5553 setflags = !InITBlock(); 5554 shift_t = SRType_LSL; 5555 shift_n = 0; 5556 break; 5557 case eEncodingT2: 5558 Rd = Bits32(opcode, 11, 8); 5559 Rn = Bits32(opcode, 19, 16); 5560 Rm = Bits32(opcode, 3, 0); 5561 setflags = BitIsSet(opcode, 20); 5562 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5563 // if Rd == '1111' && S == '1' then SEE TST (register); 5564 if (Rd == 15 && setflags) 5565 return EmulateTSTReg(opcode, eEncodingT2); 5566 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5567 return false; 5568 break; 5569 case eEncodingA1: 5570 Rd = Bits32(opcode, 15, 12); 5571 Rn = Bits32(opcode, 19, 16); 5572 Rm = Bits32(opcode, 3, 0); 5573 setflags = BitIsSet(opcode, 20); 5574 shift_n = DecodeImmShiftARM(opcode, shift_t); 5575 5576 if (Rd == 15 && setflags) 5577 return EmulateSUBSPcLrEtc (opcode, encoding); 5578 break; 5579 default: 5580 return false; 5581 } 5582 5583 // Read the first operand. 5584 uint32_t val1 = ReadCoreReg(Rn, &success); 5585 if (!success) 5586 return false; 5587 5588 // Read the second operand. 5589 uint32_t val2 = ReadCoreReg(Rm, &success); 5590 if (!success) 5591 return false; 5592 5593 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5594 if (!success) 5595 return false; 5596 uint32_t result = val1 & shifted; 5597 5598 EmulateInstruction::Context context; 5599 context.type = EmulateInstruction::eContextImmediate; 5600 context.SetNoArgs (); 5601 5602 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5603 return false; 5604 } 5605 return true; 5606} 5607 5608// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5609// immediate value, and writes the result to the destination register. It can optionally update the 5610// condition flags based on the result. 5611bool 5612EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5613{ 5614#if 0 5615 // ARM pseudo code... 5616 if ConditionPassed() then 5617 EncodingSpecificOperations(); 5618 result = R[n] AND NOT(imm32); 5619 if d == 15 then // Can only occur for ARM encoding 5620 ALUWritePC(result); // setflags is always FALSE here 5621 else 5622 R[d] = result; 5623 if setflags then 5624 APSR.N = result<31>; 5625 APSR.Z = IsZeroBit(result); 5626 APSR.C = carry; 5627 // APSR.V unchanged 5628#endif 5629 5630 bool success = false; 5631 5632 if (ConditionPassed(opcode)) 5633 { 5634 uint32_t Rd, Rn; 5635 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5636 bool setflags; 5637 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5638 switch (encoding) 5639 { 5640 case eEncodingT1: 5641 Rd = Bits32(opcode, 11, 8); 5642 Rn = Bits32(opcode, 19, 16); 5643 setflags = BitIsSet(opcode, 20); 5644 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5645 if (BadReg(Rd) || BadReg(Rn)) 5646 return false; 5647 break; 5648 case eEncodingA1: 5649 Rd = Bits32(opcode, 15, 12); 5650 Rn = Bits32(opcode, 19, 16); 5651 setflags = BitIsSet(opcode, 20); 5652 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5653 5654 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5655 if (Rd == 15 && setflags) 5656 return EmulateSUBSPcLrEtc (opcode, encoding); 5657 break; 5658 default: 5659 return false; 5660 } 5661 5662 // Read the first operand. 5663 uint32_t val1 = ReadCoreReg(Rn, &success); 5664 if (!success) 5665 return false; 5666 5667 uint32_t result = val1 & ~imm32; 5668 5669 EmulateInstruction::Context context; 5670 context.type = EmulateInstruction::eContextImmediate; 5671 context.SetNoArgs (); 5672 5673 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5674 return false; 5675 } 5676 return true; 5677} 5678 5679// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5680// optionally-shifted register value, and writes the result to the destination register. 5681// It can optionally update the condition flags based on the result. 5682bool 5683EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5684{ 5685#if 0 5686 // ARM pseudo code... 5687 if ConditionPassed() then 5688 EncodingSpecificOperations(); 5689 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5690 result = R[n] AND NOT(shifted); 5691 if d == 15 then // Can only occur for ARM encoding 5692 ALUWritePC(result); // setflags is always FALSE here 5693 else 5694 R[d] = result; 5695 if setflags then 5696 APSR.N = result<31>; 5697 APSR.Z = IsZeroBit(result); 5698 APSR.C = carry; 5699 // APSR.V unchanged 5700#endif 5701 5702 bool success = false; 5703 5704 if (ConditionPassed(opcode)) 5705 { 5706 uint32_t Rd, Rn, Rm; 5707 ARM_ShifterType shift_t; 5708 uint32_t shift_n; // the shift applied to the value read from Rm 5709 bool setflags; 5710 uint32_t carry; 5711 switch (encoding) 5712 { 5713 case eEncodingT1: 5714 Rd = Rn = Bits32(opcode, 2, 0); 5715 Rm = Bits32(opcode, 5, 3); 5716 setflags = !InITBlock(); 5717 shift_t = SRType_LSL; 5718 shift_n = 0; 5719 break; 5720 case eEncodingT2: 5721 Rd = Bits32(opcode, 11, 8); 5722 Rn = Bits32(opcode, 19, 16); 5723 Rm = Bits32(opcode, 3, 0); 5724 setflags = BitIsSet(opcode, 20); 5725 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5726 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5727 return false; 5728 break; 5729 case eEncodingA1: 5730 Rd = Bits32(opcode, 15, 12); 5731 Rn = Bits32(opcode, 19, 16); 5732 Rm = Bits32(opcode, 3, 0); 5733 setflags = BitIsSet(opcode, 20); 5734 shift_n = DecodeImmShiftARM(opcode, shift_t); 5735 5736 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5737 if (Rd == 15 && setflags) 5738 return EmulateSUBSPcLrEtc (opcode, encoding); 5739 break; 5740 default: 5741 return false; 5742 } 5743 5744 // Read the first operand. 5745 uint32_t val1 = ReadCoreReg(Rn, &success); 5746 if (!success) 5747 return false; 5748 5749 // Read the second operand. 5750 uint32_t val2 = ReadCoreReg(Rm, &success); 5751 if (!success) 5752 return false; 5753 5754 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5755 if (!success) 5756 return false; 5757 uint32_t result = val1 & ~shifted; 5758 5759 EmulateInstruction::Context context; 5760 context.type = EmulateInstruction::eContextImmediate; 5761 context.SetNoArgs (); 5762 5763 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5764 return false; 5765 } 5766 return true; 5767} 5768 5769// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5770// from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5771bool 5772EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5773{ 5774#if 0 5775 if ConditionPassed() then 5776 EncodingSpecificOperations(); 5777 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5778 address = if index then offset_addr else R[n]; 5779 data = MemU[address,4]; 5780 if wback then R[n] = offset_addr; 5781 if t == 15 then 5782 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5783 elsif UnalignedSupport() || address<1:0> = '00' then 5784 R[t] = data; 5785 else // Can only apply before ARMv7 5786 R[t] = ROR(data, 8*UInt(address<1:0>)); 5787#endif 5788 5789 bool success = false; 5790 5791 if (ConditionPassed(opcode)) 5792 { 5793 const uint32_t addr_byte_size = GetAddressByteSize(); 5794 5795 uint32_t t; 5796 uint32_t n; 5797 uint32_t imm32; 5798 bool index; 5799 bool add; 5800 bool wback; 5801 5802 switch (encoding) 5803 { 5804 case eEncodingA1: 5805 // if Rn == '1111' then SEE LDR (literal); 5806 // if P == '0' && W == '1' then SEE LDRT; 5807 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5808 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5809 t = Bits32 (opcode, 15, 12); 5810 n = Bits32 (opcode, 19, 16); 5811 imm32 = Bits32 (opcode, 11, 0); 5812 5813 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5814 index = BitIsSet (opcode, 24); 5815 add = BitIsSet (opcode, 23); 5816 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5817 5818 // if wback && n == t then UNPREDICTABLE; 5819 if (wback && (n == t)) 5820 return false; 5821 5822 break; 5823 5824 default: 5825 return false; 5826 } 5827 5828 addr_t address; 5829 addr_t offset_addr; 5830 addr_t base_address = ReadCoreReg (n, &success); 5831 if (!success) 5832 return false; 5833 5834 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5835 if (add) 5836 offset_addr = base_address + imm32; 5837 else 5838 offset_addr = base_address - imm32; 5839 5840 // address = if index then offset_addr else R[n]; 5841 if (index) 5842 address = offset_addr; 5843 else 5844 address = base_address; 5845 5846 // data = MemU[address,4]; 5847 5848 RegisterInfo base_reg; 5849 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5850 5851 EmulateInstruction::Context context; 5852 context.type = eContextRegisterLoad; 5853 context.SetRegisterPlusOffset (base_reg, address - base_address); 5854 5855 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5856 if (!success) 5857 return false; 5858 5859 // if wback then R[n] = offset_addr; 5860 if (wback) 5861 { 5862 context.type = eContextAdjustBaseRegister; 5863 context.SetAddress (offset_addr); 5864 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5865 return false; 5866 } 5867 5868 // if t == 15 then 5869 if (t == 15) 5870 { 5871 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5872 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5873 { 5874 // LoadWritePC (data); 5875 context.type = eContextRegisterLoad; 5876 context.SetRegisterPlusOffset (base_reg, address - base_address); 5877 LoadWritePC (context, data); 5878 } 5879 else 5880 return false; 5881 } 5882 // elsif UnalignedSupport() || address<1:0> = '00' then 5883 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5884 { 5885 // R[t] = data; 5886 context.type = eContextRegisterLoad; 5887 context.SetRegisterPlusOffset (base_reg, address - base_address); 5888 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5889 return false; 5890 } 5891 // else // Can only apply before ARMv7 5892 else 5893 { 5894 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5895 data = ROR (data, Bits32 (address, 1, 0), &success); 5896 if (!success) 5897 return false; 5898 context.type = eContextRegisterLoad; 5899 context.SetImmediate (data); 5900 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5901 return false; 5902 } 5903 5904 } 5905 return true; 5906} 5907 5908// LDR (register) calculates an address from a base register value and an offset register value, loads a word 5909// from memory, and writes it to a resgister. The offset register value can optionally be shifted. 5910bool 5911EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5912{ 5913#if 0 5914 if ConditionPassed() then 5915 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5916 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5917 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5918 address = if index then offset_addr else R[n]; 5919 data = MemU[address,4]; 5920 if wback then R[n] = offset_addr; 5921 if t == 15 then 5922 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5923 elsif UnalignedSupport() || address<1:0> = '00' then 5924 R[t] = data; 5925 else // Can only apply before ARMv7 5926 if CurrentInstrSet() == InstrSet_ARM then 5927 R[t] = ROR(data, 8*UInt(address<1:0>)); 5928 else 5929 R[t] = bits(32) UNKNOWN; 5930#endif 5931 5932 bool success = false; 5933 5934 if (ConditionPassed(opcode)) 5935 { 5936 const uint32_t addr_byte_size = GetAddressByteSize(); 5937 5938 uint32_t t; 5939 uint32_t n; 5940 uint32_t m; 5941 bool index; 5942 bool add; 5943 bool wback; 5944 ARM_ShifterType shift_t; 5945 uint32_t shift_n; 5946 5947 switch (encoding) 5948 { 5949 case eEncodingT1: 5950 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5951 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5952 t = Bits32 (opcode, 2, 0); 5953 n = Bits32 (opcode, 5, 3); 5954 m = Bits32 (opcode, 8, 6); 5955 5956 // index = TRUE; add = TRUE; wback = FALSE; 5957 index = true; 5958 add = true; 5959 wback = false; 5960 5961 // (shift_t, shift_n) = (SRType_LSL, 0); 5962 shift_t = SRType_LSL; 5963 shift_n = 0; 5964 5965 break; 5966 5967 case eEncodingT2: 5968 // if Rn == '1111' then SEE LDR (literal); 5969 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5970 t = Bits32 (opcode, 15, 12); 5971 n = Bits32 (opcode, 19, 16); 5972 m = Bits32 (opcode, 3, 0); 5973 5974 // index = TRUE; add = TRUE; wback = FALSE; 5975 index = true; 5976 add = true; 5977 wback = false; 5978 5979 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5980 shift_t = SRType_LSL; 5981 shift_n = Bits32 (opcode, 5, 4); 5982 5983 // if BadReg(m) then UNPREDICTABLE; 5984 if (BadReg (m)) 5985 return false; 5986 5987 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5988 if ((t == 15) && InITBlock() && !LastInITBlock()) 5989 return false; 5990 5991 break; 5992 5993 case eEncodingA1: 5994 { 5995 // if P == '0' && W == '1' then SEE LDRT; 5996 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5997 t = Bits32 (opcode, 15, 12); 5998 n = Bits32 (opcode, 19, 16); 5999 m = Bits32 (opcode, 3, 0); 6000 6001 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6002 index = BitIsSet (opcode, 24); 6003 add = BitIsSet (opcode, 23); 6004 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6005 6006 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6007 uint32_t type = Bits32 (opcode, 6, 5); 6008 uint32_t imm5 = Bits32 (opcode, 11, 7); 6009 shift_n = DecodeImmShift (type, imm5, shift_t); 6010 6011 // if m == 15 then UNPREDICTABLE; 6012 if (m == 15) 6013 return false; 6014 6015 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6016 if (wback && ((n == 15) || (n == t))) 6017 return false; 6018 } 6019 break; 6020 6021 6022 default: 6023 return false; 6024 } 6025 6026 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6027 if (!success) 6028 return false; 6029 6030 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6031 if (!success) 6032 return false; 6033 6034 addr_t offset_addr; 6035 addr_t address; 6036 6037 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6038 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6039 if (!success) 6040 return false; 6041 6042 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6043 if (add) 6044 offset_addr = Rn + offset; 6045 else 6046 offset_addr = Rn - offset; 6047 6048 // address = if index then offset_addr else R[n]; 6049 if (index) 6050 address = offset_addr; 6051 else 6052 address = Rn; 6053 6054 // data = MemU[address,4]; 6055 RegisterInfo base_reg; 6056 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6057 6058 EmulateInstruction::Context context; 6059 context.type = eContextRegisterLoad; 6060 context.SetRegisterPlusOffset (base_reg, address - Rn); 6061 6062 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6063 if (!success) 6064 return false; 6065 6066 // if wback then R[n] = offset_addr; 6067 if (wback) 6068 { 6069 context.type = eContextAdjustBaseRegister; 6070 context.SetAddress (offset_addr); 6071 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6072 return false; 6073 } 6074 6075 // if t == 15 then 6076 if (t == 15) 6077 { 6078 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6079 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6080 { 6081 context.type = eContextRegisterLoad; 6082 context.SetRegisterPlusOffset (base_reg, address - Rn); 6083 LoadWritePC (context, data); 6084 } 6085 else 6086 return false; 6087 } 6088 // elsif UnalignedSupport() || address<1:0> = '00' then 6089 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6090 { 6091 // R[t] = data; 6092 context.type = eContextRegisterLoad; 6093 context.SetRegisterPlusOffset (base_reg, address - Rn); 6094 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6095 return false; 6096 } 6097 else // Can only apply before ARMv7 6098 { 6099 // if CurrentInstrSet() == InstrSet_ARM then 6100 if (CurrentInstrSet () == eModeARM) 6101 { 6102 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6103 data = ROR (data, Bits32 (address, 1, 0), &success); 6104 if (!success) 6105 return false; 6106 context.type = eContextRegisterLoad; 6107 context.SetImmediate (data); 6108 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6109 return false; 6110 } 6111 else 6112 { 6113 // R[t] = bits(32) UNKNOWN; 6114 WriteBits32Unknown (t); 6115 } 6116 } 6117 } 6118 return true; 6119} 6120 6121// LDRB (immediate, Thumb) 6122bool 6123EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6124{ 6125#if 0 6126 if ConditionPassed() then 6127 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6128 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6129 address = if index then offset_addr else R[n]; 6130 R[t] = ZeroExtend(MemU[address,1], 32); 6131 if wback then R[n] = offset_addr; 6132#endif 6133 6134 bool success = false; 6135 6136 if (ConditionPassed(opcode)) 6137 { 6138 uint32_t t; 6139 uint32_t n; 6140 uint32_t imm32; 6141 bool index; 6142 bool add; 6143 bool wback; 6144 6145 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6146 switch (encoding) 6147 { 6148 case eEncodingT1: 6149 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6150 t = Bits32 (opcode, 2, 0); 6151 n = Bits32 (opcode, 5, 3); 6152 imm32 = Bits32 (opcode, 10, 6); 6153 6154 // index = TRUE; add = TRUE; wback = FALSE; 6155 index = true; 6156 add = true; 6157 wback= false; 6158 6159 break; 6160 6161 case eEncodingT2: 6162 // if Rt == '1111' then SEE PLD; 6163 // if Rn == '1111' then SEE LDRB (literal); 6164 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6165 t = Bits32 (opcode, 15, 12); 6166 n = Bits32 (opcode, 19, 16); 6167 imm32 = Bits32 (opcode, 11, 0); 6168 6169 // index = TRUE; add = TRUE; wback = FALSE; 6170 index = true; 6171 add = true; 6172 wback = false; 6173 6174 // if t == 13 then UNPREDICTABLE; 6175 if (t == 13) 6176 return false; 6177 6178 break; 6179 6180 case eEncodingT3: 6181 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6182 // if Rn == '1111' then SEE LDRB (literal); 6183 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6184 // if P == '0' && W == '0' then UNDEFINED; 6185 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6186 return false; 6187 6188 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6189 t = Bits32 (opcode, 15, 12); 6190 n = Bits32 (opcode, 19, 16); 6191 imm32 = Bits32 (opcode, 7, 0); 6192 6193 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6194 index = BitIsSet (opcode, 10); 6195 add = BitIsSet (opcode, 9); 6196 wback = BitIsSet (opcode, 8); 6197 6198 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6199 if (BadReg (t) || (wback && (n == t))) 6200 return false; 6201 6202 break; 6203 6204 default: 6205 return false; 6206 } 6207 6208 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6209 if (!success) 6210 return false; 6211 6212 addr_t address; 6213 addr_t offset_addr; 6214 6215 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6216 if (add) 6217 offset_addr = Rn + imm32; 6218 else 6219 offset_addr = Rn - imm32; 6220 6221 // address = if index then offset_addr else R[n]; 6222 if (index) 6223 address = offset_addr; 6224 else 6225 address = Rn; 6226 6227 // R[t] = ZeroExtend(MemU[address,1], 32); 6228 RegisterInfo base_reg; 6229 RegisterInfo data_reg; 6230 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6231 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6232 6233 EmulateInstruction::Context context; 6234 context.type = eContextRegisterLoad; 6235 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6236 6237 uint64_t data = MemURead (context, address, 1, 0, &success); 6238 if (!success) 6239 return false; 6240 6241 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6242 return false; 6243 6244 // if wback then R[n] = offset_addr; 6245 if (wback) 6246 { 6247 context.type = eContextAdjustBaseRegister; 6248 context.SetAddress (offset_addr); 6249 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6250 return false; 6251 } 6252 } 6253 return true; 6254} 6255 6256// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6257// zero-extends it to form a 32-bit word and writes it to a register. 6258bool 6259EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6260{ 6261#if 0 6262 if ConditionPassed() then 6263 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6264 base = Align(PC,4); 6265 address = if add then (base + imm32) else (base - imm32); 6266 R[t] = ZeroExtend(MemU[address,1], 32); 6267#endif 6268 6269 bool success = false; 6270 6271 if (ConditionPassed(opcode)) 6272 { 6273 uint32_t t; 6274 uint32_t imm32; 6275 bool add; 6276 switch (encoding) 6277 { 6278 case eEncodingT1: 6279 // if Rt == '1111' then SEE PLD; 6280 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6281 t = Bits32 (opcode, 15, 12); 6282 imm32 = Bits32 (opcode, 11, 0); 6283 add = BitIsSet (opcode, 23); 6284 6285 // if t == 13 then UNPREDICTABLE; 6286 if (t == 13) 6287 return false; 6288 6289 break; 6290 6291 case eEncodingA1: 6292 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6293 t = Bits32 (opcode, 15, 12); 6294 imm32 = Bits32 (opcode, 11, 0); 6295 add = BitIsSet (opcode, 23); 6296 6297 // if t == 15 then UNPREDICTABLE; 6298 if (t == 15) 6299 return false; 6300 break; 6301 6302 default: 6303 return false; 6304 } 6305 6306 // base = Align(PC,4); 6307 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6308 if (!success) 6309 return false; 6310 6311 uint32_t base = AlignPC (pc_val); 6312 6313 addr_t address; 6314 // address = if add then (base + imm32) else (base - imm32); 6315 if (add) 6316 address = base + imm32; 6317 else 6318 address = base - imm32; 6319 6320 // R[t] = ZeroExtend(MemU[address,1], 32); 6321 EmulateInstruction::Context context; 6322 context.type = eContextRelativeBranchImmediate; 6323 context.SetImmediate (address - base); 6324 6325 uint64_t data = MemURead (context, address, 1, 0, &success); 6326 if (!success) 6327 return false; 6328 6329 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6330 return false; 6331 } 6332 return true; 6333} 6334 6335// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6336// memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6337// optionally be shifted. 6338bool 6339EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6340{ 6341#if 0 6342 if ConditionPassed() then 6343 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6344 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6345 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6346 address = if index then offset_addr else R[n]; 6347 R[t] = ZeroExtend(MemU[address,1],32); 6348 if wback then R[n] = offset_addr; 6349#endif 6350 6351 bool success = false; 6352 6353 if (ConditionPassed(opcode)) 6354 { 6355 uint32_t t; 6356 uint32_t n; 6357 uint32_t m; 6358 bool index; 6359 bool add; 6360 bool wback; 6361 ARM_ShifterType shift_t; 6362 uint32_t shift_n; 6363 6364 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6365 switch (encoding) 6366 { 6367 case eEncodingT1: 6368 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6369 t = Bits32 (opcode, 2, 0); 6370 n = Bits32 (opcode, 5, 3); 6371 m = Bits32 (opcode, 8, 6); 6372 6373 // index = TRUE; add = TRUE; wback = FALSE; 6374 index = true; 6375 add = true; 6376 wback = false; 6377 6378 // (shift_t, shift_n) = (SRType_LSL, 0); 6379 shift_t = SRType_LSL; 6380 shift_n = 0; 6381 break; 6382 6383 case eEncodingT2: 6384 // if Rt == '1111' then SEE PLD; 6385 // if Rn == '1111' then SEE LDRB (literal); 6386 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6387 t = Bits32 (opcode, 15, 12); 6388 n = Bits32 (opcode, 19, 16); 6389 m = Bits32 (opcode, 3, 0); 6390 6391 // index = TRUE; add = TRUE; wback = FALSE; 6392 index = true; 6393 add = true; 6394 wback = false; 6395 6396 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6397 shift_t = SRType_LSL; 6398 shift_n = Bits32 (opcode, 5, 4); 6399 6400 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6401 if ((t == 13) || BadReg (m)) 6402 return false; 6403 break; 6404 6405 case eEncodingA1: 6406 { 6407 // if P == '0' && W == '1' then SEE LDRBT; 6408 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6409 t = Bits32 (opcode, 15, 12); 6410 n = Bits32 (opcode, 19, 16); 6411 m = Bits32 (opcode, 3, 0); 6412 6413 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6414 index = BitIsSet (opcode, 24); 6415 add = BitIsSet (opcode, 23); 6416 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6417 6418 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6419 uint32_t type = Bits32 (opcode, 6, 5); 6420 uint32_t imm5 = Bits32 (opcode, 11, 7); 6421 shift_n = DecodeImmShift (type, imm5, shift_t); 6422 6423 // if t == 15 || m == 15 then UNPREDICTABLE; 6424 if ((t == 15) || (m == 15)) 6425 return false; 6426 6427 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6428 if (wback && ((n == 15) || (n == t))) 6429 return false; 6430 } 6431 break; 6432 6433 default: 6434 return false; 6435 } 6436 6437 addr_t offset_addr; 6438 addr_t address; 6439 6440 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6441 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6442 if (!success) 6443 return false; 6444 6445 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6446 if (!success) 6447 return false; 6448 6449 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6450 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6451 if (!success) 6452 return false; 6453 6454 if (add) 6455 offset_addr = Rn + offset; 6456 else 6457 offset_addr = Rn - offset; 6458 6459 // address = if index then offset_addr else R[n]; 6460 if (index) 6461 address = offset_addr; 6462 else 6463 address = Rn; 6464 6465 // R[t] = ZeroExtend(MemU[address,1],32); 6466 RegisterInfo base_reg; 6467 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6468 6469 EmulateInstruction::Context context; 6470 context.type = eContextRegisterLoad; 6471 context.SetRegisterPlusOffset (base_reg, address - Rn); 6472 6473 uint64_t data = MemURead (context, address, 1, 0, &success); 6474 if (!success) 6475 return false; 6476 6477 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6478 return false; 6479 6480 // if wback then R[n] = offset_addr; 6481 if (wback) 6482 { 6483 context.type = eContextAdjustBaseRegister; 6484 context.SetAddress (offset_addr); 6485 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6486 return false; 6487 } 6488 } 6489 return true; 6490} 6491 6492// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6493// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6494// post-indexed, or pre-indexed addressing. 6495bool 6496EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6497{ 6498#if 0 6499 if ConditionPassed() then 6500 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6501 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6502 address = if index then offset_addr else R[n]; 6503 data = MemU[address,2]; 6504 if wback then R[n] = offset_addr; 6505 if UnalignedSupport() || address<0> = '0' then 6506 R[t] = ZeroExtend(data, 32); 6507 else // Can only apply before ARMv7 6508 R[t] = bits(32) UNKNOWN; 6509#endif 6510 6511 6512 bool success = false; 6513 6514 if (ConditionPassed(opcode)) 6515 { 6516 uint32_t t; 6517 uint32_t n; 6518 uint32_t imm32; 6519 bool index; 6520 bool add; 6521 bool wback; 6522 6523 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6524 switch (encoding) 6525 { 6526 case eEncodingT1: 6527 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6528 t = Bits32 (opcode, 2, 0); 6529 n = Bits32 (opcode, 5, 3); 6530 imm32 = Bits32 (opcode, 10, 6) << 1; 6531 6532 // index = TRUE; add = TRUE; wback = FALSE; 6533 index = true; 6534 add = true; 6535 wback = false; 6536 6537 break; 6538 6539 case eEncodingT2: 6540 // if Rt == '1111' then SEE "Unallocated memory hints"; 6541 // if Rn == '1111' then SEE LDRH (literal); 6542 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6543 t = Bits32 (opcode, 15, 12); 6544 n = Bits32 (opcode, 19, 16); 6545 imm32 = Bits32 (opcode, 11, 0); 6546 6547 // index = TRUE; add = TRUE; wback = FALSE; 6548 index = true; 6549 add = true; 6550 wback = false; 6551 6552 // if t == 13 then UNPREDICTABLE; 6553 if (t == 13) 6554 return false; 6555 break; 6556 6557 case eEncodingT3: 6558 // if Rn == '1111' then SEE LDRH (literal); 6559 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6560 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6561 // if P == '0' && W == '0' then UNDEFINED; 6562 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6563 return false; 6564 6565 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6566 t = Bits32 (opcode, 15, 12); 6567 n = Bits32 (opcode, 19, 16); 6568 imm32 = Bits32 (opcode, 7, 0); 6569 6570 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6571 index = BitIsSet (opcode, 10); 6572 add = BitIsSet (opcode, 9); 6573 wback = BitIsSet (opcode, 8); 6574 6575 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6576 if (BadReg (t) || (wback && (n == t))) 6577 return false; 6578 break; 6579 6580 default: 6581 return false; 6582 } 6583 6584 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6585 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6586 if (!success) 6587 return false; 6588 6589 addr_t offset_addr; 6590 addr_t address; 6591 6592 if (add) 6593 offset_addr = Rn + imm32; 6594 else 6595 offset_addr = Rn - imm32; 6596 6597 // address = if index then offset_addr else R[n]; 6598 if (index) 6599 address = offset_addr; 6600 else 6601 address = Rn; 6602 6603 // data = MemU[address,2]; 6604 RegisterInfo base_reg; 6605 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6606 6607 EmulateInstruction::Context context; 6608 context.type = eContextRegisterLoad; 6609 context.SetRegisterPlusOffset (base_reg, address - Rn); 6610 6611 uint64_t data = MemURead (context, address, 2, 0, &success); 6612 if (!success) 6613 return false; 6614 6615 // if wback then R[n] = offset_addr; 6616 if (wback) 6617 { 6618 context.type = eContextAdjustBaseRegister; 6619 context.SetAddress (offset_addr); 6620 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6621 return false; 6622 } 6623 6624 // if UnalignedSupport() || address<0> = '0' then 6625 if (UnalignedSupport () || BitIsClear (address, 0)) 6626 { 6627 // R[t] = ZeroExtend(data, 32); 6628 context.type = eContextRegisterLoad; 6629 context.SetRegisterPlusOffset (base_reg, address - Rn); 6630 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6631 return false; 6632 } 6633 else // Can only apply before ARMv7 6634 { 6635 // R[t] = bits(32) UNKNOWN; 6636 WriteBits32Unknown (t); 6637 } 6638 } 6639 return true; 6640} 6641 6642// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6643// zero-extends it to form a 32-bit word, and writes it to a register. 6644bool 6645EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6646{ 6647#if 0 6648 if ConditionPassed() then 6649 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6650 base = Align(PC,4); 6651 address = if add then (base + imm32) else (base - imm32); 6652 data = MemU[address,2]; 6653 if UnalignedSupport() || address<0> = '0' then 6654 R[t] = ZeroExtend(data, 32); 6655 else // Can only apply before ARMv7 6656 R[t] = bits(32) UNKNOWN; 6657#endif 6658 6659 bool success = false; 6660 6661 if (ConditionPassed(opcode)) 6662 { 6663 uint32_t t; 6664 uint32_t imm32; 6665 bool add; 6666 6667 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6668 switch (encoding) 6669 { 6670 case eEncodingT1: 6671 // if Rt == '1111' then SEE "Unallocated memory hints"; 6672 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6673 t = Bits32 (opcode, 15, 12); 6674 imm32 = Bits32 (opcode, 11, 0); 6675 add = BitIsSet (opcode, 23); 6676 6677 // if t == 13 then UNPREDICTABLE; 6678 if (t == 13) 6679 return false; 6680 6681 break; 6682 6683 case eEncodingA1: 6684 { 6685 uint32_t imm4H = Bits32 (opcode, 11, 8); 6686 uint32_t imm4L = Bits32 (opcode, 3, 0); 6687 6688 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6689 t = Bits32 (opcode, 15, 12); 6690 imm32 = (imm4H << 4) | imm4L; 6691 add = BitIsSet (opcode, 23); 6692 6693 // if t == 15 then UNPREDICTABLE; 6694 if (t == 15) 6695 return false; 6696 break; 6697 } 6698 6699 default: 6700 return false; 6701 } 6702 6703 // base = Align(PC,4); 6704 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6705 if (!success) 6706 return false; 6707 6708 addr_t base = AlignPC (pc_value); 6709 addr_t address; 6710 6711 // address = if add then (base + imm32) else (base - imm32); 6712 if (add) 6713 address = base + imm32; 6714 else 6715 address = base - imm32; 6716 6717 // data = MemU[address,2]; 6718 RegisterInfo base_reg; 6719 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6720 6721 EmulateInstruction::Context context; 6722 context.type = eContextRegisterLoad; 6723 context.SetRegisterPlusOffset (base_reg, address - base); 6724 6725 uint64_t data = MemURead (context, address, 2, 0, &success); 6726 if (!success) 6727 return false; 6728 6729 6730 // if UnalignedSupport() || address<0> = '0' then 6731 if (UnalignedSupport () || BitIsClear (address, 0)) 6732 { 6733 // R[t] = ZeroExtend(data, 32); 6734 context.type = eContextRegisterLoad; 6735 context.SetRegisterPlusOffset (base_reg, address - base); 6736 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6737 return false; 6738 6739 } 6740 else // Can only apply before ARMv7 6741 { 6742 // R[t] = bits(32) UNKNOWN; 6743 WriteBits32Unknown (t); 6744 } 6745 } 6746 return true; 6747} 6748 6749// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6750// from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6751// be shifted left by 0, 1, 2, or 3 bits. 6752bool 6753EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6754{ 6755#if 0 6756 if ConditionPassed() then 6757 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6758 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6759 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6760 address = if index then offset_addr else R[n]; 6761 data = MemU[address,2]; 6762 if wback then R[n] = offset_addr; 6763 if UnalignedSupport() || address<0> = '0' then 6764 R[t] = ZeroExtend(data, 32); 6765 else // Can only apply before ARMv7 6766 R[t] = bits(32) UNKNOWN; 6767#endif 6768 6769 bool success = false; 6770 6771 if (ConditionPassed(opcode)) 6772 { 6773 uint32_t t; 6774 uint32_t n; 6775 uint32_t m; 6776 bool index; 6777 bool add; 6778 bool wback; 6779 ARM_ShifterType shift_t; 6780 uint32_t shift_n; 6781 6782 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6783 switch (encoding) 6784 { 6785 case eEncodingT1: 6786 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6787 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6788 t = Bits32 (opcode, 2, 0); 6789 n = Bits32 (opcode, 5, 3); 6790 m = Bits32 (opcode, 8, 6); 6791 6792 // index = TRUE; add = TRUE; wback = FALSE; 6793 index = true; 6794 add = true; 6795 wback = false; 6796 6797 // (shift_t, shift_n) = (SRType_LSL, 0); 6798 shift_t = SRType_LSL; 6799 shift_n = 0; 6800 6801 break; 6802 6803 case eEncodingT2: 6804 // if Rn == '1111' then SEE LDRH (literal); 6805 // if Rt == '1111' then SEE "Unallocated memory hints"; 6806 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6807 t = Bits32 (opcode, 15, 12); 6808 n = Bits32 (opcode, 19, 16); 6809 m = Bits32 (opcode, 3, 0); 6810 6811 // index = TRUE; add = TRUE; wback = FALSE; 6812 index = true; 6813 add = true; 6814 wback = false; 6815 6816 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6817 shift_t = SRType_LSL; 6818 shift_n = Bits32 (opcode, 5, 4); 6819 6820 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6821 if ((t == 13) || BadReg (m)) 6822 return false; 6823 break; 6824 6825 case eEncodingA1: 6826 // if P == '0' && W == '1' then SEE LDRHT; 6827 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6828 t = Bits32 (opcode, 15, 12); 6829 n = Bits32 (opcode, 19, 16); 6830 m = Bits32 (opcode, 3, 0); 6831 6832 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6833 index = BitIsSet (opcode, 24); 6834 add = BitIsSet (opcode, 23); 6835 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6836 6837 // (shift_t, shift_n) = (SRType_LSL, 0); 6838 shift_t = SRType_LSL; 6839 shift_n = 0; 6840 6841 // if t == 15 || m == 15 then UNPREDICTABLE; 6842 if ((t == 15) || (m == 15)) 6843 return false; 6844 6845 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6846 if (wback && ((n == 15) || (n == t))) 6847 return false; 6848 6849 break; 6850 6851 default: 6852 return false; 6853 } 6854 6855 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6856 6857 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6858 if (!success) 6859 return false; 6860 6861 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6862 if (!success) 6863 return false; 6864 6865 addr_t offset_addr; 6866 addr_t address; 6867 6868 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6869 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6870 if (!success) 6871 return false; 6872 6873 if (add) 6874 offset_addr = Rn + offset; 6875 else 6876 offset_addr = Rn - offset; 6877 6878 // address = if index then offset_addr else R[n]; 6879 if (index) 6880 address = offset_addr; 6881 else 6882 address = Rn; 6883 6884 // data = MemU[address,2]; 6885 RegisterInfo base_reg; 6886 RegisterInfo offset_reg; 6887 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6888 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 6889 6890 EmulateInstruction::Context context; 6891 context.type = eContextRegisterLoad; 6892 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6893 uint64_t data = MemURead (context, address, 2, 0, &success); 6894 if (!success) 6895 return false; 6896 6897 // if wback then R[n] = offset_addr; 6898 if (wback) 6899 { 6900 context.type = eContextAdjustBaseRegister; 6901 context.SetAddress (offset_addr); 6902 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6903 return false; 6904 } 6905 6906 // if UnalignedSupport() || address<0> = '0' then 6907 if (UnalignedSupport() || BitIsClear (address, 0)) 6908 { 6909 // R[t] = ZeroExtend(data, 32); 6910 context.type = eContextRegisterLoad; 6911 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6912 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6913 return false; 6914 } 6915 else // Can only apply before ARMv7 6916 { 6917 // R[t] = bits(32) UNKNOWN; 6918 WriteBits32Unknown (t); 6919 } 6920 } 6921 return true; 6922} 6923 6924// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6925// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6926// or pre-indexed addressing. 6927bool 6928EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6929{ 6930#if 0 6931 if ConditionPassed() then 6932 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6933 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6934 address = if index then offset_addr else R[n]; 6935 R[t] = SignExtend(MemU[address,1], 32); 6936 if wback then R[n] = offset_addr; 6937#endif 6938 6939 bool success = false; 6940 6941 if (ConditionPassed(opcode)) 6942 { 6943 uint32_t t; 6944 uint32_t n; 6945 uint32_t imm32; 6946 bool index; 6947 bool add; 6948 bool wback; 6949 6950 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6951 switch (encoding) 6952 { 6953 case eEncodingT1: 6954 // if Rt == '1111' then SEE PLI; 6955 // if Rn == '1111' then SEE LDRSB (literal); 6956 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6957 t = Bits32 (opcode, 15, 12); 6958 n = Bits32 (opcode, 19, 16); 6959 imm32 = Bits32 (opcode, 11, 0); 6960 6961 // index = TRUE; add = TRUE; wback = FALSE; 6962 index = true; 6963 add = true; 6964 wback = false; 6965 6966 // if t == 13 then UNPREDICTABLE; 6967 if (t == 13) 6968 return false; 6969 6970 break; 6971 6972 case eEncodingT2: 6973 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 6974 // if Rn == '1111' then SEE LDRSB (literal); 6975 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 6976 // if P == '0' && W == '0' then UNDEFINED; 6977 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6978 return false; 6979 6980 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6981 t = Bits32 (opcode, 15, 12); 6982 n = Bits32 (opcode, 19, 16); 6983 imm32 = Bits32 (opcode, 7, 0); 6984 6985 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6986 index = BitIsSet (opcode, 10); 6987 add = BitIsSet (opcode, 9); 6988 wback = BitIsSet (opcode, 8); 6989 6990 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6991 if (((t == 13) || ((t == 15) 6992 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 6993 || (wback && (n == t))) 6994 return false; 6995 6996 break; 6997 6998 case eEncodingA1: 6999 { 7000 // if Rn == '1111' then SEE LDRSB (literal); 7001 // if P == '0' && W == '1' then SEE LDRSBT; 7002 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7003 t = Bits32 (opcode, 15, 12); 7004 n = Bits32 (opcode, 19, 16); 7005 7006 uint32_t imm4H = Bits32 (opcode, 11, 8); 7007 uint32_t imm4L = Bits32 (opcode, 3, 0); 7008 imm32 = (imm4H << 4) | imm4L; 7009 7010 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7011 index = BitIsSet (opcode, 24); 7012 add = BitIsSet (opcode, 23); 7013 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7014 7015 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7016 if ((t == 15) || (wback && (n == t))) 7017 return false; 7018 7019 break; 7020 } 7021 7022 default: 7023 return false; 7024 } 7025 7026 uint64_t Rn = ReadCoreReg (n, &success); 7027 if (!success) 7028 return false; 7029 7030 addr_t offset_addr; 7031 addr_t address; 7032 7033 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7034 if (add) 7035 offset_addr = Rn + imm32; 7036 else 7037 offset_addr = Rn - imm32; 7038 7039 // address = if index then offset_addr else R[n]; 7040 if (index) 7041 address = offset_addr; 7042 else 7043 address = Rn; 7044 7045 // R[t] = SignExtend(MemU[address,1], 32); 7046 RegisterInfo base_reg; 7047 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7048 7049 EmulateInstruction::Context context; 7050 context.type = eContextRegisterLoad; 7051 context.SetRegisterPlusOffset (base_reg, address - Rn); 7052 7053 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7054 if (!success) 7055 return false; 7056 7057 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7058 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7059 return false; 7060 7061 // if wback then R[n] = offset_addr; 7062 if (wback) 7063 { 7064 context.type = eContextAdjustBaseRegister; 7065 context.SetAddress (offset_addr); 7066 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7067 return false; 7068 } 7069 } 7070 7071 return true; 7072} 7073 7074// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7075// sign-extends it to form a 32-bit word, and writes tit to a register. 7076bool 7077EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7078{ 7079#if 0 7080 if ConditionPassed() then 7081 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7082 base = Align(PC,4); 7083 address = if add then (base + imm32) else (base - imm32); 7084 R[t] = SignExtend(MemU[address,1], 32); 7085#endif 7086 7087 bool success = false; 7088 7089 if (ConditionPassed(opcode)) 7090 { 7091 uint32_t t; 7092 uint32_t imm32; 7093 bool add; 7094 7095 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7096 switch (encoding) 7097 { 7098 case eEncodingT1: 7099 // if Rt == '1111' then SEE PLI; 7100 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7101 t = Bits32 (opcode, 15, 12); 7102 imm32 = Bits32 (opcode, 11, 0); 7103 add = BitIsSet (opcode, 23); 7104 7105 // if t == 13 then UNPREDICTABLE; 7106 if (t == 13) 7107 return false; 7108 7109 break; 7110 7111 case eEncodingA1: 7112 { 7113 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7114 t = Bits32 (opcode, 15, 12); 7115 uint32_t imm4H = Bits32 (opcode, 11, 8); 7116 uint32_t imm4L = Bits32 (opcode, 3, 0); 7117 imm32 = (imm4H << 4) | imm4L; 7118 add = BitIsSet (opcode, 23); 7119 7120 // if t == 15 then UNPREDICTABLE; 7121 if (t == 15) 7122 return false; 7123 7124 break; 7125 } 7126 7127 default: 7128 return false; 7129 } 7130 7131 // base = Align(PC,4); 7132 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7133 if (!success) 7134 return false; 7135 uint64_t base = AlignPC (pc_value); 7136 7137 // address = if add then (base + imm32) else (base - imm32); 7138 addr_t address; 7139 if (add) 7140 address = base + imm32; 7141 else 7142 address = base - imm32; 7143 7144 // R[t] = SignExtend(MemU[address,1], 32); 7145 RegisterInfo base_reg; 7146 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7147 7148 EmulateInstruction::Context context; 7149 context.type = eContextRegisterLoad; 7150 context.SetRegisterPlusOffset (base_reg, address - base); 7151 7152 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7153 if (!success) 7154 return false; 7155 7156 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7157 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7158 return false; 7159 } 7160 return true; 7161} 7162 7163// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7164// memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7165// shifted left by 0, 1, 2, or 3 bits. 7166bool 7167EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7168{ 7169#if 0 7170 if ConditionPassed() then 7171 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7172 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7173 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7174 address = if index then offset_addr else R[n]; 7175 R[t] = SignExtend(MemU[address,1], 32); 7176 if wback then R[n] = offset_addr; 7177#endif 7178 7179 bool success = false; 7180 7181 if (ConditionPassed(opcode)) 7182 { 7183 uint32_t t; 7184 uint32_t n; 7185 uint32_t m; 7186 bool index; 7187 bool add; 7188 bool wback; 7189 ARM_ShifterType shift_t; 7190 uint32_t shift_n; 7191 7192 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7193 switch (encoding) 7194 { 7195 case eEncodingT1: 7196 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7197 t = Bits32 (opcode, 2, 0); 7198 n = Bits32 (opcode, 5, 3); 7199 m = Bits32 (opcode, 8, 6); 7200 7201 // index = TRUE; add = TRUE; wback = FALSE; 7202 index = true; 7203 add = true; 7204 wback = false; 7205 7206 // (shift_t, shift_n) = (SRType_LSL, 0); 7207 shift_t = SRType_LSL; 7208 shift_n = 0; 7209 7210 break; 7211 7212 case eEncodingT2: 7213 // if Rt == '1111' then SEE PLI; 7214 // if Rn == '1111' then SEE LDRSB (literal); 7215 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7216 t = Bits32 (opcode, 15, 12); 7217 n = Bits32 (opcode, 19, 16); 7218 m = Bits32 (opcode, 3, 0); 7219 7220 // index = TRUE; add = TRUE; wback = FALSE; 7221 index = true; 7222 add = true; 7223 wback = false; 7224 7225 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7226 shift_t = SRType_LSL; 7227 shift_n = Bits32 (opcode, 5, 4); 7228 7229 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7230 if ((t == 13) || BadReg (m)) 7231 return false; 7232 break; 7233 7234 case eEncodingA1: 7235 // if P == '0' && W == '1' then SEE LDRSBT; 7236 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7237 t = Bits32 (opcode, 15, 12); 7238 n = Bits32 (opcode, 19, 16); 7239 m = Bits32 (opcode, 3, 0); 7240 7241 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7242 index = BitIsSet (opcode, 24); 7243 add = BitIsSet (opcode, 23); 7244 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7245 7246 // (shift_t, shift_n) = (SRType_LSL, 0); 7247 shift_t = SRType_LSL; 7248 shift_n = 0; 7249 7250 // if t == 15 || m == 15 then UNPREDICTABLE; 7251 if ((t == 15) || (m == 15)) 7252 return false; 7253 7254 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7255 if (wback && ((n == 15) || (n == t))) 7256 return false; 7257 break; 7258 7259 default: 7260 return false; 7261 } 7262 7263 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7264 if (!success) 7265 return false; 7266 7267 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7268 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7269 if (!success) 7270 return false; 7271 7272 addr_t offset_addr; 7273 addr_t address; 7274 7275 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7276 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7277 if (!success) 7278 return false; 7279 7280 if (add) 7281 offset_addr = Rn + offset; 7282 else 7283 offset_addr = Rn - offset; 7284 7285 // address = if index then offset_addr else R[n]; 7286 if (index) 7287 address = offset_addr; 7288 else 7289 address = Rn; 7290 7291 // R[t] = SignExtend(MemU[address,1], 32); 7292 RegisterInfo base_reg; 7293 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7294 RegisterInfo offset_reg; 7295 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7296 7297 EmulateInstruction::Context context; 7298 context.type = eContextRegisterLoad; 7299 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7300 7301 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7302 if (!success) 7303 return false; 7304 7305 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7306 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7307 return false; 7308 7309 // if wback then R[n] = offset_addr; 7310 if (wback) 7311 { 7312 context.type = eContextAdjustBaseRegister; 7313 context.SetAddress (offset_addr); 7314 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7315 return false; 7316 } 7317 } 7318 return true; 7319} 7320 7321// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7322// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7323// pre-indexed addressing. 7324bool 7325EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7326{ 7327#if 0 7328 if ConditionPassed() then 7329 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7330 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7331 address = if index then offset_addr else R[n]; 7332 data = MemU[address,2]; 7333 if wback then R[n] = offset_addr; 7334 if UnalignedSupport() || address<0> = '0' then 7335 R[t] = SignExtend(data, 32); 7336 else // Can only apply before ARMv7 7337 R[t] = bits(32) UNKNOWN; 7338#endif 7339 7340 bool success = false; 7341 7342 if (ConditionPassed(opcode)) 7343 { 7344 uint32_t t; 7345 uint32_t n; 7346 uint32_t imm32; 7347 bool index; 7348 bool add; 7349 bool wback; 7350 7351 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7352 switch (encoding) 7353 { 7354 case eEncodingT1: 7355 // if Rn == '1111' then SEE LDRSH (literal); 7356 // if Rt == '1111' then SEE "Unallocated memory hints"; 7357 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7358 t = Bits32 (opcode, 15, 12); 7359 n = Bits32 (opcode, 19, 16); 7360 imm32 = Bits32 (opcode, 11, 0); 7361 7362 // index = TRUE; add = TRUE; wback = FALSE; 7363 index = true; 7364 add = true; 7365 wback = false; 7366 7367 // if t == 13 then UNPREDICTABLE; 7368 if (t == 13) 7369 return false; 7370 7371 break; 7372 7373 case eEncodingT2: 7374 // if Rn == '1111' then SEE LDRSH (literal); 7375 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7376 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7377 // if P == '0' && W == '0' then UNDEFINED; 7378 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7379 return false; 7380 7381 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7382 t = Bits32 (opcode, 15, 12); 7383 n = Bits32 (opcode, 19, 16); 7384 imm32 = Bits32 (opcode, 7, 0); 7385 7386 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7387 index = BitIsSet (opcode, 10); 7388 add = BitIsSet (opcode, 9); 7389 wback = BitIsSet (opcode, 8); 7390 7391 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7392 if (BadReg (t) || (wback && (n == t))) 7393 return false; 7394 7395 break; 7396 7397 case eEncodingA1: 7398 { 7399 // if Rn == '1111' then SEE LDRSH (literal); 7400 // if P == '0' && W == '1' then SEE LDRSHT; 7401 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7402 t = Bits32 (opcode, 15, 12); 7403 n = Bits32 (opcode, 19, 16); 7404 uint32_t imm4H = Bits32 (opcode, 11,8); 7405 uint32_t imm4L = Bits32 (opcode, 3, 0); 7406 imm32 = (imm4H << 4) | imm4L; 7407 7408 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7409 index = BitIsSet (opcode, 24); 7410 add = BitIsSet (opcode, 23); 7411 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7412 7413 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7414 if ((t == 15) || (wback && (n == t))) 7415 return false; 7416 7417 break; 7418 } 7419 7420 default: 7421 return false; 7422 } 7423 7424 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7425 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7426 if (!success) 7427 return false; 7428 7429 addr_t offset_addr; 7430 if (add) 7431 offset_addr = Rn + imm32; 7432 else 7433 offset_addr = Rn - imm32; 7434 7435 // address = if index then offset_addr else R[n]; 7436 addr_t address; 7437 if (index) 7438 address = offset_addr; 7439 else 7440 address = Rn; 7441 7442 // data = MemU[address,2]; 7443 RegisterInfo base_reg; 7444 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7445 7446 EmulateInstruction::Context context; 7447 context.type = eContextRegisterLoad; 7448 context.SetRegisterPlusOffset (base_reg, address - Rn); 7449 7450 uint64_t data = MemURead (context, address, 2, 0, &success); 7451 if (!success) 7452 return false; 7453 7454 // if wback then R[n] = offset_addr; 7455 if (wback) 7456 { 7457 context.type = eContextAdjustBaseRegister; 7458 context.SetAddress (offset_addr); 7459 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7460 return false; 7461 } 7462 7463 // if UnalignedSupport() || address<0> = '0' then 7464 if (UnalignedSupport() || BitIsClear (address, 0)) 7465 { 7466 // R[t] = SignExtend(data, 32); 7467 int64_t signed_data = llvm::SignExtend64<16>(data); 7468 context.type = eContextRegisterLoad; 7469 context.SetRegisterPlusOffset (base_reg, address - Rn); 7470 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7471 return false; 7472 } 7473 else // Can only apply before ARMv7 7474 { 7475 // R[t] = bits(32) UNKNOWN; 7476 WriteBits32Unknown (t); 7477 } 7478 } 7479 return true; 7480} 7481 7482// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7483// sign-extends it to from a 32-bit word, and writes it to a register. 7484bool 7485EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7486{ 7487#if 0 7488 if ConditionPassed() then 7489 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7490 base = Align(PC,4); 7491 address = if add then (base + imm32) else (base - imm32); 7492 data = MemU[address,2]; 7493 if UnalignedSupport() || address<0> = '0' then 7494 R[t] = SignExtend(data, 32); 7495 else // Can only apply before ARMv7 7496 R[t] = bits(32) UNKNOWN; 7497#endif 7498 7499 bool success = false; 7500 7501 if (ConditionPassed(opcode)) 7502 { 7503 uint32_t t; 7504 uint32_t imm32; 7505 bool add; 7506 7507 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7508 switch (encoding) 7509 { 7510 case eEncodingT1: 7511 // if Rt == '1111' then SEE "Unallocated memory hints"; 7512 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7513 t = Bits32 (opcode, 15, 12); 7514 imm32 = Bits32 (opcode, 11, 0); 7515 add = BitIsSet (opcode, 23); 7516 7517 // if t == 13 then UNPREDICTABLE; 7518 if (t == 13) 7519 return false; 7520 7521 break; 7522 7523 case eEncodingA1: 7524 { 7525 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7526 t = Bits32 (opcode, 15, 12); 7527 uint32_t imm4H = Bits32 (opcode, 11, 8); 7528 uint32_t imm4L = Bits32 (opcode, 3, 0); 7529 imm32 = (imm4H << 4) | imm4L; 7530 add = BitIsSet (opcode, 23); 7531 7532 // if t == 15 then UNPREDICTABLE; 7533 if (t == 15) 7534 return false; 7535 7536 break; 7537 } 7538 default: 7539 return false; 7540 } 7541 7542 // base = Align(PC,4); 7543 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7544 if (!success) 7545 return false; 7546 7547 uint64_t base = AlignPC (pc_value); 7548 7549 addr_t address; 7550 // address = if add then (base + imm32) else (base - imm32); 7551 if (add) 7552 address = base + imm32; 7553 else 7554 address = base - imm32; 7555 7556 // data = MemU[address,2]; 7557 RegisterInfo base_reg; 7558 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7559 7560 EmulateInstruction::Context context; 7561 context.type = eContextRegisterLoad; 7562 context.SetRegisterPlusOffset (base_reg, imm32); 7563 7564 uint64_t data = MemURead (context, address, 2, 0, &success); 7565 if (!success) 7566 return false; 7567 7568 // if UnalignedSupport() || address<0> = '0' then 7569 if (UnalignedSupport() || BitIsClear (address, 0)) 7570 { 7571 // R[t] = SignExtend(data, 32); 7572 int64_t signed_data = llvm::SignExtend64<16>(data); 7573 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7574 return false; 7575 } 7576 else // Can only apply before ARMv7 7577 { 7578 // R[t] = bits(32) UNKNOWN; 7579 WriteBits32Unknown (t); 7580 } 7581 } 7582 return true; 7583} 7584 7585// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7586// from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7587// shifted left by 0, 1, 2, or 3 bits. 7588bool 7589EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7590{ 7591#if 0 7592 if ConditionPassed() then 7593 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7594 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7595 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7596 address = if index then offset_addr else R[n]; 7597 data = MemU[address,2]; 7598 if wback then R[n] = offset_addr; 7599 if UnalignedSupport() || address<0> = '0' then 7600 R[t] = SignExtend(data, 32); 7601 else // Can only apply before ARMv7 7602 R[t] = bits(32) UNKNOWN; 7603#endif 7604 7605 bool success = false; 7606 7607 if (ConditionPassed(opcode)) 7608 { 7609 uint32_t t; 7610 uint32_t n; 7611 uint32_t m; 7612 bool index; 7613 bool add; 7614 bool wback; 7615 ARM_ShifterType shift_t; 7616 uint32_t shift_n; 7617 7618 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7619 switch (encoding) 7620 { 7621 case eEncodingT1: 7622 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7623 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7624 t = Bits32 (opcode, 2, 0); 7625 n = Bits32 (opcode, 5, 3); 7626 m = Bits32 (opcode, 8, 6); 7627 7628 // index = TRUE; add = TRUE; wback = FALSE; 7629 index = true; 7630 add = true; 7631 wback = false; 7632 7633 // (shift_t, shift_n) = (SRType_LSL, 0); 7634 shift_t = SRType_LSL; 7635 shift_n = 0; 7636 7637 break; 7638 7639 case eEncodingT2: 7640 // if Rn == '1111' then SEE LDRSH (literal); 7641 // if Rt == '1111' then SEE "Unallocated memory hints"; 7642 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7643 t = Bits32 (opcode, 15, 12); 7644 n = Bits32 (opcode, 19, 16); 7645 m = Bits32 (opcode, 3, 0); 7646 7647 // index = TRUE; add = TRUE; wback = FALSE; 7648 index = true; 7649 add = true; 7650 wback = false; 7651 7652 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7653 shift_t = SRType_LSL; 7654 shift_n = Bits32 (opcode, 5, 4); 7655 7656 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7657 if ((t == 13) || BadReg (m)) 7658 return false; 7659 7660 break; 7661 7662 case eEncodingA1: 7663 // if P == '0' && W == '1' then SEE LDRSHT; 7664 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7665 t = Bits32 (opcode, 15, 12); 7666 n = Bits32 (opcode, 19, 16); 7667 m = Bits32 (opcode, 3, 0); 7668 7669 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7670 index = BitIsSet (opcode, 24); 7671 add = BitIsSet (opcode, 23); 7672 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7673 7674 // (shift_t, shift_n) = (SRType_LSL, 0); 7675 shift_t = SRType_LSL; 7676 shift_n = 0; 7677 7678 // if t == 15 || m == 15 then UNPREDICTABLE; 7679 if ((t == 15) || (m == 15)) 7680 return false; 7681 7682 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7683 if (wback && ((n == 15) || (n == t))) 7684 return false; 7685 7686 break; 7687 7688 default: 7689 return false; 7690 } 7691 7692 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7693 if (!success) 7694 return false; 7695 7696 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7697 if (!success) 7698 return false; 7699 7700 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7701 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7702 if (!success) 7703 return false; 7704 7705 addr_t offset_addr; 7706 addr_t address; 7707 7708 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7709 if (add) 7710 offset_addr = Rn + offset; 7711 else 7712 offset_addr = Rn - offset; 7713 7714 // address = if index then offset_addr else R[n]; 7715 if (index) 7716 address = offset_addr; 7717 else 7718 address = Rn; 7719 7720 // data = MemU[address,2]; 7721 RegisterInfo base_reg; 7722 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7723 7724 RegisterInfo offset_reg; 7725 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7726 7727 EmulateInstruction::Context context; 7728 context.type = eContextRegisterLoad; 7729 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7730 7731 uint64_t data = MemURead (context, address, 2, 0, &success); 7732 if (!success) 7733 return false; 7734 7735 // if wback then R[n] = offset_addr; 7736 if (wback) 7737 { 7738 context.type = eContextAdjustBaseRegister; 7739 context.SetAddress (offset_addr); 7740 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7741 return false; 7742 } 7743 7744 // if UnalignedSupport() || address<0> = '0' then 7745 if (UnalignedSupport() || BitIsClear (address, 0)) 7746 { 7747 // R[t] = SignExtend(data, 32); 7748 context.type = eContextRegisterLoad; 7749 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7750 7751 int64_t signed_data = llvm::SignExtend64<16>(data); 7752 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7753 return false; 7754 } 7755 else // Can only apply before ARMv7 7756 { 7757 // R[t] = bits(32) UNKNOWN; 7758 WriteBits32Unknown (t); 7759 } 7760 } 7761 return true; 7762} 7763 7764// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7765// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7766bool 7767EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7768{ 7769#if 0 7770 if ConditionPassed() then 7771 EncodingSpecificOperations(); 7772 rotated = ROR(R[m], rotation); 7773 R[d] = SignExtend(rotated<7:0>, 32); 7774#endif 7775 7776 bool success = false; 7777 7778 if (ConditionPassed(opcode)) 7779 { 7780 uint32_t d; 7781 uint32_t m; 7782 uint32_t rotation; 7783 7784 // EncodingSpecificOperations(); 7785 switch (encoding) 7786 { 7787 case eEncodingT1: 7788 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7789 d = Bits32 (opcode, 2, 0); 7790 m = Bits32 (opcode, 5, 3); 7791 rotation = 0; 7792 7793 break; 7794 7795 case eEncodingT2: 7796 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7797 d = Bits32 (opcode, 11, 8); 7798 m = Bits32 (opcode, 3, 0); 7799 rotation = Bits32 (opcode, 5, 4) << 3; 7800 7801 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7802 if (BadReg (d) || BadReg (m)) 7803 return false; 7804 7805 break; 7806 7807 case eEncodingA1: 7808 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7809 d = Bits32 (opcode, 15, 12); 7810 m = Bits32 (opcode, 3, 0); 7811 rotation = Bits32 (opcode, 11, 10) << 3; 7812 7813 // if d == 15 || m == 15 then UNPREDICTABLE; 7814 if ((d == 15) || (m == 15)) 7815 return false; 7816 7817 break; 7818 7819 default: 7820 return false; 7821 } 7822 7823 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7824 if (!success) 7825 return false; 7826 7827 // rotated = ROR(R[m], rotation); 7828 uint64_t rotated = ROR (Rm, rotation, &success); 7829 if (!success) 7830 return false; 7831 7832 // R[d] = SignExtend(rotated<7:0>, 32); 7833 int64_t data = llvm::SignExtend64<8>(rotated); 7834 7835 RegisterInfo source_reg; 7836 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7837 7838 EmulateInstruction::Context context; 7839 context.type = eContextRegisterLoad; 7840 context.SetRegister (source_reg); 7841 7842 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7843 return false; 7844 } 7845 return true; 7846} 7847 7848// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7849// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7850bool 7851EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7852{ 7853#if 0 7854 if ConditionPassed() then 7855 EncodingSpecificOperations(); 7856 rotated = ROR(R[m], rotation); 7857 R[d] = SignExtend(rotated<15:0>, 32); 7858#endif 7859 7860 bool success = false; 7861 7862 if (ConditionPassed(opcode)) 7863 { 7864 uint32_t d; 7865 uint32_t m; 7866 uint32_t rotation; 7867 7868 // EncodingSpecificOperations(); 7869 switch (encoding) 7870 { 7871 case eEncodingT1: 7872 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7873 d = Bits32 (opcode, 2, 0); 7874 m = Bits32 (opcode, 5, 3); 7875 rotation = 0; 7876 7877 break; 7878 7879 case eEncodingT2: 7880 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7881 d = Bits32 (opcode, 11, 8); 7882 m = Bits32 (opcode, 3, 0); 7883 rotation = Bits32 (opcode, 5, 4) << 3; 7884 7885 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7886 if (BadReg (d) || BadReg (m)) 7887 return false; 7888 7889 break; 7890 7891 case eEncodingA1: 7892 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7893 d = Bits32 (opcode, 15, 12); 7894 m = Bits32 (opcode, 3, 0); 7895 rotation = Bits32 (opcode, 11, 10) << 3; 7896 7897 // if d == 15 || m == 15 then UNPREDICTABLE; 7898 if ((d == 15) || (m == 15)) 7899 return false; 7900 7901 break; 7902 7903 default: 7904 return false; 7905 } 7906 7907 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7908 if (!success) 7909 return false; 7910 7911 // rotated = ROR(R[m], rotation); 7912 uint64_t rotated = ROR (Rm, rotation, &success); 7913 if (!success) 7914 return false; 7915 7916 // R[d] = SignExtend(rotated<15:0>, 32); 7917 RegisterInfo source_reg; 7918 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7919 7920 EmulateInstruction::Context context; 7921 context.type = eContextRegisterLoad; 7922 context.SetRegister (source_reg); 7923 7924 int64_t data = llvm::SignExtend64<16> (rotated); 7925 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7926 return false; 7927 } 7928 7929 return true; 7930} 7931 7932// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 7933// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7934bool 7935EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 7936{ 7937#if 0 7938 if ConditionPassed() then 7939 EncodingSpecificOperations(); 7940 rotated = ROR(R[m], rotation); 7941 R[d] = ZeroExtend(rotated<7:0>, 32); 7942#endif 7943 7944 bool success = false; 7945 7946 if (ConditionPassed(opcode)) 7947 { 7948 uint32_t d; 7949 uint32_t m; 7950 uint32_t rotation; 7951 7952 // EncodingSpecificOperations(); 7953 switch (encoding) 7954 { 7955 case eEncodingT1: 7956 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7957 d = Bits32 (opcode, 2, 0); 7958 m = Bits32 (opcode, 5, 3); 7959 rotation = 0; 7960 7961 break; 7962 7963 case eEncodingT2: 7964 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7965 d = Bits32 (opcode, 11, 8); 7966 m = Bits32 (opcode, 3, 0); 7967 rotation = Bits32 (opcode, 5, 4) << 3; 7968 7969 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7970 if (BadReg (d) || BadReg (m)) 7971 return false; 7972 7973 break; 7974 7975 case eEncodingA1: 7976 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7977 d = Bits32 (opcode, 15, 12); 7978 m = Bits32 (opcode, 3, 0); 7979 rotation = Bits32 (opcode, 11, 10) << 3; 7980 7981 // if d == 15 || m == 15 then UNPREDICTABLE; 7982 if ((d == 15) || (m == 15)) 7983 return false; 7984 7985 break; 7986 7987 default: 7988 return false; 7989 } 7990 7991 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7992 if (!success) 7993 return false; 7994 7995 // rotated = ROR(R[m], rotation); 7996 uint64_t rotated = ROR (Rm, rotation, &success); 7997 if (!success) 7998 return false; 7999 8000 // R[d] = ZeroExtend(rotated<7:0>, 32); 8001 RegisterInfo source_reg; 8002 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8003 8004 EmulateInstruction::Context context; 8005 context.type = eContextRegisterLoad; 8006 context.SetRegister (source_reg); 8007 8008 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 8009 return false; 8010 } 8011 return true; 8012} 8013 8014// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 8015// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 8016bool 8017EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 8018{ 8019#if 0 8020 if ConditionPassed() then 8021 EncodingSpecificOperations(); 8022 rotated = ROR(R[m], rotation); 8023 R[d] = ZeroExtend(rotated<15:0>, 32); 8024#endif 8025 8026 bool success = false; 8027 8028 if (ConditionPassed(opcode)) 8029 { 8030 uint32_t d; 8031 uint32_t m; 8032 uint32_t rotation; 8033 8034 switch (encoding) 8035 { 8036 case eEncodingT1: 8037 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8038 d = Bits32 (opcode, 2, 0); 8039 m = Bits32 (opcode, 5, 3); 8040 rotation = 0; 8041 8042 break; 8043 8044 case eEncodingT2: 8045 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8046 d = Bits32 (opcode, 11, 8); 8047 m = Bits32 (opcode, 3, 0); 8048 rotation = Bits32 (opcode, 5, 4) << 3; 8049 8050 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8051 if (BadReg (d) || BadReg (m)) 8052 return false; 8053 8054 break; 8055 8056 case eEncodingA1: 8057 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8058 d = Bits32 (opcode, 15, 12); 8059 m = Bits32 (opcode, 3, 0); 8060 rotation = Bits32 (opcode, 11, 10) << 3; 8061 8062 // if d == 15 || m == 15 then UNPREDICTABLE; 8063 if ((d == 15) || (m == 15)) 8064 return false; 8065 8066 break; 8067 8068 default: 8069 return false; 8070 } 8071 8072 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8073 if (!success) 8074 return false; 8075 8076 // rotated = ROR(R[m], rotation); 8077 uint64_t rotated = ROR (Rm, rotation, &success); 8078 if (!success) 8079 return false; 8080 8081 // R[d] = ZeroExtend(rotated<15:0>, 32); 8082 RegisterInfo source_reg; 8083 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8084 8085 EmulateInstruction::Context context; 8086 context.type = eContextRegisterLoad; 8087 context.SetRegister (source_reg); 8088 8089 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8090 return false; 8091 } 8092 return true; 8093} 8094 8095// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8096// word respectively. 8097bool 8098EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8099{ 8100#if 0 8101 if ConditionPassed() then 8102 EncodingSpecificOperations(); 8103 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8104 UNPREDICTABLE; 8105 else 8106 address = if increment then R[n] else R[n]-8; 8107 if wordhigher then address = address+4; 8108 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8109 BranchWritePC(MemA[address,4]); 8110 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8111#endif 8112 8113 bool success = false; 8114 8115 if (ConditionPassed(opcode)) 8116 { 8117 uint32_t n; 8118 bool wback; 8119 bool increment; 8120 bool wordhigher; 8121 8122 // EncodingSpecificOperations(); 8123 switch (encoding) 8124 { 8125 case eEncodingT1: 8126 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8127 n = Bits32 (opcode, 19, 16); 8128 wback = BitIsSet (opcode, 21); 8129 increment = false; 8130 wordhigher = false; 8131 8132 // if n == 15 then UNPREDICTABLE; 8133 if (n == 15) 8134 return false; 8135 8136 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8137 if (InITBlock() && !LastInITBlock()) 8138 return false; 8139 8140 break; 8141 8142 case eEncodingT2: 8143 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8144 n = Bits32 (opcode, 19, 16); 8145 wback = BitIsSet (opcode, 21); 8146 increment = true; 8147 wordhigher = false; 8148 8149 // if n == 15 then UNPREDICTABLE; 8150 if (n == 15) 8151 return false; 8152 8153 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8154 if (InITBlock() && !LastInITBlock()) 8155 return false; 8156 8157 break; 8158 8159 case eEncodingA1: 8160 // n = UInt(Rn); 8161 n = Bits32 (opcode, 19, 16); 8162 8163 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8164 wback = BitIsSet (opcode, 21); 8165 increment = BitIsSet (opcode, 23); 8166 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8167 8168 // if n == 15 then UNPREDICTABLE; 8169 if (n == 15) 8170 return false; 8171 8172 break; 8173 8174 default: 8175 return false; 8176 } 8177 8178 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8179 if (!CurrentModeIsPrivileged ()) 8180 // UNPREDICTABLE; 8181 return false; 8182 else 8183 { 8184 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8185 if (!success) 8186 return false; 8187 8188 addr_t address; 8189 // address = if increment then R[n] else R[n]-8; 8190 if (increment) 8191 address = Rn; 8192 else 8193 address = Rn - 8; 8194 8195 // if wordhigher then address = address+4; 8196 if (wordhigher) 8197 address = address + 4; 8198 8199 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8200 RegisterInfo base_reg; 8201 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8202 8203 EmulateInstruction::Context context; 8204 context.type = eContextReturnFromException; 8205 context.SetRegisterPlusOffset (base_reg, address - Rn); 8206 8207 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8208 if (!success) 8209 return false; 8210 8211 CPSRWriteByInstr (data, 15, true); 8212 8213 // BranchWritePC(MemA[address,4]); 8214 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8215 if (!success) 8216 return false; 8217 8218 BranchWritePC (context, data2); 8219 8220 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8221 if (wback) 8222 { 8223 context.type = eContextAdjustBaseRegister; 8224 if (increment) 8225 { 8226 context.SetOffset (8); 8227 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8228 return false; 8229 } 8230 else 8231 { 8232 context.SetOffset (-8); 8233 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8234 return false; 8235 } 8236 } // if wback 8237 } 8238 } // if ConditionPassed() 8239 return true; 8240} 8241 8242// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8243// and writes the result to the destination register. It can optionally update the condition flags based on 8244// the result. 8245bool 8246EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8247{ 8248#if 0 8249 // ARM pseudo code... 8250 if ConditionPassed() then 8251 EncodingSpecificOperations(); 8252 result = R[n] EOR imm32; 8253 if d == 15 then // Can only occur for ARM encoding 8254 ALUWritePC(result); // setflags is always FALSE here 8255 else 8256 R[d] = result; 8257 if setflags then 8258 APSR.N = result<31>; 8259 APSR.Z = IsZeroBit(result); 8260 APSR.C = carry; 8261 // APSR.V unchanged 8262#endif 8263 8264 bool success = false; 8265 8266 if (ConditionPassed(opcode)) 8267 { 8268 uint32_t Rd, Rn; 8269 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8270 bool setflags; 8271 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8272 switch (encoding) 8273 { 8274 case eEncodingT1: 8275 Rd = Bits32(opcode, 11, 8); 8276 Rn = Bits32(opcode, 19, 16); 8277 setflags = BitIsSet(opcode, 20); 8278 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8279 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8280 if (Rd == 15 && setflags) 8281 return EmulateTEQImm (opcode, eEncodingT1); 8282 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8283 return false; 8284 break; 8285 case eEncodingA1: 8286 Rd = Bits32(opcode, 15, 12); 8287 Rn = Bits32(opcode, 19, 16); 8288 setflags = BitIsSet(opcode, 20); 8289 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8290 8291 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8292 if (Rd == 15 && setflags) 8293 return EmulateSUBSPcLrEtc (opcode, encoding); 8294 break; 8295 default: 8296 return false; 8297 } 8298 8299 // Read the first operand. 8300 uint32_t val1 = ReadCoreReg(Rn, &success); 8301 if (!success) 8302 return false; 8303 8304 uint32_t result = val1 ^ imm32; 8305 8306 EmulateInstruction::Context context; 8307 context.type = EmulateInstruction::eContextImmediate; 8308 context.SetNoArgs (); 8309 8310 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8311 return false; 8312 } 8313 return true; 8314} 8315 8316// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8317// optionally-shifted register value, and writes the result to the destination register. 8318// It can optionally update the condition flags based on the result. 8319bool 8320EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8321{ 8322#if 0 8323 // ARM pseudo code... 8324 if ConditionPassed() then 8325 EncodingSpecificOperations(); 8326 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8327 result = R[n] EOR shifted; 8328 if d == 15 then // Can only occur for ARM encoding 8329 ALUWritePC(result); // setflags is always FALSE here 8330 else 8331 R[d] = result; 8332 if setflags then 8333 APSR.N = result<31>; 8334 APSR.Z = IsZeroBit(result); 8335 APSR.C = carry; 8336 // APSR.V unchanged 8337#endif 8338 8339 bool success = false; 8340 8341 if (ConditionPassed(opcode)) 8342 { 8343 uint32_t Rd, Rn, Rm; 8344 ARM_ShifterType shift_t; 8345 uint32_t shift_n; // the shift applied to the value read from Rm 8346 bool setflags; 8347 uint32_t carry; 8348 switch (encoding) 8349 { 8350 case eEncodingT1: 8351 Rd = Rn = Bits32(opcode, 2, 0); 8352 Rm = Bits32(opcode, 5, 3); 8353 setflags = !InITBlock(); 8354 shift_t = SRType_LSL; 8355 shift_n = 0; 8356 break; 8357 case eEncodingT2: 8358 Rd = Bits32(opcode, 11, 8); 8359 Rn = Bits32(opcode, 19, 16); 8360 Rm = Bits32(opcode, 3, 0); 8361 setflags = BitIsSet(opcode, 20); 8362 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8363 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8364 if (Rd == 15 && setflags) 8365 return EmulateTEQReg (opcode, eEncodingT1); 8366 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8367 return false; 8368 break; 8369 case eEncodingA1: 8370 Rd = Bits32(opcode, 15, 12); 8371 Rn = Bits32(opcode, 19, 16); 8372 Rm = Bits32(opcode, 3, 0); 8373 setflags = BitIsSet(opcode, 20); 8374 shift_n = DecodeImmShiftARM(opcode, shift_t); 8375 8376 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8377 if (Rd == 15 && setflags) 8378 return EmulateSUBSPcLrEtc (opcode, encoding); 8379 break; 8380 default: 8381 return false; 8382 } 8383 8384 // Read the first operand. 8385 uint32_t val1 = ReadCoreReg(Rn, &success); 8386 if (!success) 8387 return false; 8388 8389 // Read the second operand. 8390 uint32_t val2 = ReadCoreReg(Rm, &success); 8391 if (!success) 8392 return false; 8393 8394 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8395 if (!success) 8396 return false; 8397 uint32_t result = val1 ^ shifted; 8398 8399 EmulateInstruction::Context context; 8400 context.type = EmulateInstruction::eContextImmediate; 8401 context.SetNoArgs (); 8402 8403 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8404 return false; 8405 } 8406 return true; 8407} 8408 8409// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8410// writes the result to the destination register. It can optionally update the condition flags based 8411// on the result. 8412bool 8413EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8414{ 8415#if 0 8416 // ARM pseudo code... 8417 if ConditionPassed() then 8418 EncodingSpecificOperations(); 8419 result = R[n] OR imm32; 8420 if d == 15 then // Can only occur for ARM encoding 8421 ALUWritePC(result); // setflags is always FALSE here 8422 else 8423 R[d] = result; 8424 if setflags then 8425 APSR.N = result<31>; 8426 APSR.Z = IsZeroBit(result); 8427 APSR.C = carry; 8428 // APSR.V unchanged 8429#endif 8430 8431 bool success = false; 8432 8433 if (ConditionPassed(opcode)) 8434 { 8435 uint32_t Rd, Rn; 8436 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8437 bool setflags; 8438 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8439 switch (encoding) 8440 { 8441 case eEncodingT1: 8442 Rd = Bits32(opcode, 11, 8); 8443 Rn = Bits32(opcode, 19, 16); 8444 setflags = BitIsSet(opcode, 20); 8445 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8446 // if Rn == '1111' then SEE MOV (immediate); 8447 if (Rn == 15) 8448 return EmulateMOVRdImm (opcode, eEncodingT2); 8449 if (BadReg(Rd) || Rn == 13) 8450 return false; 8451 break; 8452 case eEncodingA1: 8453 Rd = Bits32(opcode, 15, 12); 8454 Rn = Bits32(opcode, 19, 16); 8455 setflags = BitIsSet(opcode, 20); 8456 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8457 8458 if (Rd == 15 && setflags) 8459 return EmulateSUBSPcLrEtc (opcode, encoding); 8460 break; 8461 default: 8462 return false; 8463 } 8464 8465 // Read the first operand. 8466 uint32_t val1 = ReadCoreReg(Rn, &success); 8467 if (!success) 8468 return false; 8469 8470 uint32_t result = val1 | imm32; 8471 8472 EmulateInstruction::Context context; 8473 context.type = EmulateInstruction::eContextImmediate; 8474 context.SetNoArgs (); 8475 8476 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8477 return false; 8478 } 8479 return true; 8480} 8481 8482// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8483// value, and writes the result to the destination register. It can optionally update the condition flags based 8484// on the result. 8485bool 8486EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8487{ 8488#if 0 8489 // ARM pseudo code... 8490 if ConditionPassed() then 8491 EncodingSpecificOperations(); 8492 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8493 result = R[n] OR shifted; 8494 if d == 15 then // Can only occur for ARM encoding 8495 ALUWritePC(result); // setflags is always FALSE here 8496 else 8497 R[d] = result; 8498 if setflags then 8499 APSR.N = result<31>; 8500 APSR.Z = IsZeroBit(result); 8501 APSR.C = carry; 8502 // APSR.V unchanged 8503#endif 8504 8505 bool success = false; 8506 8507 if (ConditionPassed(opcode)) 8508 { 8509 uint32_t Rd, Rn, Rm; 8510 ARM_ShifterType shift_t; 8511 uint32_t shift_n; // the shift applied to the value read from Rm 8512 bool setflags; 8513 uint32_t carry; 8514 switch (encoding) 8515 { 8516 case eEncodingT1: 8517 Rd = Rn = Bits32(opcode, 2, 0); 8518 Rm = Bits32(opcode, 5, 3); 8519 setflags = !InITBlock(); 8520 shift_t = SRType_LSL; 8521 shift_n = 0; 8522 break; 8523 case eEncodingT2: 8524 Rd = Bits32(opcode, 11, 8); 8525 Rn = Bits32(opcode, 19, 16); 8526 Rm = Bits32(opcode, 3, 0); 8527 setflags = BitIsSet(opcode, 20); 8528 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8529 // if Rn == '1111' then SEE MOV (register); 8530 if (Rn == 15) 8531 return EmulateMOVRdRm (opcode, eEncodingT3); 8532 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8533 return false; 8534 break; 8535 case eEncodingA1: 8536 Rd = Bits32(opcode, 15, 12); 8537 Rn = Bits32(opcode, 19, 16); 8538 Rm = Bits32(opcode, 3, 0); 8539 setflags = BitIsSet(opcode, 20); 8540 shift_n = DecodeImmShiftARM(opcode, shift_t); 8541 8542 if (Rd == 15 && setflags) 8543 return EmulateSUBSPcLrEtc (opcode, encoding); 8544 break; 8545 default: 8546 return false; 8547 } 8548 8549 // Read the first operand. 8550 uint32_t val1 = ReadCoreReg(Rn, &success); 8551 if (!success) 8552 return false; 8553 8554 // Read the second operand. 8555 uint32_t val2 = ReadCoreReg(Rm, &success); 8556 if (!success) 8557 return false; 8558 8559 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8560 if (!success) 8561 return false; 8562 uint32_t result = val1 | shifted; 8563 8564 EmulateInstruction::Context context; 8565 context.type = EmulateInstruction::eContextImmediate; 8566 context.SetNoArgs (); 8567 8568 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8569 return false; 8570 } 8571 return true; 8572} 8573 8574// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8575// the destination register. It can optionally update the condition flags based on the result. 8576bool 8577EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8578{ 8579#if 0 8580 // ARM pseudo code... 8581 if ConditionPassed() then 8582 EncodingSpecificOperations(); 8583 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8584 if d == 15 then // Can only occur for ARM encoding 8585 ALUWritePC(result); // setflags is always FALSE here 8586 else 8587 R[d] = result; 8588 if setflags then 8589 APSR.N = result<31>; 8590 APSR.Z = IsZeroBit(result); 8591 APSR.C = carry; 8592 APSR.V = overflow; 8593#endif 8594 8595 bool success = false; 8596 8597 uint32_t Rd; // the destination register 8598 uint32_t Rn; // the first operand 8599 bool setflags; 8600 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8601 switch (encoding) { 8602 case eEncodingT1: 8603 Rd = Bits32(opcode, 2, 0); 8604 Rn = Bits32(opcode, 5, 3); 8605 setflags = !InITBlock(); 8606 imm32 = 0; 8607 break; 8608 case eEncodingT2: 8609 Rd = Bits32(opcode, 11, 8); 8610 Rn = Bits32(opcode, 19, 16); 8611 setflags = BitIsSet(opcode, 20); 8612 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8613 if (BadReg(Rd) || BadReg(Rn)) 8614 return false; 8615 break; 8616 case eEncodingA1: 8617 Rd = Bits32(opcode, 15, 12); 8618 Rn = Bits32(opcode, 19, 16); 8619 setflags = BitIsSet(opcode, 20); 8620 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8621 8622 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8623 if (Rd == 15 && setflags) 8624 return EmulateSUBSPcLrEtc (opcode, encoding); 8625 break; 8626 default: 8627 return false; 8628 } 8629 // Read the register value from the operand register Rn. 8630 uint32_t reg_val = ReadCoreReg(Rn, &success); 8631 if (!success) 8632 return false; 8633 8634 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8635 8636 EmulateInstruction::Context context; 8637 context.type = EmulateInstruction::eContextImmediate; 8638 context.SetNoArgs (); 8639 8640 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8641 return false; 8642 8643 return true; 8644} 8645 8646// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8647// result to the destination register. It can optionally update the condition flags based on the result. 8648bool 8649EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8650{ 8651#if 0 8652 // ARM pseudo code... 8653 if ConditionPassed() then 8654 EncodingSpecificOperations(); 8655 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8656 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8657 if d == 15 then // Can only occur for ARM encoding 8658 ALUWritePC(result); // setflags is always FALSE here 8659 else 8660 R[d] = result; 8661 if setflags then 8662 APSR.N = result<31>; 8663 APSR.Z = IsZeroBit(result); 8664 APSR.C = carry; 8665 APSR.V = overflow; 8666#endif 8667 8668 bool success = false; 8669 8670 uint32_t Rd; // the destination register 8671 uint32_t Rn; // the first operand 8672 uint32_t Rm; // the second operand 8673 bool setflags; 8674 ARM_ShifterType shift_t; 8675 uint32_t shift_n; // the shift applied to the value read from Rm 8676 switch (encoding) { 8677 case eEncodingT1: 8678 Rd = Bits32(opcode, 11, 8); 8679 Rn = Bits32(opcode, 19, 16); 8680 Rm = Bits32(opcode, 3, 0); 8681 setflags = BitIsSet(opcode, 20); 8682 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8683 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8684 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8685 return false; 8686 break; 8687 case eEncodingA1: 8688 Rd = Bits32(opcode, 15, 12); 8689 Rn = Bits32(opcode, 19, 16); 8690 Rm = Bits32(opcode, 3, 0); 8691 setflags = BitIsSet(opcode, 20); 8692 shift_n = DecodeImmShiftARM(opcode, shift_t); 8693 8694 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8695 if (Rd == 15 && setflags) 8696 return EmulateSUBSPcLrEtc (opcode, encoding); 8697 break; 8698 default: 8699 return false; 8700 } 8701 // Read the register value from register Rn. 8702 uint32_t val1 = ReadCoreReg(Rn, &success); 8703 if (!success) 8704 return false; 8705 8706 // Read the register value from register Rm. 8707 uint32_t val2 = ReadCoreReg(Rm, &success); 8708 if (!success) 8709 return false; 8710 8711 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8712 if (!success) 8713 return false; 8714 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8715 8716 EmulateInstruction::Context context; 8717 context.type = EmulateInstruction::eContextImmediate; 8718 context.SetNoArgs(); 8719 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8720 return false; 8721 8722 return true; 8723} 8724 8725// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8726// an immediate value, and writes the result to the destination register. It can optionally update the condition 8727// flags based on the result. 8728bool 8729EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8730{ 8731#if 0 8732 // ARM pseudo code... 8733 if ConditionPassed() then 8734 EncodingSpecificOperations(); 8735 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8736 if d == 15 then 8737 ALUWritePC(result); // setflags is always FALSE here 8738 else 8739 R[d] = result; 8740 if setflags then 8741 APSR.N = result<31>; 8742 APSR.Z = IsZeroBit(result); 8743 APSR.C = carry; 8744 APSR.V = overflow; 8745#endif 8746 8747 bool success = false; 8748 8749 uint32_t Rd; // the destination register 8750 uint32_t Rn; // the first operand 8751 bool setflags; 8752 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8753 switch (encoding) { 8754 case eEncodingA1: 8755 Rd = Bits32(opcode, 15, 12); 8756 Rn = Bits32(opcode, 19, 16); 8757 setflags = BitIsSet(opcode, 20); 8758 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8759 8760 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8761 if (Rd == 15 && setflags) 8762 return EmulateSUBSPcLrEtc (opcode, encoding); 8763 break; 8764 default: 8765 return false; 8766 } 8767 // Read the register value from the operand register Rn. 8768 uint32_t reg_val = ReadCoreReg(Rn, &success); 8769 if (!success) 8770 return false; 8771 8772 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8773 8774 EmulateInstruction::Context context; 8775 context.type = EmulateInstruction::eContextImmediate; 8776 context.SetNoArgs (); 8777 8778 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8779 return false; 8780 8781 return true; 8782} 8783 8784// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8785// optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8786// condition flags based on the result. 8787bool 8788EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8789{ 8790#if 0 8791 // ARM pseudo code... 8792 if ConditionPassed() then 8793 EncodingSpecificOperations(); 8794 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8795 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8796 if d == 15 then 8797 ALUWritePC(result); // setflags is always FALSE here 8798 else 8799 R[d] = result; 8800 if setflags then 8801 APSR.N = result<31>; 8802 APSR.Z = IsZeroBit(result); 8803 APSR.C = carry; 8804 APSR.V = overflow; 8805#endif 8806 8807 bool success = false; 8808 8809 uint32_t Rd; // the destination register 8810 uint32_t Rn; // the first operand 8811 uint32_t Rm; // the second operand 8812 bool setflags; 8813 ARM_ShifterType shift_t; 8814 uint32_t shift_n; // the shift applied to the value read from Rm 8815 switch (encoding) { 8816 case eEncodingA1: 8817 Rd = Bits32(opcode, 15, 12); 8818 Rn = Bits32(opcode, 19, 16); 8819 Rm = Bits32(opcode, 3, 0); 8820 setflags = BitIsSet(opcode, 20); 8821 shift_n = DecodeImmShiftARM(opcode, shift_t); 8822 8823 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8824 if (Rd == 15 && setflags) 8825 return EmulateSUBSPcLrEtc (opcode, encoding); 8826 break; 8827 default: 8828 return false; 8829 } 8830 // Read the register value from register Rn. 8831 uint32_t val1 = ReadCoreReg(Rn, &success); 8832 if (!success) 8833 return false; 8834 8835 // Read the register value from register Rm. 8836 uint32_t val2 = ReadCoreReg(Rm, &success); 8837 if (!success) 8838 return false; 8839 8840 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8841 if (!success) 8842 return false; 8843 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8844 8845 EmulateInstruction::Context context; 8846 context.type = EmulateInstruction::eContextImmediate; 8847 context.SetNoArgs(); 8848 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8849 return false; 8850 8851 return true; 8852} 8853 8854// Subtract with Carry (immediate) subtracts an immediate value and the value of 8855// NOT (Carry flag) from a register value, and writes the result to the destination register. 8856// It can optionally update the condition flags based on the result. 8857bool 8858EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8859{ 8860#if 0 8861 // ARM pseudo code... 8862 if ConditionPassed() then 8863 EncodingSpecificOperations(); 8864 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8865 if d == 15 then // Can only occur for ARM encoding 8866 ALUWritePC(result); // setflags is always FALSE here 8867 else 8868 R[d] = result; 8869 if setflags then 8870 APSR.N = result<31>; 8871 APSR.Z = IsZeroBit(result); 8872 APSR.C = carry; 8873 APSR.V = overflow; 8874#endif 8875 8876 bool success = false; 8877 8878 uint32_t Rd; // the destination register 8879 uint32_t Rn; // the first operand 8880 bool setflags; 8881 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8882 switch (encoding) { 8883 case eEncodingT1: 8884 Rd = Bits32(opcode, 11, 8); 8885 Rn = Bits32(opcode, 19, 16); 8886 setflags = BitIsSet(opcode, 20); 8887 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8888 if (BadReg(Rd) || BadReg(Rn)) 8889 return false; 8890 break; 8891 case eEncodingA1: 8892 Rd = Bits32(opcode, 15, 12); 8893 Rn = Bits32(opcode, 19, 16); 8894 setflags = BitIsSet(opcode, 20); 8895 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8896 8897 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8898 if (Rd == 15 && setflags) 8899 return EmulateSUBSPcLrEtc (opcode, encoding); 8900 break; 8901 default: 8902 return false; 8903 } 8904 // Read the register value from the operand register Rn. 8905 uint32_t reg_val = ReadCoreReg(Rn, &success); 8906 if (!success) 8907 return false; 8908 8909 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 8910 8911 EmulateInstruction::Context context; 8912 context.type = EmulateInstruction::eContextImmediate; 8913 context.SetNoArgs (); 8914 8915 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8916 return false; 8917 8918 return true; 8919} 8920 8921// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 8922// NOT (Carry flag) from a register value, and writes the result to the destination register. 8923// It can optionally update the condition flags based on the result. 8924bool 8925EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 8926{ 8927#if 0 8928 // ARM pseudo code... 8929 if ConditionPassed() then 8930 EncodingSpecificOperations(); 8931 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8932 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 8933 if d == 15 then // Can only occur for ARM encoding 8934 ALUWritePC(result); // setflags is always FALSE here 8935 else 8936 R[d] = result; 8937 if setflags then 8938 APSR.N = result<31>; 8939 APSR.Z = IsZeroBit(result); 8940 APSR.C = carry; 8941 APSR.V = overflow; 8942#endif 8943 8944 bool success = false; 8945 8946 uint32_t Rd; // the destination register 8947 uint32_t Rn; // the first operand 8948 uint32_t Rm; // the second operand 8949 bool setflags; 8950 ARM_ShifterType shift_t; 8951 uint32_t shift_n; // the shift applied to the value read from Rm 8952 switch (encoding) { 8953 case eEncodingT1: 8954 Rd = Rn = Bits32(opcode, 2, 0); 8955 Rm = Bits32(opcode, 5, 3); 8956 setflags = !InITBlock(); 8957 shift_t = SRType_LSL; 8958 shift_n = 0; 8959 break; 8960 case eEncodingT2: 8961 Rd = Bits32(opcode, 11, 8); 8962 Rn = Bits32(opcode, 19, 16); 8963 Rm = Bits32(opcode, 3, 0); 8964 setflags = BitIsSet(opcode, 20); 8965 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8966 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8967 return false; 8968 break; 8969 case eEncodingA1: 8970 Rd = Bits32(opcode, 15, 12); 8971 Rn = Bits32(opcode, 19, 16); 8972 Rm = Bits32(opcode, 3, 0); 8973 setflags = BitIsSet(opcode, 20); 8974 shift_n = DecodeImmShiftARM(opcode, shift_t); 8975 8976 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8977 if (Rd == 15 && setflags) 8978 return EmulateSUBSPcLrEtc (opcode, encoding); 8979 break; 8980 default: 8981 return false; 8982 } 8983 // Read the register value from register Rn. 8984 uint32_t val1 = ReadCoreReg(Rn, &success); 8985 if (!success) 8986 return false; 8987 8988 // Read the register value from register Rm. 8989 uint32_t val2 = ReadCoreReg(Rm, &success); 8990 if (!success) 8991 return false; 8992 8993 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8994 if (!success) 8995 return false; 8996 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 8997 8998 EmulateInstruction::Context context; 8999 context.type = EmulateInstruction::eContextImmediate; 9000 context.SetNoArgs(); 9001 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9002 return false; 9003 9004 return true; 9005} 9006 9007// This instruction subtracts an immediate value from a register value, and writes the result 9008// to the destination register. It can optionally update the condition flags based on the result. 9009bool 9010EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9011{ 9012#if 0 9013 // ARM pseudo code... 9014 if ConditionPassed() then 9015 EncodingSpecificOperations(); 9016 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9017 R[d] = result; 9018 if setflags then 9019 APSR.N = result<31>; 9020 APSR.Z = IsZeroBit(result); 9021 APSR.C = carry; 9022 APSR.V = overflow; 9023#endif 9024 9025 bool success = false; 9026 9027 uint32_t Rd; // the destination register 9028 uint32_t Rn; // the first operand 9029 bool setflags; 9030 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9031 switch (encoding) { 9032 case eEncodingT1: 9033 Rd = Bits32(opcode, 2, 0); 9034 Rn = Bits32(opcode, 5, 3); 9035 setflags = !InITBlock(); 9036 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9037 break; 9038 case eEncodingT2: 9039 Rd = Rn = Bits32(opcode, 10, 8); 9040 setflags = !InITBlock(); 9041 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9042 break; 9043 case eEncodingT3: 9044 Rd = Bits32(opcode, 11, 8); 9045 Rn = Bits32(opcode, 19, 16); 9046 setflags = BitIsSet(opcode, 20); 9047 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9048 9049 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9050 if (Rd == 15 && setflags) 9051 return EmulateCMPImm (opcode, eEncodingT2); 9052 9053 // if Rn == '1101' then SEE SUB (SP minus immediate); 9054 if (Rn == 13) 9055 return EmulateSUBSPImm (opcode, eEncodingT2); 9056 9057 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9058 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9059 return false; 9060 break; 9061 case eEncodingT4: 9062 Rd = Bits32(opcode, 11, 8); 9063 Rn = Bits32(opcode, 19, 16); 9064 setflags = BitIsSet(opcode, 20); 9065 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9066 9067 // if Rn == '1111' then SEE ADR; 9068 if (Rn == 15) 9069 return EmulateADR (opcode, eEncodingT2); 9070 9071 // if Rn == '1101' then SEE SUB (SP minus immediate); 9072 if (Rn == 13) 9073 return EmulateSUBSPImm (opcode, eEncodingT3); 9074 9075 if (BadReg(Rd)) 9076 return false; 9077 break; 9078 default: 9079 return false; 9080 } 9081 // Read the register value from the operand register Rn. 9082 uint32_t reg_val = ReadCoreReg(Rn, &success); 9083 if (!success) 9084 return false; 9085 9086 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9087 9088 EmulateInstruction::Context context; 9089 context.type = EmulateInstruction::eContextImmediate; 9090 context.SetNoArgs (); 9091 9092 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9093 return false; 9094 9095 return true; 9096} 9097 9098// This instruction subtracts an immediate value from a register value, and writes the result 9099// to the destination register. It can optionally update the condition flags based on the result. 9100bool 9101EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9102{ 9103#if 0 9104 // ARM pseudo code... 9105 if ConditionPassed() then 9106 EncodingSpecificOperations(); 9107 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9108 if d == 15 then 9109 ALUWritePC(result); // setflags is always FALSE here 9110 else 9111 R[d] = result; 9112 if setflags then 9113 APSR.N = result<31>; 9114 APSR.Z = IsZeroBit(result); 9115 APSR.C = carry; 9116 APSR.V = overflow; 9117#endif 9118 9119 bool success = false; 9120 9121 uint32_t Rd; // the destination register 9122 uint32_t Rn; // the first operand 9123 bool setflags; 9124 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9125 switch (encoding) { 9126 case eEncodingA1: 9127 Rd = Bits32(opcode, 15, 12); 9128 Rn = Bits32(opcode, 19, 16); 9129 setflags = BitIsSet(opcode, 20); 9130 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9131 9132 // if Rn == '1111' && S == '0' then SEE ADR; 9133 if (Rn == 15 && !setflags) 9134 return EmulateADR (opcode, eEncodingA2); 9135 9136 // if Rn == '1101' then SEE SUB (SP minus immediate); 9137 if (Rn == 13) 9138 return EmulateSUBSPImm (opcode, eEncodingA1); 9139 9140 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9141 if (Rd == 15 && setflags) 9142 return EmulateSUBSPcLrEtc (opcode, encoding); 9143 break; 9144 default: 9145 return false; 9146 } 9147 // Read the register value from the operand register Rn. 9148 uint32_t reg_val = ReadCoreReg(Rn, &success); 9149 if (!success) 9150 return false; 9151 9152 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9153 9154 EmulateInstruction::Context context; 9155 context.type = EmulateInstruction::eContextImmediate; 9156 context.SetNoArgs (); 9157 9158 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9159 return false; 9160 9161 return true; 9162} 9163 9164// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9165// immediate value. It updates the condition flags based on the result, and discards the result. 9166bool 9167EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9168{ 9169#if 0 9170 // ARM pseudo code... 9171 if ConditionPassed() then 9172 EncodingSpecificOperations(); 9173 result = R[n] EOR imm32; 9174 APSR.N = result<31>; 9175 APSR.Z = IsZeroBit(result); 9176 APSR.C = carry; 9177 // APSR.V unchanged 9178#endif 9179 9180 bool success = false; 9181 9182 if (ConditionPassed(opcode)) 9183 { 9184 uint32_t Rn; 9185 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9186 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9187 switch (encoding) 9188 { 9189 case eEncodingT1: 9190 Rn = Bits32(opcode, 19, 16); 9191 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9192 if (BadReg(Rn)) 9193 return false; 9194 break; 9195 case eEncodingA1: 9196 Rn = Bits32(opcode, 19, 16); 9197 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9198 break; 9199 default: 9200 return false; 9201 } 9202 9203 // Read the first operand. 9204 uint32_t val1 = ReadCoreReg(Rn, &success); 9205 if (!success) 9206 return false; 9207 9208 uint32_t result = val1 ^ imm32; 9209 9210 EmulateInstruction::Context context; 9211 context.type = EmulateInstruction::eContextImmediate; 9212 context.SetNoArgs (); 9213 9214 if (!WriteFlags(context, result, carry)) 9215 return false; 9216 } 9217 return true; 9218} 9219 9220// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9221// optionally-shifted register value. It updates the condition flags based on the result, and discards 9222// the result. 9223bool 9224EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9225{ 9226#if 0 9227 // ARM pseudo code... 9228 if ConditionPassed() then 9229 EncodingSpecificOperations(); 9230 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9231 result = R[n] EOR shifted; 9232 APSR.N = result<31>; 9233 APSR.Z = IsZeroBit(result); 9234 APSR.C = carry; 9235 // APSR.V unchanged 9236#endif 9237 9238 bool success = false; 9239 9240 if (ConditionPassed(opcode)) 9241 { 9242 uint32_t Rn, Rm; 9243 ARM_ShifterType shift_t; 9244 uint32_t shift_n; // the shift applied to the value read from Rm 9245 uint32_t carry; 9246 switch (encoding) 9247 { 9248 case eEncodingT1: 9249 Rn = Bits32(opcode, 19, 16); 9250 Rm = Bits32(opcode, 3, 0); 9251 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9252 if (BadReg(Rn) || BadReg(Rm)) 9253 return false; 9254 break; 9255 case eEncodingA1: 9256 Rn = Bits32(opcode, 19, 16); 9257 Rm = Bits32(opcode, 3, 0); 9258 shift_n = DecodeImmShiftARM(opcode, shift_t); 9259 break; 9260 default: 9261 return false; 9262 } 9263 9264 // Read the first operand. 9265 uint32_t val1 = ReadCoreReg(Rn, &success); 9266 if (!success) 9267 return false; 9268 9269 // Read the second operand. 9270 uint32_t val2 = ReadCoreReg(Rm, &success); 9271 if (!success) 9272 return false; 9273 9274 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9275 if (!success) 9276 return false; 9277 uint32_t result = val1 ^ shifted; 9278 9279 EmulateInstruction::Context context; 9280 context.type = EmulateInstruction::eContextImmediate; 9281 context.SetNoArgs (); 9282 9283 if (!WriteFlags(context, result, carry)) 9284 return false; 9285 } 9286 return true; 9287} 9288 9289// Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9290// It updates the condition flags based on the result, and discards the result. 9291bool 9292EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9293{ 9294#if 0 9295 // ARM pseudo code... 9296 if ConditionPassed() then 9297 EncodingSpecificOperations(); 9298 result = R[n] AND imm32; 9299 APSR.N = result<31>; 9300 APSR.Z = IsZeroBit(result); 9301 APSR.C = carry; 9302 // APSR.V unchanged 9303#endif 9304 9305 bool success = false; 9306 9307 if (ConditionPassed(opcode)) 9308 { 9309 uint32_t Rn; 9310 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9311 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9312 switch (encoding) 9313 { 9314 case eEncodingT1: 9315 Rn = Bits32(opcode, 19, 16); 9316 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9317 if (BadReg(Rn)) 9318 return false; 9319 break; 9320 case eEncodingA1: 9321 Rn = Bits32(opcode, 19, 16); 9322 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9323 break; 9324 default: 9325 return false; 9326 } 9327 9328 // Read the first operand. 9329 uint32_t val1 = ReadCoreReg(Rn, &success); 9330 if (!success) 9331 return false; 9332 9333 uint32_t result = val1 & imm32; 9334 9335 EmulateInstruction::Context context; 9336 context.type = EmulateInstruction::eContextImmediate; 9337 context.SetNoArgs (); 9338 9339 if (!WriteFlags(context, result, carry)) 9340 return false; 9341 } 9342 return true; 9343} 9344 9345// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9346// It updates the condition flags based on the result, and discards the result. 9347bool 9348EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9349{ 9350#if 0 9351 // ARM pseudo code... 9352 if ConditionPassed() then 9353 EncodingSpecificOperations(); 9354 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9355 result = R[n] AND shifted; 9356 APSR.N = result<31>; 9357 APSR.Z = IsZeroBit(result); 9358 APSR.C = carry; 9359 // APSR.V unchanged 9360#endif 9361 9362 bool success = false; 9363 9364 if (ConditionPassed(opcode)) 9365 { 9366 uint32_t Rn, Rm; 9367 ARM_ShifterType shift_t; 9368 uint32_t shift_n; // the shift applied to the value read from Rm 9369 uint32_t carry; 9370 switch (encoding) 9371 { 9372 case eEncodingT1: 9373 Rn = Bits32(opcode, 2, 0); 9374 Rm = Bits32(opcode, 5, 3); 9375 shift_t = SRType_LSL; 9376 shift_n = 0; 9377 break; 9378 case eEncodingT2: 9379 Rn = Bits32(opcode, 19, 16); 9380 Rm = Bits32(opcode, 3, 0); 9381 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9382 if (BadReg(Rn) || BadReg(Rm)) 9383 return false; 9384 break; 9385 case eEncodingA1: 9386 Rn = Bits32(opcode, 19, 16); 9387 Rm = Bits32(opcode, 3, 0); 9388 shift_n = DecodeImmShiftARM(opcode, shift_t); 9389 break; 9390 default: 9391 return false; 9392 } 9393 9394 // Read the first operand. 9395 uint32_t val1 = ReadCoreReg(Rn, &success); 9396 if (!success) 9397 return false; 9398 9399 // Read the second operand. 9400 uint32_t val2 = ReadCoreReg(Rm, &success); 9401 if (!success) 9402 return false; 9403 9404 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9405 if (!success) 9406 return false; 9407 uint32_t result = val1 & shifted; 9408 9409 EmulateInstruction::Context context; 9410 context.type = EmulateInstruction::eContextImmediate; 9411 context.SetNoArgs (); 9412 9413 if (!WriteFlags(context, result, carry)) 9414 return false; 9415 } 9416 return true; 9417} 9418 9419// A8.6.216 SUB (SP minus register) 9420bool 9421EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9422{ 9423#if 0 9424 if ConditionPassed() then 9425 EncodingSpecificOperations(); 9426 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9427 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9428 if d == 15 then // Can only occur for ARM encoding 9429 ALUWritePC(result); // setflags is always FALSE here 9430 else 9431 R[d] = result; 9432 if setflags then 9433 APSR.N = result<31>; 9434 APSR.Z = IsZeroBit(result); 9435 APSR.C = carry; 9436 APSR.V = overflow; 9437#endif 9438 9439 bool success = false; 9440 9441 if (ConditionPassed(opcode)) 9442 { 9443 uint32_t d; 9444 uint32_t m; 9445 bool setflags; 9446 ARM_ShifterType shift_t; 9447 uint32_t shift_n; 9448 9449 switch (encoding) 9450 { 9451 case eEncodingT1: 9452 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9453 d = Bits32 (opcode, 11, 8); 9454 m = Bits32 (opcode, 3, 0); 9455 setflags = BitIsSet (opcode, 20); 9456 9457 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9458 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9459 9460 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9461 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9462 return false; 9463 9464 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9465 if ((d == 15) || BadReg (m)) 9466 return false; 9467 break; 9468 9469 case eEncodingA1: 9470 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9471 d = Bits32 (opcode, 15, 12); 9472 m = Bits32 (opcode, 3, 0); 9473 setflags = BitIsSet (opcode, 20); 9474 9475 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9476 if (d == 15 && setflags) 9477 EmulateSUBSPcLrEtc (opcode, encoding); 9478 9479 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9480 shift_n = DecodeImmShiftARM (opcode, shift_t); 9481 break; 9482 9483 default: 9484 return false; 9485 } 9486 9487 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9488 uint32_t Rm = ReadCoreReg (m, &success); 9489 if (!success) 9490 return false; 9491 9492 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9493 if (!success) 9494 return false; 9495 9496 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9497 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9498 if (!success) 9499 return false; 9500 9501 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9502 9503 EmulateInstruction::Context context; 9504 context.type = eContextArithmetic; 9505 RegisterInfo sp_reg; 9506 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9507 RegisterInfo dwarf_reg; 9508 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9509 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9510 9511 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9512 return false; 9513 } 9514 return true; 9515} 9516 9517 9518// A8.6.7 ADD (register-shifted register) 9519bool 9520EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9521{ 9522#if 0 9523 if ConditionPassed() then 9524 EncodingSpecificOperations(); 9525 shift_n = UInt(R[s]<7:0>); 9526 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9527 (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9528 R[d] = result; 9529 if setflags then 9530 APSR.N = result<31>; 9531 APSR.Z = IsZeroBit(result); 9532 APSR.C = carry; 9533 APSR.V = overflow; 9534#endif 9535 9536 bool success = false; 9537 9538 if (ConditionPassed(opcode)) 9539 { 9540 uint32_t d; 9541 uint32_t n; 9542 uint32_t m; 9543 uint32_t s; 9544 bool setflags; 9545 ARM_ShifterType shift_t; 9546 9547 switch (encoding) 9548 { 9549 case eEncodingA1: 9550 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9551 d = Bits32 (opcode, 15, 12); 9552 n = Bits32 (opcode, 19, 16); 9553 m = Bits32 (opcode, 3, 0); 9554 s = Bits32 (opcode, 11, 8); 9555 9556 // setflags = (S == �1�); shift_t = DecodeRegShift(type); 9557 setflags = BitIsSet (opcode, 20); 9558 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9559 9560 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9561 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9562 return false; 9563 break; 9564 9565 default: 9566 return false; 9567 } 9568 9569 // shift_n = UInt(R[s]<7:0>); 9570 uint32_t Rs = ReadCoreReg (s, &success); 9571 if (!success) 9572 return false; 9573 9574 uint32_t shift_n = Bits32 (Rs, 7, 0); 9575 9576 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9577 uint32_t Rm = ReadCoreReg (m, &success); 9578 if (!success) 9579 return false; 9580 9581 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9582 if (!success) 9583 return false; 9584 9585 // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9586 uint32_t Rn = ReadCoreReg (n, &success); 9587 if (!success) 9588 return false; 9589 9590 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9591 9592 // R[d] = result; 9593 EmulateInstruction::Context context; 9594 context.type = eContextArithmetic; 9595 RegisterInfo reg_n; 9596 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9597 RegisterInfo reg_m; 9598 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9599 9600 context.SetRegisterRegisterOperands (reg_n, reg_m); 9601 9602 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9603 return false; 9604 9605 // if setflags then 9606 // APSR.N = result<31>; 9607 // APSR.Z = IsZeroBit(result); 9608 // APSR.C = carry; 9609 // APSR.V = overflow; 9610 if (setflags) 9611 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9612 } 9613 return true; 9614} 9615 9616// A8.6.213 SUB (register) 9617bool 9618EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9619{ 9620#if 0 9621 if ConditionPassed() then 9622 EncodingSpecificOperations(); 9623 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9624 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9625 if d == 15 then // Can only occur for ARM encoding 9626 ALUWritePC(result); // setflags is always FALSE here 9627 else 9628 R[d] = result; 9629 if setflags then 9630 APSR.N = result<31>; 9631 APSR.Z = IsZeroBit(result); 9632 APSR.C = carry; 9633 APSR.V = overflow; 9634#endif 9635 9636 bool success = false; 9637 9638 if (ConditionPassed(opcode)) 9639 { 9640 uint32_t d; 9641 uint32_t n; 9642 uint32_t m; 9643 bool setflags; 9644 ARM_ShifterType shift_t; 9645 uint32_t shift_n; 9646 9647 switch (encoding) 9648 { 9649 case eEncodingT1: 9650 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9651 d = Bits32 (opcode, 2, 0); 9652 n = Bits32 (opcode, 5, 3); 9653 m = Bits32 (opcode, 8, 6); 9654 setflags = !InITBlock(); 9655 9656 // (shift_t, shift_n) = (SRType_LSL, 0); 9657 shift_t = SRType_LSL; 9658 shift_n = 0; 9659 9660 break; 9661 9662 case eEncodingT2: 9663 // if Rd == �1111� && S == �1� then SEE CMP (register); 9664 // if Rn == �1101� then SEE SUB (SP minus register); 9665 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9666 d = Bits32 (opcode, 11, 8); 9667 n = Bits32 (opcode, 19, 16); 9668 m = Bits32 (opcode, 3, 0); 9669 setflags = BitIsSet (opcode, 20); 9670 9671 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9672 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9673 9674 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9675 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9676 return false; 9677 9678 break; 9679 9680 case eEncodingA1: 9681 // if Rn == �1101� then SEE SUB (SP minus register); 9682 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9683 d = Bits32 (opcode, 15, 12); 9684 n = Bits32 (opcode, 19, 16); 9685 m = Bits32 (opcode, 3, 0); 9686 setflags = BitIsSet (opcode, 20); 9687 9688 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9689 if ((d == 15) && setflags) 9690 EmulateSUBSPcLrEtc (opcode, encoding); 9691 9692 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9693 shift_n = DecodeImmShiftARM (opcode, shift_t); 9694 9695 break; 9696 9697 default: 9698 return false; 9699 } 9700 9701 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9702 uint32_t Rm = ReadCoreReg (m, &success); 9703 if (!success) 9704 return false; 9705 9706 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9707 if (!success) 9708 return false; 9709 9710 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9711 uint32_t Rn = ReadCoreReg (n, &success); 9712 if (!success) 9713 return false; 9714 9715 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9716 9717 // if d == 15 then // Can only occur for ARM encoding 9718 // ALUWritePC(result); // setflags is always FALSE here 9719 // else 9720 // R[d] = result; 9721 // if setflags then 9722 // APSR.N = result<31>; 9723 // APSR.Z = IsZeroBit(result); 9724 // APSR.C = carry; 9725 // APSR.V = overflow; 9726 9727 EmulateInstruction::Context context; 9728 context.type = eContextArithmetic; 9729 RegisterInfo reg_n; 9730 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9731 RegisterInfo reg_m; 9732 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9733 context.SetRegisterRegisterOperands (reg_n, reg_m); 9734 9735 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9736 return false; 9737 } 9738 return true; 9739} 9740 9741// A8.6.202 STREX 9742// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9743// word from a register to memory if the executing processor has exclusive access to the memory addressed. 9744bool 9745EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9746{ 9747#if 0 9748 if ConditionPassed() then 9749 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9750 address = R[n] + imm32; 9751 if ExclusiveMonitorsPass(address,4) then 9752 MemA[address,4] = R[t]; 9753 R[d] = 0; 9754 else 9755 R[d] = 1; 9756#endif 9757 9758 bool success = false; 9759 9760 if (ConditionPassed(opcode)) 9761 { 9762 uint32_t d; 9763 uint32_t t; 9764 uint32_t n; 9765 uint32_t imm32; 9766 const uint32_t addr_byte_size = GetAddressByteSize(); 9767 9768 switch (encoding) 9769 { 9770 case eEncodingT1: 9771 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 9772 d = Bits32 (opcode, 11, 8); 9773 t = Bits32 (opcode, 15, 12); 9774 n = Bits32 (opcode, 19, 16); 9775 imm32 = Bits32 (opcode, 7, 0) << 2; 9776 9777 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9778 if (BadReg (d) || BadReg (t) || (n == 15)) 9779 return false; 9780 9781 // if d == n || d == t then UNPREDICTABLE; 9782 if ((d == n) || (d == t)) 9783 return false; 9784 9785 break; 9786 9787 case eEncodingA1: 9788 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9789 d = Bits32 (opcode, 15, 12); 9790 t = Bits32 (opcode, 3, 0); 9791 n = Bits32 (opcode, 19, 16); 9792 imm32 = 0; 9793 9794 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9795 if ((d == 15) || (t == 15) || (n == 15)) 9796 return false; 9797 9798 // if d == n || d == t then UNPREDICTABLE; 9799 if ((d == n) || (d == t)) 9800 return false; 9801 9802 break; 9803 9804 default: 9805 return false; 9806 } 9807 9808 // address = R[n] + imm32; 9809 uint32_t Rn = ReadCoreReg (n, &success); 9810 if (!success) 9811 return false; 9812 9813 addr_t address = Rn + imm32; 9814 9815 RegisterInfo base_reg; 9816 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9817 RegisterInfo data_reg; 9818 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9819 EmulateInstruction::Context context; 9820 context.type = eContextRegisterStore; 9821 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9822 9823 // if ExclusiveMonitorsPass(address,4) then 9824 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9825 // always return true. 9826 if (true) 9827 { 9828 // MemA[address,4] = R[t]; 9829 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9830 if (!success) 9831 return false; 9832 9833 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9834 return false; 9835 9836 // R[d] = 0; 9837 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9838 return false; 9839 } 9840 else 9841 { 9842 // R[d] = 1; 9843 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9844 return false; 9845 } 9846 } 9847 return true; 9848} 9849 9850// A8.6.197 STRB (immediate, ARM) 9851bool 9852EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9853{ 9854#if 0 9855 if ConditionPassed() then 9856 EncodingSpecificOperations(); 9857 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9858 address = if index then offset_addr else R[n]; 9859 MemU[address,1] = R[t]<7:0>; 9860 if wback then R[n] = offset_addr; 9861#endif 9862 9863 bool success = false; 9864 9865 if (ConditionPassed(opcode)) 9866 { 9867 uint32_t t; 9868 uint32_t n; 9869 uint32_t imm32; 9870 bool index; 9871 bool add; 9872 bool wback; 9873 9874 switch (encoding) 9875 { 9876 case eEncodingA1: 9877 // if P == �0� && W == �1� then SEE STRBT; 9878 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9879 t = Bits32 (opcode, 15, 12); 9880 n = Bits32 (opcode, 19, 16); 9881 imm32 = Bits32 (opcode, 11, 0); 9882 9883 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9884 index = BitIsSet (opcode, 24); 9885 add = BitIsSet (opcode, 23); 9886 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9887 9888 // if t == 15 then UNPREDICTABLE; 9889 if (t == 15) 9890 return false; 9891 9892 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9893 if (wback && ((n == 15) || (n == t))) 9894 return false; 9895 9896 break; 9897 9898 default: 9899 return false; 9900 } 9901 9902 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9903 uint32_t Rn = ReadCoreReg (n, &success); 9904 if (!success) 9905 return false; 9906 9907 addr_t offset_addr; 9908 if (add) 9909 offset_addr = Rn + imm32; 9910 else 9911 offset_addr = Rn - imm32; 9912 9913 // address = if index then offset_addr else R[n]; 9914 addr_t address; 9915 if (index) 9916 address = offset_addr; 9917 else 9918 address = Rn; 9919 9920 // MemU[address,1] = R[t]<7:0>; 9921 uint32_t Rt = ReadCoreReg (t, &success); 9922 if (!success) 9923 return false; 9924 9925 RegisterInfo base_reg; 9926 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9927 RegisterInfo data_reg; 9928 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9929 EmulateInstruction::Context context; 9930 context.type = eContextRegisterStore; 9931 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9932 9933 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 9934 return false; 9935 9936 // if wback then R[n] = offset_addr; 9937 if (wback) 9938 { 9939 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9940 return false; 9941 } 9942 } 9943 return true; 9944} 9945 9946// A8.6.194 STR (immediate, ARM) 9947bool 9948EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9949{ 9950#if 0 9951 if ConditionPassed() then 9952 EncodingSpecificOperations(); 9953 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9954 address = if index then offset_addr else R[n]; 9955 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9956 if wback then R[n] = offset_addr; 9957#endif 9958 9959 bool success = false; 9960 9961 if (ConditionPassed(opcode)) 9962 { 9963 uint32_t t; 9964 uint32_t n; 9965 uint32_t imm32; 9966 bool index; 9967 bool add; 9968 bool wback; 9969 9970 const uint32_t addr_byte_size = GetAddressByteSize(); 9971 9972 switch (encoding) 9973 { 9974 case eEncodingA1: 9975 // if P == �0� && W == �1� then SEE STRT; 9976 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH; 9977 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9978 t = Bits32 (opcode, 15, 12); 9979 n = Bits32 (opcode, 19, 16); 9980 imm32 = Bits32 (opcode, 11, 0); 9981 9982 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9983 index = BitIsSet (opcode, 24); 9984 add = BitIsSet (opcode, 23); 9985 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9986 9987 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9988 if (wback && ((n == 15) || (n == t))) 9989 return false; 9990 9991 break; 9992 9993 default: 9994 return false; 9995 } 9996 9997 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9998 uint32_t Rn = ReadCoreReg (n, &success); 9999 if (!success) 10000 return false; 10001 10002 addr_t offset_addr; 10003 if (add) 10004 offset_addr = Rn + imm32; 10005 else 10006 offset_addr = Rn - imm32; 10007 10008 // address = if index then offset_addr else R[n]; 10009 addr_t address; 10010 if (index) 10011 address = offset_addr; 10012 else 10013 address = Rn; 10014 10015 RegisterInfo base_reg; 10016 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10017 RegisterInfo data_reg; 10018 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10019 EmulateInstruction::Context context; 10020 context.type = eContextRegisterStore; 10021 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10022 10023 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10024 uint32_t Rt = ReadCoreReg (t, &success); 10025 if (!success) 10026 return false; 10027 10028 if (t == 15) 10029 { 10030 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10031 if (!success) 10032 return false; 10033 10034 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10035 return false; 10036 } 10037 else 10038 { 10039 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10040 return false; 10041 } 10042 10043 // if wback then R[n] = offset_addr; 10044 if (wback) 10045 { 10046 context.type = eContextAdjustBaseRegister; 10047 context.SetImmediate (offset_addr); 10048 10049 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10050 return false; 10051 } 10052 } 10053 return true; 10054} 10055 10056// A8.6.66 LDRD (immediate) 10057// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10058// words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10059bool 10060EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10061{ 10062#if 0 10063 if ConditionPassed() then 10064 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10065 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10066 address = if index then offset_addr else R[n]; 10067 R[t] = MemA[address,4]; 10068 R[t2] = MemA[address+4,4]; 10069 if wback then R[n] = offset_addr; 10070#endif 10071 10072 bool success = false; 10073 10074 if (ConditionPassed(opcode)) 10075 { 10076 uint32_t t; 10077 uint32_t t2; 10078 uint32_t n; 10079 uint32_t imm32; 10080 bool index; 10081 bool add; 10082 bool wback; 10083 10084 switch (encoding) 10085 { 10086 case eEncodingT1: 10087 //if P == �0� && W == �0� then SEE �Related encodings�; 10088 //if Rn == �1111� then SEE LDRD (literal); 10089 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10090 t = Bits32 (opcode, 15, 12); 10091 t2 = Bits32 (opcode, 11, 8); 10092 n = Bits32 (opcode, 19, 16); 10093 imm32 = Bits32 (opcode, 7, 0) << 2; 10094 10095 //index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10096 index = BitIsSet (opcode, 24); 10097 add = BitIsSet (opcode, 23); 10098 wback = BitIsSet (opcode, 21); 10099 10100 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10101 if (wback && ((n == t) || (n == t2))) 10102 return false; 10103 10104 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10105 if (BadReg (t) || BadReg (t2) || (t == t2)) 10106 return false; 10107 10108 break; 10109 10110 case eEncodingA1: 10111 //if Rn == �1111� then SEE LDRD (literal); 10112 //if Rt<0> == �1� then UNPREDICTABLE; 10113 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10114 t = Bits32 (opcode, 15, 12); 10115 if (BitIsSet (t, 0)) 10116 return false; 10117 t2 = t + 1; 10118 n = Bits32 (opcode, 19, 16); 10119 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10120 10121 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10122 index = BitIsSet (opcode, 24); 10123 add = BitIsSet (opcode, 23); 10124 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10125 10126 //if P == �0� && W == �1� then UNPREDICTABLE; 10127 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10128 return false; 10129 10130 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10131 if (wback && ((n == t) || (n == t2))) 10132 return false; 10133 10134 //if t2 == 15 then UNPREDICTABLE; 10135 if (t2 == 15) 10136 return false; 10137 10138 break; 10139 10140 default: 10141 return false; 10142 } 10143 10144 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10145 uint32_t Rn = ReadCoreReg (n, &success); 10146 if (!success) 10147 return false; 10148 10149 addr_t offset_addr; 10150 if (add) 10151 offset_addr = Rn + imm32; 10152 else 10153 offset_addr = Rn - imm32; 10154 10155 //address = if index then offset_addr else R[n]; 10156 addr_t address; 10157 if (index) 10158 address = offset_addr; 10159 else 10160 address = Rn; 10161 10162 //R[t] = MemA[address,4]; 10163 RegisterInfo base_reg; 10164 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10165 10166 EmulateInstruction::Context context; 10167 context.type = eContextRegisterLoad; 10168 context.SetRegisterPlusOffset (base_reg, address - Rn); 10169 10170 const uint32_t addr_byte_size = GetAddressByteSize(); 10171 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10172 if (!success) 10173 return false; 10174 10175 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10176 return false; 10177 10178 //R[t2] = MemA[address+4,4]; 10179 10180 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10181 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10182 if (!success) 10183 return false; 10184 10185 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10186 return false; 10187 10188 //if wback then R[n] = offset_addr; 10189 if (wback) 10190 { 10191 context.type = eContextAdjustBaseRegister; 10192 context.SetAddress (offset_addr); 10193 10194 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10195 return false; 10196 } 10197 } 10198 return true; 10199} 10200 10201// A8.6.68 LDRD (register) 10202// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10203// words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10204bool 10205EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10206{ 10207#if 0 10208 if ConditionPassed() then 10209 EncodingSpecificOperations(); 10210 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10211 address = if index then offset_addr else R[n]; 10212 R[t] = MemA[address,4]; 10213 R[t2] = MemA[address+4,4]; 10214 if wback then R[n] = offset_addr; 10215#endif 10216 10217 bool success = false; 10218 10219 if (ConditionPassed(opcode)) 10220 { 10221 uint32_t t; 10222 uint32_t t2; 10223 uint32_t n; 10224 uint32_t m; 10225 bool index; 10226 bool add; 10227 bool wback; 10228 10229 switch (encoding) 10230 { 10231 case eEncodingA1: 10232 // if Rt<0> == �1� then UNPREDICTABLE; 10233 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10234 t = Bits32 (opcode, 15, 12); 10235 if (BitIsSet (t, 0)) 10236 return false; 10237 t2 = t + 1; 10238 n = Bits32 (opcode, 19, 16); 10239 m = Bits32 (opcode, 3, 0); 10240 10241 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10242 index = BitIsSet (opcode, 24); 10243 add = BitIsSet (opcode, 23); 10244 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10245 10246 // if P == �0� && W == �1� then UNPREDICTABLE; 10247 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10248 return false; 10249 10250 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10251 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10252 return false; 10253 10254 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10255 if (wback && ((n == 15) || (n == t) || (n == t2))) 10256 return false; 10257 10258 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10259 if ((ArchVersion() < 6) && wback && (m == n)) 10260 return false; 10261 break; 10262 10263 default: 10264 return false; 10265 } 10266 10267 uint32_t Rn = ReadCoreReg (n, &success); 10268 if (!success) 10269 return false; 10270 RegisterInfo base_reg; 10271 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10272 10273 uint32_t Rm = ReadCoreReg (m, &success); 10274 if (!success) 10275 return false; 10276 RegisterInfo offset_reg; 10277 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10278 10279 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10280 addr_t offset_addr; 10281 if (add) 10282 offset_addr = Rn + Rm; 10283 else 10284 offset_addr = Rn - Rm; 10285 10286 // address = if index then offset_addr else R[n]; 10287 addr_t address; 10288 if (index) 10289 address = offset_addr; 10290 else 10291 address = Rn; 10292 10293 EmulateInstruction::Context context; 10294 context.type = eContextRegisterLoad; 10295 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10296 10297 // R[t] = MemA[address,4]; 10298 const uint32_t addr_byte_size = GetAddressByteSize(); 10299 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10300 if (!success) 10301 return false; 10302 10303 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10304 return false; 10305 10306 // R[t2] = MemA[address+4,4]; 10307 10308 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10309 if (!success) 10310 return false; 10311 10312 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10313 return false; 10314 10315 // if wback then R[n] = offset_addr; 10316 if (wback) 10317 { 10318 context.type = eContextAdjustBaseRegister; 10319 context.SetAddress (offset_addr); 10320 10321 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10322 return false; 10323 } 10324 } 10325 return true; 10326} 10327 10328// A8.6.200 STRD (immediate) 10329// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10330// stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10331bool 10332EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10333{ 10334#if 0 10335 if ConditionPassed() then 10336 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10337 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10338 address = if index then offset_addr else R[n]; 10339 MemA[address,4] = R[t]; 10340 MemA[address+4,4] = R[t2]; 10341 if wback then R[n] = offset_addr; 10342#endif 10343 10344 bool success = false; 10345 10346 if (ConditionPassed(opcode)) 10347 { 10348 uint32_t t; 10349 uint32_t t2; 10350 uint32_t n; 10351 uint32_t imm32; 10352 bool index; 10353 bool add; 10354 bool wback; 10355 10356 switch (encoding) 10357 { 10358 case eEncodingT1: 10359 // if P == �0� && W == �0� then SEE �Related encodings�; 10360 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10361 t = Bits32 (opcode, 15, 12); 10362 t2 = Bits32 (opcode, 11, 8); 10363 n = Bits32 (opcode, 19, 16); 10364 imm32 = Bits32 (opcode, 7, 0) << 2; 10365 10366 // index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10367 index = BitIsSet (opcode, 24); 10368 add = BitIsSet (opcode, 23); 10369 wback = BitIsSet (opcode, 21); 10370 10371 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10372 if (wback && ((n == t) || (n == t2))) 10373 return false; 10374 10375 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10376 if ((n == 15) || BadReg (t) || BadReg (t2)) 10377 return false; 10378 10379 break; 10380 10381 case eEncodingA1: 10382 // if Rt<0> == �1� then UNPREDICTABLE; 10383 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10384 t = Bits32 (opcode, 15, 12); 10385 if (BitIsSet (t, 0)) 10386 return false; 10387 10388 t2 = t + 1; 10389 n = Bits32 (opcode, 19, 16); 10390 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10391 10392 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10393 index = BitIsSet (opcode, 24); 10394 add = BitIsSet (opcode, 23); 10395 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10396 10397 // if P == �0� && W == �1� then UNPREDICTABLE; 10398 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10399 return false; 10400 10401 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10402 if (wback && ((n == 15) || (n == t) || (n == t2))) 10403 return false; 10404 10405 // if t2 == 15 then UNPREDICTABLE; 10406 if (t2 == 15) 10407 return false; 10408 10409 break; 10410 10411 default: 10412 return false; 10413 } 10414 10415 RegisterInfo base_reg; 10416 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10417 10418 uint32_t Rn = ReadCoreReg (n, &success); 10419 if (!success) 10420 return false; 10421 10422 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10423 addr_t offset_addr; 10424 if (add) 10425 offset_addr = Rn + imm32; 10426 else 10427 offset_addr = Rn - imm32; 10428 10429 //address = if index then offset_addr else R[n]; 10430 addr_t address; 10431 if (index) 10432 address = offset_addr; 10433 else 10434 address = Rn; 10435 10436 //MemA[address,4] = R[t]; 10437 RegisterInfo data_reg; 10438 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10439 10440 uint32_t data = ReadCoreReg (t, &success); 10441 if (!success) 10442 return false; 10443 10444 EmulateInstruction::Context context; 10445 context.type = eContextRegisterStore; 10446 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10447 10448 const uint32_t addr_byte_size = GetAddressByteSize(); 10449 10450 if (!MemAWrite (context, address, data, addr_byte_size)) 10451 return false; 10452 10453 //MemA[address+4,4] = R[t2]; 10454 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10455 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10456 10457 data = ReadCoreReg (t2, &success); 10458 if (!success) 10459 return false; 10460 10461 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10462 return false; 10463 10464 //if wback then R[n] = offset_addr; 10465 if (wback) 10466 { 10467 context.type = eContextAdjustBaseRegister; 10468 context.SetAddress (offset_addr); 10469 10470 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10471 return false; 10472 } 10473 } 10474 return true; 10475} 10476 10477 10478// A8.6.201 STRD (register) 10479bool 10480EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10481{ 10482#if 0 10483 if ConditionPassed() then 10484 EncodingSpecificOperations(); 10485 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10486 address = if index then offset_addr else R[n]; 10487 MemA[address,4] = R[t]; 10488 MemA[address+4,4] = R[t2]; 10489 if wback then R[n] = offset_addr; 10490#endif 10491 10492 bool success = false; 10493 10494 if (ConditionPassed(opcode)) 10495 { 10496 uint32_t t; 10497 uint32_t t2; 10498 uint32_t n; 10499 uint32_t m; 10500 bool index; 10501 bool add; 10502 bool wback; 10503 10504 switch (encoding) 10505 { 10506 case eEncodingA1: 10507 // if Rt<0> == �1� then UNPREDICTABLE; 10508 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10509 t = Bits32 (opcode, 15, 12); 10510 if (BitIsSet (t, 0)) 10511 return false; 10512 10513 t2 = t+1; 10514 n = Bits32 (opcode, 19, 16); 10515 m = Bits32 (opcode, 3, 0); 10516 10517 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10518 index = BitIsSet (opcode, 24); 10519 add = BitIsSet (opcode, 23); 10520 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10521 10522 // if P == �0� && W == �1� then UNPREDICTABLE; 10523 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10524 return false; 10525 10526 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10527 if ((t2 == 15) || (m == 15)) 10528 return false; 10529 10530 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10531 if (wback && ((n == 15) || (n == t) || (n == t2))) 10532 return false; 10533 10534 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10535 if ((ArchVersion() < 6) && wback && (m == n)) 10536 return false; 10537 10538 break; 10539 10540 default: 10541 return false; 10542 } 10543 10544 RegisterInfo base_reg; 10545 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10546 RegisterInfo offset_reg; 10547 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10548 RegisterInfo data_reg; 10549 10550 uint32_t Rn = ReadCoreReg (n, &success); 10551 if (!success) 10552 return false; 10553 10554 uint32_t Rm = ReadCoreReg (m, &success); 10555 if (!success) 10556 return false; 10557 10558 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10559 addr_t offset_addr; 10560 if (add) 10561 offset_addr = Rn + Rm; 10562 else 10563 offset_addr = Rn - Rm; 10564 10565 // address = if index then offset_addr else R[n]; 10566 addr_t address; 10567 if (index) 10568 address = offset_addr; 10569 else 10570 address = Rn; 10571 // MemA[address,4] = R[t]; 10572 uint32_t Rt = ReadCoreReg (t, &success); 10573 if (!success) 10574 return false; 10575 10576 EmulateInstruction::Context context; 10577 context.type = eContextRegisterStore; 10578 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10579 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10580 10581 const uint32_t addr_byte_size = GetAddressByteSize(); 10582 10583 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10584 return false; 10585 10586 // MemA[address+4,4] = R[t2]; 10587 uint32_t Rt2 = ReadCoreReg (t2, &success); 10588 if (!success) 10589 return false; 10590 10591 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10592 10593 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10594 10595 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10596 return false; 10597 10598 // if wback then R[n] = offset_addr; 10599 if (wback) 10600 { 10601 context.type = eContextAdjustBaseRegister; 10602 context.SetAddress (offset_addr); 10603 10604 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10605 return false; 10606 10607 } 10608 } 10609 return true; 10610} 10611 10612// A8.6.319 VLDM 10613// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10614// an ARM core register. 10615bool 10616EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10617{ 10618#if 0 10619 if ConditionPassed() then 10620 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10621 address = if add then R[n] else R[n]-imm32; 10622 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10623 for r = 0 to regs-1 10624 if single_regs then 10625 S[d+r] = MemA[address,4]; address = address+4; 10626 else 10627 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10628 // Combine the word-aligned words in the correct order for current endianness. 10629 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10630#endif 10631 10632 bool success = false; 10633 10634 if (ConditionPassed(opcode)) 10635 { 10636 bool single_regs; 10637 bool add; 10638 bool wback; 10639 uint32_t d; 10640 uint32_t n; 10641 uint32_t imm32; 10642 uint32_t regs; 10643 10644 switch (encoding) 10645 { 10646 case eEncodingT1: 10647 case eEncodingA1: 10648 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10649 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10650 // if P == �1� && W == �0� then SEE VLDR; 10651 // if P == U && W == �1� then UNDEFINED; 10652 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10653 return false; 10654 10655 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10656 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10657 single_regs = false; 10658 add = BitIsSet (opcode, 23); 10659 wback = BitIsSet (opcode, 21); 10660 10661 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10662 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10663 n = Bits32 (opcode, 19, 16); 10664 imm32 = Bits32 (opcode, 7, 0) << 2; 10665 10666 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�. 10667 regs = Bits32 (opcode, 7, 0) / 2; 10668 10669 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10670 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10671 return false; 10672 10673 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10674 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10675 return false; 10676 10677 break; 10678 10679 case eEncodingT2: 10680 case eEncodingA2: 10681 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10682 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10683 // if P == �1� && W == �0� then SEE VLDR; 10684 // if P == U && W == �1� then UNDEFINED; 10685 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10686 return false; 10687 10688 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10689 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10690 single_regs = true; 10691 add = BitIsSet (opcode, 23); 10692 wback = BitIsSet (opcode, 21); 10693 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10694 n = Bits32 (opcode, 19, 16); 10695 10696 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10697 imm32 = Bits32 (opcode, 7, 0) << 2; 10698 regs = Bits32 (opcode, 7, 0); 10699 10700 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10701 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10702 return false; 10703 10704 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10705 if ((regs == 0) || ((d + regs) > 32)) 10706 return false; 10707 break; 10708 10709 default: 10710 return false; 10711 } 10712 10713 RegisterInfo base_reg; 10714 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10715 10716 uint32_t Rn = ReadCoreReg (n, &success); 10717 if (!success) 10718 return false; 10719 10720 // address = if add then R[n] else R[n]-imm32; 10721 addr_t address; 10722 if (add) 10723 address = Rn; 10724 else 10725 address = Rn - imm32; 10726 10727 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10728 EmulateInstruction::Context context; 10729 10730 if (wback) 10731 { 10732 uint32_t value; 10733 if (add) 10734 value = Rn + imm32; 10735 else 10736 value = Rn - imm32; 10737 10738 context.type = eContextAdjustBaseRegister; 10739 context.SetImmediateSigned (value - Rn); 10740 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10741 return false; 10742 10743 } 10744 10745 const uint32_t addr_byte_size = GetAddressByteSize(); 10746 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10747 10748 context.type = eContextRegisterLoad; 10749 10750 // for r = 0 to regs-1 10751 for (uint32_t r = 0; r < regs; ++r) 10752 { 10753 if (single_regs) 10754 { 10755 // S[d+r] = MemA[address,4]; address = address+4; 10756 context.SetRegisterPlusOffset (base_reg, address - Rn); 10757 10758 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10759 if (!success) 10760 return false; 10761 10762 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10763 return false; 10764 10765 address = address + 4; 10766 } 10767 else 10768 { 10769 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10770 context.SetRegisterPlusOffset (base_reg, address - Rn); 10771 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10772 if (!success) 10773 return false; 10774 10775 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10776 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10777 if (!success) 10778 return false; 10779 10780 address = address + 8; 10781 // // Combine the word-aligned words in the correct order for current endianness. 10782 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10783 uint64_t data; 10784 if (GetByteOrder() == eByteOrderBig) 10785 { 10786 data = word1; 10787 data = (data << 32) | word2; 10788 } 10789 else 10790 { 10791 data = word2; 10792 data = (data << 32) | word1; 10793 } 10794 10795 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10796 return false; 10797 } 10798 } 10799 } 10800 return true; 10801} 10802 10803// A8.6.399 VSTM 10804// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10805// ARM core register. 10806bool 10807EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10808{ 10809#if 0 10810 if ConditionPassed() then 10811 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10812 address = if add then R[n] else R[n]-imm32; 10813 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10814 for r = 0 to regs-1 10815 if single_regs then 10816 MemA[address,4] = S[d+r]; address = address+4; 10817 else 10818 // Store as two word-aligned words in the correct order for current endianness. 10819 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10820 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10821 address = address+8; 10822#endif 10823 10824 bool success = false; 10825 10826 if (ConditionPassed (opcode)) 10827 { 10828 bool single_regs; 10829 bool add; 10830 bool wback; 10831 uint32_t d; 10832 uint32_t n; 10833 uint32_t imm32; 10834 uint32_t regs; 10835 10836 switch (encoding) 10837 { 10838 case eEncodingT1: 10839 case eEncodingA1: 10840 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10841 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10842 // if P == �1� && W == �0� then SEE VSTR; 10843 // if P == U && W == �1� then UNDEFINED; 10844 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10845 return false; 10846 10847 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10848 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10849 single_regs = false; 10850 add = BitIsSet (opcode, 23); 10851 wback = BitIsSet (opcode, 21); 10852 10853 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10854 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10855 n = Bits32 (opcode, 19, 16); 10856 imm32 = Bits32 (opcode, 7, 0) << 2; 10857 10858 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�. 10859 regs = Bits32 (opcode, 7, 0) / 2; 10860 10861 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10862 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10863 return false; 10864 10865 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10866 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10867 return false; 10868 10869 break; 10870 10871 case eEncodingT2: 10872 case eEncodingA2: 10873 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10874 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10875 // if P == �1� && W == �0� then SEE VSTR; 10876 // if P == U && W == �1� then UNDEFINED; 10877 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10878 return false; 10879 10880 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10881 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10882 single_regs = true; 10883 add = BitIsSet (opcode, 23); 10884 wback = BitIsSet (opcode, 21); 10885 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10886 n = Bits32 (opcode, 19, 16); 10887 10888 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10889 imm32 = Bits32 (opcode, 7, 0) << 2; 10890 regs = Bits32 (opcode, 7, 0); 10891 10892 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10893 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 10894 return false; 10895 10896 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10897 if ((regs == 0) || ((d + regs) > 32)) 10898 return false; 10899 10900 break; 10901 10902 default: 10903 return false; 10904 } 10905 10906 RegisterInfo base_reg; 10907 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10908 10909 uint32_t Rn = ReadCoreReg (n, &success); 10910 if (!success) 10911 return false; 10912 10913 // address = if add then R[n] else R[n]-imm32; 10914 addr_t address; 10915 if (add) 10916 address = Rn; 10917 else 10918 address = Rn - imm32; 10919 10920 EmulateInstruction::Context context; 10921 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10922 if (wback) 10923 { 10924 uint32_t value; 10925 if (add) 10926 value = Rn + imm32; 10927 else 10928 value = Rn - imm32; 10929 10930 context.type = eContextAdjustBaseRegister; 10931 context.SetRegisterPlusOffset (base_reg, value - Rn); 10932 10933 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10934 return false; 10935 } 10936 10937 const uint32_t addr_byte_size = GetAddressByteSize(); 10938 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10939 10940 context.type = eContextRegisterStore; 10941 // for r = 0 to regs-1 10942 for (int r = 0; r < regs; ++r) 10943 { 10944 10945 if (single_regs) 10946 { 10947 // MemA[address,4] = S[d+r]; address = address+4; 10948 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10949 if (!success) 10950 return false; 10951 10952 RegisterInfo data_reg; 10953 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10954 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10955 if (!MemAWrite (context, address, data, addr_byte_size)) 10956 return false; 10957 10958 address = address + 4; 10959 } 10960 else 10961 { 10962 // // Store as two word-aligned words in the correct order for current endianness. 10963 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10964 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10965 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10966 if (!success) 10967 return false; 10968 10969 RegisterInfo data_reg; 10970 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10971 10972 if (GetByteOrder() == eByteOrderBig) 10973 { 10974 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10975 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 10976 return false; 10977 10978 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10979 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 10980 return false; 10981 } 10982 else 10983 { 10984 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10985 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 10986 return false; 10987 10988 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10989 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 10990 return false; 10991 } 10992 // address = address+8; 10993 address = address + 8; 10994 } 10995 } 10996 } 10997 return true; 10998} 10999 11000// A8.6.320 11001// This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with 11002// an optional offset. 11003bool 11004EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 11005{ 11006#if 0 11007 if ConditionPassed() then 11008 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11009 base = if n == 15 then Align(PC,4) else R[n]; 11010 address = if add then (base + imm32) else (base - imm32); 11011 if single_reg then 11012 S[d] = MemA[address,4]; 11013 else 11014 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11015 // Combine the word-aligned words in the correct order for current endianness. 11016 D[d] = if BigEndian() then word1:word2 else word2:word1; 11017#endif 11018 11019 bool success = false; 11020 11021 if (ConditionPassed (opcode)) 11022 { 11023 bool single_reg; 11024 bool add; 11025 uint32_t imm32; 11026 uint32_t d; 11027 uint32_t n; 11028 11029 switch (encoding) 11030 { 11031 case eEncodingT1: 11032 case eEncodingA1: 11033 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11034 single_reg = false; 11035 add = BitIsSet (opcode, 23); 11036 imm32 = Bits32 (opcode, 7, 0) << 2; 11037 11038 // d = UInt(D:Vd); n = UInt(Rn); 11039 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11040 n = Bits32 (opcode, 19, 16); 11041 11042 break; 11043 11044 case eEncodingT2: 11045 case eEncodingA2: 11046 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11047 single_reg = true; 11048 add = BitIsSet (opcode, 23); 11049 imm32 = Bits32 (opcode, 7, 0) << 2; 11050 11051 // d = UInt(Vd:D); n = UInt(Rn); 11052 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11053 n = Bits32 (opcode, 19, 16); 11054 11055 break; 11056 11057 default: 11058 return false; 11059 } 11060 RegisterInfo base_reg; 11061 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11062 11063 uint32_t Rn = ReadCoreReg (n, &success); 11064 if (!success) 11065 return false; 11066 11067 // base = if n == 15 then Align(PC,4) else R[n]; 11068 uint32_t base; 11069 if (n == 15) 11070 base = AlignPC (Rn); 11071 else 11072 base = Rn; 11073 11074 // address = if add then (base + imm32) else (base - imm32); 11075 addr_t address; 11076 if (add) 11077 address = base + imm32; 11078 else 11079 address = base - imm32; 11080 11081 const uint32_t addr_byte_size = GetAddressByteSize(); 11082 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11083 11084 EmulateInstruction::Context context; 11085 context.type = eContextRegisterLoad; 11086 context.SetRegisterPlusOffset (base_reg, address - base); 11087 11088 if (single_reg) 11089 { 11090 // S[d] = MemA[address,4]; 11091 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11092 if (!success) 11093 return false; 11094 11095 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11096 return false; 11097 } 11098 else 11099 { 11100 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11101 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11102 if (!success) 11103 return false; 11104 11105 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11106 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11107 if (!success) 11108 return false; 11109 // // Combine the word-aligned words in the correct order for current endianness. 11110 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11111 uint64_t data64; 11112 if (GetByteOrder() == eByteOrderBig) 11113 { 11114 data64 = word1; 11115 data64 = (data64 << 32) | word2; 11116 } 11117 else 11118 { 11119 data64 = word2; 11120 data64 = (data64 << 32) | word1; 11121 } 11122 11123 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11124 return false; 11125 } 11126 } 11127 return true; 11128} 11129 11130// A8.6.400 VSTR 11131// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11132// optional offset. 11133bool 11134EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11135{ 11136#if 0 11137 if ConditionPassed() then 11138 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11139 address = if add then (R[n] + imm32) else (R[n] - imm32); 11140 if single_reg then 11141 MemA[address,4] = S[d]; 11142 else 11143 // Store as two word-aligned words in the correct order for current endianness. 11144 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11145 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11146#endif 11147 11148 bool success = false; 11149 11150 if (ConditionPassed (opcode)) 11151 { 11152 bool single_reg; 11153 bool add; 11154 uint32_t imm32; 11155 uint32_t d; 11156 uint32_t n; 11157 11158 switch (encoding) 11159 { 11160 case eEncodingT1: 11161 case eEncodingA1: 11162 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11163 single_reg = false; 11164 add = BitIsSet (opcode, 23); 11165 imm32 = Bits32 (opcode, 7, 0) << 2; 11166 11167 // d = UInt(D:Vd); n = UInt(Rn); 11168 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11169 n = Bits32 (opcode, 19, 16); 11170 11171 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11172 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11173 return false; 11174 11175 break; 11176 11177 case eEncodingT2: 11178 case eEncodingA2: 11179 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11180 single_reg = true; 11181 add = BitIsSet (opcode, 23); 11182 imm32 = Bits32 (opcode, 7, 0) << 2; 11183 11184 // d = UInt(Vd:D); n = UInt(Rn); 11185 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11186 n = Bits32 (opcode, 19, 16); 11187 11188 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11189 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11190 return false; 11191 11192 break; 11193 11194 default: 11195 return false; 11196 } 11197 11198 RegisterInfo base_reg; 11199 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11200 11201 uint32_t Rn = ReadCoreReg (n, &success); 11202 if (!success) 11203 return false; 11204 11205 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11206 addr_t address; 11207 if (add) 11208 address = Rn + imm32; 11209 else 11210 address = Rn - imm32; 11211 11212 const uint32_t addr_byte_size = GetAddressByteSize(); 11213 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11214 11215 RegisterInfo data_reg; 11216 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11217 EmulateInstruction::Context context; 11218 context.type = eContextRegisterStore; 11219 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11220 11221 if (single_reg) 11222 { 11223 // MemA[address,4] = S[d]; 11224 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11225 if (!success) 11226 return false; 11227 11228 if (!MemAWrite (context, address, data, addr_byte_size)) 11229 return false; 11230 } 11231 else 11232 { 11233 // // Store as two word-aligned words in the correct order for current endianness. 11234 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11235 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11236 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11237 if (!success) 11238 return false; 11239 11240 if (GetByteOrder() == eByteOrderBig) 11241 { 11242 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11243 return false; 11244 11245 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11246 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11247 return false; 11248 } 11249 else 11250 { 11251 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11252 return false; 11253 11254 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11255 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11256 return false; 11257 } 11258 } 11259 } 11260 return true; 11261} 11262 11263// A8.6.307 VLDI1 (multiple single elements) 11264// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11265// element of each register is loaded. 11266bool 11267EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11268{ 11269#if 0 11270 if ConditionPassed() then 11271 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11272 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11273 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11274 for r = 0 to regs-1 11275 for e = 0 to elements-1 11276 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11277 address = address + ebytes; 11278#endif 11279 11280 bool success = false; 11281 11282 if (ConditionPassed (opcode)) 11283 { 11284 uint32_t regs; 11285 uint32_t alignment; 11286 uint32_t ebytes; 11287 uint32_t esize; 11288 uint32_t elements; 11289 uint32_t d; 11290 uint32_t n; 11291 uint32_t m; 11292 bool wback; 11293 bool register_index; 11294 11295 switch (encoding) 11296 { 11297 case eEncodingT1: 11298 case eEncodingA1: 11299 { 11300 // case type of 11301 // when �0111� 11302 // regs = 1; if align<1> == �1� then UNDEFINED; 11303 // when �1010� 11304 // regs = 2; if align == �11� then UNDEFINED; 11305 // when �0110� 11306 // regs = 3; if align<1> == �1� then UNDEFINED; 11307 // when �0010� 11308 // regs = 4; 11309 // otherwise 11310 // SEE �Related encodings�; 11311 uint32_t type = Bits32 (opcode, 11, 8); 11312 uint32_t align = Bits32 (opcode, 5, 4); 11313 if (type == 7) // '0111' 11314 { 11315 regs = 1; 11316 if (BitIsSet (align, 1)) 11317 return false; 11318 } 11319 else if (type == 10) // '1010' 11320 { 11321 regs = 2; 11322 if (align == 3) 11323 return false; 11324 11325 } 11326 else if (type == 6) // '0110' 11327 { 11328 regs = 3; 11329 if (BitIsSet (align, 1)) 11330 return false; 11331 } 11332 else if (type == 2) // '0010' 11333 { 11334 regs = 4; 11335 } 11336 else 11337 return false; 11338 11339 // alignment = if align == �00� then 1 else 4 << UInt(align); 11340 if (align == 0) 11341 alignment = 1; 11342 else 11343 alignment = 4 << align; 11344 11345 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11346 ebytes = 1 << Bits32 (opcode, 7, 6); 11347 esize = 8 * ebytes; 11348 elements = 8 / ebytes; 11349 11350 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11351 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11352 n = Bits32 (opcode, 19, 15); 11353 m = Bits32 (opcode, 3, 0); 11354 11355 // wback = (m != 15); register_index = (m != 15 && m != 13); 11356 wback = (m != 15); 11357 register_index = ((m != 15) && (m != 13)); 11358 11359 // if d+regs > 32 then UNPREDICTABLE; 11360 if ((d + regs) > 32) 11361 return false; 11362 } 11363 break; 11364 11365 default: 11366 return false; 11367 } 11368 11369 RegisterInfo base_reg; 11370 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11371 11372 uint32_t Rn = ReadCoreReg (n, &success); 11373 if (!success) 11374 return false; 11375 11376 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11377 addr_t address = Rn; 11378 if ((address % alignment) != 0) 11379 return false; 11380 11381 EmulateInstruction::Context context; 11382 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11383 if (wback) 11384 { 11385 uint32_t Rm = ReadCoreReg (m, &success); 11386 if (!success) 11387 return false; 11388 11389 uint32_t offset; 11390 if (register_index) 11391 offset = Rm; 11392 else 11393 offset = 8 * regs; 11394 11395 uint32_t value = Rn + offset; 11396 context.type = eContextAdjustBaseRegister; 11397 context.SetRegisterPlusOffset (base_reg, offset); 11398 11399 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11400 return false; 11401 11402 } 11403 11404 // for r = 0 to regs-1 11405 for (int r = 0; r < regs; ++r) 11406 { 11407 // for e = 0 to elements-1 11408 uint64_t assembled_data = 0; 11409 for (int e = 0; e < elements; ++e) 11410 { 11411 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11412 context.type = eContextRegisterLoad; 11413 context.SetRegisterPlusOffset (base_reg, address - Rn); 11414 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11415 if (!success) 11416 return false; 11417 11418 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11419 11420 // address = address + ebytes; 11421 address = address + ebytes; 11422 } 11423 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11424 return false; 11425 } 11426 } 11427 return true; 11428} 11429 11430// A8.6.308 VLD1 (single element to one lane) 11431// 11432bool 11433EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11434{ 11435#if 0 11436 if ConditionPassed() then 11437 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11438 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11439 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11440 Elem[D[d],index,esize] = MemU[address,ebytes]; 11441#endif 11442 11443 bool success = false; 11444 11445 if (ConditionPassed (opcode)) 11446 { 11447 uint32_t ebytes; 11448 uint32_t esize; 11449 uint32_t index; 11450 uint32_t alignment; 11451 uint32_t d; 11452 uint32_t n; 11453 uint32_t m; 11454 bool wback; 11455 bool register_index; 11456 11457 switch (encoding) 11458 { 11459 case eEncodingT1: 11460 case eEncodingA1: 11461 { 11462 uint32_t size = Bits32 (opcode, 11, 10); 11463 uint32_t index_align = Bits32 (opcode, 7, 4); 11464 // if size == �11� then SEE VLD1 (single element to all lanes); 11465 if (size == 3) 11466 return EmulateVLD1SingleAll (opcode, encoding); 11467 // case size of 11468 if (size == 0) // when '00' 11469 { 11470 // if index_align<0> != �0� then UNDEFINED; 11471 if (BitIsClear (index_align, 0)) 11472 return false; 11473 11474 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11475 ebytes = 1; 11476 esize = 8; 11477 index = Bits32 (index_align, 3, 1); 11478 alignment = 1; 11479 } 11480 else if (size == 1) // when �01� 11481 { 11482 // if index_align<1> != �0� then UNDEFINED; 11483 if (BitIsClear (index_align, 1)) 11484 return false; 11485 11486 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11487 ebytes = 2; 11488 esize = 16; 11489 index = Bits32 (index_align, 3, 2); 11490 11491 // alignment = if index_align<0> == �0� then 1 else 2; 11492 if (BitIsClear (index_align, 0)) 11493 alignment = 1; 11494 else 11495 alignment = 2; 11496 } 11497 else if (size == 2) // when �10� 11498 { 11499 // if index_align<2> != �0� then UNDEFINED; 11500 if (BitIsClear (index_align, 2)) 11501 return false; 11502 11503 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11504 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11505 return false; 11506 11507 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11508 ebytes = 4; 11509 esize = 32; 11510 index = Bit32 (index_align, 3); 11511 11512 // alignment = if index_align<1:0> == �00� then 1 else 4; 11513 if (Bits32 (index_align, 1, 0) == 0) 11514 alignment = 1; 11515 else 11516 alignment = 4; 11517 } 11518 else 11519 { 11520 return false; 11521 } 11522 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11523 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11524 n = Bits32 (opcode, 19, 16); 11525 m = Bits32 (opcode, 3, 0); 11526 11527 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11528 wback = (m != 15); 11529 register_index = ((m != 15) && (m != 13)); 11530 11531 if (n == 15) 11532 return false; 11533 11534 } 11535 break; 11536 11537 default: 11538 return false; 11539 } 11540 11541 RegisterInfo base_reg; 11542 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11543 11544 uint32_t Rn = ReadCoreReg (n, &success); 11545 if (!success) 11546 return false; 11547 11548 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11549 addr_t address = Rn; 11550 if ((address % alignment) != 0) 11551 return false; 11552 11553 EmulateInstruction::Context context; 11554 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11555 if (wback) 11556 { 11557 uint32_t Rm = ReadCoreReg (m, &success); 11558 if (!success) 11559 return false; 11560 11561 uint32_t offset; 11562 if (register_index) 11563 offset = Rm; 11564 else 11565 offset = ebytes; 11566 11567 uint32_t value = Rn + offset; 11568 11569 context.type = eContextAdjustBaseRegister; 11570 context.SetRegisterPlusOffset (base_reg, offset); 11571 11572 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11573 return false; 11574 } 11575 11576 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11577 uint32_t element = MemURead (context, address, esize, 0, &success); 11578 if (!success) 11579 return false; 11580 11581 element = element << (index * esize); 11582 11583 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11584 if (!success) 11585 return false; 11586 11587 uint64_t all_ones = -1; 11588 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11589 // at element & to the right of element. 11590 if (index > 0) 11591 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11592 // now mask should be 0's where element goes & 1's 11593 // everywhere else. 11594 11595 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11596 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11597 11598 context.type = eContextRegisterLoad; 11599 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11600 return false; 11601 } 11602 return true; 11603} 11604 11605// A8.6.391 VST1 (multiple single elements) 11606// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without 11607// interleaving. Every element of each register is stored. 11608bool 11609EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11610{ 11611#if 0 11612 if ConditionPassed() then 11613 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11614 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11615 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11616 for r = 0 to regs-1 11617 for e = 0 to elements-1 11618 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11619 address = address + ebytes; 11620#endif 11621 11622 bool success = false; 11623 11624 if (ConditionPassed (opcode)) 11625 { 11626 uint32_t regs; 11627 uint32_t alignment; 11628 uint32_t ebytes; 11629 uint32_t esize; 11630 uint32_t elements; 11631 uint32_t d; 11632 uint32_t n; 11633 uint32_t m; 11634 bool wback; 11635 bool register_index; 11636 11637 switch (encoding) 11638 { 11639 case eEncodingT1: 11640 case eEncodingA1: 11641 { 11642 uint32_t type = Bits32 (opcode, 11, 8); 11643 uint32_t align = Bits32 (opcode, 5, 4); 11644 11645 // case type of 11646 if (type == 7) // when �0111� 11647 { 11648 // regs = 1; if align<1> == �1� then UNDEFINED; 11649 regs = 1; 11650 if (BitIsSet (align, 1)) 11651 return false; 11652 } 11653 else if (type == 10) // when �1010� 11654 { 11655 // regs = 2; if align == �11� then UNDEFINED; 11656 regs = 2; 11657 if (align == 3) 11658 return false; 11659 } 11660 else if (type == 6) // when �0110� 11661 { 11662 // regs = 3; if align<1> == �1� then UNDEFINED; 11663 regs = 3; 11664 if (BitIsSet (align, 1)) 11665 return false; 11666 } 11667 else if (type == 2) // when �0010� 11668 // regs = 4; 11669 regs = 4; 11670 else // otherwise 11671 // SEE �Related encodings�; 11672 return false; 11673 11674 // alignment = if align == �00� then 1 else 4 << UInt(align); 11675 if (align == 0) 11676 alignment = 1; 11677 else 11678 alignment = 4 << align; 11679 11680 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11681 ebytes = 1 << Bits32 (opcode,7, 6); 11682 esize = 8 * ebytes; 11683 elements = 8 / ebytes; 11684 11685 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11686 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11687 n = Bits32 (opcode, 19, 16); 11688 m = Bits32 (opcode, 3, 0); 11689 11690 // wback = (m != 15); register_index = (m != 15 && m != 13); 11691 wback = (m != 15); 11692 register_index = ((m != 15) && (m != 13)); 11693 11694 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11695 if ((d + regs) > 32) 11696 return false; 11697 11698 if (n == 15) 11699 return false; 11700 11701 } 11702 break; 11703 11704 default: 11705 return false; 11706 } 11707 11708 RegisterInfo base_reg; 11709 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11710 11711 uint32_t Rn = ReadCoreReg (n, &success); 11712 if (!success) 11713 return false; 11714 11715 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11716 addr_t address = Rn; 11717 if ((address % alignment) != 0) 11718 return false; 11719 11720 EmulateInstruction::Context context; 11721 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11722 if (wback) 11723 { 11724 uint32_t Rm = ReadCoreReg (m, &success); 11725 if (!success) 11726 return false; 11727 11728 uint32_t offset; 11729 if (register_index) 11730 offset = Rm; 11731 else 11732 offset = 8 * regs; 11733 11734 context.type = eContextAdjustBaseRegister; 11735 context.SetRegisterPlusOffset (base_reg, offset); 11736 11737 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11738 return false; 11739 } 11740 11741 RegisterInfo data_reg; 11742 context.type = eContextRegisterStore; 11743 // for r = 0 to regs-1 11744 for (int r = 0; r < regs; ++r) 11745 { 11746 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11747 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11748 if (!success) 11749 return false; 11750 11751 // for e = 0 to elements-1 11752 for (int e = 0; e < elements; ++e) 11753 { 11754 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11755 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11756 11757 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11758 if (!MemUWrite (context, address, word, ebytes)) 11759 return false; 11760 11761 // address = address + ebytes; 11762 address = address + ebytes; 11763 } 11764 } 11765 } 11766 return true; 11767} 11768 11769// A8.6.392 VST1 (single element from one lane) 11770// This instruction stores one element to memory from one element of a register. 11771bool 11772EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11773{ 11774#if 0 11775 if ConditionPassed() then 11776 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11777 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11778 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11779 MemU[address,ebytes] = Elem[D[d],index,esize]; 11780#endif 11781 11782 bool success = false; 11783 11784 if (ConditionPassed (opcode)) 11785 { 11786 uint32_t ebytes; 11787 uint32_t esize; 11788 uint32_t index; 11789 uint32_t alignment; 11790 uint32_t d; 11791 uint32_t n; 11792 uint32_t m; 11793 bool wback; 11794 bool register_index; 11795 11796 switch (encoding) 11797 { 11798 case eEncodingT1: 11799 case eEncodingA1: 11800 { 11801 uint32_t size = Bits32 (opcode, 11, 10); 11802 uint32_t index_align = Bits32 (opcode, 7, 4); 11803 11804 // if size == �11� then UNDEFINED; 11805 if (size == 3) 11806 return false; 11807 11808 // case size of 11809 if (size == 0) // when �00� 11810 { 11811 // if index_align<0> != �0� then UNDEFINED; 11812 if (BitIsClear (index_align, 0)) 11813 return false; 11814 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11815 ebytes = 1; 11816 esize = 8; 11817 index = Bits32 (index_align, 3, 1); 11818 alignment = 1; 11819 } 11820 else if (size == 1) // when �01� 11821 { 11822 // if index_align<1> != �0� then UNDEFINED; 11823 if (BitIsClear (index_align, 1)) 11824 return false; 11825 11826 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11827 ebytes = 2; 11828 esize = 16; 11829 index = Bits32 (index_align, 3, 2); 11830 11831 // alignment = if index_align<0> == �0� then 1 else 2; 11832 if (BitIsClear (index_align, 0)) 11833 alignment = 1; 11834 else 11835 alignment = 2; 11836 } 11837 else if (size == 2) // when �10� 11838 { 11839 // if index_align<2> != �0� then UNDEFINED; 11840 if (BitIsClear (index_align, 2)) 11841 return false; 11842 11843 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11844 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11845 return false; 11846 11847 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11848 ebytes = 4; 11849 esize = 32; 11850 index = Bit32 (index_align, 3); 11851 11852 // alignment = if index_align<1:0> == �00� then 1 else 4; 11853 if (Bits32 (index_align, 1, 0) == 0) 11854 alignment = 1; 11855 else 11856 alignment = 4; 11857 } 11858 else 11859 { 11860 return false; 11861 } 11862 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11863 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11864 n = Bits32 (opcode, 19, 16); 11865 m = Bits32 (opcode, 3, 0); 11866 11867 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11868 wback = (m != 15); 11869 register_index = ((m != 15) && (m != 13)); 11870 11871 if (n == 15) 11872 return false; 11873 } 11874 break; 11875 11876 default: 11877 return false; 11878 } 11879 11880 RegisterInfo base_reg; 11881 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11882 11883 uint32_t Rn = ReadCoreReg (n, &success); 11884 if (!success) 11885 return false; 11886 11887 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11888 addr_t address = Rn; 11889 if ((address % alignment) != 0) 11890 return false; 11891 11892 EmulateInstruction::Context context; 11893 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11894 if (wback) 11895 { 11896 uint32_t Rm = ReadCoreReg (m, &success); 11897 if (!success) 11898 return false; 11899 11900 uint32_t offset; 11901 if (register_index) 11902 offset = Rm; 11903 else 11904 offset = ebytes; 11905 11906 context.type = eContextAdjustBaseRegister; 11907 context.SetRegisterPlusOffset (base_reg, offset); 11908 11909 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11910 return false; 11911 } 11912 11913 // MemU[address,ebytes] = Elem[D[d],index,esize]; 11914 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11915 if (!success) 11916 return false; 11917 11918 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 11919 11920 RegisterInfo data_reg; 11921 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 11922 context.type = eContextRegisterStore; 11923 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11924 11925 if (!MemUWrite (context, address, word, ebytes)) 11926 return false; 11927 } 11928 return true; 11929} 11930 11931// A8.6.309 VLD1 (single element to all lanes) 11932// This instruction loads one element from memory into every element of one or two vectors. 11933bool 11934EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 11935{ 11936#if 0 11937 if ConditionPassed() then 11938 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11939 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11940 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11941 replicated_element = Replicate(MemU[address,ebytes], elements); 11942 for r = 0 to regs-1 11943 D[d+r] = replicated_element; 11944#endif 11945 11946 bool success = false; 11947 11948 if (ConditionPassed (opcode)) 11949 { 11950 uint32_t ebytes; 11951 uint32_t elements; 11952 uint32_t regs; 11953 uint32_t alignment; 11954 uint32_t d; 11955 uint32_t n; 11956 uint32_t m; 11957 bool wback; 11958 bool register_index; 11959 11960 switch (encoding) 11961 { 11962 case eEncodingT1: 11963 case eEncodingA1: 11964 { 11965 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED; 11966 uint32_t size = Bits32 (opcode, 7, 6); 11967 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 11968 return false; 11969 11970 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2; 11971 ebytes = 1 << size; 11972 elements = 8 / ebytes; 11973 if (BitIsClear (opcode, 5)) 11974 regs = 1; 11975 else 11976 regs = 2; 11977 11978 //alignment = if a == �0� then 1 else ebytes; 11979 if (BitIsClear (opcode, 4)) 11980 alignment = 1; 11981 else 11982 alignment = ebytes; 11983 11984 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11985 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11986 n = Bits32 (opcode, 19, 16); 11987 m = Bits32 (opcode, 3, 0); 11988 11989 //wback = (m != 15); register_index = (m != 15 && m != 13); 11990 wback = (m != 15); 11991 register_index = ((m != 15) && (m != 13)); 11992 11993 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11994 if ((d + regs) > 32) 11995 return false; 11996 11997 if (n == 15) 11998 return false; 11999 } 12000 break; 12001 12002 default: 12003 return false; 12004 } 12005 12006 RegisterInfo base_reg; 12007 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12008 12009 uint32_t Rn = ReadCoreReg (n, &success); 12010 if (!success) 12011 return false; 12012 12013 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12014 addr_t address = Rn; 12015 if ((address % alignment) != 0) 12016 return false; 12017 12018 EmulateInstruction::Context context; 12019 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12020 if (wback) 12021 { 12022 uint32_t Rm = ReadCoreReg (m, &success); 12023 if (!success) 12024 return false; 12025 12026 uint32_t offset; 12027 if (register_index) 12028 offset = Rm; 12029 else 12030 offset = ebytes; 12031 12032 context.type = eContextAdjustBaseRegister; 12033 context.SetRegisterPlusOffset (base_reg, offset); 12034 12035 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12036 return false; 12037 } 12038 12039 // replicated_element = Replicate(MemU[address,ebytes], elements); 12040 12041 context.type = eContextRegisterLoad; 12042 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12043 if (!success) 12044 return false; 12045 12046 uint64_t replicated_element = 0; 12047 uint32_t esize = ebytes * 8; 12048 for (int e = 0; e < elements; ++e) 12049 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12050 12051 // for r = 0 to regs-1 12052 for (int r = 0; r < regs; ++r) 12053 { 12054 // D[d+r] = replicated_element; 12055 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12056 return false; 12057 } 12058 } 12059 return true; 12060} 12061 12062// B6.2.13 SUBS PC, LR and related instructions 12063//The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12064// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12065bool 12066EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12067{ 12068#if 0 12069 if ConditionPassed() then 12070 EncodingSpecificOperations(); 12071 if CurrentInstrSet() == InstrSet_ThumbEE then 12072 UNPREDICTABLE; 12073 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12074 case opcode of 12075 when �0000� result = R[n] AND operand2; // AND 12076 when �0001� result = R[n] EOR operand2; // EOR 12077 when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12078 when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12079 when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12080 when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12081 when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12082 when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12083 when �1100� result = R[n] OR operand2; // ORR 12084 when �1101� result = operand2; // MOV 12085 when �1110� result = R[n] AND NOT(operand2); // BIC 12086 when �1111� result = NOT(operand2); // MVN 12087 CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12088 BranchWritePC(result); 12089#endif 12090 12091 bool success = false; 12092 12093 if (ConditionPassed (opcode)) 12094 { 12095 uint32_t n; 12096 uint32_t m; 12097 uint32_t imm32; 12098 bool register_form; 12099 ARM_ShifterType shift_t; 12100 uint32_t shift_n; 12101 uint32_t code; 12102 12103 switch (encoding) 12104 { 12105 case eEncodingT1: 12106 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12107 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB 12108 n = 14; 12109 imm32 = Bits32 (opcode, 7, 0); 12110 register_form = false; 12111 code = 2; 12112 12113 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12114 if (InITBlock() && !LastInITBlock()) 12115 return false; 12116 12117 break; 12118 12119 case eEncodingA1: 12120 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12121 n = Bits32 (opcode, 19, 16); 12122 imm32 = ARMExpandImm (opcode); 12123 register_form = false; 12124 code = Bits32 (opcode, 24, 21); 12125 12126 break; 12127 12128 case eEncodingA2: 12129 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12130 n = Bits32 (opcode, 19, 16); 12131 m = Bits32 (opcode, 3, 0); 12132 register_form = true; 12133 12134 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12135 shift_n = DecodeImmShiftARM (opcode, shift_t); 12136 12137 break; 12138 12139 default: 12140 return false; 12141 } 12142 12143 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12144 uint32_t operand2; 12145 if (register_form) 12146 { 12147 uint32_t Rm = ReadCoreReg (m, &success); 12148 if (!success) 12149 return false; 12150 12151 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12152 if (!success) 12153 return false; 12154 } 12155 else 12156 { 12157 operand2 = imm32; 12158 } 12159 12160 uint32_t Rn = ReadCoreReg (n, &success); 12161 if (!success) 12162 return false; 12163 12164 AddWithCarryResult result; 12165 12166 // case opcode of 12167 switch (code) 12168 { 12169 case 0: // when �0000� 12170 // result = R[n] AND operand2; // AND 12171 result.result = Rn & operand2; 12172 break; 12173 12174 case 1: // when �0001� 12175 // result = R[n] EOR operand2; // EOR 12176 result.result = Rn ^ operand2; 12177 break; 12178 12179 case 2: // when �0010� 12180 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12181 result = AddWithCarry (Rn, ~(operand2), 1); 12182 break; 12183 12184 case 3: // when �0011� 12185 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12186 result = AddWithCarry (~(Rn), operand2, 1); 12187 break; 12188 12189 case 4: // when �0100� 12190 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12191 result = AddWithCarry (Rn, operand2, 0); 12192 break; 12193 12194 case 5: // when �0101� 12195 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12196 result = AddWithCarry (Rn, operand2, APSR_C); 12197 break; 12198 12199 case 6: // when �0110� 12200 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12201 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12202 break; 12203 12204 case 7: // when �0111� 12205 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12206 result = AddWithCarry (~(Rn), operand2, APSR_C); 12207 break; 12208 12209 case 10: // when �1100� 12210 // result = R[n] OR operand2; // ORR 12211 result.result = Rn | operand2; 12212 break; 12213 12214 case 11: // when �1101� 12215 // result = operand2; // MOV 12216 result.result = operand2; 12217 break; 12218 12219 case 12: // when �1110� 12220 // result = R[n] AND NOT(operand2); // BIC 12221 result.result = Rn & ~(operand2); 12222 break; 12223 12224 case 15: // when �1111� 12225 // result = NOT(operand2); // MVN 12226 result.result = ~(operand2); 12227 break; 12228 12229 default: 12230 return false; 12231 } 12232 // CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12233 12234 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12235 // the best. 12236 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12237 if (!success) 12238 return false; 12239 12240 CPSRWriteByInstr (spsr, 15, true); 12241 12242 // BranchWritePC(result); 12243 EmulateInstruction::Context context; 12244 context.type = eContextAdjustPC; 12245 context.SetImmediate (result.result); 12246 12247 BranchWritePC (context, result.result); 12248 } 12249 return true; 12250} 12251 12252EmulateInstructionARM::ARMOpcode* 12253EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12254{ 12255 static ARMOpcode 12256 g_arm_opcodes[] = 12257 { 12258 //---------------------------------------------------------------------- 12259 // Prologue instructions 12260 //---------------------------------------------------------------------- 12261 12262 // push register(s) 12263 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12264 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12265 12266 // set r7 to point to a stack offset 12267 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12268 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12269 // copy the stack pointer to ip 12270 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12271 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12272 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12273 12274 // adjust the stack pointer 12275 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12276 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12277 12278 // push one register 12279 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12280 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12281 12282 // vector push consecutive extension register(s) 12283 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12284 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12285 12286 //---------------------------------------------------------------------- 12287 // Epilogue instructions 12288 //---------------------------------------------------------------------- 12289 12290 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12291 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12292 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12293 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12294 12295 //---------------------------------------------------------------------- 12296 // Supervisor Call (previously Software Interrupt) 12297 //---------------------------------------------------------------------- 12298 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12299 12300 //---------------------------------------------------------------------- 12301 // Branch instructions 12302 //---------------------------------------------------------------------- 12303 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12304 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 12305 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12306 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12307 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12308 // for example, "bx lr" 12309 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12310 // bxj 12311 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12312 12313 //---------------------------------------------------------------------- 12314 // Data-processing instructions 12315 //---------------------------------------------------------------------- 12316 // adc (immediate) 12317 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12318 // adc (register) 12319 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12320 // add (immediate) 12321 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12322 // add (register) 12323 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12324 // add (register-shifted register) 12325 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12326 // adr 12327 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12328 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12329 // and (immediate) 12330 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12331 // and (register) 12332 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12333 // bic (immediate) 12334 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12335 // bic (register) 12336 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12337 // eor (immediate) 12338 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12339 // eor (register) 12340 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12341 // orr (immediate) 12342 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12343 // orr (register) 12344 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12345 // rsb (immediate) 12346 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12347 // rsb (register) 12348 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12349 // rsc (immediate) 12350 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12351 // rsc (register) 12352 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12353 // sbc (immediate) 12354 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12355 // sbc (register) 12356 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12357 // sub (immediate, ARM) 12358 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12359 // sub (sp minus immediate) 12360 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12361 // sub (register) 12362 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12363 // teq (immediate) 12364 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12365 // teq (register) 12366 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12367 // tst (immediate) 12368 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12369 // tst (register) 12370 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12371 12372 // mov (immediate) 12373 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12374 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12375 // mov (register) 12376 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12377 // mvn (immediate) 12378 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12379 // mvn (register) 12380 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12381 // cmn (immediate) 12382 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12383 // cmn (register) 12384 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12385 // cmp (immediate) 12386 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12387 // cmp (register) 12388 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12389 // asr (immediate) 12390 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12391 // asr (register) 12392 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12393 // lsl (immediate) 12394 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12395 // lsl (register) 12396 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12397 // lsr (immediate) 12398 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12399 // lsr (register) 12400 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12401 // rrx is a special case encoding of ror (immediate) 12402 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12403 // ror (immediate) 12404 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12405 // ror (register) 12406 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12407 // mul 12408 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12409 12410 // subs pc, lr and related instructions 12411 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12412 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12413 12414 //---------------------------------------------------------------------- 12415 // Load instructions 12416 //---------------------------------------------------------------------- 12417 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12418 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12419 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12420 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12421 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12422 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12423 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12424 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12425 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12426 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12427 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12428 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12429 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12430 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12431 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12432 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12433 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12434 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12435 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12436 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12437 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12438 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12439 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12440 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12441 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12442 12443 //---------------------------------------------------------------------- 12444 // Store instructions 12445 //---------------------------------------------------------------------- 12446 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12447 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12448 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12449 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12450 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12451 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12452 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12453 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12454 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12455 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12456 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12457 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12458 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12459 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12460 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12461 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12462 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12463 12464 //---------------------------------------------------------------------- 12465 // Other instructions 12466 //---------------------------------------------------------------------- 12467 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12468 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12469 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12470 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12471 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12472 12473 }; 12474 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 12475 12476 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12477 { 12478 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12479 (g_arm_opcodes[i].variants & arm_isa) != 0) 12480 return &g_arm_opcodes[i]; 12481 } 12482 return NULL; 12483} 12484 12485 12486EmulateInstructionARM::ARMOpcode* 12487EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12488{ 12489 12490 static ARMOpcode 12491 g_thumb_opcodes[] = 12492 { 12493 //---------------------------------------------------------------------- 12494 // Prologue instructions 12495 //---------------------------------------------------------------------- 12496 12497 // push register(s) 12498 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12499 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12500 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12501 12502 // set r7 to point to a stack offset 12503 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12504 // copy the stack pointer to r7 12505 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12506 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12507 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12508 12509 // PC-relative load into register (see also EmulateADDSPRm) 12510 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12511 12512 // adjust the stack pointer 12513 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12514 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12515 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12516 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12517 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12518 12519 // vector push consecutive extension register(s) 12520 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12521 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12522 12523 //---------------------------------------------------------------------- 12524 // Epilogue instructions 12525 //---------------------------------------------------------------------- 12526 12527 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12528 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12529 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12530 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12531 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12532 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12533 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12534 12535 //---------------------------------------------------------------------- 12536 // Supervisor Call (previously Software Interrupt) 12537 //---------------------------------------------------------------------- 12538 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12539 12540 //---------------------------------------------------------------------- 12541 // If Then makes up to four following instructions conditional. 12542 //---------------------------------------------------------------------- 12543 // The next 5 opcode _must_ come before the if then instruction 12544 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12545 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12546 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12547 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12548 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12549 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12550 12551 //---------------------------------------------------------------------- 12552 // Branch instructions 12553 //---------------------------------------------------------------------- 12554 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12555 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12556 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12557 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12558 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12559 // J1 == J2 == 1 12560 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12561 // J1 == J2 == 1 12562 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12563 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12564 // for example, "bx lr" 12565 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12566 // bxj 12567 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12568 // compare and branch 12569 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12570 // table branch byte 12571 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12572 // table branch halfword 12573 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12574 12575 //---------------------------------------------------------------------- 12576 // Data-processing instructions 12577 //---------------------------------------------------------------------- 12578 // adc (immediate) 12579 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12580 // adc (register) 12581 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12582 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12583 // add (register) 12584 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12585 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12586 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12587 // adr 12588 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12589 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12590 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12591 // and (immediate) 12592 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12593 // and (register) 12594 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12595 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12596 // bic (immediate) 12597 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12598 // bic (register) 12599 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12600 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12601 // eor (immediate) 12602 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12603 // eor (register) 12604 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12605 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12606 // orr (immediate) 12607 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12608 // orr (register) 12609 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12610 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12611 // rsb (immediate) 12612 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12613 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12614 // rsb (register) 12615 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12616 // sbc (immediate) 12617 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12618 // sbc (register) 12619 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12620 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12621 // add (immediate, Thumb) 12622 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12623 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12624 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12625 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12626 // sub (immediate, Thumb) 12627 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12628 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12629 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12630 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12631 // sub (sp minus immediate) 12632 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12633 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12634 // sub (register) 12635 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12636 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12637 // teq (immediate) 12638 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12639 // teq (register) 12640 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12641 // tst (immediate) 12642 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12643 // tst (register) 12644 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12645 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12646 12647 12648 // move from high register to high register 12649 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12650 // move from low register to low register 12651 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12652 // mov{s}<c>.w <Rd>, <Rm> 12653 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12654 // move immediate 12655 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12656 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12657 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12658 // mvn (immediate) 12659 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12660 // mvn (register) 12661 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12662 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12663 // cmn (immediate) 12664 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12665 // cmn (register) 12666 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12667 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12668 // cmp (immediate) 12669 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12670 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12671 // cmp (register) (Rn and Rm both from r0-r7) 12672 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12673 // cmp (register) (Rn and Rm not both from r0-r7) 12674 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12675 // asr (immediate) 12676 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12677 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12678 // asr (register) 12679 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12680 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12681 // lsl (immediate) 12682 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12683 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12684 // lsl (register) 12685 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12686 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12687 // lsr (immediate) 12688 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12689 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12690 // lsr (register) 12691 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12692 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12693 // rrx is a special case encoding of ror (immediate) 12694 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12695 // ror (immediate) 12696 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12697 // ror (register) 12698 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12699 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12700 // mul 12701 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12702 // mul 12703 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12704 12705 // subs pc, lr and related instructions 12706 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12707 12708 //---------------------------------------------------------------------- 12709 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12710 // otherwise the wrong instructions will be selected. 12711 //---------------------------------------------------------------------- 12712 12713 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12714 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12715 12716 //---------------------------------------------------------------------- 12717 // Load instructions 12718 //---------------------------------------------------------------------- 12719 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12720 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12721 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12722 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12723 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12724 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12725 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12726 // Thumb2 PC-relative load into register 12727 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12728 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12729 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12730 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12731 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12732 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12733 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12734 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12735 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12736 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12737 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12738 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12739 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12740 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12741 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12742 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12743 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12744 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12745 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12746 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12747 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12748 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12749 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12750 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12751 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12752 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12753 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12754 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12755 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12756 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12757 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12758 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12759 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12760 12761 //---------------------------------------------------------------------- 12762 // Store instructions 12763 //---------------------------------------------------------------------- 12764 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12765 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12766 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12767 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12768 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12769 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12770 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12771 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12772 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12773 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12774 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12775 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12776 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12777 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12778 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12779 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12780 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12781 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12782 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12783 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12784 { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12785 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12786 12787 //---------------------------------------------------------------------- 12788 // Other instructions 12789 //---------------------------------------------------------------------- 12790 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12791 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12792 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12793 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12794 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12795 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12796 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12797 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12798 }; 12799 12800 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 12801 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12802 { 12803 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12804 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12805 return &g_thumb_opcodes[i]; 12806 } 12807 return NULL; 12808} 12809 12810bool 12811EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12812{ 12813 m_arch = arch; 12814 m_arm_isa = 0; 12815 const char *arch_cstr = arch.GetArchitectureName (); 12816 if (arch_cstr) 12817 { 12818 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12819 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12820 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12821 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12822 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12823 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12824 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12825 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12826 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12827 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12828 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12829 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12830 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12831 } 12832 return m_arm_isa != 0; 12833} 12834 12835bool 12836EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12837{ 12838 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12839 { 12840 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12841 m_opcode_mode = eModeThumb; 12842 else 12843 { 12844 AddressClass addr_class = inst_addr.GetAddressClass(); 12845 12846 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 12847 m_opcode_mode = eModeARM; 12848 else if (addr_class == eAddressClassCodeAlternateISA) 12849 m_opcode_mode = eModeThumb; 12850 else 12851 return false; 12852 } 12853 if (m_opcode_mode == eModeThumb) 12854 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 12855 else 12856 m_opcode_cpsr = CPSR_MODE_USR; 12857 return true; 12858 } 12859 return false; 12860} 12861 12862bool 12863EmulateInstructionARM::ReadInstruction () 12864{ 12865 bool success = false; 12866 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 12867 if (success) 12868 { 12869 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 12870 if (success) 12871 { 12872 Context read_inst_context; 12873 read_inst_context.type = eContextReadOpcode; 12874 read_inst_context.SetNoArgs (); 12875 12876 if (m_opcode_cpsr & MASK_CPSR_T) 12877 { 12878 m_opcode_mode = eModeThumb; 12879 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 12880 12881 if (success) 12882 { 12883 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 12884 { 12885 m_opcode.SetOpcode16 (thumb_opcode); 12886 } 12887 else 12888 { 12889 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success)); 12890 } 12891 } 12892 } 12893 else 12894 { 12895 m_opcode_mode = eModeARM; 12896 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success)); 12897 } 12898 } 12899 } 12900 if (!success) 12901 { 12902 m_opcode_mode = eModeInvalid; 12903 m_addr = LLDB_INVALID_ADDRESS; 12904 } 12905 return success; 12906} 12907 12908uint32_t 12909EmulateInstructionARM::ArchVersion () 12910{ 12911 return m_arm_isa; 12912} 12913 12914bool 12915EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) 12916{ 12917 // If we are ignoring conditions, then always return true. 12918 // this allows us to iterate over disassembly code and still 12919 // emulate an instruction even if we don't have all the right 12920 // bits set in the CPSR register... 12921 if (m_ignore_conditions) 12922 return true; 12923 12924 if (is_conditional) 12925 *is_conditional = true; 12926 12927 const uint32_t cond = CurrentCond (opcode); 12928 12929 if (cond == UINT32_MAX) 12930 return false; 12931 12932 bool result = false; 12933 switch (UnsignedBits(cond, 3, 1)) 12934 { 12935 case 0: 12936 if (m_opcode_cpsr == 0) 12937 result = true; 12938 else 12939 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 12940 break; 12941 case 1: 12942 if (m_opcode_cpsr == 0) 12943 result = true; 12944 else 12945 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 12946 break; 12947 case 2: 12948 if (m_opcode_cpsr == 0) 12949 result = true; 12950 else 12951 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 12952 break; 12953 case 3: 12954 if (m_opcode_cpsr == 0) 12955 result = true; 12956 else 12957 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 12958 break; 12959 case 4: 12960 if (m_opcode_cpsr == 0) 12961 result = true; 12962 else 12963 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12964 break; 12965 case 5: 12966 if (m_opcode_cpsr == 0) 12967 result = true; 12968 else 12969 { 12970 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12971 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12972 result = n == v; 12973 } 12974 break; 12975 case 6: 12976 if (m_opcode_cpsr == 0) 12977 result = true; 12978 else 12979 { 12980 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12981 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12982 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12983 } 12984 break; 12985 case 7: 12986 // Always execute (cond == 0b1110, or the special 0b1111 which gives 12987 // opcodes different meanings, but always means execution happpens. 12988 if (is_conditional) 12989 *is_conditional = false; 12990 result = true; 12991 break; 12992 } 12993 12994 if (cond & 1) 12995 result = !result; 12996 return result; 12997} 12998 12999uint32_t 13000EmulateInstructionARM::CurrentCond (const uint32_t opcode) 13001{ 13002 switch (m_opcode_mode) 13003 { 13004 case eModeInvalid: 13005 break; 13006 13007 case eModeARM: 13008 return UnsignedBits(opcode, 31, 28); 13009 13010 case eModeThumb: 13011 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13012 // 'cond' field of the encoding. 13013 { 13014 const uint32_t byte_size = m_opcode.GetByteSize(); 13015 if (byte_size == 2) 13016 { 13017 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 13018 return Bits32(opcode, 11, 7); 13019 } 13020 else if (byte_size == 4) 13021 { 13022 if (Bits32(opcode, 31, 27) == 0x1e && 13023 Bits32(opcode, 15, 14) == 0x02 && 13024 Bits32(opcode, 12, 12) == 0x00 && 13025 Bits32(opcode, 25, 22) <= 0x0d) 13026 { 13027 return Bits32(opcode, 25, 22); 13028 } 13029 } 13030 else 13031 // We have an invalid thumb instruction, let's bail out. 13032 break; 13033 13034 return m_it_session.GetCond(); 13035 } 13036 } 13037 return UINT32_MAX; // Return invalid value 13038} 13039 13040bool 13041EmulateInstructionARM::InITBlock() 13042{ 13043 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13044} 13045 13046bool 13047EmulateInstructionARM::LastInITBlock() 13048{ 13049 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13050} 13051 13052bool 13053EmulateInstructionARM::BadMode (uint32_t mode) 13054{ 13055 13056 switch (mode) 13057 { 13058 case 16: return false; // '10000' 13059 case 17: return false; // '10001' 13060 case 18: return false; // '10010' 13061 case 19: return false; // '10011' 13062 case 22: return false; // '10110' 13063 case 23: return false; // '10111' 13064 case 27: return false; // '11011' 13065 case 31: return false; // '11111' 13066 default: return true; 13067 } 13068 return true; 13069} 13070 13071bool 13072EmulateInstructionARM::CurrentModeIsPrivileged () 13073{ 13074 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13075 13076 if (BadMode (mode)) 13077 return false; 13078 13079 if (mode == 16) 13080 return false; 13081 13082 return true; 13083} 13084 13085void 13086EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13087{ 13088 bool privileged = CurrentModeIsPrivileged(); 13089 13090 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13091 13092 if (BitIsSet (bytemask, 3)) 13093 { 13094 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13095 if (affect_execstate) 13096 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13097 } 13098 13099 if (BitIsSet (bytemask, 2)) 13100 { 13101 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13102 } 13103 13104 if (BitIsSet (bytemask, 1)) 13105 { 13106 if (affect_execstate) 13107 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13108 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13109 if (privileged) 13110 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13111 } 13112 13113 if (BitIsSet (bytemask, 0)) 13114 { 13115 if (privileged) 13116 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13117 if (affect_execstate) 13118 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13119 if (privileged) 13120 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13121 } 13122 13123 m_opcode_cpsr = tmp_cpsr; 13124} 13125 13126 13127bool 13128EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13129{ 13130 addr_t target; 13131 13132 // Check the current instruction set. 13133 if (CurrentInstrSet() == eModeARM) 13134 target = addr & 0xfffffffc; 13135 else 13136 target = addr & 0xfffffffe; 13137 13138 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13139 return false; 13140 13141 return true; 13142} 13143 13144// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13145bool 13146EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13147{ 13148 addr_t target; 13149 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13150 // we want to record it and issue a WriteRegister callback so the clients 13151 // can track the mode changes accordingly. 13152 bool cpsr_changed = false; 13153 13154 if (BitIsSet(addr, 0)) 13155 { 13156 if (CurrentInstrSet() != eModeThumb) 13157 { 13158 SelectInstrSet(eModeThumb); 13159 cpsr_changed = true; 13160 } 13161 target = addr & 0xfffffffe; 13162 context.SetISA (eModeThumb); 13163 } 13164 else if (BitIsClear(addr, 1)) 13165 { 13166 if (CurrentInstrSet() != eModeARM) 13167 { 13168 SelectInstrSet(eModeARM); 13169 cpsr_changed = true; 13170 } 13171 target = addr & 0xfffffffc; 13172 context.SetISA (eModeARM); 13173 } 13174 else 13175 return false; // address<1:0> == '10' => UNPREDICTABLE 13176 13177 if (cpsr_changed) 13178 { 13179 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13180 return false; 13181 } 13182 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13183 return false; 13184 13185 return true; 13186} 13187 13188// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13189bool 13190EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13191{ 13192 if (ArchVersion() >= ARMv5T) 13193 return BXWritePC(context, addr); 13194 else 13195 return BranchWritePC((const Context)context, addr); 13196} 13197 13198// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13199bool 13200EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13201{ 13202 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13203 return BXWritePC(context, addr); 13204 else 13205 return BranchWritePC((const Context)context, addr); 13206} 13207 13208EmulateInstructionARM::Mode 13209EmulateInstructionARM::CurrentInstrSet () 13210{ 13211 return m_opcode_mode; 13212} 13213 13214// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13215// ReadInstruction() is performed. This function has a side effect of updating 13216// the m_new_inst_cpsr member variable if necessary. 13217bool 13218EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13219{ 13220 m_new_inst_cpsr = m_opcode_cpsr; 13221 switch (arm_or_thumb) 13222 { 13223 default: 13224 return false; 13225 case eModeARM: 13226 // Clear the T bit. 13227 m_new_inst_cpsr &= ~MASK_CPSR_T; 13228 break; 13229 case eModeThumb: 13230 // Set the T bit. 13231 m_new_inst_cpsr |= MASK_CPSR_T; 13232 break; 13233 } 13234 return true; 13235} 13236 13237// This function returns TRUE if the processor currently provides support for 13238// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13239// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13240bool 13241EmulateInstructionARM::UnalignedSupport() 13242{ 13243 return (ArchVersion() >= ARMv7); 13244} 13245 13246// The main addition and subtraction instructions can produce status information 13247// about both unsigned carry and signed overflow conditions. This status 13248// information can be used to synthesize multi-word additions and subtractions. 13249EmulateInstructionARM::AddWithCarryResult 13250EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13251{ 13252 uint32_t result; 13253 uint8_t carry_out; 13254 uint8_t overflow; 13255 13256 uint64_t unsigned_sum = x + y + carry_in; 13257 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13258 13259 result = UnsignedBits(unsigned_sum, 31, 0); 13260// carry_out = (result == unsigned_sum ? 0 : 1); 13261 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13262 13263 if (carry_in) 13264 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13265 else 13266 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13267 13268 AddWithCarryResult res = { result, carry_out, overflow }; 13269 return res; 13270} 13271 13272uint32_t 13273EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13274{ 13275 uint32_t reg_kind, reg_num; 13276 switch (num) 13277 { 13278 case SP_REG: 13279 reg_kind = eRegisterKindGeneric; 13280 reg_num = LLDB_REGNUM_GENERIC_SP; 13281 break; 13282 case LR_REG: 13283 reg_kind = eRegisterKindGeneric; 13284 reg_num = LLDB_REGNUM_GENERIC_RA; 13285 break; 13286 case PC_REG: 13287 reg_kind = eRegisterKindGeneric; 13288 reg_num = LLDB_REGNUM_GENERIC_PC; 13289 break; 13290 default: 13291 if (num < SP_REG) 13292 { 13293 reg_kind = eRegisterKindDWARF; 13294 reg_num = dwarf_r0 + num; 13295 } 13296 else 13297 { 13298 //assert(0 && "Invalid register number"); 13299 *success = false; 13300 return UINT32_MAX; 13301 } 13302 break; 13303 } 13304 13305 // Read our register. 13306 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13307 13308 // When executing an ARM instruction , PC reads as the address of the current 13309 // instruction plus 8. 13310 // When executing a Thumb instruction , PC reads as the address of the current 13311 // instruction plus 4. 13312 if (num == 15) 13313 { 13314 if (CurrentInstrSet() == eModeARM) 13315 val += 8; 13316 else 13317 val += 4; 13318 } 13319 13320 return val; 13321} 13322 13323// Write the result to the ARM core register Rd, and optionally update the 13324// condition flags based on the result. 13325// 13326// This helper method tries to encapsulate the following pseudocode from the 13327// ARM Architecture Reference Manual: 13328// 13329// if d == 15 then // Can only occur for encoding A1 13330// ALUWritePC(result); // setflags is always FALSE here 13331// else 13332// R[d] = result; 13333// if setflags then 13334// APSR.N = result<31>; 13335// APSR.Z = IsZeroBit(result); 13336// APSR.C = carry; 13337// // APSR.V unchanged 13338// 13339// In the above case, the API client does not pass in the overflow arg, which 13340// defaults to ~0u. 13341bool 13342EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13343 const uint32_t result, 13344 const uint32_t Rd, 13345 bool setflags, 13346 const uint32_t carry, 13347 const uint32_t overflow) 13348{ 13349 if (Rd == 15) 13350 { 13351 if (!ALUWritePC (context, result)) 13352 return false; 13353 } 13354 else 13355 { 13356 uint32_t reg_kind, reg_num; 13357 switch (Rd) 13358 { 13359 case SP_REG: 13360 reg_kind = eRegisterKindGeneric; 13361 reg_num = LLDB_REGNUM_GENERIC_SP; 13362 break; 13363 case LR_REG: 13364 reg_kind = eRegisterKindGeneric; 13365 reg_num = LLDB_REGNUM_GENERIC_RA; 13366 break; 13367 default: 13368 reg_kind = eRegisterKindDWARF; 13369 reg_num = dwarf_r0 + Rd; 13370 } 13371 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13372 return false; 13373 if (setflags) 13374 return WriteFlags (context, result, carry, overflow); 13375 } 13376 return true; 13377} 13378 13379// This helper method tries to encapsulate the following pseudocode from the 13380// ARM Architecture Reference Manual: 13381// 13382// APSR.N = result<31>; 13383// APSR.Z = IsZeroBit(result); 13384// APSR.C = carry; 13385// APSR.V = overflow 13386// 13387// Default arguments can be specified for carry and overflow parameters, which means 13388// not to update the respective flags. 13389bool 13390EmulateInstructionARM::WriteFlags (Context &context, 13391 const uint32_t result, 13392 const uint32_t carry, 13393 const uint32_t overflow) 13394{ 13395 m_new_inst_cpsr = m_opcode_cpsr; 13396 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13397 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13398 if (carry != ~0u) 13399 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13400 if (overflow != ~0u) 13401 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13402 if (m_new_inst_cpsr != m_opcode_cpsr) 13403 { 13404 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13405 return false; 13406 } 13407 return true; 13408} 13409 13410bool 13411EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13412{ 13413 // Advance the ITSTATE bits to their values for the next instruction. 13414 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13415 m_it_session.ITAdvance(); 13416 13417 ARMOpcode *opcode_data = NULL; 13418 13419 if (m_opcode_mode == eModeThumb) 13420 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13421 else if (m_opcode_mode == eModeARM) 13422 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13423 13424 if (opcode_data == NULL) 13425 return false; 13426 13427 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13428 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13429 13430 bool success = false; 13431 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13432 { 13433 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13434 dwarf_cpsr, 13435 0, 13436 &success); 13437 } 13438 13439 // Only return false if we are unable to read the CPSR if we care about conditions 13440 if (success == false && m_ignore_conditions == false) 13441 return false; 13442 13443 uint32_t orig_pc_value = 0; 13444 if (auto_advance_pc) 13445 { 13446 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13447 if (!success) 13448 return false; 13449 } 13450 13451 // Call the Emulate... function. 13452 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13453 if (!success) 13454 return false; 13455 13456 if (auto_advance_pc) 13457 { 13458 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13459 if (!success) 13460 return false; 13461 13462 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13463 { 13464 if (opcode_data->size == eSize32) 13465 after_pc_value += 4; 13466 else if (opcode_data->size == eSize16) 13467 after_pc_value += 2; 13468 13469 EmulateInstruction::Context context; 13470 context.type = eContextAdvancePC; 13471 context.SetNoArgs(); 13472 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13473 return false; 13474 13475 } 13476 } 13477 return true; 13478} 13479 13480bool 13481EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13482{ 13483 if (!test_data) 13484 { 13485 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13486 return false; 13487 } 13488 13489 static ConstString opcode_key ("opcode"); 13490 static ConstString before_key ("before_state"); 13491 static ConstString after_key ("after_state"); 13492 13493 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13494 13495 uint32_t test_opcode; 13496 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13497 { 13498 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13499 return false; 13500 } 13501 test_opcode = value_sp->GetUInt64Value (); 13502 13503 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13504 { 13505 m_opcode_mode = eModeARM; 13506 m_opcode.SetOpcode32 (test_opcode); 13507 } 13508 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13509 { 13510 m_opcode_mode = eModeThumb; 13511 if (test_opcode < 0x10000) 13512 m_opcode.SetOpcode16 (test_opcode); 13513 else 13514 m_opcode.SetOpcode32 (test_opcode); 13515 13516 } 13517 else 13518 { 13519 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13520 return false; 13521 } 13522 13523 EmulationStateARM before_state; 13524 EmulationStateARM after_state; 13525 13526 value_sp = test_data->GetValueForKey (before_key); 13527 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13528 { 13529 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13530 return false; 13531 } 13532 13533 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13534 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13535 { 13536 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13537 return false; 13538 } 13539 13540 value_sp = test_data->GetValueForKey (after_key); 13541 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13542 { 13543 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13544 return false; 13545 } 13546 13547 state_dictionary = value_sp->GetAsDictionary (); 13548 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13549 { 13550 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13551 return false; 13552 } 13553 13554 SetBaton ((void *) &before_state); 13555 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13556 &EmulationStateARM::WritePseudoMemory, 13557 &EmulationStateARM::ReadPseudoRegister, 13558 &EmulationStateARM::WritePseudoRegister); 13559 13560 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13561 if (!success) 13562 { 13563 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13564 return false; 13565 } 13566 13567 success = before_state.CompareState (after_state); 13568 if (!success) 13569 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13570 13571 return success; 13572} 13573// 13574// 13575//const char * 13576//EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13577//{ 13578// if (reg_kind == eRegisterKindGeneric) 13579// { 13580// switch (reg_num) 13581// { 13582// case LLDB_REGNUM_GENERIC_PC: return "pc"; 13583// case LLDB_REGNUM_GENERIC_SP: return "sp"; 13584// case LLDB_REGNUM_GENERIC_FP: return "fp"; 13585// case LLDB_REGNUM_GENERIC_RA: return "lr"; 13586// case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13587// default: return NULL; 13588// } 13589// } 13590// else if (reg_kind == eRegisterKindDWARF) 13591// { 13592// return GetARMDWARFRegisterName (reg_num); 13593// } 13594// return NULL; 13595//} 13596// 13597bool 13598EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13599{ 13600 unwind_plan.Clear(); 13601 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13602 13603 UnwindPlan::RowSP row(new UnwindPlan::Row); 13604 13605 // Our previous Call Frame Address is the stack pointer 13606 row->SetCFARegister (dwarf_sp); 13607 13608 // Our previous PC is in the LR 13609 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true); 13610 unwind_plan.AppendRow (row); 13611 13612 // All other registers are the same. 13613 13614 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13615 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 13616 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 13617 return true; 13618} 13619