1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include <stdlib.h> 11 12 #include "EmulateInstructionARM.h" 13 #include "EmulationStateARM.h" 14 #include "lldb/Core/ArchSpec.h" 15 #include "lldb/Core/Address.h" 16 #include "lldb/Core/ConstString.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Core/Stream.h" 19 #include "lldb/Symbol/UnwindPlan.h" 20 21 #include "Plugins/Process/Utility/ARMDefines.h" 22 #include "Plugins/Process/Utility/ARMUtils.h" 23 #include "Utility/ARM_DWARF_Registers.h" 24 25 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function 26 // and CountTrailingZeros_32 function 27 28 using namespace lldb; 29 using namespace lldb_private; 30 31 // Convenient macro definitions. 32 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 33 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 34 35 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 36 37 //---------------------------------------------------------------------- 38 // 39 // ITSession implementation 40 // 41 //---------------------------------------------------------------------- 42 43 // A8.6.50 44 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 45 static uint32_t 46 CountITSize (uint32_t ITMask) { 47 // First count the trailing zeros of the IT mask. 48 uint32_t TZ = llvm::CountTrailingZeros_32(ITMask); 49 if (TZ > 3) 50 { 51 printf("Encoding error: IT Mask '0000'\n"); 52 return 0; 53 } 54 return (4 - TZ); 55 } 56 57 // Init ITState. Note that at least one bit is always 1 in mask. 58 bool ITSession::InitIT(uint32_t bits7_0) 59 { 60 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 61 if (ITCounter == 0) 62 return false; 63 64 // A8.6.50 IT 65 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 66 if (FirstCond == 0xF) 67 { 68 printf("Encoding error: IT FirstCond '1111'\n"); 69 return false; 70 } 71 if (FirstCond == 0xE && ITCounter != 1) 72 { 73 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 74 return false; 75 } 76 77 ITState = bits7_0; 78 return true; 79 } 80 81 // Update ITState if necessary. 82 void ITSession::ITAdvance() 83 { 84 //assert(ITCounter); 85 --ITCounter; 86 if (ITCounter == 0) 87 ITState = 0; 88 else 89 { 90 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 91 SetBits32(ITState, 4, 0, NewITState4_0); 92 } 93 } 94 95 // Return true if we're inside an IT Block. 96 bool ITSession::InITBlock() 97 { 98 return ITCounter != 0; 99 } 100 101 // Return true if we're the last instruction inside an IT Block. 102 bool ITSession::LastInITBlock() 103 { 104 return ITCounter == 1; 105 } 106 107 // Get condition bits for the current thumb instruction. 108 uint32_t ITSession::GetCond() 109 { 110 if (InITBlock()) 111 return Bits32(ITState, 7, 4); 112 else 113 return COND_AL; 114 } 115 116 // ARM constants used during decoding 117 #define REG_RD 0 118 #define LDM_REGLIST 1 119 #define SP_REG 13 120 #define LR_REG 14 121 #define PC_REG 15 122 #define PC_REGLIST_BIT 0x8000 123 124 #define ARMv4 (1u << 0) 125 #define ARMv4T (1u << 1) 126 #define ARMv5T (1u << 2) 127 #define ARMv5TE (1u << 3) 128 #define ARMv5TEJ (1u << 4) 129 #define ARMv6 (1u << 5) 130 #define ARMv6K (1u << 6) 131 #define ARMv6T2 (1u << 7) 132 #define ARMv7 (1u << 8) 133 #define ARMv7S (1u << 9) 134 #define ARMv8 (1u << 10) 135 #define ARMvAll (0xffffffffu) 136 137 #define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 138 #define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 139 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 140 #define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 141 #define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 142 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8) 143 #define ARMV7_ABOVE (ARMv7|ARMv7S|ARMv8) 144 145 #define No_VFP 0 146 #define VFPv1 (1u << 1) 147 #define VFPv2 (1u << 2) 148 #define VFPv3 (1u << 3) 149 #define AdvancedSIMD (1u << 4) 150 151 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 152 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 153 #define VFPv2v3 (VFPv2 | VFPv3) 154 155 //---------------------------------------------------------------------- 156 // 157 // EmulateInstructionARM implementation 158 // 159 //---------------------------------------------------------------------- 160 161 void 162 EmulateInstructionARM::Initialize () 163 { 164 PluginManager::RegisterPlugin (GetPluginNameStatic (), 165 GetPluginDescriptionStatic (), 166 CreateInstance); 167 } 168 169 void 170 EmulateInstructionARM::Terminate () 171 { 172 PluginManager::UnregisterPlugin (CreateInstance); 173 } 174 175 const char * 176 EmulateInstructionARM::GetPluginNameStatic () 177 { 178 return "lldb.emulate-instruction.arm"; 179 } 180 181 const char * 182 EmulateInstructionARM::GetPluginDescriptionStatic () 183 { 184 return "Emulate instructions for the ARM architecture."; 185 } 186 187 EmulateInstruction * 188 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) 189 { 190 if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type)) 191 { 192 if (arch.GetTriple().getArch() == llvm::Triple::arm) 193 { 194 std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 195 196 if (emulate_insn_ap.get()) 197 return emulate_insn_ap.release(); 198 } 199 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 200 { 201 std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 202 203 if (emulate_insn_ap.get()) 204 return emulate_insn_ap.release(); 205 } 206 } 207 208 return NULL; 209 } 210 211 bool 212 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch) 213 { 214 if (arch.GetTriple().getArch () == llvm::Triple::arm) 215 return true; 216 else if (arch.GetTriple().getArch () == llvm::Triple::thumb) 217 return true; 218 219 return false; 220 } 221 222 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 223 bool 224 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 225 { 226 EmulateInstruction::Context context; 227 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 228 context.SetNoArgs (); 229 230 uint32_t random_data = rand (); 231 const uint32_t addr_byte_size = GetAddressByteSize(); 232 233 if (!MemAWrite (context, address, random_data, addr_byte_size)) 234 return false; 235 236 return true; 237 } 238 239 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 240 bool 241 EmulateInstructionARM::WriteBits32Unknown (int n) 242 { 243 EmulateInstruction::Context context; 244 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 245 context.SetNoArgs (); 246 247 bool success; 248 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 249 250 if (!success) 251 return false; 252 253 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 254 return false; 255 256 return true; 257 } 258 259 bool 260 EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo ®_info) 261 { 262 if (reg_kind == eRegisterKindGeneric) 263 { 264 switch (reg_num) 265 { 266 case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break; 267 case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break; 268 case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break; 269 case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break; 270 case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break; 271 default: return false; 272 } 273 } 274 275 if (reg_kind == eRegisterKindDWARF) 276 return GetARMDWARFRegisterInfo(reg_num, reg_info); 277 return false; 278 } 279 280 uint32_t 281 EmulateInstructionARM::GetFramePointerRegisterNumber () const 282 { 283 if (m_opcode_mode == eModeThumb) 284 { 285 switch (m_arch.GetTriple().getOS()) 286 { 287 case llvm::Triple::Darwin: 288 case llvm::Triple::MacOSX: 289 case llvm::Triple::IOS: 290 return 7; 291 default: 292 break; 293 } 294 } 295 return 11; 296 } 297 298 uint32_t 299 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 300 { 301 if (m_opcode_mode == eModeThumb) 302 { 303 switch (m_arch.GetTriple().getOS()) 304 { 305 case llvm::Triple::Darwin: 306 case llvm::Triple::MacOSX: 307 case llvm::Triple::IOS: 308 return dwarf_r7; 309 default: 310 break; 311 } 312 } 313 return dwarf_r11; 314 } 315 316 // Push Multiple Registers stores multiple registers to the stack, storing to 317 // consecutive memory locations ending just below the address in SP, and updates 318 // SP to point to the start of the stored data. 319 bool 320 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 321 { 322 #if 0 323 // ARM pseudo code... 324 if (ConditionPassed()) 325 { 326 EncodingSpecificOperations(); 327 NullCheckIfThumbEE(13); 328 address = SP - 4*BitCount(registers); 329 330 for (i = 0 to 14) 331 { 332 if (registers<i> == '1') 333 { 334 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 335 MemA[address,4] = bits(32) UNKNOWN; 336 else 337 MemA[address,4] = R[i]; 338 address = address + 4; 339 } 340 } 341 342 if (registers<15> == '1') // Only possible for encoding A1 or A2 343 MemA[address,4] = PCStoreValue(); 344 345 SP = SP - 4*BitCount(registers); 346 } 347 #endif 348 349 bool conditional = false; 350 bool success = false; 351 if (ConditionPassed(opcode, &conditional)) 352 { 353 const uint32_t addr_byte_size = GetAddressByteSize(); 354 const addr_t sp = ReadCoreReg (SP_REG, &success); 355 if (!success) 356 return false; 357 uint32_t registers = 0; 358 uint32_t Rt; // the source register 359 switch (encoding) { 360 case eEncodingT1: 361 registers = Bits32(opcode, 7, 0); 362 // The M bit represents LR. 363 if (Bit32(opcode, 8)) 364 registers |= (1u << 14); 365 // if BitCount(registers) < 1 then UNPREDICTABLE; 366 if (BitCount(registers) < 1) 367 return false; 368 break; 369 case eEncodingT2: 370 // Ignore bits 15 & 13. 371 registers = Bits32(opcode, 15, 0) & ~0xa000; 372 // if BitCount(registers) < 2 then UNPREDICTABLE; 373 if (BitCount(registers) < 2) 374 return false; 375 break; 376 case eEncodingT3: 377 Rt = Bits32(opcode, 15, 12); 378 // if BadReg(t) then UNPREDICTABLE; 379 if (BadReg(Rt)) 380 return false; 381 registers = (1u << Rt); 382 break; 383 case eEncodingA1: 384 registers = Bits32(opcode, 15, 0); 385 // Instead of return false, let's handle the following case as well, 386 // which amounts to pushing one reg onto the full descending stacks. 387 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 388 break; 389 case eEncodingA2: 390 Rt = Bits32(opcode, 15, 12); 391 // if t == 13 then UNPREDICTABLE; 392 if (Rt == dwarf_sp) 393 return false; 394 registers = (1u << Rt); 395 break; 396 default: 397 return false; 398 } 399 addr_t sp_offset = addr_byte_size * BitCount (registers); 400 addr_t addr = sp - sp_offset; 401 uint32_t i; 402 403 EmulateInstruction::Context context; 404 if (conditional) 405 context.type = EmulateInstruction::eContextRegisterStore; 406 else 407 context.type = EmulateInstruction::eContextPushRegisterOnStack; 408 RegisterInfo reg_info; 409 RegisterInfo sp_reg; 410 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 411 for (i=0; i<15; ++i) 412 { 413 if (BitIsSet (registers, i)) 414 { 415 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 416 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 417 uint32_t reg_value = ReadCoreReg(i, &success); 418 if (!success) 419 return false; 420 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 421 return false; 422 addr += addr_byte_size; 423 } 424 } 425 426 if (BitIsSet (registers, 15)) 427 { 428 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 429 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 430 const uint32_t pc = ReadCoreReg(PC_REG, &success); 431 if (!success) 432 return false; 433 if (!MemAWrite (context, addr, pc, addr_byte_size)) 434 return false; 435 } 436 437 context.type = EmulateInstruction::eContextAdjustStackPointer; 438 context.SetImmediateSigned (-sp_offset); 439 440 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 441 return false; 442 } 443 return true; 444 } 445 446 // Pop Multiple Registers loads multiple registers from the stack, loading from 447 // consecutive memory locations staring at the address in SP, and updates 448 // SP to point just above the loaded data. 449 bool 450 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 451 { 452 #if 0 453 // ARM pseudo code... 454 if (ConditionPassed()) 455 { 456 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 457 address = SP; 458 for i = 0 to 14 459 if registers<i> == '1' then 460 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 461 if registers<15> == '1' then 462 if UnalignedAllowed then 463 LoadWritePC(MemU[address,4]); 464 else 465 LoadWritePC(MemA[address,4]); 466 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 467 if registers<13> == '1' then SP = bits(32) UNKNOWN; 468 } 469 #endif 470 471 bool success = false; 472 473 bool conditional = false; 474 if (ConditionPassed(opcode, &conditional)) 475 { 476 const uint32_t addr_byte_size = GetAddressByteSize(); 477 const addr_t sp = ReadCoreReg (SP_REG, &success); 478 if (!success) 479 return false; 480 uint32_t registers = 0; 481 uint32_t Rt; // the destination register 482 switch (encoding) { 483 case eEncodingT1: 484 registers = Bits32(opcode, 7, 0); 485 // The P bit represents PC. 486 if (Bit32(opcode, 8)) 487 registers |= (1u << 15); 488 // if BitCount(registers) < 1 then UNPREDICTABLE; 489 if (BitCount(registers) < 1) 490 return false; 491 break; 492 case eEncodingT2: 493 // Ignore bit 13. 494 registers = Bits32(opcode, 15, 0) & ~0x2000; 495 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 496 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 497 return false; 498 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 499 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 500 return false; 501 break; 502 case eEncodingT3: 503 Rt = Bits32(opcode, 15, 12); 504 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 505 if (Rt == 13) 506 return false; 507 if (Rt == 15 && InITBlock() && !LastInITBlock()) 508 return false; 509 registers = (1u << Rt); 510 break; 511 case eEncodingA1: 512 registers = Bits32(opcode, 15, 0); 513 // Instead of return false, let's handle the following case as well, 514 // which amounts to popping one reg from the full descending stacks. 515 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 516 517 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 518 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 519 return false; 520 break; 521 case eEncodingA2: 522 Rt = Bits32(opcode, 15, 12); 523 // if t == 13 then UNPREDICTABLE; 524 if (Rt == dwarf_sp) 525 return false; 526 registers = (1u << Rt); 527 break; 528 default: 529 return false; 530 } 531 addr_t sp_offset = addr_byte_size * BitCount (registers); 532 addr_t addr = sp; 533 uint32_t i, data; 534 535 EmulateInstruction::Context context; 536 if (conditional) 537 context.type = EmulateInstruction::eContextRegisterLoad; 538 else 539 context.type = EmulateInstruction::eContextPopRegisterOffStack; 540 541 RegisterInfo sp_reg; 542 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 543 544 for (i=0; i<15; ++i) 545 { 546 if (BitIsSet (registers, i)) 547 { 548 context.SetRegisterPlusOffset (sp_reg, addr - sp); 549 data = MemARead(context, addr, 4, 0, &success); 550 if (!success) 551 return false; 552 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 553 return false; 554 addr += addr_byte_size; 555 } 556 } 557 558 if (BitIsSet (registers, 15)) 559 { 560 context.SetRegisterPlusOffset (sp_reg, addr - sp); 561 data = MemARead(context, addr, 4, 0, &success); 562 if (!success) 563 return false; 564 // In ARMv5T and above, this is an interworking branch. 565 if (!LoadWritePC(context, data)) 566 return false; 567 addr += addr_byte_size; 568 } 569 570 context.type = EmulateInstruction::eContextAdjustStackPointer; 571 context.SetImmediateSigned (sp_offset); 572 573 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 574 return false; 575 } 576 return true; 577 } 578 579 // Set r7 or ip to point to saved value residing within the stack. 580 // ADD (SP plus immediate) 581 bool 582 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 583 { 584 #if 0 585 // ARM pseudo code... 586 if (ConditionPassed()) 587 { 588 EncodingSpecificOperations(); 589 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 590 if d == 15 then 591 ALUWritePC(result); // setflags is always FALSE here 592 else 593 R[d] = result; 594 if setflags then 595 APSR.N = result<31>; 596 APSR.Z = IsZeroBit(result); 597 APSR.C = carry; 598 APSR.V = overflow; 599 } 600 #endif 601 602 bool success = false; 603 604 if (ConditionPassed(opcode)) 605 { 606 const addr_t sp = ReadCoreReg (SP_REG, &success); 607 if (!success) 608 return false; 609 uint32_t Rd; // the destination register 610 uint32_t imm32; 611 switch (encoding) { 612 case eEncodingT1: 613 Rd = 7; 614 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 615 break; 616 case eEncodingA1: 617 Rd = Bits32(opcode, 15, 12); 618 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 619 break; 620 default: 621 return false; 622 } 623 addr_t sp_offset = imm32; 624 addr_t addr = sp + sp_offset; // a pointer to the stack area 625 626 EmulateInstruction::Context context; 627 context.type = eContextSetFramePointer; 628 RegisterInfo sp_reg; 629 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 630 context.SetRegisterPlusOffset (sp_reg, sp_offset); 631 632 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 633 return false; 634 } 635 return true; 636 } 637 638 // Set r7 or ip to the current stack pointer. 639 // MOV (register) 640 bool 641 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 642 { 643 #if 0 644 // ARM pseudo code... 645 if (ConditionPassed()) 646 { 647 EncodingSpecificOperations(); 648 result = R[m]; 649 if d == 15 then 650 ALUWritePC(result); // setflags is always FALSE here 651 else 652 R[d] = result; 653 if setflags then 654 APSR.N = result<31>; 655 APSR.Z = IsZeroBit(result); 656 // APSR.C unchanged 657 // APSR.V unchanged 658 } 659 #endif 660 661 bool success = false; 662 663 if (ConditionPassed(opcode)) 664 { 665 const addr_t sp = ReadCoreReg (SP_REG, &success); 666 if (!success) 667 return false; 668 uint32_t Rd; // the destination register 669 switch (encoding) { 670 case eEncodingT1: 671 Rd = 7; 672 break; 673 case eEncodingA1: 674 Rd = 12; 675 break; 676 default: 677 return false; 678 } 679 680 EmulateInstruction::Context context; 681 if (Rd == GetFramePointerRegisterNumber()) 682 context.type = EmulateInstruction::eContextSetFramePointer; 683 else 684 context.type = EmulateInstruction::eContextRegisterPlusOffset; 685 RegisterInfo sp_reg; 686 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 687 context.SetRegisterPlusOffset (sp_reg, 0); 688 689 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 690 return false; 691 } 692 return true; 693 } 694 695 // Move from high register (r8-r15) to low register (r0-r7). 696 // MOV (register) 697 bool 698 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 699 { 700 return EmulateMOVRdRm (opcode, encoding); 701 } 702 703 // Move from register to register. 704 // MOV (register) 705 bool 706 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 707 { 708 #if 0 709 // ARM pseudo code... 710 if (ConditionPassed()) 711 { 712 EncodingSpecificOperations(); 713 result = R[m]; 714 if d == 15 then 715 ALUWritePC(result); // setflags is always FALSE here 716 else 717 R[d] = result; 718 if setflags then 719 APSR.N = result<31>; 720 APSR.Z = IsZeroBit(result); 721 // APSR.C unchanged 722 // APSR.V unchanged 723 } 724 #endif 725 726 bool success = false; 727 728 if (ConditionPassed(opcode)) 729 { 730 uint32_t Rm; // the source register 731 uint32_t Rd; // the destination register 732 bool setflags; 733 switch (encoding) { 734 case eEncodingT1: 735 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 736 Rm = Bits32(opcode, 6, 3); 737 setflags = false; 738 if (Rd == 15 && InITBlock() && !LastInITBlock()) 739 return false; 740 break; 741 case eEncodingT2: 742 Rd = Bits32(opcode, 2, 0); 743 Rm = Bits32(opcode, 5, 3); 744 setflags = true; 745 if (InITBlock()) 746 return false; 747 break; 748 case eEncodingT3: 749 Rd = Bits32(opcode, 11, 8); 750 Rm = Bits32(opcode, 3, 0); 751 setflags = BitIsSet(opcode, 20); 752 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 753 if (setflags && (BadReg(Rd) || BadReg(Rm))) 754 return false; 755 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 756 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 757 return false; 758 break; 759 case eEncodingA1: 760 Rd = Bits32(opcode, 15, 12); 761 Rm = Bits32(opcode, 3, 0); 762 setflags = BitIsSet(opcode, 20); 763 764 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 765 if (Rd == 15 && setflags) 766 return EmulateSUBSPcLrEtc (opcode, encoding); 767 break; 768 default: 769 return false; 770 } 771 uint32_t result = ReadCoreReg(Rm, &success); 772 if (!success) 773 return false; 774 775 // The context specifies that Rm is to be moved into Rd. 776 EmulateInstruction::Context context; 777 context.type = EmulateInstruction::eContextRegisterLoad; 778 RegisterInfo dwarf_reg; 779 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 780 context.SetRegister (dwarf_reg); 781 782 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 783 return false; 784 } 785 return true; 786 } 787 788 // Move (immediate) writes an immediate value to the destination register. It 789 // can optionally update the condition flags based on the value. 790 // MOV (immediate) 791 bool 792 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 793 { 794 #if 0 795 // ARM pseudo code... 796 if (ConditionPassed()) 797 { 798 EncodingSpecificOperations(); 799 result = imm32; 800 if d == 15 then // Can only occur for ARM encoding 801 ALUWritePC(result); // setflags is always FALSE here 802 else 803 R[d] = result; 804 if setflags then 805 APSR.N = result<31>; 806 APSR.Z = IsZeroBit(result); 807 APSR.C = carry; 808 // APSR.V unchanged 809 } 810 #endif 811 812 if (ConditionPassed(opcode)) 813 { 814 uint32_t Rd; // the destination register 815 uint32_t imm32; // the immediate value to be written to Rd 816 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 817 // for setflags == false, this value is a don't care 818 // initialized to 0 to silence the static analyzer 819 bool setflags; 820 switch (encoding) { 821 case eEncodingT1: 822 Rd = Bits32(opcode, 10, 8); 823 setflags = !InITBlock(); 824 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 825 carry = APSR_C; 826 827 break; 828 829 case eEncodingT2: 830 Rd = Bits32(opcode, 11, 8); 831 setflags = BitIsSet(opcode, 20); 832 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 833 if (BadReg(Rd)) 834 return false; 835 836 break; 837 838 case eEncodingT3: 839 { 840 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 841 Rd = Bits32 (opcode, 11, 8); 842 setflags = false; 843 uint32_t imm4 = Bits32 (opcode, 19, 16); 844 uint32_t imm3 = Bits32 (opcode, 14, 12); 845 uint32_t i = Bit32 (opcode, 26); 846 uint32_t imm8 = Bits32 (opcode, 7, 0); 847 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 848 849 // if BadReg(d) then UNPREDICTABLE; 850 if (BadReg (Rd)) 851 return false; 852 } 853 break; 854 855 case eEncodingA1: 856 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 857 Rd = Bits32 (opcode, 15, 12); 858 setflags = BitIsSet (opcode, 20); 859 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 860 861 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 862 if ((Rd == 15) && setflags) 863 return EmulateSUBSPcLrEtc (opcode, encoding); 864 865 break; 866 867 case eEncodingA2: 868 { 869 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 870 Rd = Bits32 (opcode, 15, 12); 871 setflags = false; 872 uint32_t imm4 = Bits32 (opcode, 19, 16); 873 uint32_t imm12 = Bits32 (opcode, 11, 0); 874 imm32 = (imm4 << 12) | imm12; 875 876 // if d == 15 then UNPREDICTABLE; 877 if (Rd == 15) 878 return false; 879 } 880 break; 881 882 default: 883 return false; 884 } 885 uint32_t result = imm32; 886 887 // The context specifies that an immediate is to be moved into Rd. 888 EmulateInstruction::Context context; 889 context.type = EmulateInstruction::eContextImmediate; 890 context.SetNoArgs (); 891 892 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 893 return false; 894 } 895 return true; 896 } 897 898 // MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 899 // register. These 32 bits do not depend on whether the source register values are considered to be signed values or 900 // unsigned values. 901 // 902 // Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 903 // limited to only a few forms of the instruction. 904 bool 905 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 906 { 907 #if 0 908 if ConditionPassed() then 909 EncodingSpecificOperations(); 910 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 911 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 912 result = operand1 * operand2; 913 R[d] = result<31:0>; 914 if setflags then 915 APSR.N = result<31>; 916 APSR.Z = IsZeroBit(result); 917 if ArchVersion() == 4 then 918 APSR.C = bit UNKNOWN; 919 // else APSR.C unchanged 920 // APSR.V always unchanged 921 #endif 922 923 if (ConditionPassed(opcode)) 924 { 925 uint32_t d; 926 uint32_t n; 927 uint32_t m; 928 bool setflags; 929 930 // EncodingSpecificOperations(); 931 switch (encoding) 932 { 933 case eEncodingT1: 934 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 935 d = Bits32 (opcode, 2, 0); 936 n = Bits32 (opcode, 5, 3); 937 m = Bits32 (opcode, 2, 0); 938 setflags = !InITBlock(); 939 940 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 941 if ((ArchVersion() < ARMv6) && (d == n)) 942 return false; 943 944 break; 945 946 case eEncodingT2: 947 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 948 d = Bits32 (opcode, 11, 8); 949 n = Bits32 (opcode, 19, 16); 950 m = Bits32 (opcode, 3, 0); 951 setflags = false; 952 953 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 954 if (BadReg (d) || BadReg (n) || BadReg (m)) 955 return false; 956 957 break; 958 959 case eEncodingA1: 960 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 961 d = Bits32 (opcode, 19, 16); 962 n = Bits32 (opcode, 3, 0); 963 m = Bits32 (opcode, 11, 8); 964 setflags = BitIsSet (opcode, 20); 965 966 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 967 if ((d == 15) || (n == 15) || (m == 15)) 968 return false; 969 970 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 971 if ((ArchVersion() < ARMv6) && (d == n)) 972 return false; 973 974 break; 975 976 default: 977 return false; 978 } 979 980 bool success = false; 981 982 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 983 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 984 if (!success) 985 return false; 986 987 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 988 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 989 if (!success) 990 return false; 991 992 // result = operand1 * operand2; 993 uint64_t result = operand1 * operand2; 994 995 // R[d] = result<31:0>; 996 RegisterInfo op1_reg; 997 RegisterInfo op2_reg; 998 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 999 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1000 1001 EmulateInstruction::Context context; 1002 context.type = eContextArithmetic; 1003 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 1004 1005 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 1006 return false; 1007 1008 // if setflags then 1009 if (setflags) 1010 { 1011 // APSR.N = result<31>; 1012 // APSR.Z = IsZeroBit(result); 1013 m_new_inst_cpsr = m_opcode_cpsr; 1014 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 1015 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1016 if (m_new_inst_cpsr != m_opcode_cpsr) 1017 { 1018 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1019 return false; 1020 } 1021 1022 // if ArchVersion() == 4 then 1023 // APSR.C = bit UNKNOWN; 1024 } 1025 } 1026 return true; 1027 } 1028 1029 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1030 // It can optionally update the condition flags based on the value. 1031 bool 1032 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1033 { 1034 #if 0 1035 // ARM pseudo code... 1036 if (ConditionPassed()) 1037 { 1038 EncodingSpecificOperations(); 1039 result = NOT(imm32); 1040 if d == 15 then // Can only occur for ARM encoding 1041 ALUWritePC(result); // setflags is always FALSE here 1042 else 1043 R[d] = result; 1044 if setflags then 1045 APSR.N = result<31>; 1046 APSR.Z = IsZeroBit(result); 1047 APSR.C = carry; 1048 // APSR.V unchanged 1049 } 1050 #endif 1051 1052 if (ConditionPassed(opcode)) 1053 { 1054 uint32_t Rd; // the destination register 1055 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1056 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1057 bool setflags; 1058 switch (encoding) { 1059 case eEncodingT1: 1060 Rd = Bits32(opcode, 11, 8); 1061 setflags = BitIsSet(opcode, 20); 1062 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1063 break; 1064 case eEncodingA1: 1065 Rd = Bits32(opcode, 15, 12); 1066 setflags = BitIsSet(opcode, 20); 1067 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1068 1069 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1070 if (Rd == 15 && setflags) 1071 return EmulateSUBSPcLrEtc (opcode, encoding); 1072 break; 1073 default: 1074 return false; 1075 } 1076 uint32_t result = ~imm32; 1077 1078 // The context specifies that an immediate is to be moved into Rd. 1079 EmulateInstruction::Context context; 1080 context.type = EmulateInstruction::eContextImmediate; 1081 context.SetNoArgs (); 1082 1083 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1084 return false; 1085 } 1086 return true; 1087 } 1088 1089 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1090 // It can optionally update the condition flags based on the result. 1091 bool 1092 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1093 { 1094 #if 0 1095 // ARM pseudo code... 1096 if (ConditionPassed()) 1097 { 1098 EncodingSpecificOperations(); 1099 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1100 result = NOT(shifted); 1101 if d == 15 then // Can only occur for ARM encoding 1102 ALUWritePC(result); // setflags is always FALSE here 1103 else 1104 R[d] = result; 1105 if setflags then 1106 APSR.N = result<31>; 1107 APSR.Z = IsZeroBit(result); 1108 APSR.C = carry; 1109 // APSR.V unchanged 1110 } 1111 #endif 1112 1113 if (ConditionPassed(opcode)) 1114 { 1115 uint32_t Rm; // the source register 1116 uint32_t Rd; // the destination register 1117 ARM_ShifterType shift_t; 1118 uint32_t shift_n; // the shift applied to the value read from Rm 1119 bool setflags; 1120 uint32_t carry; // the carry bit after the shift operation 1121 switch (encoding) { 1122 case eEncodingT1: 1123 Rd = Bits32(opcode, 2, 0); 1124 Rm = Bits32(opcode, 5, 3); 1125 setflags = !InITBlock(); 1126 shift_t = SRType_LSL; 1127 shift_n = 0; 1128 if (InITBlock()) 1129 return false; 1130 break; 1131 case eEncodingT2: 1132 Rd = Bits32(opcode, 11, 8); 1133 Rm = Bits32(opcode, 3, 0); 1134 setflags = BitIsSet(opcode, 20); 1135 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1136 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1137 if (BadReg(Rd) || BadReg(Rm)) 1138 return false; 1139 break; 1140 case eEncodingA1: 1141 Rd = Bits32(opcode, 15, 12); 1142 Rm = Bits32(opcode, 3, 0); 1143 setflags = BitIsSet(opcode, 20); 1144 shift_n = DecodeImmShiftARM(opcode, shift_t); 1145 break; 1146 default: 1147 return false; 1148 } 1149 bool success = false; 1150 uint32_t value = ReadCoreReg(Rm, &success); 1151 if (!success) 1152 return false; 1153 1154 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1155 if (!success) 1156 return false; 1157 uint32_t result = ~shifted; 1158 1159 // The context specifies that an immediate is to be moved into Rd. 1160 EmulateInstruction::Context context; 1161 context.type = EmulateInstruction::eContextImmediate; 1162 context.SetNoArgs (); 1163 1164 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1165 return false; 1166 } 1167 return true; 1168 } 1169 1170 // PC relative immediate load into register, possibly followed by ADD (SP plus register). 1171 // LDR (literal) 1172 bool 1173 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1174 { 1175 #if 0 1176 // ARM pseudo code... 1177 if (ConditionPassed()) 1178 { 1179 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1180 base = Align(PC,4); 1181 address = if add then (base + imm32) else (base - imm32); 1182 data = MemU[address,4]; 1183 if t == 15 then 1184 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1185 elsif UnalignedSupport() || address<1:0> = '00' then 1186 R[t] = data; 1187 else // Can only apply before ARMv7 1188 if CurrentInstrSet() == InstrSet_ARM then 1189 R[t] = ROR(data, 8*UInt(address<1:0>)); 1190 else 1191 R[t] = bits(32) UNKNOWN; 1192 } 1193 #endif 1194 1195 if (ConditionPassed(opcode)) 1196 { 1197 bool success = false; 1198 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1199 if (!success) 1200 return false; 1201 1202 // PC relative immediate load context 1203 EmulateInstruction::Context context; 1204 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1205 RegisterInfo pc_reg; 1206 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1207 context.SetRegisterPlusOffset (pc_reg, 0); 1208 1209 uint32_t Rt; // the destination register 1210 uint32_t imm32; // immediate offset from the PC 1211 bool add; // +imm32 or -imm32? 1212 addr_t base; // the base address 1213 addr_t address; // the PC relative address 1214 uint32_t data; // the literal data value from the PC relative load 1215 switch (encoding) { 1216 case eEncodingT1: 1217 Rt = Bits32(opcode, 10, 8); 1218 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1219 add = true; 1220 break; 1221 case eEncodingT2: 1222 Rt = Bits32(opcode, 15, 12); 1223 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1224 add = BitIsSet(opcode, 23); 1225 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1226 return false; 1227 break; 1228 default: 1229 return false; 1230 } 1231 1232 base = Align(pc, 4); 1233 if (add) 1234 address = base + imm32; 1235 else 1236 address = base - imm32; 1237 1238 context.SetRegisterPlusOffset(pc_reg, address - base); 1239 data = MemURead(context, address, 4, 0, &success); 1240 if (!success) 1241 return false; 1242 1243 if (Rt == 15) 1244 { 1245 if (Bits32(address, 1, 0) == 0) 1246 { 1247 // In ARMv5T and above, this is an interworking branch. 1248 if (!LoadWritePC(context, data)) 1249 return false; 1250 } 1251 else 1252 return false; 1253 } 1254 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1255 { 1256 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1257 return false; 1258 } 1259 else // We don't handle ARM for now. 1260 return false; 1261 1262 } 1263 return true; 1264 } 1265 1266 // An add operation to adjust the SP. 1267 // ADD (SP plus immediate) 1268 bool 1269 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1270 { 1271 #if 0 1272 // ARM pseudo code... 1273 if (ConditionPassed()) 1274 { 1275 EncodingSpecificOperations(); 1276 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1277 if d == 15 then // Can only occur for ARM encoding 1278 ALUWritePC(result); // setflags is always FALSE here 1279 else 1280 R[d] = result; 1281 if setflags then 1282 APSR.N = result<31>; 1283 APSR.Z = IsZeroBit(result); 1284 APSR.C = carry; 1285 APSR.V = overflow; 1286 } 1287 #endif 1288 1289 bool success = false; 1290 1291 if (ConditionPassed(opcode)) 1292 { 1293 const addr_t sp = ReadCoreReg (SP_REG, &success); 1294 if (!success) 1295 return false; 1296 uint32_t imm32; // the immediate operand 1297 uint32_t d; 1298 bool setflags; 1299 switch (encoding) 1300 { 1301 case eEncodingT1: 1302 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1303 d = Bits32 (opcode, 10, 8); 1304 setflags = false; 1305 imm32 = (Bits32 (opcode, 7, 0) << 2); 1306 1307 break; 1308 1309 case eEncodingT2: 1310 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1311 d = 13; 1312 setflags = false; 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 } 1340 return true; 1341 } 1342 1343 // An add operation to adjust the SP. 1344 // ADD (SP plus register) 1345 bool 1346 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1347 { 1348 #if 0 1349 // ARM pseudo code... 1350 if (ConditionPassed()) 1351 { 1352 EncodingSpecificOperations(); 1353 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1354 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1355 if d == 15 then 1356 ALUWritePC(result); // setflags is always FALSE here 1357 else 1358 R[d] = result; 1359 if setflags then 1360 APSR.N = result<31>; 1361 APSR.Z = IsZeroBit(result); 1362 APSR.C = carry; 1363 APSR.V = overflow; 1364 } 1365 #endif 1366 1367 bool success = false; 1368 1369 if (ConditionPassed(opcode)) 1370 { 1371 const addr_t sp = ReadCoreReg (SP_REG, &success); 1372 if (!success) 1373 return false; 1374 uint32_t Rm; // the second operand 1375 switch (encoding) { 1376 case eEncodingT2: 1377 Rm = Bits32(opcode, 6, 3); 1378 break; 1379 default: 1380 return false; 1381 } 1382 int32_t reg_value = ReadCoreReg(Rm, &success); 1383 if (!success) 1384 return false; 1385 1386 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1387 1388 EmulateInstruction::Context context; 1389 context.type = eContextArithmetic; 1390 RegisterInfo sp_reg; 1391 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1392 1393 RegisterInfo other_reg; 1394 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1395 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1396 1397 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1398 return false; 1399 } 1400 return true; 1401 } 1402 1403 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1404 // at a PC-relative address, and changes instruction set from ARM to Thumb, or 1405 // from Thumb to ARM. 1406 // BLX (immediate) 1407 bool 1408 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1409 { 1410 #if 0 1411 // ARM pseudo code... 1412 if (ConditionPassed()) 1413 { 1414 EncodingSpecificOperations(); 1415 if CurrentInstrSet() == InstrSet_ARM then 1416 LR = PC - 4; 1417 else 1418 LR = PC<31:1> : '1'; 1419 if targetInstrSet == InstrSet_ARM then 1420 targetAddress = Align(PC,4) + imm32; 1421 else 1422 targetAddress = PC + imm32; 1423 SelectInstrSet(targetInstrSet); 1424 BranchWritePC(targetAddress); 1425 } 1426 #endif 1427 1428 bool success = true; 1429 1430 if (ConditionPassed(opcode)) 1431 { 1432 EmulateInstruction::Context context; 1433 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1434 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1435 if (!success) 1436 return false; 1437 addr_t lr; // next instruction address 1438 addr_t target; // target address 1439 int32_t imm32; // PC-relative offset 1440 switch (encoding) { 1441 case eEncodingT1: 1442 { 1443 lr = pc | 1u; // return address 1444 uint32_t S = Bit32(opcode, 26); 1445 uint32_t imm10 = Bits32(opcode, 25, 16); 1446 uint32_t J1 = Bit32(opcode, 13); 1447 uint32_t J2 = Bit32(opcode, 11); 1448 uint32_t imm11 = Bits32(opcode, 10, 0); 1449 uint32_t I1 = !(J1 ^ S); 1450 uint32_t I2 = !(J2 ^ S); 1451 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1452 imm32 = llvm::SignExtend32<25>(imm25); 1453 target = pc + imm32; 1454 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1455 if (InITBlock() && !LastInITBlock()) 1456 return false; 1457 break; 1458 } 1459 case eEncodingT2: 1460 { 1461 lr = pc | 1u; // return address 1462 uint32_t S = Bit32(opcode, 26); 1463 uint32_t imm10H = Bits32(opcode, 25, 16); 1464 uint32_t J1 = Bit32(opcode, 13); 1465 uint32_t J2 = Bit32(opcode, 11); 1466 uint32_t imm10L = Bits32(opcode, 10, 1); 1467 uint32_t I1 = !(J1 ^ S); 1468 uint32_t I2 = !(J2 ^ S); 1469 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1470 imm32 = llvm::SignExtend32<25>(imm25); 1471 target = Align(pc, 4) + imm32; 1472 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1473 if (InITBlock() && !LastInITBlock()) 1474 return false; 1475 break; 1476 } 1477 case eEncodingA1: 1478 lr = pc - 4; // return address 1479 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1480 target = Align(pc, 4) + imm32; 1481 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1482 break; 1483 case eEncodingA2: 1484 lr = pc - 4; // return address 1485 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1486 target = pc + imm32; 1487 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1488 break; 1489 default: 1490 return false; 1491 } 1492 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1493 return false; 1494 if (!BranchWritePC(context, target)) 1495 return false; 1496 } 1497 return true; 1498 } 1499 1500 // Branch with Link and Exchange (register) calls a subroutine at an address and 1501 // instruction set specified by a register. 1502 // BLX (register) 1503 bool 1504 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1505 { 1506 #if 0 1507 // ARM pseudo code... 1508 if (ConditionPassed()) 1509 { 1510 EncodingSpecificOperations(); 1511 target = R[m]; 1512 if CurrentInstrSet() == InstrSet_ARM then 1513 next_instr_addr = PC - 4; 1514 LR = next_instr_addr; 1515 else 1516 next_instr_addr = PC - 2; 1517 LR = next_instr_addr<31:1> : '1'; 1518 BXWritePC(target); 1519 } 1520 #endif 1521 1522 bool success = false; 1523 1524 if (ConditionPassed(opcode)) 1525 { 1526 EmulateInstruction::Context context; 1527 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1528 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1529 addr_t lr; // next instruction address 1530 if (!success) 1531 return false; 1532 uint32_t Rm; // the register with the target address 1533 switch (encoding) { 1534 case eEncodingT1: 1535 lr = (pc - 2) | 1u; // return address 1536 Rm = Bits32(opcode, 6, 3); 1537 // if m == 15 then UNPREDICTABLE; 1538 if (Rm == 15) 1539 return false; 1540 if (InITBlock() && !LastInITBlock()) 1541 return false; 1542 break; 1543 case eEncodingA1: 1544 lr = pc - 4; // return address 1545 Rm = Bits32(opcode, 3, 0); 1546 // if m == 15 then UNPREDICTABLE; 1547 if (Rm == 15) 1548 return false; 1549 break; 1550 default: 1551 return false; 1552 } 1553 addr_t target = ReadCoreReg (Rm, &success); 1554 if (!success) 1555 return false; 1556 RegisterInfo dwarf_reg; 1557 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1558 context.SetRegister (dwarf_reg); 1559 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1560 return false; 1561 if (!BXWritePC(context, target)) 1562 return false; 1563 } 1564 return true; 1565 } 1566 1567 // Branch and Exchange causes a branch to an address and instruction set specified by a register. 1568 bool 1569 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1570 { 1571 #if 0 1572 // ARM pseudo code... 1573 if (ConditionPassed()) 1574 { 1575 EncodingSpecificOperations(); 1576 BXWritePC(R[m]); 1577 } 1578 #endif 1579 1580 if (ConditionPassed(opcode)) 1581 { 1582 EmulateInstruction::Context context; 1583 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1584 uint32_t Rm; // the register with the target address 1585 switch (encoding) { 1586 case eEncodingT1: 1587 Rm = Bits32(opcode, 6, 3); 1588 if (InITBlock() && !LastInITBlock()) 1589 return false; 1590 break; 1591 case eEncodingA1: 1592 Rm = Bits32(opcode, 3, 0); 1593 break; 1594 default: 1595 return false; 1596 } 1597 bool success = false; 1598 addr_t target = ReadCoreReg (Rm, &success); 1599 if (!success) 1600 return false; 1601 1602 RegisterInfo dwarf_reg; 1603 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1604 context.SetRegister (dwarf_reg); 1605 if (!BXWritePC(context, target)) 1606 return false; 1607 } 1608 return true; 1609 } 1610 1611 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1612 // address and instruction set specified by a register as though it were a BX instruction. 1613 // 1614 // TODO: Emulate Jazelle architecture? 1615 // We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1616 bool 1617 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1618 { 1619 #if 0 1620 // ARM pseudo code... 1621 if (ConditionPassed()) 1622 { 1623 EncodingSpecificOperations(); 1624 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1625 BXWritePC(R[m]); 1626 else 1627 if JazelleAcceptsExecution() then 1628 SwitchToJazelleExecution(); 1629 else 1630 SUBARCHITECTURE_DEFINED handler call; 1631 } 1632 #endif 1633 1634 if (ConditionPassed(opcode)) 1635 { 1636 EmulateInstruction::Context context; 1637 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1638 uint32_t Rm; // the register with the target address 1639 switch (encoding) { 1640 case eEncodingT1: 1641 Rm = Bits32(opcode, 19, 16); 1642 if (BadReg(Rm)) 1643 return false; 1644 if (InITBlock() && !LastInITBlock()) 1645 return false; 1646 break; 1647 case eEncodingA1: 1648 Rm = Bits32(opcode, 3, 0); 1649 if (Rm == 15) 1650 return false; 1651 break; 1652 default: 1653 return false; 1654 } 1655 bool success = false; 1656 addr_t target = ReadCoreReg (Rm, &success); 1657 if (!success) 1658 return false; 1659 1660 RegisterInfo dwarf_reg; 1661 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1662 context.SetRegister (dwarf_reg); 1663 if (!BXWritePC(context, target)) 1664 return false; 1665 } 1666 return true; 1667 } 1668 1669 // Set r7 to point to some ip offset. 1670 // SUB (immediate) 1671 bool 1672 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1673 { 1674 #if 0 1675 // ARM pseudo code... 1676 if (ConditionPassed()) 1677 { 1678 EncodingSpecificOperations(); 1679 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1680 if d == 15 then // Can only occur for ARM encoding 1681 ALUWritePC(result); // setflags is always FALSE here 1682 else 1683 R[d] = result; 1684 if setflags then 1685 APSR.N = result<31>; 1686 APSR.Z = IsZeroBit(result); 1687 APSR.C = carry; 1688 APSR.V = overflow; 1689 } 1690 #endif 1691 1692 if (ConditionPassed(opcode)) 1693 { 1694 bool success = false; 1695 const addr_t ip = ReadCoreReg (12, &success); 1696 if (!success) 1697 return false; 1698 uint32_t imm32; 1699 switch (encoding) { 1700 case eEncodingA1: 1701 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1702 break; 1703 default: 1704 return false; 1705 } 1706 addr_t ip_offset = imm32; 1707 addr_t addr = ip - ip_offset; // the adjusted ip value 1708 1709 EmulateInstruction::Context context; 1710 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1711 RegisterInfo dwarf_reg; 1712 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1713 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1714 1715 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1716 return false; 1717 } 1718 return true; 1719 } 1720 1721 // Set ip to point to some stack offset. 1722 // SUB (SP minus immediate) 1723 bool 1724 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1725 { 1726 #if 0 1727 // ARM pseudo code... 1728 if (ConditionPassed()) 1729 { 1730 EncodingSpecificOperations(); 1731 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1732 if d == 15 then // Can only occur for ARM encoding 1733 ALUWritePC(result); // setflags is always FALSE here 1734 else 1735 R[d] = result; 1736 if setflags then 1737 APSR.N = result<31>; 1738 APSR.Z = IsZeroBit(result); 1739 APSR.C = carry; 1740 APSR.V = overflow; 1741 } 1742 #endif 1743 1744 if (ConditionPassed(opcode)) 1745 { 1746 bool success = false; 1747 const addr_t sp = ReadCoreReg (SP_REG, &success); 1748 if (!success) 1749 return false; 1750 uint32_t imm32; 1751 switch (encoding) { 1752 case eEncodingA1: 1753 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1754 break; 1755 default: 1756 return false; 1757 } 1758 addr_t sp_offset = imm32; 1759 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1760 1761 EmulateInstruction::Context context; 1762 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1763 RegisterInfo dwarf_reg; 1764 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1765 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1766 1767 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1768 return false; 1769 } 1770 return true; 1771 } 1772 1773 // This instruction subtracts an immediate value from the SP value, and writes 1774 // the result to the destination register. 1775 // 1776 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1777 bool 1778 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1779 { 1780 #if 0 1781 // ARM pseudo code... 1782 if (ConditionPassed()) 1783 { 1784 EncodingSpecificOperations(); 1785 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1786 if d == 15 then // Can only occur for ARM encoding 1787 ALUWritePC(result); // setflags is always FALSE here 1788 else 1789 R[d] = result; 1790 if setflags then 1791 APSR.N = result<31>; 1792 APSR.Z = IsZeroBit(result); 1793 APSR.C = carry; 1794 APSR.V = overflow; 1795 } 1796 #endif 1797 1798 bool success = false; 1799 if (ConditionPassed(opcode)) 1800 { 1801 const addr_t sp = ReadCoreReg (SP_REG, &success); 1802 if (!success) 1803 return false; 1804 1805 uint32_t Rd; 1806 bool setflags; 1807 uint32_t imm32; 1808 switch (encoding) { 1809 case eEncodingT1: 1810 Rd = 13; 1811 setflags = false; 1812 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1813 break; 1814 case eEncodingT2: 1815 Rd = Bits32(opcode, 11, 8); 1816 setflags = BitIsSet(opcode, 20); 1817 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1818 if (Rd == 15 && setflags) 1819 return EmulateCMPImm(opcode, eEncodingT2); 1820 if (Rd == 15 && !setflags) 1821 return false; 1822 break; 1823 case eEncodingT3: 1824 Rd = Bits32(opcode, 11, 8); 1825 setflags = false; 1826 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1827 if (Rd == 15) 1828 return false; 1829 break; 1830 case eEncodingA1: 1831 Rd = Bits32(opcode, 15, 12); 1832 setflags = BitIsSet(opcode, 20); 1833 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1834 1835 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1836 if (Rd == 15 && setflags) 1837 return EmulateSUBSPcLrEtc (opcode, encoding); 1838 break; 1839 default: 1840 return false; 1841 } 1842 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1843 1844 EmulateInstruction::Context context; 1845 if (Rd == 13) 1846 { 1847 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1848 // value gets passed down to context.SetImmediateSigned. 1849 context.type = EmulateInstruction::eContextAdjustStackPointer; 1850 context.SetImmediateSigned (-imm64); // the stack pointer offset 1851 } 1852 else 1853 { 1854 context.type = EmulateInstruction::eContextImmediate; 1855 context.SetNoArgs (); 1856 } 1857 1858 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1859 return false; 1860 } 1861 return true; 1862 } 1863 1864 // A store operation to the stack that also updates the SP. 1865 bool 1866 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1867 { 1868 #if 0 1869 // ARM pseudo code... 1870 if (ConditionPassed()) 1871 { 1872 EncodingSpecificOperations(); 1873 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1874 address = if index then offset_addr else R[n]; 1875 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1876 if wback then R[n] = offset_addr; 1877 } 1878 #endif 1879 1880 bool conditional = false; 1881 bool success = false; 1882 if (ConditionPassed(opcode, &conditional)) 1883 { 1884 const uint32_t addr_byte_size = GetAddressByteSize(); 1885 const addr_t sp = ReadCoreReg (SP_REG, &success); 1886 if (!success) 1887 return false; 1888 uint32_t Rt; // the source register 1889 uint32_t imm12; 1890 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1891 1892 bool index; 1893 bool add; 1894 bool wback; 1895 switch (encoding) { 1896 case eEncodingA1: 1897 Rt = Bits32(opcode, 15, 12); 1898 imm12 = Bits32(opcode, 11, 0); 1899 Rn = Bits32 (opcode, 19, 16); 1900 1901 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1902 return false; 1903 1904 index = BitIsSet (opcode, 24); 1905 add = BitIsSet (opcode, 23); 1906 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1907 1908 if (wback && ((Rn == 15) || (Rn == Rt))) 1909 return false; 1910 break; 1911 default: 1912 return false; 1913 } 1914 addr_t offset_addr; 1915 if (add) 1916 offset_addr = sp + imm12; 1917 else 1918 offset_addr = sp - imm12; 1919 1920 addr_t addr; 1921 if (index) 1922 addr = offset_addr; 1923 else 1924 addr = sp; 1925 1926 EmulateInstruction::Context context; 1927 if (conditional) 1928 context.type = EmulateInstruction::eContextRegisterStore; 1929 else 1930 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1931 RegisterInfo sp_reg; 1932 RegisterInfo dwarf_reg; 1933 1934 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1935 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 1936 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 1937 if (Rt != 15) 1938 { 1939 uint32_t reg_value = ReadCoreReg(Rt, &success); 1940 if (!success) 1941 return false; 1942 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1943 return false; 1944 } 1945 else 1946 { 1947 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1948 if (!success) 1949 return false; 1950 if (!MemUWrite (context, addr, pc, addr_byte_size)) 1951 return false; 1952 } 1953 1954 1955 if (wback) 1956 { 1957 context.type = EmulateInstruction::eContextAdjustStackPointer; 1958 context.SetImmediateSigned (addr - sp); 1959 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 1960 return false; 1961 } 1962 } 1963 return true; 1964 } 1965 1966 // Vector Push stores multiple extension registers to the stack. 1967 // It also updates SP to point to the start of the stored data. 1968 bool 1969 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 1970 { 1971 #if 0 1972 // ARM pseudo code... 1973 if (ConditionPassed()) 1974 { 1975 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1976 address = SP - imm32; 1977 SP = SP - imm32; 1978 if single_regs then 1979 for r = 0 to regs-1 1980 MemA[address,4] = S[d+r]; address = address+4; 1981 else 1982 for r = 0 to regs-1 1983 // Store as two word-aligned words in the correct order for current endianness. 1984 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1985 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1986 address = address+8; 1987 } 1988 #endif 1989 1990 bool success = false; 1991 bool conditional = false; 1992 if (ConditionPassed(opcode, &conditional)) 1993 { 1994 const uint32_t addr_byte_size = GetAddressByteSize(); 1995 const addr_t sp = ReadCoreReg (SP_REG, &success); 1996 if (!success) 1997 return false; 1998 bool single_regs; 1999 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2000 uint32_t imm32; // stack offset 2001 uint32_t regs; // number of registers 2002 switch (encoding) { 2003 case eEncodingT1: 2004 case eEncodingA1: 2005 single_regs = false; 2006 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2007 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2008 // If UInt(imm8) is odd, see "FSTMX". 2009 regs = Bits32(opcode, 7, 0) / 2; 2010 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2011 if (regs == 0 || regs > 16 || (d + regs) > 32) 2012 return false; 2013 break; 2014 case eEncodingT2: 2015 case eEncodingA2: 2016 single_regs = true; 2017 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2018 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2019 regs = Bits32(opcode, 7, 0); 2020 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2021 if (regs == 0 || regs > 16 || (d + regs) > 32) 2022 return false; 2023 break; 2024 default: 2025 return false; 2026 } 2027 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2028 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2029 addr_t sp_offset = imm32; 2030 addr_t addr = sp - sp_offset; 2031 uint32_t i; 2032 2033 EmulateInstruction::Context context; 2034 if (conditional) 2035 context.type = EmulateInstruction::eContextRegisterStore; 2036 else 2037 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2038 RegisterInfo dwarf_reg; 2039 RegisterInfo sp_reg; 2040 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2041 for (i=0; i<regs; ++i) 2042 { 2043 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2044 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2045 // uint64_t to accommodate 64-bit registers. 2046 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2047 if (!success) 2048 return false; 2049 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2050 return false; 2051 addr += reg_byte_size; 2052 } 2053 2054 context.type = EmulateInstruction::eContextAdjustStackPointer; 2055 context.SetImmediateSigned (-sp_offset); 2056 2057 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2058 return false; 2059 } 2060 return true; 2061 } 2062 2063 // Vector Pop loads multiple extension registers from the stack. 2064 // It also updates SP to point just above the loaded data. 2065 bool 2066 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2067 { 2068 #if 0 2069 // ARM pseudo code... 2070 if (ConditionPassed()) 2071 { 2072 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2073 address = SP; 2074 SP = SP + imm32; 2075 if single_regs then 2076 for r = 0 to regs-1 2077 S[d+r] = MemA[address,4]; address = address+4; 2078 else 2079 for r = 0 to regs-1 2080 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2081 // Combine the word-aligned words in the correct order for current endianness. 2082 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2083 } 2084 #endif 2085 2086 bool success = false; 2087 bool conditional = false; 2088 if (ConditionPassed(opcode, &conditional)) 2089 { 2090 const uint32_t addr_byte_size = GetAddressByteSize(); 2091 const addr_t sp = ReadCoreReg (SP_REG, &success); 2092 if (!success) 2093 return false; 2094 bool single_regs; 2095 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2096 uint32_t imm32; // stack offset 2097 uint32_t regs; // number of registers 2098 switch (encoding) { 2099 case eEncodingT1: 2100 case eEncodingA1: 2101 single_regs = false; 2102 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2103 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2104 // If UInt(imm8) is odd, see "FLDMX". 2105 regs = Bits32(opcode, 7, 0) / 2; 2106 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2107 if (regs == 0 || regs > 16 || (d + regs) > 32) 2108 return false; 2109 break; 2110 case eEncodingT2: 2111 case eEncodingA2: 2112 single_regs = true; 2113 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2114 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2115 regs = Bits32(opcode, 7, 0); 2116 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2117 if (regs == 0 || regs > 16 || (d + regs) > 32) 2118 return false; 2119 break; 2120 default: 2121 return false; 2122 } 2123 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2124 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2125 addr_t sp_offset = imm32; 2126 addr_t addr = sp; 2127 uint32_t i; 2128 uint64_t data; // uint64_t to accomodate 64-bit registers. 2129 2130 EmulateInstruction::Context context; 2131 if (conditional) 2132 context.type = EmulateInstruction::eContextRegisterLoad; 2133 else 2134 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2135 RegisterInfo dwarf_reg; 2136 RegisterInfo sp_reg; 2137 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2138 for (i=0; i<regs; ++i) 2139 { 2140 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2141 context.SetRegisterPlusOffset (sp_reg, addr - sp); 2142 data = MemARead(context, addr, reg_byte_size, 0, &success); 2143 if (!success) 2144 return false; 2145 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2146 return false; 2147 addr += reg_byte_size; 2148 } 2149 2150 context.type = EmulateInstruction::eContextAdjustStackPointer; 2151 context.SetImmediateSigned (sp_offset); 2152 2153 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2154 return false; 2155 } 2156 return true; 2157 } 2158 2159 // SVC (previously SWI) 2160 bool 2161 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2162 { 2163 #if 0 2164 // ARM pseudo code... 2165 if (ConditionPassed()) 2166 { 2167 EncodingSpecificOperations(); 2168 CallSupervisor(); 2169 } 2170 #endif 2171 2172 bool success = false; 2173 2174 if (ConditionPassed(opcode)) 2175 { 2176 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2177 addr_t lr; // next instruction address 2178 if (!success) 2179 return false; 2180 uint32_t imm32; // the immediate constant 2181 uint32_t mode; // ARM or Thumb mode 2182 switch (encoding) { 2183 case eEncodingT1: 2184 lr = (pc + 2) | 1u; // return address 2185 imm32 = Bits32(opcode, 7, 0); 2186 mode = eModeThumb; 2187 break; 2188 case eEncodingA1: 2189 lr = pc + 4; // return address 2190 imm32 = Bits32(opcode, 23, 0); 2191 mode = eModeARM; 2192 break; 2193 default: 2194 return false; 2195 } 2196 2197 EmulateInstruction::Context context; 2198 context.type = EmulateInstruction::eContextSupervisorCall; 2199 context.SetISAAndImmediate (mode, imm32); 2200 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2201 return false; 2202 } 2203 return true; 2204 } 2205 2206 // If Then makes up to four following instructions (the IT block) conditional. 2207 bool 2208 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2209 { 2210 #if 0 2211 // ARM pseudo code... 2212 EncodingSpecificOperations(); 2213 ITSTATE.IT<7:0> = firstcond:mask; 2214 #endif 2215 2216 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2217 return true; 2218 } 2219 2220 bool 2221 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2222 { 2223 // NOP, nothing to do... 2224 return true; 2225 } 2226 2227 // Branch causes a branch to a target address. 2228 bool 2229 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2230 { 2231 #if 0 2232 // ARM pseudo code... 2233 if (ConditionPassed()) 2234 { 2235 EncodingSpecificOperations(); 2236 BranchWritePC(PC + imm32); 2237 } 2238 #endif 2239 2240 bool success = false; 2241 2242 if (ConditionPassed(opcode)) 2243 { 2244 EmulateInstruction::Context context; 2245 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2246 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2247 if (!success) 2248 return false; 2249 addr_t target; // target address 2250 int32_t imm32; // PC-relative offset 2251 switch (encoding) { 2252 case eEncodingT1: 2253 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2254 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2255 target = pc + imm32; 2256 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2257 break; 2258 case eEncodingT2: 2259 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2260 target = pc + imm32; 2261 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2262 break; 2263 case eEncodingT3: 2264 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2265 { 2266 uint32_t S = Bit32(opcode, 26); 2267 uint32_t imm6 = Bits32(opcode, 21, 16); 2268 uint32_t J1 = Bit32(opcode, 13); 2269 uint32_t J2 = Bit32(opcode, 11); 2270 uint32_t imm11 = Bits32(opcode, 10, 0); 2271 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2272 imm32 = llvm::SignExtend32<21>(imm21); 2273 target = pc + imm32; 2274 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2275 break; 2276 } 2277 case eEncodingT4: 2278 { 2279 uint32_t S = Bit32(opcode, 26); 2280 uint32_t imm10 = Bits32(opcode, 25, 16); 2281 uint32_t J1 = Bit32(opcode, 13); 2282 uint32_t J2 = Bit32(opcode, 11); 2283 uint32_t imm11 = Bits32(opcode, 10, 0); 2284 uint32_t I1 = !(J1 ^ S); 2285 uint32_t I2 = !(J2 ^ S); 2286 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2287 imm32 = llvm::SignExtend32<25>(imm25); 2288 target = pc + imm32; 2289 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2290 break; 2291 } 2292 case eEncodingA1: 2293 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2294 target = pc + imm32; 2295 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2296 break; 2297 default: 2298 return false; 2299 } 2300 if (!BranchWritePC(context, target)) 2301 return false; 2302 } 2303 return true; 2304 } 2305 2306 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2307 // zero and conditionally branch forward a constant value. They do not affect the condition flags. 2308 // CBNZ, CBZ 2309 bool 2310 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2311 { 2312 #if 0 2313 // ARM pseudo code... 2314 EncodingSpecificOperations(); 2315 if nonzero ^ IsZero(R[n]) then 2316 BranchWritePC(PC + imm32); 2317 #endif 2318 2319 bool success = false; 2320 2321 // Read the register value from the operand register Rn. 2322 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2323 if (!success) 2324 return false; 2325 2326 EmulateInstruction::Context context; 2327 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2328 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2329 if (!success) 2330 return false; 2331 2332 addr_t target; // target address 2333 uint32_t imm32; // PC-relative offset to branch forward 2334 bool nonzero; 2335 switch (encoding) { 2336 case eEncodingT1: 2337 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2338 nonzero = BitIsSet(opcode, 11); 2339 target = pc + imm32; 2340 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2341 break; 2342 default: 2343 return false; 2344 } 2345 if (nonzero ^ (reg_val == 0)) 2346 if (!BranchWritePC(context, target)) 2347 return false; 2348 2349 return true; 2350 } 2351 2352 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2353 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2354 // The branch length is twice the value of the byte returned from the table. 2355 // 2356 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2357 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2358 // The branch length is twice the value of the halfword returned from the table. 2359 // TBB, TBH 2360 bool 2361 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2362 { 2363 #if 0 2364 // ARM pseudo code... 2365 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2366 if is_tbh then 2367 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2368 else 2369 halfwords = UInt(MemU[R[n]+R[m], 1]); 2370 BranchWritePC(PC + 2*halfwords); 2371 #endif 2372 2373 bool success = false; 2374 2375 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2376 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2377 bool is_tbh; // true if table branch halfword 2378 switch (encoding) { 2379 case eEncodingT1: 2380 Rn = Bits32(opcode, 19, 16); 2381 Rm = Bits32(opcode, 3, 0); 2382 is_tbh = BitIsSet(opcode, 4); 2383 if (Rn == 13 || BadReg(Rm)) 2384 return false; 2385 if (InITBlock() && !LastInITBlock()) 2386 return false; 2387 break; 2388 default: 2389 return false; 2390 } 2391 2392 // Read the address of the table from the operand register Rn. 2393 // The PC can be used, in which case the table immediately follows this instruction. 2394 uint32_t base = ReadCoreReg(Rm, &success); 2395 if (!success) 2396 return false; 2397 2398 // the table index 2399 uint32_t index = ReadCoreReg(Rm, &success); 2400 if (!success) 2401 return false; 2402 2403 // the offsetted table address 2404 addr_t addr = base + (is_tbh ? index*2 : index); 2405 2406 // PC-relative offset to branch forward 2407 EmulateInstruction::Context context; 2408 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2409 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2410 if (!success) 2411 return false; 2412 2413 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2414 if (!success) 2415 return false; 2416 2417 // target address 2418 addr_t target = pc + offset; 2419 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2420 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2421 2422 if (!BranchWritePC(context, target)) 2423 return false; 2424 2425 return true; 2426 } 2427 2428 // This instruction adds an immediate value to a register value, and writes the result to the destination register. 2429 // It can optionally update the condition flags based on the result. 2430 bool 2431 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2432 { 2433 #if 0 2434 if ConditionPassed() then 2435 EncodingSpecificOperations(); 2436 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2437 R[d] = result; 2438 if setflags then 2439 APSR.N = result<31>; 2440 APSR.Z = IsZeroBit(result); 2441 APSR.C = carry; 2442 APSR.V = overflow; 2443 #endif 2444 2445 bool success = false; 2446 2447 if (ConditionPassed(opcode)) 2448 { 2449 uint32_t d; 2450 uint32_t n; 2451 bool setflags; 2452 uint32_t imm32; 2453 uint32_t carry_out; 2454 2455 //EncodingSpecificOperations(); 2456 switch (encoding) 2457 { 2458 case eEncodingT1: 2459 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2460 d = Bits32 (opcode, 2, 0); 2461 n = Bits32 (opcode, 5, 3); 2462 setflags = !InITBlock(); 2463 imm32 = Bits32 (opcode, 8,6); 2464 2465 break; 2466 2467 case eEncodingT2: 2468 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2469 d = Bits32 (opcode, 10, 8); 2470 n = Bits32 (opcode, 10, 8); 2471 setflags = !InITBlock(); 2472 imm32 = Bits32 (opcode, 7, 0); 2473 2474 break; 2475 2476 case eEncodingT3: 2477 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2478 // if Rn == '1101' then SEE ADD (SP plus immediate); 2479 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2480 d = Bits32 (opcode, 11, 8); 2481 n = Bits32 (opcode, 19, 16); 2482 setflags = BitIsSet (opcode, 20); 2483 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2484 2485 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2486 if (BadReg (d) || (n == 15)) 2487 return false; 2488 2489 break; 2490 2491 case eEncodingT4: 2492 { 2493 // if Rn == '1111' then SEE ADR; 2494 // if Rn == '1101' then SEE ADD (SP plus immediate); 2495 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2496 d = Bits32 (opcode, 11, 8); 2497 n = Bits32 (opcode, 19, 16); 2498 setflags = false; 2499 uint32_t i = Bit32 (opcode, 26); 2500 uint32_t imm3 = Bits32 (opcode, 14, 12); 2501 uint32_t imm8 = Bits32 (opcode, 7, 0); 2502 imm32 = (i << 11) | (imm3 << 8) | imm8; 2503 2504 // if BadReg(d) then UNPREDICTABLE; 2505 if (BadReg (d)) 2506 return false; 2507 2508 break; 2509 } 2510 default: 2511 return false; 2512 } 2513 2514 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2515 if (!success) 2516 return false; 2517 2518 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2519 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2520 2521 RegisterInfo reg_n; 2522 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2523 2524 EmulateInstruction::Context context; 2525 context.type = eContextArithmetic; 2526 context.SetRegisterPlusOffset (reg_n, imm32); 2527 2528 //R[d] = result; 2529 //if setflags then 2530 //APSR.N = result<31>; 2531 //APSR.Z = IsZeroBit(result); 2532 //APSR.C = carry; 2533 //APSR.V = overflow; 2534 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2535 return false; 2536 2537 } 2538 return true; 2539 } 2540 2541 // This instruction adds an immediate value to a register value, and writes the result to the destination 2542 // register. It can optionally update the condition flags based on the result. 2543 bool 2544 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2545 { 2546 #if 0 2547 // ARM pseudo code... 2548 if ConditionPassed() then 2549 EncodingSpecificOperations(); 2550 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2551 if d == 15 then 2552 ALUWritePC(result); // setflags is always FALSE here 2553 else 2554 R[d] = result; 2555 if setflags then 2556 APSR.N = result<31>; 2557 APSR.Z = IsZeroBit(result); 2558 APSR.C = carry; 2559 APSR.V = overflow; 2560 #endif 2561 2562 bool success = false; 2563 2564 if (ConditionPassed(opcode)) 2565 { 2566 uint32_t Rd, Rn; 2567 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2568 bool setflags; 2569 switch (encoding) 2570 { 2571 case eEncodingA1: 2572 Rd = Bits32(opcode, 15, 12); 2573 Rn = Bits32(opcode, 19, 16); 2574 setflags = BitIsSet(opcode, 20); 2575 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2576 break; 2577 default: 2578 return false; 2579 } 2580 2581 // Read the first operand. 2582 uint32_t val1 = ReadCoreReg(Rn, &success); 2583 if (!success) 2584 return false; 2585 2586 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2587 2588 EmulateInstruction::Context context; 2589 context.type = eContextArithmetic; 2590 RegisterInfo dwarf_reg; 2591 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2592 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2593 2594 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2595 return false; 2596 } 2597 return true; 2598 } 2599 2600 // This instruction adds a register value and an optionally-shifted register value, and writes the result 2601 // to the destination register. It can optionally update the condition flags based on the result. 2602 bool 2603 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2604 { 2605 #if 0 2606 // ARM pseudo code... 2607 if ConditionPassed() then 2608 EncodingSpecificOperations(); 2609 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2610 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2611 if d == 15 then 2612 ALUWritePC(result); // setflags is always FALSE here 2613 else 2614 R[d] = result; 2615 if setflags then 2616 APSR.N = result<31>; 2617 APSR.Z = IsZeroBit(result); 2618 APSR.C = carry; 2619 APSR.V = overflow; 2620 #endif 2621 2622 bool success = false; 2623 2624 if (ConditionPassed(opcode)) 2625 { 2626 uint32_t Rd, Rn, Rm; 2627 ARM_ShifterType shift_t; 2628 uint32_t shift_n; // the shift applied to the value read from Rm 2629 bool setflags; 2630 switch (encoding) 2631 { 2632 case eEncodingT1: 2633 Rd = Bits32(opcode, 2, 0); 2634 Rn = Bits32(opcode, 5, 3); 2635 Rm = Bits32(opcode, 8, 6); 2636 setflags = !InITBlock(); 2637 shift_t = SRType_LSL; 2638 shift_n = 0; 2639 break; 2640 case eEncodingT2: 2641 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2642 Rm = Bits32(opcode, 6, 3); 2643 setflags = false; 2644 shift_t = SRType_LSL; 2645 shift_n = 0; 2646 if (Rn == 15 && Rm == 15) 2647 return false; 2648 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2649 return false; 2650 break; 2651 case eEncodingA1: 2652 Rd = Bits32(opcode, 15, 12); 2653 Rn = Bits32(opcode, 19, 16); 2654 Rm = Bits32(opcode, 3, 0); 2655 setflags = BitIsSet(opcode, 20); 2656 shift_n = DecodeImmShiftARM(opcode, shift_t); 2657 break; 2658 default: 2659 return false; 2660 } 2661 2662 // Read the first operand. 2663 uint32_t val1 = ReadCoreReg(Rn, &success); 2664 if (!success) 2665 return false; 2666 2667 // Read the second operand. 2668 uint32_t val2 = ReadCoreReg(Rm, &success); 2669 if (!success) 2670 return false; 2671 2672 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2673 if (!success) 2674 return false; 2675 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2676 2677 EmulateInstruction::Context context; 2678 context.type = eContextArithmetic; 2679 RegisterInfo op1_reg; 2680 RegisterInfo op2_reg; 2681 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2682 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2683 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2684 2685 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2686 return false; 2687 } 2688 return true; 2689 } 2690 2691 // Compare Negative (immediate) adds a register value and an immediate value. 2692 // It updates the condition flags based on the result, and discards the result. 2693 bool 2694 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2695 { 2696 #if 0 2697 // ARM pseudo code... 2698 if ConditionPassed() then 2699 EncodingSpecificOperations(); 2700 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2701 APSR.N = result<31>; 2702 APSR.Z = IsZeroBit(result); 2703 APSR.C = carry; 2704 APSR.V = overflow; 2705 #endif 2706 2707 bool success = false; 2708 2709 uint32_t Rn; // the first operand 2710 uint32_t imm32; // the immediate value to be compared with 2711 switch (encoding) { 2712 case eEncodingT1: 2713 Rn = Bits32(opcode, 19, 16); 2714 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2715 if (Rn == 15) 2716 return false; 2717 break; 2718 case eEncodingA1: 2719 Rn = Bits32(opcode, 19, 16); 2720 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2721 break; 2722 default: 2723 return false; 2724 } 2725 // Read the register value from the operand register Rn. 2726 uint32_t reg_val = ReadCoreReg(Rn, &success); 2727 if (!success) 2728 return false; 2729 2730 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2731 2732 EmulateInstruction::Context context; 2733 context.type = EmulateInstruction::eContextImmediate; 2734 context.SetNoArgs (); 2735 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2736 return false; 2737 2738 return true; 2739 } 2740 2741 // Compare Negative (register) adds a register value and an optionally-shifted register value. 2742 // It updates the condition flags based on the result, and discards the result. 2743 bool 2744 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2745 { 2746 #if 0 2747 // ARM pseudo code... 2748 if ConditionPassed() then 2749 EncodingSpecificOperations(); 2750 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2751 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2752 APSR.N = result<31>; 2753 APSR.Z = IsZeroBit(result); 2754 APSR.C = carry; 2755 APSR.V = overflow; 2756 #endif 2757 2758 bool success = false; 2759 2760 uint32_t Rn; // the first operand 2761 uint32_t Rm; // the second operand 2762 ARM_ShifterType shift_t; 2763 uint32_t shift_n; // the shift applied to the value read from Rm 2764 switch (encoding) { 2765 case eEncodingT1: 2766 Rn = Bits32(opcode, 2, 0); 2767 Rm = Bits32(opcode, 5, 3); 2768 shift_t = SRType_LSL; 2769 shift_n = 0; 2770 break; 2771 case eEncodingT2: 2772 Rn = Bits32(opcode, 19, 16); 2773 Rm = Bits32(opcode, 3, 0); 2774 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2775 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2776 if (Rn == 15 || BadReg(Rm)) 2777 return false; 2778 break; 2779 case eEncodingA1: 2780 Rn = Bits32(opcode, 19, 16); 2781 Rm = Bits32(opcode, 3, 0); 2782 shift_n = DecodeImmShiftARM(opcode, shift_t); 2783 break; 2784 default: 2785 return false; 2786 } 2787 // Read the register value from register Rn. 2788 uint32_t val1 = ReadCoreReg(Rn, &success); 2789 if (!success) 2790 return false; 2791 2792 // Read the register value from register Rm. 2793 uint32_t val2 = ReadCoreReg(Rm, &success); 2794 if (!success) 2795 return false; 2796 2797 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2798 if (!success) 2799 return false; 2800 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2801 2802 EmulateInstruction::Context context; 2803 context.type = EmulateInstruction::eContextImmediate; 2804 context.SetNoArgs(); 2805 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2806 return false; 2807 2808 return true; 2809 } 2810 2811 // Compare (immediate) subtracts an immediate value from a register value. 2812 // It updates the condition flags based on the result, and discards the result. 2813 bool 2814 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2815 { 2816 #if 0 2817 // ARM pseudo code... 2818 if ConditionPassed() then 2819 EncodingSpecificOperations(); 2820 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2821 APSR.N = result<31>; 2822 APSR.Z = IsZeroBit(result); 2823 APSR.C = carry; 2824 APSR.V = overflow; 2825 #endif 2826 2827 bool success = false; 2828 2829 uint32_t Rn; // the first operand 2830 uint32_t imm32; // the immediate value to be compared with 2831 switch (encoding) { 2832 case eEncodingT1: 2833 Rn = Bits32(opcode, 10, 8); 2834 imm32 = Bits32(opcode, 7, 0); 2835 break; 2836 case eEncodingT2: 2837 Rn = Bits32(opcode, 19, 16); 2838 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2839 if (Rn == 15) 2840 return false; 2841 break; 2842 case eEncodingA1: 2843 Rn = Bits32(opcode, 19, 16); 2844 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2845 break; 2846 default: 2847 return false; 2848 } 2849 // Read the register value from the operand register Rn. 2850 uint32_t reg_val = ReadCoreReg(Rn, &success); 2851 if (!success) 2852 return false; 2853 2854 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2855 2856 EmulateInstruction::Context context; 2857 context.type = EmulateInstruction::eContextImmediate; 2858 context.SetNoArgs (); 2859 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2860 return false; 2861 2862 return true; 2863 } 2864 2865 // Compare (register) subtracts an optionally-shifted register value from a register value. 2866 // It updates the condition flags based on the result, and discards the result. 2867 bool 2868 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2869 { 2870 #if 0 2871 // ARM pseudo code... 2872 if ConditionPassed() then 2873 EncodingSpecificOperations(); 2874 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2875 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2876 APSR.N = result<31>; 2877 APSR.Z = IsZeroBit(result); 2878 APSR.C = carry; 2879 APSR.V = overflow; 2880 #endif 2881 2882 bool success = false; 2883 2884 uint32_t Rn; // the first operand 2885 uint32_t Rm; // the second operand 2886 ARM_ShifterType shift_t; 2887 uint32_t shift_n; // the shift applied to the value read from Rm 2888 switch (encoding) { 2889 case eEncodingT1: 2890 Rn = Bits32(opcode, 2, 0); 2891 Rm = Bits32(opcode, 5, 3); 2892 shift_t = SRType_LSL; 2893 shift_n = 0; 2894 break; 2895 case eEncodingT2: 2896 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2897 Rm = Bits32(opcode, 6, 3); 2898 shift_t = SRType_LSL; 2899 shift_n = 0; 2900 if (Rn < 8 && Rm < 8) 2901 return false; 2902 if (Rn == 15 || Rm == 15) 2903 return false; 2904 break; 2905 case eEncodingA1: 2906 Rn = Bits32(opcode, 19, 16); 2907 Rm = Bits32(opcode, 3, 0); 2908 shift_n = DecodeImmShiftARM(opcode, shift_t); 2909 break; 2910 default: 2911 return false; 2912 } 2913 // Read the register value from register Rn. 2914 uint32_t val1 = ReadCoreReg(Rn, &success); 2915 if (!success) 2916 return false; 2917 2918 // Read the register value from register Rm. 2919 uint32_t val2 = ReadCoreReg(Rm, &success); 2920 if (!success) 2921 return false; 2922 2923 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2924 if (!success) 2925 return false; 2926 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 2927 2928 EmulateInstruction::Context context; 2929 context.type = EmulateInstruction::eContextImmediate; 2930 context.SetNoArgs(); 2931 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2932 return false; 2933 2934 return true; 2935 } 2936 2937 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2938 // shifting in copies of its sign bit, and writes the result to the destination register. It can 2939 // optionally update the condition flags based on the result. 2940 bool 2941 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 2942 { 2943 #if 0 2944 // ARM pseudo code... 2945 if ConditionPassed() then 2946 EncodingSpecificOperations(); 2947 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2948 if d == 15 then // Can only occur for ARM encoding 2949 ALUWritePC(result); // setflags is always FALSE here 2950 else 2951 R[d] = result; 2952 if setflags then 2953 APSR.N = result<31>; 2954 APSR.Z = IsZeroBit(result); 2955 APSR.C = carry; 2956 // APSR.V unchanged 2957 #endif 2958 2959 return EmulateShiftImm (opcode, encoding, SRType_ASR); 2960 } 2961 2962 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 2963 // shifting in copies of its sign bit, and writes the result to the destination register. 2964 // The variable number of bits is read from the bottom byte of a register. It can optionally update 2965 // the condition flags based on the result. 2966 bool 2967 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 2968 { 2969 #if 0 2970 // ARM pseudo code... 2971 if ConditionPassed() then 2972 EncodingSpecificOperations(); 2973 shift_n = UInt(R[m]<7:0>); 2974 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2975 R[d] = result; 2976 if setflags then 2977 APSR.N = result<31>; 2978 APSR.Z = IsZeroBit(result); 2979 APSR.C = carry; 2980 // APSR.V unchanged 2981 #endif 2982 2983 return EmulateShiftReg (opcode, encoding, SRType_ASR); 2984 } 2985 2986 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 2987 // shifting in zeros, and writes the result to the destination register. It can optionally 2988 // update the condition flags based on the result. 2989 bool 2990 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 2991 { 2992 #if 0 2993 // ARM pseudo code... 2994 if ConditionPassed() then 2995 EncodingSpecificOperations(); 2996 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 2997 if d == 15 then // Can only occur for ARM encoding 2998 ALUWritePC(result); // setflags is always FALSE here 2999 else 3000 R[d] = result; 3001 if setflags then 3002 APSR.N = result<31>; 3003 APSR.Z = IsZeroBit(result); 3004 APSR.C = carry; 3005 // APSR.V unchanged 3006 #endif 3007 3008 return EmulateShiftImm (opcode, encoding, SRType_LSL); 3009 } 3010 3011 // Logical Shift Left (register) shifts a register value left by a variable number of bits, 3012 // shifting in zeros, and writes the result to the destination register. The variable number 3013 // of bits is read from the bottom byte of a register. It can optionally update the condition 3014 // flags based on the result. 3015 bool 3016 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 3017 { 3018 #if 0 3019 // ARM pseudo code... 3020 if ConditionPassed() then 3021 EncodingSpecificOperations(); 3022 shift_n = UInt(R[m]<7:0>); 3023 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3024 R[d] = result; 3025 if setflags then 3026 APSR.N = result<31>; 3027 APSR.Z = IsZeroBit(result); 3028 APSR.C = carry; 3029 // APSR.V unchanged 3030 #endif 3031 3032 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3033 } 3034 3035 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3036 // shifting in zeros, and writes the result to the destination register. It can optionally 3037 // update the condition flags based on the result. 3038 bool 3039 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3040 { 3041 #if 0 3042 // ARM pseudo code... 3043 if ConditionPassed() then 3044 EncodingSpecificOperations(); 3045 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3046 if d == 15 then // Can only occur for ARM encoding 3047 ALUWritePC(result); // setflags is always FALSE here 3048 else 3049 R[d] = result; 3050 if setflags then 3051 APSR.N = result<31>; 3052 APSR.Z = IsZeroBit(result); 3053 APSR.C = carry; 3054 // APSR.V unchanged 3055 #endif 3056 3057 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3058 } 3059 3060 // Logical Shift Right (register) shifts a register value right by a variable number of bits, 3061 // shifting in zeros, and writes the result to the destination register. The variable number 3062 // of bits is read from the bottom byte of a register. It can optionally update the condition 3063 // flags based on the result. 3064 bool 3065 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3066 { 3067 #if 0 3068 // ARM pseudo code... 3069 if ConditionPassed() then 3070 EncodingSpecificOperations(); 3071 shift_n = UInt(R[m]<7:0>); 3072 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3073 R[d] = result; 3074 if setflags then 3075 APSR.N = result<31>; 3076 APSR.Z = IsZeroBit(result); 3077 APSR.C = carry; 3078 // APSR.V unchanged 3079 #endif 3080 3081 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3082 } 3083 3084 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3085 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3086 // It can optionally update the condition flags based on the result. 3087 bool 3088 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3089 { 3090 #if 0 3091 // ARM pseudo code... 3092 if ConditionPassed() then 3093 EncodingSpecificOperations(); 3094 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3095 if d == 15 then // Can only occur for ARM encoding 3096 ALUWritePC(result); // setflags is always FALSE here 3097 else 3098 R[d] = result; 3099 if setflags then 3100 APSR.N = result<31>; 3101 APSR.Z = IsZeroBit(result); 3102 APSR.C = carry; 3103 // APSR.V unchanged 3104 #endif 3105 3106 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3107 } 3108 3109 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3110 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3111 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3112 // flags based on the result. 3113 bool 3114 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3115 { 3116 #if 0 3117 // ARM pseudo code... 3118 if ConditionPassed() then 3119 EncodingSpecificOperations(); 3120 shift_n = UInt(R[m]<7:0>); 3121 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3122 R[d] = result; 3123 if setflags then 3124 APSR.N = result<31>; 3125 APSR.Z = IsZeroBit(result); 3126 APSR.C = carry; 3127 // APSR.V unchanged 3128 #endif 3129 3130 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3131 } 3132 3133 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3134 // with the carry flag shifted into bit [31]. 3135 // 3136 // RRX can optionally update the condition flags based on the result. 3137 // In that case, bit [0] is shifted into the carry flag. 3138 bool 3139 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3140 { 3141 #if 0 3142 // ARM pseudo code... 3143 if ConditionPassed() then 3144 EncodingSpecificOperations(); 3145 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3146 if d == 15 then // Can only occur for ARM encoding 3147 ALUWritePC(result); // setflags is always FALSE here 3148 else 3149 R[d] = result; 3150 if setflags then 3151 APSR.N = result<31>; 3152 APSR.Z = IsZeroBit(result); 3153 APSR.C = carry; 3154 // APSR.V unchanged 3155 #endif 3156 3157 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3158 } 3159 3160 bool 3161 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3162 { 3163 // assert(shift_type == SRType_ASR 3164 // || shift_type == SRType_LSL 3165 // || shift_type == SRType_LSR 3166 // || shift_type == SRType_ROR 3167 // || shift_type == SRType_RRX); 3168 3169 bool success = false; 3170 3171 if (ConditionPassed(opcode)) 3172 { 3173 uint32_t Rd; // the destination register 3174 uint32_t Rm; // the first operand register 3175 uint32_t imm5; // encoding for the shift amount 3176 uint32_t carry; // the carry bit after the shift operation 3177 bool setflags; 3178 3179 // Special case handling! 3180 // A8.6.139 ROR (immediate) -- Encoding T1 3181 ARMEncoding use_encoding = encoding; 3182 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3183 { 3184 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3185 // have the same decoding of bit fields as the other Thumb2 shift operations. 3186 use_encoding = eEncodingT2; 3187 } 3188 3189 switch (use_encoding) { 3190 case eEncodingT1: 3191 // Due to the above special case handling! 3192 if (shift_type == SRType_ROR) 3193 return false; 3194 3195 Rd = Bits32(opcode, 2, 0); 3196 Rm = Bits32(opcode, 5, 3); 3197 setflags = !InITBlock(); 3198 imm5 = Bits32(opcode, 10, 6); 3199 break; 3200 case eEncodingT2: 3201 // A8.6.141 RRX 3202 // There's no imm form of RRX instructions. 3203 if (shift_type == SRType_RRX) 3204 return false; 3205 3206 Rd = Bits32(opcode, 11, 8); 3207 Rm = Bits32(opcode, 3, 0); 3208 setflags = BitIsSet(opcode, 20); 3209 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3210 if (BadReg(Rd) || BadReg(Rm)) 3211 return false; 3212 break; 3213 case eEncodingA1: 3214 Rd = Bits32(opcode, 15, 12); 3215 Rm = Bits32(opcode, 3, 0); 3216 setflags = BitIsSet(opcode, 20); 3217 imm5 = Bits32(opcode, 11, 7); 3218 break; 3219 default: 3220 return false; 3221 } 3222 3223 // A8.6.139 ROR (immediate) 3224 if (shift_type == SRType_ROR && imm5 == 0) 3225 shift_type = SRType_RRX; 3226 3227 // Get the first operand. 3228 uint32_t value = ReadCoreReg (Rm, &success); 3229 if (!success) 3230 return false; 3231 3232 // Decode the shift amount if not RRX. 3233 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3234 3235 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3236 if (!success) 3237 return false; 3238 3239 // The context specifies that an immediate is to be moved into Rd. 3240 EmulateInstruction::Context context; 3241 context.type = EmulateInstruction::eContextImmediate; 3242 context.SetNoArgs (); 3243 3244 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3245 return false; 3246 } 3247 return true; 3248 } 3249 3250 bool 3251 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3252 { 3253 // assert(shift_type == SRType_ASR 3254 // || shift_type == SRType_LSL 3255 // || shift_type == SRType_LSR 3256 // || shift_type == SRType_ROR); 3257 3258 bool success = false; 3259 3260 if (ConditionPassed(opcode)) 3261 { 3262 uint32_t Rd; // the destination register 3263 uint32_t Rn; // the first operand register 3264 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3265 uint32_t carry; // the carry bit after the shift operation 3266 bool setflags; 3267 switch (encoding) { 3268 case eEncodingT1: 3269 Rd = Bits32(opcode, 2, 0); 3270 Rn = Rd; 3271 Rm = Bits32(opcode, 5, 3); 3272 setflags = !InITBlock(); 3273 break; 3274 case eEncodingT2: 3275 Rd = Bits32(opcode, 11, 8); 3276 Rn = Bits32(opcode, 19, 16); 3277 Rm = Bits32(opcode, 3, 0); 3278 setflags = BitIsSet(opcode, 20); 3279 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3280 return false; 3281 break; 3282 case eEncodingA1: 3283 Rd = Bits32(opcode, 15, 12); 3284 Rn = Bits32(opcode, 3, 0); 3285 Rm = Bits32(opcode, 11, 8); 3286 setflags = BitIsSet(opcode, 20); 3287 if (Rd == 15 || Rn == 15 || Rm == 15) 3288 return false; 3289 break; 3290 default: 3291 return false; 3292 } 3293 3294 // Get the first operand. 3295 uint32_t value = ReadCoreReg (Rn, &success); 3296 if (!success) 3297 return false; 3298 // Get the Rm register content. 3299 uint32_t val = ReadCoreReg (Rm, &success); 3300 if (!success) 3301 return false; 3302 3303 // Get the shift amount. 3304 uint32_t amt = Bits32(val, 7, 0); 3305 3306 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3307 if (!success) 3308 return false; 3309 3310 // The context specifies that an immediate is to be moved into Rd. 3311 EmulateInstruction::Context context; 3312 context.type = EmulateInstruction::eContextImmediate; 3313 context.SetNoArgs (); 3314 3315 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3316 return false; 3317 } 3318 return true; 3319 } 3320 3321 // LDM loads multiple registers from consecutive memory locations, using an 3322 // address from a base register. Optionally the address just above the highest of those locations 3323 // can be written back to the base register. 3324 bool 3325 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3326 { 3327 #if 0 3328 // ARM pseudo code... 3329 if ConditionPassed() 3330 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3331 address = R[n]; 3332 3333 for i = 0 to 14 3334 if registers<i> == '1' then 3335 R[i] = MemA[address, 4]; address = address + 4; 3336 if registers<15> == '1' then 3337 LoadWritePC (MemA[address, 4]); 3338 3339 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3340 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3341 3342 #endif 3343 3344 bool success = false; 3345 bool conditional = false; 3346 if (ConditionPassed(opcode, &conditional)) 3347 { 3348 uint32_t n; 3349 uint32_t registers = 0; 3350 bool wback; 3351 const uint32_t addr_byte_size = GetAddressByteSize(); 3352 switch (encoding) 3353 { 3354 case eEncodingT1: 3355 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3356 n = Bits32 (opcode, 10, 8); 3357 registers = Bits32 (opcode, 7, 0); 3358 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3359 wback = BitIsClear (registers, n); 3360 // if BitCount(registers) < 1 then UNPREDICTABLE; 3361 if (BitCount(registers) < 1) 3362 return false; 3363 break; 3364 case eEncodingT2: 3365 // if W == '1' && Rn == '1101' then SEE POP; 3366 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3367 n = Bits32 (opcode, 19, 16); 3368 registers = Bits32 (opcode, 15, 0); 3369 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3370 wback = BitIsSet (opcode, 21); 3371 3372 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3373 if ((n == 15) 3374 || (BitCount (registers) < 2) 3375 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3376 return false; 3377 3378 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3379 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3380 return false; 3381 3382 // if wback && registers<n> == '1' then UNPREDICTABLE; 3383 if (wback 3384 && BitIsSet (registers, n)) 3385 return false; 3386 break; 3387 3388 case eEncodingA1: 3389 n = Bits32 (opcode, 19, 16); 3390 registers = Bits32 (opcode, 15, 0); 3391 wback = BitIsSet (opcode, 21); 3392 if ((n == 15) 3393 || (BitCount (registers) < 1)) 3394 return false; 3395 break; 3396 default: 3397 return false; 3398 } 3399 3400 int32_t offset = 0; 3401 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3402 if (!success) 3403 return false; 3404 3405 EmulateInstruction::Context context; 3406 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3407 RegisterInfo dwarf_reg; 3408 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3409 context.SetRegisterPlusOffset (dwarf_reg, offset); 3410 3411 for (int i = 0; i < 14; ++i) 3412 { 3413 if (BitIsSet (registers, i)) 3414 { 3415 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3416 context.SetRegisterPlusOffset (dwarf_reg, offset); 3417 if (wback && (n == 13)) // Pop Instruction 3418 { 3419 if (conditional) 3420 context.type = EmulateInstruction::eContextRegisterLoad; 3421 else 3422 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3423 } 3424 3425 // R[i] = MemA [address, 4]; address = address + 4; 3426 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3427 if (!success) 3428 return false; 3429 3430 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3431 return false; 3432 3433 offset += addr_byte_size; 3434 } 3435 } 3436 3437 if (BitIsSet (registers, 15)) 3438 { 3439 //LoadWritePC (MemA [address, 4]); 3440 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3441 context.SetRegisterPlusOffset (dwarf_reg, offset); 3442 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3443 if (!success) 3444 return false; 3445 // In ARMv5T and above, this is an interworking branch. 3446 if (!LoadWritePC(context, data)) 3447 return false; 3448 } 3449 3450 if (wback && BitIsClear (registers, n)) 3451 { 3452 // R[n] = R[n] + 4 * BitCount (registers) 3453 int32_t offset = addr_byte_size * BitCount (registers); 3454 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3455 context.SetRegisterPlusOffset (dwarf_reg, offset); 3456 3457 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3458 return false; 3459 } 3460 if (wback && BitIsSet (registers, n)) 3461 // R[n] bits(32) UNKNOWN; 3462 return WriteBits32Unknown (n); 3463 } 3464 return true; 3465 } 3466 3467 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3468 // The consecutive memory locations end at this address and the address just below the lowest of those locations 3469 // can optionally be written back to the base register. 3470 bool 3471 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3472 { 3473 #if 0 3474 // ARM pseudo code... 3475 if ConditionPassed() then 3476 EncodingSpecificOperations(); 3477 address = R[n] - 4*BitCount(registers) + 4; 3478 3479 for i = 0 to 14 3480 if registers<i> == '1' then 3481 R[i] = MemA[address,4]; address = address + 4; 3482 3483 if registers<15> == '1' then 3484 LoadWritePC(MemA[address,4]); 3485 3486 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3487 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3488 #endif 3489 3490 bool success = false; 3491 3492 if (ConditionPassed(opcode)) 3493 { 3494 uint32_t n; 3495 uint32_t registers = 0; 3496 bool wback; 3497 const uint32_t addr_byte_size = GetAddressByteSize(); 3498 3499 // EncodingSpecificOperations(); 3500 switch (encoding) 3501 { 3502 case eEncodingA1: 3503 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3504 n = Bits32 (opcode, 19, 16); 3505 registers = Bits32 (opcode, 15, 0); 3506 wback = BitIsSet (opcode, 21); 3507 3508 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3509 if ((n == 15) || (BitCount (registers) < 1)) 3510 return false; 3511 3512 break; 3513 3514 default: 3515 return false; 3516 } 3517 // address = R[n] - 4*BitCount(registers) + 4; 3518 3519 int32_t offset = 0; 3520 addr_t Rn = ReadCoreReg (n, &success); 3521 3522 if (!success) 3523 return false; 3524 3525 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3526 3527 EmulateInstruction::Context context; 3528 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3529 RegisterInfo dwarf_reg; 3530 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3531 context.SetRegisterPlusOffset (dwarf_reg, offset); 3532 3533 // for i = 0 to 14 3534 for (int i = 0; i < 14; ++i) 3535 { 3536 // if registers<i> == '1' then 3537 if (BitIsSet (registers, i)) 3538 { 3539 // R[i] = MemA[address,4]; address = address + 4; 3540 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3541 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3542 if (!success) 3543 return false; 3544 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3545 return false; 3546 offset += addr_byte_size; 3547 } 3548 } 3549 3550 // if registers<15> == '1' then 3551 // LoadWritePC(MemA[address,4]); 3552 if (BitIsSet (registers, 15)) 3553 { 3554 context.SetRegisterPlusOffset (dwarf_reg, offset); 3555 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3556 if (!success) 3557 return false; 3558 // In ARMv5T and above, this is an interworking branch. 3559 if (!LoadWritePC(context, data)) 3560 return false; 3561 } 3562 3563 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3564 if (wback && BitIsClear (registers, n)) 3565 { 3566 if (!success) 3567 return false; 3568 3569 offset = (addr_byte_size * BitCount (registers)) * -1; 3570 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3571 context.SetImmediateSigned (offset); 3572 addr_t addr = Rn + offset; 3573 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3574 return false; 3575 } 3576 3577 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3578 if (wback && BitIsSet (registers, n)) 3579 return WriteBits32Unknown (n); 3580 } 3581 return true; 3582 } 3583 3584 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3585 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3586 // be optionally written back to the base register. 3587 bool 3588 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3589 { 3590 #if 0 3591 // ARM pseudo code... 3592 if ConditionPassed() then 3593 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3594 address = R[n] - 4*BitCount(registers); 3595 3596 for i = 0 to 14 3597 if registers<i> == '1' then 3598 R[i] = MemA[address,4]; address = address + 4; 3599 if registers<15> == '1' then 3600 LoadWritePC(MemA[address,4]); 3601 3602 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3603 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3604 #endif 3605 3606 bool success = false; 3607 3608 if (ConditionPassed(opcode)) 3609 { 3610 uint32_t n; 3611 uint32_t registers = 0; 3612 bool wback; 3613 const uint32_t addr_byte_size = GetAddressByteSize(); 3614 switch (encoding) 3615 { 3616 case eEncodingT1: 3617 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3618 n = Bits32 (opcode, 19, 16); 3619 registers = Bits32 (opcode, 15, 0); 3620 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3621 wback = BitIsSet (opcode, 21); 3622 3623 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3624 if ((n == 15) 3625 || (BitCount (registers) < 2) 3626 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3627 return false; 3628 3629 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3630 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3631 return false; 3632 3633 // if wback && registers<n> == '1' then UNPREDICTABLE; 3634 if (wback && BitIsSet (registers, n)) 3635 return false; 3636 3637 break; 3638 3639 case eEncodingA1: 3640 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3641 n = Bits32 (opcode, 19, 16); 3642 registers = Bits32 (opcode, 15, 0); 3643 wback = BitIsSet (opcode, 21); 3644 3645 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3646 if ((n == 15) || (BitCount (registers) < 1)) 3647 return false; 3648 3649 break; 3650 3651 default: 3652 return false; 3653 } 3654 3655 // address = R[n] - 4*BitCount(registers); 3656 3657 int32_t offset = 0; 3658 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3659 3660 if (!success) 3661 return false; 3662 3663 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3664 EmulateInstruction::Context context; 3665 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3666 RegisterInfo dwarf_reg; 3667 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3668 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3669 3670 for (int i = 0; i < 14; ++i) 3671 { 3672 if (BitIsSet (registers, i)) 3673 { 3674 // R[i] = MemA[address,4]; address = address + 4; 3675 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3676 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3677 if (!success) 3678 return false; 3679 3680 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3681 return false; 3682 3683 offset += addr_byte_size; 3684 } 3685 } 3686 3687 // if registers<15> == '1' then 3688 // LoadWritePC(MemA[address,4]); 3689 if (BitIsSet (registers, 15)) 3690 { 3691 context.SetRegisterPlusOffset (dwarf_reg, offset); 3692 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3693 if (!success) 3694 return false; 3695 // In ARMv5T and above, this is an interworking branch. 3696 if (!LoadWritePC(context, data)) 3697 return false; 3698 } 3699 3700 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3701 if (wback && BitIsClear (registers, n)) 3702 { 3703 if (!success) 3704 return false; 3705 3706 offset = (addr_byte_size * BitCount (registers)) * -1; 3707 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3708 context.SetImmediateSigned (offset); 3709 addr_t addr = Rn + offset; 3710 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3711 return false; 3712 } 3713 3714 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3715 if (wback && BitIsSet (registers, n)) 3716 return WriteBits32Unknown (n); 3717 } 3718 return true; 3719 } 3720 3721 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3722 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3723 // optinoally be written back to the base register. 3724 bool 3725 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3726 { 3727 #if 0 3728 if ConditionPassed() then 3729 EncodingSpecificOperations(); 3730 address = R[n] + 4; 3731 3732 for i = 0 to 14 3733 if registers<i> == '1' then 3734 R[i] = MemA[address,4]; address = address + 4; 3735 if registers<15> == '1' then 3736 LoadWritePC(MemA[address,4]); 3737 3738 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3739 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3740 #endif 3741 3742 bool success = false; 3743 3744 if (ConditionPassed(opcode)) 3745 { 3746 uint32_t n; 3747 uint32_t registers = 0; 3748 bool wback; 3749 const uint32_t addr_byte_size = GetAddressByteSize(); 3750 switch (encoding) 3751 { 3752 case eEncodingA1: 3753 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3754 n = Bits32 (opcode, 19, 16); 3755 registers = Bits32 (opcode, 15, 0); 3756 wback = BitIsSet (opcode, 21); 3757 3758 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3759 if ((n == 15) || (BitCount (registers) < 1)) 3760 return false; 3761 3762 break; 3763 default: 3764 return false; 3765 } 3766 // address = R[n] + 4; 3767 3768 int32_t offset = 0; 3769 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3770 3771 if (!success) 3772 return false; 3773 3774 addr_t address = Rn + addr_byte_size; 3775 3776 EmulateInstruction::Context context; 3777 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3778 RegisterInfo dwarf_reg; 3779 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3780 context.SetRegisterPlusOffset (dwarf_reg, offset); 3781 3782 for (int i = 0; i < 14; ++i) 3783 { 3784 if (BitIsSet (registers, i)) 3785 { 3786 // R[i] = MemA[address,4]; address = address + 4; 3787 3788 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3789 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3790 if (!success) 3791 return false; 3792 3793 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3794 return false; 3795 3796 offset += addr_byte_size; 3797 } 3798 } 3799 3800 // if registers<15> == '1' then 3801 // LoadWritePC(MemA[address,4]); 3802 if (BitIsSet (registers, 15)) 3803 { 3804 context.SetRegisterPlusOffset (dwarf_reg, offset); 3805 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3806 if (!success) 3807 return false; 3808 // In ARMv5T and above, this is an interworking branch. 3809 if (!LoadWritePC(context, data)) 3810 return false; 3811 } 3812 3813 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3814 if (wback && BitIsClear (registers, n)) 3815 { 3816 if (!success) 3817 return false; 3818 3819 offset = addr_byte_size * BitCount (registers); 3820 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3821 context.SetImmediateSigned (offset); 3822 addr_t addr = Rn + offset; 3823 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3824 return false; 3825 } 3826 3827 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3828 if (wback && BitIsSet (registers, n)) 3829 return WriteBits32Unknown (n); 3830 } 3831 return true; 3832 } 3833 3834 // Load Register (immediate) calculates an address from a base register value and 3835 // an immediate offset, loads a word from memory, and writes to a register. 3836 // LDR (immediate, Thumb) 3837 bool 3838 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3839 { 3840 #if 0 3841 // ARM pseudo code... 3842 if (ConditionPassed()) 3843 { 3844 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3845 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3846 address = if index then offset_addr else R[n]; 3847 data = MemU[address,4]; 3848 if wback then R[n] = offset_addr; 3849 if t == 15 then 3850 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3851 elsif UnalignedSupport() || address<1:0> = '00' then 3852 R[t] = data; 3853 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3854 } 3855 #endif 3856 3857 bool success = false; 3858 3859 if (ConditionPassed(opcode)) 3860 { 3861 uint32_t Rt; // the destination register 3862 uint32_t Rn; // the base register 3863 uint32_t imm32; // the immediate offset used to form the address 3864 addr_t offset_addr; // the offset address 3865 addr_t address; // the calculated address 3866 uint32_t data; // the literal data value from memory load 3867 bool add, index, wback; 3868 switch (encoding) { 3869 case eEncodingT1: 3870 Rt = Bits32(opcode, 2, 0); 3871 Rn = Bits32(opcode, 5, 3); 3872 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3873 // index = TRUE; add = TRUE; wback = FALSE 3874 add = true; 3875 index = true; 3876 wback = false; 3877 3878 break; 3879 3880 case eEncodingT2: 3881 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3882 Rt = Bits32 (opcode, 10, 8); 3883 Rn = 13; 3884 imm32 = Bits32 (opcode, 7, 0) << 2; 3885 3886 // index = TRUE; add = TRUE; wback = FALSE; 3887 index = true; 3888 add = true; 3889 wback = false; 3890 3891 break; 3892 3893 case eEncodingT3: 3894 // if Rn == '1111' then SEE LDR (literal); 3895 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3896 Rt = Bits32 (opcode, 15, 12); 3897 Rn = Bits32 (opcode, 19, 16); 3898 imm32 = Bits32 (opcode, 11, 0); 3899 3900 // index = TRUE; add = TRUE; wback = FALSE; 3901 index = true; 3902 add = true; 3903 wback = false; 3904 3905 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3906 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3907 return false; 3908 3909 break; 3910 3911 case eEncodingT4: 3912 // if Rn == '1111' then SEE LDR (literal); 3913 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3914 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3915 // if P == '0' && W == '0' then UNDEFINED; 3916 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3917 return false; 3918 3919 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3920 Rt = Bits32 (opcode, 15, 12); 3921 Rn = Bits32 (opcode, 19, 16); 3922 imm32 = Bits32 (opcode, 7, 0); 3923 3924 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3925 index = BitIsSet (opcode, 10); 3926 add = BitIsSet (opcode, 9); 3927 wback = BitIsSet (opcode, 8); 3928 3929 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3930 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3931 return false; 3932 3933 break; 3934 3935 default: 3936 return false; 3937 } 3938 uint32_t base = ReadCoreReg (Rn, &success); 3939 if (!success) 3940 return false; 3941 if (add) 3942 offset_addr = base + imm32; 3943 else 3944 offset_addr = base - imm32; 3945 3946 address = (index ? offset_addr : base); 3947 3948 RegisterInfo base_reg; 3949 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 3950 if (wback) 3951 { 3952 EmulateInstruction::Context ctx; 3953 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 3954 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3955 3956 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3957 return false; 3958 } 3959 3960 // Prepare to write to the Rt register. 3961 EmulateInstruction::Context context; 3962 context.type = EmulateInstruction::eContextRegisterLoad; 3963 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3964 3965 // Read memory from the address. 3966 data = MemURead(context, address, 4, 0, &success); 3967 if (!success) 3968 return false; 3969 3970 if (Rt == 15) 3971 { 3972 if (Bits32(address, 1, 0) == 0) 3973 { 3974 if (!LoadWritePC(context, data)) 3975 return false; 3976 } 3977 else 3978 return false; 3979 } 3980 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3981 { 3982 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3983 return false; 3984 } 3985 else 3986 WriteBits32Unknown (Rt); 3987 } 3988 return true; 3989 } 3990 3991 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 3992 // from a base register. The consecutive memory locations start at this address, and teh address just above the last 3993 // of those locations can optionally be written back to the base register. 3994 bool 3995 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 3996 { 3997 #if 0 3998 if ConditionPassed() then 3999 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4000 address = R[n]; 4001 4002 for i = 0 to 14 4003 if registers<i> == '1' then 4004 if i == n && wback && i != LowestSetBit(registers) then 4005 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4006 else 4007 MemA[address,4] = R[i]; 4008 address = address + 4; 4009 4010 if registers<15> == '1' then // Only possible for encoding A1 4011 MemA[address,4] = PCStoreValue(); 4012 if wback then R[n] = R[n] + 4*BitCount(registers); 4013 #endif 4014 4015 bool success = false; 4016 4017 if (ConditionPassed(opcode)) 4018 { 4019 uint32_t n; 4020 uint32_t registers = 0; 4021 bool wback; 4022 const uint32_t addr_byte_size = GetAddressByteSize(); 4023 4024 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4025 switch (encoding) 4026 { 4027 case eEncodingT1: 4028 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4029 n = Bits32 (opcode, 10, 8); 4030 registers = Bits32 (opcode, 7, 0); 4031 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4032 wback = true; 4033 4034 // if BitCount(registers) < 1 then UNPREDICTABLE; 4035 if (BitCount (registers) < 1) 4036 return false; 4037 4038 break; 4039 4040 case eEncodingT2: 4041 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4042 n = Bits32 (opcode, 19, 16); 4043 registers = Bits32 (opcode, 15, 0); 4044 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4045 wback = BitIsSet (opcode, 21); 4046 4047 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4048 if ((n == 15) || (BitCount (registers) < 2)) 4049 return false; 4050 4051 // if wback && registers<n> == '1' then UNPREDICTABLE; 4052 if (wback && BitIsSet (registers, n)) 4053 return false; 4054 4055 break; 4056 4057 case eEncodingA1: 4058 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4059 n = Bits32 (opcode, 19, 16); 4060 registers = Bits32 (opcode, 15, 0); 4061 wback = BitIsSet (opcode, 21); 4062 4063 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4064 if ((n == 15) || (BitCount (registers) < 1)) 4065 return false; 4066 4067 break; 4068 4069 default: 4070 return false; 4071 } 4072 4073 // address = R[n]; 4074 int32_t offset = 0; 4075 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4076 if (!success) 4077 return false; 4078 4079 EmulateInstruction::Context context; 4080 context.type = EmulateInstruction::eContextRegisterStore; 4081 RegisterInfo base_reg; 4082 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4083 4084 // for i = 0 to 14 4085 int lowest_set_bit = 14; 4086 for (int i = 0; i < 14; ++i) 4087 { 4088 // if registers<i> == '1' then 4089 if (BitIsSet (registers, i)) 4090 { 4091 if (i < lowest_set_bit) 4092 lowest_set_bit = i; 4093 // if i == n && wback && i != LowestSetBit(registers) then 4094 if ((i == n) && wback && (i != lowest_set_bit)) 4095 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4096 WriteBits32UnknownToMemory (address + offset); 4097 else 4098 { 4099 // MemA[address,4] = R[i]; 4100 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4101 if (!success) 4102 return false; 4103 4104 RegisterInfo data_reg; 4105 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4106 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4107 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4108 return false; 4109 } 4110 4111 // address = address + 4; 4112 offset += addr_byte_size; 4113 } 4114 } 4115 4116 // if registers<15> == '1' then // Only possible for encoding A1 4117 // MemA[address,4] = PCStoreValue(); 4118 if (BitIsSet (registers, 15)) 4119 { 4120 RegisterInfo pc_reg; 4121 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4122 context.SetRegisterPlusOffset (pc_reg, 8); 4123 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4124 if (!success) 4125 return false; 4126 4127 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4128 return false; 4129 } 4130 4131 // if wback then R[n] = R[n] + 4*BitCount(registers); 4132 if (wback) 4133 { 4134 offset = addr_byte_size * BitCount (registers); 4135 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4136 context.SetImmediateSigned (offset); 4137 addr_t data = address + offset; 4138 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4139 return false; 4140 } 4141 } 4142 return true; 4143 } 4144 4145 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4146 // from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4147 // of those locations can optionally be written back to the base register. 4148 bool 4149 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4150 { 4151 #if 0 4152 if ConditionPassed() then 4153 EncodingSpecificOperations(); 4154 address = R[n] - 4*BitCount(registers) + 4; 4155 4156 for i = 0 to 14 4157 if registers<i> == '1' then 4158 if i == n && wback && i != LowestSetBit(registers) then 4159 MemA[address,4] = bits(32) UNKNOWN; 4160 else 4161 MemA[address,4] = R[i]; 4162 address = address + 4; 4163 4164 if registers<15> == '1' then 4165 MemA[address,4] = PCStoreValue(); 4166 4167 if wback then R[n] = R[n] - 4*BitCount(registers); 4168 #endif 4169 4170 bool success = false; 4171 4172 if (ConditionPassed(opcode)) 4173 { 4174 uint32_t n; 4175 uint32_t registers = 0; 4176 bool wback; 4177 const uint32_t addr_byte_size = GetAddressByteSize(); 4178 4179 // EncodingSpecificOperations(); 4180 switch (encoding) 4181 { 4182 case eEncodingA1: 4183 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4184 n = Bits32 (opcode, 19, 16); 4185 registers = Bits32 (opcode, 15, 0); 4186 wback = BitIsSet (opcode, 21); 4187 4188 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4189 if ((n == 15) || (BitCount (registers) < 1)) 4190 return false; 4191 break; 4192 default: 4193 return false; 4194 } 4195 4196 // address = R[n] - 4*BitCount(registers) + 4; 4197 int32_t offset = 0; 4198 addr_t Rn = ReadCoreReg (n, &success); 4199 if (!success) 4200 return false; 4201 4202 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4203 4204 EmulateInstruction::Context context; 4205 context.type = EmulateInstruction::eContextRegisterStore; 4206 RegisterInfo base_reg; 4207 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4208 4209 // for i = 0 to 14 4210 int lowest_bit_set = 14; 4211 for (int i = 0; i < 14; ++i) 4212 { 4213 // if registers<i> == '1' then 4214 if (BitIsSet (registers, i)) 4215 { 4216 if (i < lowest_bit_set) 4217 lowest_bit_set = i; 4218 //if i == n && wback && i != LowestSetBit(registers) then 4219 if ((i == n) && wback && (i != lowest_bit_set)) 4220 // MemA[address,4] = bits(32) UNKNOWN; 4221 WriteBits32UnknownToMemory (address + offset); 4222 else 4223 { 4224 // MemA[address,4] = R[i]; 4225 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4226 if (!success) 4227 return false; 4228 4229 RegisterInfo data_reg; 4230 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4231 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4232 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4233 return false; 4234 } 4235 4236 // address = address + 4; 4237 offset += addr_byte_size; 4238 } 4239 } 4240 4241 // if registers<15> == '1' then 4242 // MemA[address,4] = PCStoreValue(); 4243 if (BitIsSet (registers, 15)) 4244 { 4245 RegisterInfo pc_reg; 4246 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4247 context.SetRegisterPlusOffset (pc_reg, 8); 4248 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4249 if (!success) 4250 return false; 4251 4252 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4253 return false; 4254 } 4255 4256 // if wback then R[n] = R[n] - 4*BitCount(registers); 4257 if (wback) 4258 { 4259 offset = (addr_byte_size * BitCount (registers)) * -1; 4260 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4261 context.SetImmediateSigned (offset); 4262 addr_t data = Rn + offset; 4263 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4264 return false; 4265 } 4266 } 4267 return true; 4268 } 4269 4270 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4271 // from a base register. The consecutive memory locations end just below this address, and the address of the first of 4272 // those locations can optionally be written back to the base register. 4273 bool 4274 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4275 { 4276 #if 0 4277 if ConditionPassed() then 4278 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4279 address = R[n] - 4*BitCount(registers); 4280 4281 for i = 0 to 14 4282 if registers<i> == '1' then 4283 if i == n && wback && i != LowestSetBit(registers) then 4284 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4285 else 4286 MemA[address,4] = R[i]; 4287 address = address + 4; 4288 4289 if registers<15> == '1' then // Only possible for encoding A1 4290 MemA[address,4] = PCStoreValue(); 4291 4292 if wback then R[n] = R[n] - 4*BitCount(registers); 4293 #endif 4294 4295 4296 bool success = false; 4297 4298 if (ConditionPassed(opcode)) 4299 { 4300 uint32_t n; 4301 uint32_t registers = 0; 4302 bool wback; 4303 const uint32_t addr_byte_size = GetAddressByteSize(); 4304 4305 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4306 switch (encoding) 4307 { 4308 case eEncodingT1: 4309 // if W == '1' && Rn == '1101' then SEE PUSH; 4310 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4311 { 4312 // See PUSH 4313 } 4314 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4315 n = Bits32 (opcode, 19, 16); 4316 registers = Bits32 (opcode, 15, 0); 4317 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4318 wback = BitIsSet (opcode, 21); 4319 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4320 if ((n == 15) || BitCount (registers) < 2) 4321 return false; 4322 // if wback && registers<n> == '1' then UNPREDICTABLE; 4323 if (wback && BitIsSet (registers, n)) 4324 return false; 4325 break; 4326 4327 case eEncodingA1: 4328 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH; 4329 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4330 { 4331 // See Push 4332 } 4333 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4334 n = Bits32 (opcode, 19, 16); 4335 registers = Bits32 (opcode, 15, 0); 4336 wback = BitIsSet (opcode, 21); 4337 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4338 if ((n == 15) || BitCount (registers) < 1) 4339 return false; 4340 break; 4341 4342 default: 4343 return false; 4344 } 4345 4346 // address = R[n] - 4*BitCount(registers); 4347 4348 int32_t offset = 0; 4349 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4350 if (!success) 4351 return false; 4352 4353 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4354 4355 EmulateInstruction::Context context; 4356 context.type = EmulateInstruction::eContextRegisterStore; 4357 RegisterInfo base_reg; 4358 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4359 4360 // for i = 0 to 14 4361 uint32_t lowest_set_bit = 14; 4362 for (int i = 0; i < 14; ++i) 4363 { 4364 // if registers<i> == '1' then 4365 if (BitIsSet (registers, i)) 4366 { 4367 if (i < lowest_set_bit) 4368 lowest_set_bit = i; 4369 // if i == n && wback && i != LowestSetBit(registers) then 4370 if ((i == n) && wback && (i != lowest_set_bit)) 4371 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4372 WriteBits32UnknownToMemory (address + offset); 4373 else 4374 { 4375 // MemA[address,4] = R[i]; 4376 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4377 if (!success) 4378 return false; 4379 4380 RegisterInfo data_reg; 4381 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4382 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4383 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4384 return false; 4385 } 4386 4387 // address = address + 4; 4388 offset += addr_byte_size; 4389 } 4390 } 4391 4392 // if registers<15> == '1' then // Only possible for encoding A1 4393 // MemA[address,4] = PCStoreValue(); 4394 if (BitIsSet (registers, 15)) 4395 { 4396 RegisterInfo pc_reg; 4397 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4398 context.SetRegisterPlusOffset (pc_reg, 8); 4399 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4400 if (!success) 4401 return false; 4402 4403 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4404 return false; 4405 } 4406 4407 // if wback then R[n] = R[n] - 4*BitCount(registers); 4408 if (wback) 4409 { 4410 offset = (addr_byte_size * BitCount (registers)) * -1; 4411 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4412 context.SetImmediateSigned (offset); 4413 addr_t data = Rn + offset; 4414 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4415 return false; 4416 } 4417 } 4418 return true; 4419 } 4420 4421 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4422 // from a base register. The consecutive memory locations start just above this address, and the address of the last 4423 // of those locations can optionally be written back to the base register. 4424 bool 4425 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4426 { 4427 #if 0 4428 if ConditionPassed() then 4429 EncodingSpecificOperations(); 4430 address = R[n] + 4; 4431 4432 for i = 0 to 14 4433 if registers<i> == '1' then 4434 if i == n && wback && i != LowestSetBit(registers) then 4435 MemA[address,4] = bits(32) UNKNOWN; 4436 else 4437 MemA[address,4] = R[i]; 4438 address = address + 4; 4439 4440 if registers<15> == '1' then 4441 MemA[address,4] = PCStoreValue(); 4442 4443 if wback then R[n] = R[n] + 4*BitCount(registers); 4444 #endif 4445 4446 bool success = false; 4447 4448 if (ConditionPassed(opcode)) 4449 { 4450 uint32_t n; 4451 uint32_t registers = 0; 4452 bool wback; 4453 const uint32_t addr_byte_size = GetAddressByteSize(); 4454 4455 // EncodingSpecificOperations(); 4456 switch (encoding) 4457 { 4458 case eEncodingA1: 4459 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4460 n = Bits32 (opcode, 19, 16); 4461 registers = Bits32 (opcode, 15, 0); 4462 wback = BitIsSet (opcode, 21); 4463 4464 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4465 if ((n == 15) && (BitCount (registers) < 1)) 4466 return false; 4467 break; 4468 default: 4469 return false; 4470 } 4471 // address = R[n] + 4; 4472 4473 int32_t offset = 0; 4474 addr_t Rn = ReadCoreReg (n, &success); 4475 if (!success) 4476 return false; 4477 4478 addr_t address = Rn + addr_byte_size; 4479 4480 EmulateInstruction::Context context; 4481 context.type = EmulateInstruction::eContextRegisterStore; 4482 RegisterInfo base_reg; 4483 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4484 4485 uint32_t lowest_set_bit = 14; 4486 // for i = 0 to 14 4487 for (int i = 0; i < 14; ++i) 4488 { 4489 // if registers<i> == '1' then 4490 if (BitIsSet (registers, i)) 4491 { 4492 if (i < lowest_set_bit) 4493 lowest_set_bit = i; 4494 // if i == n && wback && i != LowestSetBit(registers) then 4495 if ((i == n) && wback && (i != lowest_set_bit)) 4496 // MemA[address,4] = bits(32) UNKNOWN; 4497 WriteBits32UnknownToMemory (address + offset); 4498 // else 4499 else 4500 { 4501 // MemA[address,4] = R[i]; 4502 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4503 if (!success) 4504 return false; 4505 4506 RegisterInfo data_reg; 4507 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4508 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4509 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4510 return false; 4511 } 4512 4513 // address = address + 4; 4514 offset += addr_byte_size; 4515 } 4516 } 4517 4518 // if registers<15> == '1' then 4519 // MemA[address,4] = PCStoreValue(); 4520 if (BitIsSet (registers, 15)) 4521 { 4522 RegisterInfo pc_reg; 4523 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4524 context.SetRegisterPlusOffset (pc_reg, 8); 4525 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4526 if (!success) 4527 return false; 4528 4529 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4530 return false; 4531 } 4532 4533 // if wback then R[n] = R[n] + 4*BitCount(registers); 4534 if (wback) 4535 { 4536 offset = addr_byte_size * BitCount (registers); 4537 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4538 context.SetImmediateSigned (offset); 4539 addr_t data = Rn + offset; 4540 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4541 return false; 4542 } 4543 } 4544 return true; 4545 } 4546 4547 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 4548 // from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4549 bool 4550 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4551 { 4552 #if 0 4553 if ConditionPassed() then 4554 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4555 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4556 address = if index then offset_addr else R[n]; 4557 if UnalignedSupport() || address<1:0> == '00' then 4558 MemU[address,4] = R[t]; 4559 else // Can only occur before ARMv7 4560 MemU[address,4] = bits(32) UNKNOWN; 4561 if wback then R[n] = offset_addr; 4562 #endif 4563 4564 bool success = false; 4565 4566 if (ConditionPassed(opcode)) 4567 { 4568 const uint32_t addr_byte_size = GetAddressByteSize(); 4569 4570 uint32_t t; 4571 uint32_t n; 4572 uint32_t imm32; 4573 bool index; 4574 bool add; 4575 bool wback; 4576 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4577 switch (encoding) 4578 { 4579 case eEncodingT1: 4580 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4581 t = Bits32 (opcode, 2, 0); 4582 n = Bits32 (opcode, 5, 3); 4583 imm32 = Bits32 (opcode, 10, 6) << 2; 4584 4585 // index = TRUE; add = TRUE; wback = FALSE; 4586 index = true; 4587 add = false; 4588 wback = false; 4589 break; 4590 4591 case eEncodingT2: 4592 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4593 t = Bits32 (opcode, 10, 8); 4594 n = 13; 4595 imm32 = Bits32 (opcode, 7, 0) << 2; 4596 4597 // index = TRUE; add = TRUE; wback = FALSE; 4598 index = true; 4599 add = true; 4600 wback = false; 4601 break; 4602 4603 case eEncodingT3: 4604 // if Rn == '1111' then UNDEFINED; 4605 if (Bits32 (opcode, 19, 16) == 15) 4606 return false; 4607 4608 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4609 t = Bits32 (opcode, 15, 12); 4610 n = Bits32 (opcode, 19, 16); 4611 imm32 = Bits32 (opcode, 11, 0); 4612 4613 // index = TRUE; add = TRUE; wback = FALSE; 4614 index = true; 4615 add = true; 4616 wback = false; 4617 4618 // if t == 15 then UNPREDICTABLE; 4619 if (t == 15) 4620 return false; 4621 break; 4622 4623 case eEncodingT4: 4624 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4625 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4626 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4627 if ((Bits32 (opcode, 19, 16) == 15) 4628 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4629 return false; 4630 4631 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4632 t = Bits32 (opcode, 15, 12); 4633 n = Bits32 (opcode, 19, 16); 4634 imm32 = Bits32 (opcode, 7, 0); 4635 4636 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4637 index = BitIsSet (opcode, 10); 4638 add = BitIsSet (opcode, 9); 4639 wback = BitIsSet (opcode, 8); 4640 4641 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4642 if ((t == 15) || (wback && (n == t))) 4643 return false; 4644 break; 4645 4646 default: 4647 return false; 4648 } 4649 4650 addr_t offset_addr; 4651 addr_t address; 4652 4653 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4654 uint32_t base_address = ReadCoreReg (n, &success); 4655 if (!success) 4656 return false; 4657 4658 if (add) 4659 offset_addr = base_address + imm32; 4660 else 4661 offset_addr = base_address - imm32; 4662 4663 // address = if index then offset_addr else R[n]; 4664 if (index) 4665 address = offset_addr; 4666 else 4667 address = base_address; 4668 4669 EmulateInstruction::Context context; 4670 context.type = eContextRegisterStore; 4671 RegisterInfo base_reg; 4672 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4673 4674 // if UnalignedSupport() || address<1:0> == '00' then 4675 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4676 { 4677 // MemU[address,4] = R[t]; 4678 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4679 if (!success) 4680 return false; 4681 4682 RegisterInfo data_reg; 4683 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4684 int32_t offset = address - base_address; 4685 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4686 if (!MemUWrite (context, address, data, addr_byte_size)) 4687 return false; 4688 } 4689 else 4690 { 4691 // MemU[address,4] = bits(32) UNKNOWN; 4692 WriteBits32UnknownToMemory (address); 4693 } 4694 4695 // if wback then R[n] = offset_addr; 4696 if (wback) 4697 { 4698 context.type = eContextRegisterLoad; 4699 context.SetAddress (offset_addr); 4700 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4701 return false; 4702 } 4703 } 4704 return true; 4705 } 4706 4707 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4708 // word from a register to memory. The offset register value can optionally be shifted. 4709 bool 4710 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4711 { 4712 #if 0 4713 if ConditionPassed() then 4714 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4715 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4716 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4717 address = if index then offset_addr else R[n]; 4718 if t == 15 then // Only possible for encoding A1 4719 data = PCStoreValue(); 4720 else 4721 data = R[t]; 4722 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4723 MemU[address,4] = data; 4724 else // Can only occur before ARMv7 4725 MemU[address,4] = bits(32) UNKNOWN; 4726 if wback then R[n] = offset_addr; 4727 #endif 4728 4729 bool success = false; 4730 4731 if (ConditionPassed(opcode)) 4732 { 4733 const uint32_t addr_byte_size = GetAddressByteSize(); 4734 4735 uint32_t t; 4736 uint32_t n; 4737 uint32_t m; 4738 ARM_ShifterType shift_t; 4739 uint32_t shift_n; 4740 bool index; 4741 bool add; 4742 bool wback; 4743 4744 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4745 switch (encoding) 4746 { 4747 case eEncodingT1: 4748 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4749 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4750 t = Bits32 (opcode, 2, 0); 4751 n = Bits32 (opcode, 5, 3); 4752 m = Bits32 (opcode, 8, 6); 4753 4754 // index = TRUE; add = TRUE; wback = FALSE; 4755 index = true; 4756 add = true; 4757 wback = false; 4758 4759 // (shift_t, shift_n) = (SRType_LSL, 0); 4760 shift_t = SRType_LSL; 4761 shift_n = 0; 4762 break; 4763 4764 case eEncodingT2: 4765 // if Rn == '1111' then UNDEFINED; 4766 if (Bits32 (opcode, 19, 16) == 15) 4767 return false; 4768 4769 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4770 t = Bits32 (opcode, 15, 12); 4771 n = Bits32 (opcode, 19, 16); 4772 m = Bits32 (opcode, 3, 0); 4773 4774 // index = TRUE; add = TRUE; wback = FALSE; 4775 index = true; 4776 add = true; 4777 wback = false; 4778 4779 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4780 shift_t = SRType_LSL; 4781 shift_n = Bits32 (opcode, 5, 4); 4782 4783 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4784 if ((t == 15) || (BadReg (m))) 4785 return false; 4786 break; 4787 4788 case eEncodingA1: 4789 { 4790 // if P == '0' && W == '1' then SEE STRT; 4791 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4792 t = Bits32 (opcode, 15, 12); 4793 n = Bits32 (opcode, 19, 16); 4794 m = Bits32 (opcode, 3, 0); 4795 4796 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4797 index = BitIsSet (opcode, 24); 4798 add = BitIsSet (opcode, 23); 4799 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4800 4801 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4802 uint32_t typ = Bits32 (opcode, 6, 5); 4803 uint32_t imm5 = Bits32 (opcode, 11, 7); 4804 shift_n = DecodeImmShift(typ, imm5, shift_t); 4805 4806 // if m == 15 then UNPREDICTABLE; 4807 if (m == 15) 4808 return false; 4809 4810 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4811 if (wback && ((n == 15) || (n == t))) 4812 return false; 4813 4814 break; 4815 } 4816 default: 4817 return false; 4818 } 4819 4820 addr_t offset_addr; 4821 addr_t address; 4822 int32_t offset = 0; 4823 4824 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4825 if (!success) 4826 return false; 4827 4828 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4829 if (!success) 4830 return false; 4831 4832 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4833 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4834 if (!success) 4835 return false; 4836 4837 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4838 if (add) 4839 offset_addr = base_address + offset; 4840 else 4841 offset_addr = base_address - offset; 4842 4843 // address = if index then offset_addr else R[n]; 4844 if (index) 4845 address = offset_addr; 4846 else 4847 address = base_address; 4848 4849 uint32_t data; 4850 // if t == 15 then // Only possible for encoding A1 4851 if (t == 15) 4852 // data = PCStoreValue(); 4853 data = ReadCoreReg (PC_REG, &success); 4854 else 4855 // data = R[t]; 4856 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4857 4858 if (!success) 4859 return false; 4860 4861 EmulateInstruction::Context context; 4862 context.type = eContextRegisterStore; 4863 4864 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4865 if (UnalignedSupport () 4866 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4867 || CurrentInstrSet() == eModeARM) 4868 { 4869 // MemU[address,4] = data; 4870 4871 RegisterInfo base_reg; 4872 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4873 4874 RegisterInfo data_reg; 4875 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4876 4877 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4878 if (!MemUWrite (context, address, data, addr_byte_size)) 4879 return false; 4880 4881 } 4882 else 4883 // MemU[address,4] = bits(32) UNKNOWN; 4884 WriteBits32UnknownToMemory (address); 4885 4886 // if wback then R[n] = offset_addr; 4887 if (wback) 4888 { 4889 context.type = eContextRegisterLoad; 4890 context.SetAddress (offset_addr); 4891 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4892 return false; 4893 } 4894 4895 } 4896 return true; 4897 } 4898 4899 bool 4900 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 4901 { 4902 #if 0 4903 if ConditionPassed() then 4904 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4905 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4906 address = if index then offset_addr else R[n]; 4907 MemU[address,1] = R[t]<7:0>; 4908 if wback then R[n] = offset_addr; 4909 #endif 4910 4911 4912 bool success = false; 4913 4914 if (ConditionPassed(opcode)) 4915 { 4916 uint32_t t; 4917 uint32_t n; 4918 uint32_t imm32; 4919 bool index; 4920 bool add; 4921 bool wback; 4922 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4923 switch (encoding) 4924 { 4925 case eEncodingT1: 4926 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4927 t = Bits32 (opcode, 2, 0); 4928 n = Bits32 (opcode, 5, 3); 4929 imm32 = Bits32 (opcode, 10, 6); 4930 4931 // index = TRUE; add = TRUE; wback = FALSE; 4932 index = true; 4933 add = true; 4934 wback = false; 4935 break; 4936 4937 case eEncodingT2: 4938 // if Rn == '1111' then UNDEFINED; 4939 if (Bits32 (opcode, 19, 16) == 15) 4940 return false; 4941 4942 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4943 t = Bits32 (opcode, 15, 12); 4944 n = Bits32 (opcode, 19, 16); 4945 imm32 = Bits32 (opcode, 11, 0); 4946 4947 // index = TRUE; add = TRUE; wback = FALSE; 4948 index = true; 4949 add = true; 4950 wback = false; 4951 4952 // if BadReg(t) then UNPREDICTABLE; 4953 if (BadReg (t)) 4954 return false; 4955 break; 4956 4957 case eEncodingT3: 4958 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 4959 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4960 if (Bits32 (opcode, 19, 16) == 15) 4961 return false; 4962 4963 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4964 t = Bits32 (opcode, 15, 12); 4965 n = Bits32 (opcode, 19, 16); 4966 imm32 = Bits32 (opcode, 7, 0); 4967 4968 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4969 index = BitIsSet (opcode, 10); 4970 add = BitIsSet (opcode, 9); 4971 wback = BitIsSet (opcode, 8); 4972 4973 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 4974 if ((BadReg (t)) || (wback && (n == t))) 4975 return false; 4976 break; 4977 4978 default: 4979 return false; 4980 } 4981 4982 addr_t offset_addr; 4983 addr_t address; 4984 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4985 if (!success) 4986 return false; 4987 4988 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4989 if (add) 4990 offset_addr = base_address + imm32; 4991 else 4992 offset_addr = base_address - imm32; 4993 4994 // address = if index then offset_addr else R[n]; 4995 if (index) 4996 address = offset_addr; 4997 else 4998 address = base_address; 4999 5000 // MemU[address,1] = R[t]<7:0> 5001 RegisterInfo base_reg; 5002 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5003 5004 RegisterInfo data_reg; 5005 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5006 5007 EmulateInstruction::Context context; 5008 context.type = eContextRegisterStore; 5009 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5010 5011 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5012 if (!success) 5013 return false; 5014 5015 data = Bits32 (data, 7, 0); 5016 5017 if (!MemUWrite (context, address, data, 1)) 5018 return false; 5019 5020 // if wback then R[n] = offset_addr; 5021 if (wback) 5022 { 5023 context.type = eContextRegisterLoad; 5024 context.SetAddress (offset_addr); 5025 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5026 return false; 5027 } 5028 5029 } 5030 5031 return true; 5032 } 5033 5034 // STRH (register) calculates an address from a base register value and an offset register value, and stores a 5035 // halfword from a register to memory. The offset register alue can be shifted left by 0, 1, 2, or 3 bits. 5036 bool 5037 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5038 { 5039 #if 0 5040 if ConditionPassed() then 5041 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5042 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5043 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5044 address = if index then offset_addr else R[n]; 5045 if UnalignedSupport() || address<0> == '0' then 5046 MemU[address,2] = R[t]<15:0>; 5047 else // Can only occur before ARMv7 5048 MemU[address,2] = bits(16) UNKNOWN; 5049 if wback then R[n] = offset_addr; 5050 #endif 5051 5052 bool success = false; 5053 5054 if (ConditionPassed(opcode)) 5055 { 5056 uint32_t t; 5057 uint32_t n; 5058 uint32_t m; 5059 bool index; 5060 bool add; 5061 bool wback; 5062 ARM_ShifterType shift_t; 5063 uint32_t shift_n; 5064 5065 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5066 switch (encoding) 5067 { 5068 case eEncodingT1: 5069 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5070 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5071 t = Bits32 (opcode, 2, 0); 5072 n = Bits32 (opcode, 5, 3); 5073 m = Bits32 (opcode, 8, 6); 5074 5075 // index = TRUE; add = TRUE; wback = FALSE; 5076 index = true; 5077 add = true; 5078 wback = false; 5079 5080 // (shift_t, shift_n) = (SRType_LSL, 0); 5081 shift_t = SRType_LSL; 5082 shift_n = 0; 5083 5084 break; 5085 5086 case eEncodingT2: 5087 // if Rn == '1111' then UNDEFINED; 5088 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5089 t = Bits32 (opcode, 15, 12); 5090 n = Bits32 (opcode, 19, 16); 5091 m = Bits32 (opcode, 3, 0); 5092 if (n == 15) 5093 return false; 5094 5095 // index = TRUE; add = TRUE; wback = FALSE; 5096 index = true; 5097 add = true; 5098 wback = false; 5099 5100 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5101 shift_t = SRType_LSL; 5102 shift_n = Bits32 (opcode, 5, 4); 5103 5104 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5105 if (BadReg (t) || BadReg (m)) 5106 return false; 5107 5108 break; 5109 5110 case eEncodingA1: 5111 // if P == '0' && W == '1' then SEE STRHT; 5112 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5113 t = Bits32 (opcode, 15, 12); 5114 n = Bits32 (opcode, 19, 16); 5115 m = Bits32 (opcode, 3, 0); 5116 5117 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5118 index = BitIsSet (opcode, 24); 5119 add = BitIsSet (opcode, 23); 5120 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5121 5122 // (shift_t, shift_n) = (SRType_LSL, 0); 5123 shift_t = SRType_LSL; 5124 shift_n = 0; 5125 5126 // if t == 15 || m == 15 then UNPREDICTABLE; 5127 if ((t == 15) || (m == 15)) 5128 return false; 5129 5130 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5131 if (wback && ((n == 15) || (n == t))) 5132 return false; 5133 5134 break; 5135 5136 default: 5137 return false; 5138 } 5139 5140 uint32_t Rm = ReadCoreReg (m, &success); 5141 if (!success) 5142 return false; 5143 5144 uint32_t Rn = ReadCoreReg (n, &success); 5145 if (!success) 5146 return false; 5147 5148 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5149 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5150 if (!success) 5151 return false; 5152 5153 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5154 addr_t offset_addr; 5155 if (add) 5156 offset_addr = Rn + offset; 5157 else 5158 offset_addr = Rn - offset; 5159 5160 // address = if index then offset_addr else R[n]; 5161 addr_t address; 5162 if (index) 5163 address = offset_addr; 5164 else 5165 address = Rn; 5166 5167 EmulateInstruction::Context context; 5168 context.type = eContextRegisterStore; 5169 RegisterInfo base_reg; 5170 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5171 RegisterInfo offset_reg; 5172 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5173 5174 // if UnalignedSupport() || address<0> == '0' then 5175 if (UnalignedSupport() || BitIsClear (address, 0)) 5176 { 5177 // MemU[address,2] = R[t]<15:0>; 5178 uint32_t Rt = ReadCoreReg (t, &success); 5179 if (!success) 5180 return false; 5181 5182 EmulateInstruction::Context context; 5183 context.type = eContextRegisterStore; 5184 RegisterInfo base_reg; 5185 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5186 RegisterInfo offset_reg; 5187 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5188 RegisterInfo data_reg; 5189 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5190 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5191 5192 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5193 return false; 5194 } 5195 else // Can only occur before ARMv7 5196 { 5197 // MemU[address,2] = bits(16) UNKNOWN; 5198 } 5199 5200 // if wback then R[n] = offset_addr; 5201 if (wback) 5202 { 5203 context.type = eContextAdjustBaseRegister; 5204 context.SetAddress (offset_addr); 5205 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5206 return false; 5207 } 5208 } 5209 5210 return true; 5211 } 5212 5213 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5214 // and writes the result to the destination register. It can optionally update the condition flags 5215 // based on the result. 5216 bool 5217 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5218 { 5219 #if 0 5220 // ARM pseudo code... 5221 if ConditionPassed() then 5222 EncodingSpecificOperations(); 5223 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5224 if d == 15 then // Can only occur for ARM encoding 5225 ALUWritePC(result); // setflags is always FALSE here 5226 else 5227 R[d] = result; 5228 if setflags then 5229 APSR.N = result<31>; 5230 APSR.Z = IsZeroBit(result); 5231 APSR.C = carry; 5232 APSR.V = overflow; 5233 #endif 5234 5235 bool success = false; 5236 5237 if (ConditionPassed(opcode)) 5238 { 5239 uint32_t Rd, Rn; 5240 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5241 bool setflags; 5242 switch (encoding) 5243 { 5244 case eEncodingT1: 5245 Rd = Bits32(opcode, 11, 8); 5246 Rn = Bits32(opcode, 19, 16); 5247 setflags = BitIsSet(opcode, 20); 5248 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5249 if (BadReg(Rd) || BadReg(Rn)) 5250 return false; 5251 break; 5252 case eEncodingA1: 5253 Rd = Bits32(opcode, 15, 12); 5254 Rn = Bits32(opcode, 19, 16); 5255 setflags = BitIsSet(opcode, 20); 5256 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5257 5258 if (Rd == 15 && setflags) 5259 return EmulateSUBSPcLrEtc (opcode, encoding); 5260 break; 5261 default: 5262 return false; 5263 } 5264 5265 // Read the first operand. 5266 int32_t val1 = ReadCoreReg(Rn, &success); 5267 if (!success) 5268 return false; 5269 5270 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5271 5272 EmulateInstruction::Context context; 5273 context.type = EmulateInstruction::eContextImmediate; 5274 context.SetNoArgs (); 5275 5276 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5277 return false; 5278 } 5279 return true; 5280 } 5281 5282 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5283 // register value, and writes the result to the destination register. It can optionally update the 5284 // condition flags based on the result. 5285 bool 5286 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5287 { 5288 #if 0 5289 // ARM pseudo code... 5290 if ConditionPassed() then 5291 EncodingSpecificOperations(); 5292 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5293 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5294 if d == 15 then // Can only occur for ARM encoding 5295 ALUWritePC(result); // setflags is always FALSE here 5296 else 5297 R[d] = result; 5298 if setflags then 5299 APSR.N = result<31>; 5300 APSR.Z = IsZeroBit(result); 5301 APSR.C = carry; 5302 APSR.V = overflow; 5303 #endif 5304 5305 bool success = false; 5306 5307 if (ConditionPassed(opcode)) 5308 { 5309 uint32_t Rd, Rn, Rm; 5310 ARM_ShifterType shift_t; 5311 uint32_t shift_n; // the shift applied to the value read from Rm 5312 bool setflags; 5313 switch (encoding) 5314 { 5315 case eEncodingT1: 5316 Rd = Rn = Bits32(opcode, 2, 0); 5317 Rm = Bits32(opcode, 5, 3); 5318 setflags = !InITBlock(); 5319 shift_t = SRType_LSL; 5320 shift_n = 0; 5321 break; 5322 case eEncodingT2: 5323 Rd = Bits32(opcode, 11, 8); 5324 Rn = Bits32(opcode, 19, 16); 5325 Rm = Bits32(opcode, 3, 0); 5326 setflags = BitIsSet(opcode, 20); 5327 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5328 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5329 return false; 5330 break; 5331 case eEncodingA1: 5332 Rd = Bits32(opcode, 15, 12); 5333 Rn = Bits32(opcode, 19, 16); 5334 Rm = Bits32(opcode, 3, 0); 5335 setflags = BitIsSet(opcode, 20); 5336 shift_n = DecodeImmShiftARM(opcode, shift_t); 5337 5338 if (Rd == 15 && setflags) 5339 return EmulateSUBSPcLrEtc (opcode, encoding); 5340 break; 5341 default: 5342 return false; 5343 } 5344 5345 // Read the first operand. 5346 int32_t val1 = ReadCoreReg(Rn, &success); 5347 if (!success) 5348 return false; 5349 5350 // Read the second operand. 5351 int32_t val2 = ReadCoreReg(Rm, &success); 5352 if (!success) 5353 return false; 5354 5355 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5356 if (!success) 5357 return false; 5358 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5359 5360 EmulateInstruction::Context context; 5361 context.type = EmulateInstruction::eContextImmediate; 5362 context.SetNoArgs (); 5363 5364 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5365 return false; 5366 } 5367 return true; 5368 } 5369 5370 // This instruction adds an immediate value to the PC value to form a PC-relative address, 5371 // and writes the result to the destination register. 5372 bool 5373 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5374 { 5375 #if 0 5376 // ARM pseudo code... 5377 if ConditionPassed() then 5378 EncodingSpecificOperations(); 5379 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5380 if d == 15 then // Can only occur for ARM encodings 5381 ALUWritePC(result); 5382 else 5383 R[d] = result; 5384 #endif 5385 5386 bool success = false; 5387 5388 if (ConditionPassed(opcode)) 5389 { 5390 uint32_t Rd; 5391 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5392 bool add; 5393 switch (encoding) 5394 { 5395 case eEncodingT1: 5396 Rd = Bits32(opcode, 10, 8); 5397 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5398 break; 5399 case eEncodingT2: 5400 case eEncodingT3: 5401 Rd = Bits32(opcode, 11, 8); 5402 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5403 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5404 if (BadReg(Rd)) 5405 return false; 5406 break; 5407 case eEncodingA1: 5408 case eEncodingA2: 5409 Rd = Bits32(opcode, 15, 12); 5410 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5411 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5412 break; 5413 default: 5414 return false; 5415 } 5416 5417 // Read the PC value. 5418 uint32_t pc = ReadCoreReg(PC_REG, &success); 5419 if (!success) 5420 return false; 5421 5422 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5423 5424 EmulateInstruction::Context context; 5425 context.type = EmulateInstruction::eContextImmediate; 5426 context.SetNoArgs (); 5427 5428 if (!WriteCoreReg(context, result, Rd)) 5429 return false; 5430 } 5431 return true; 5432 } 5433 5434 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5435 // to the destination register. It can optionally update the condition flags based on the result. 5436 bool 5437 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5438 { 5439 #if 0 5440 // ARM pseudo code... 5441 if ConditionPassed() then 5442 EncodingSpecificOperations(); 5443 result = R[n] AND imm32; 5444 if d == 15 then // Can only occur for ARM encoding 5445 ALUWritePC(result); // setflags is always FALSE here 5446 else 5447 R[d] = result; 5448 if setflags then 5449 APSR.N = result<31>; 5450 APSR.Z = IsZeroBit(result); 5451 APSR.C = carry; 5452 // APSR.V unchanged 5453 #endif 5454 5455 bool success = false; 5456 5457 if (ConditionPassed(opcode)) 5458 { 5459 uint32_t Rd, Rn; 5460 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5461 bool setflags; 5462 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5463 switch (encoding) 5464 { 5465 case eEncodingT1: 5466 Rd = Bits32(opcode, 11, 8); 5467 Rn = Bits32(opcode, 19, 16); 5468 setflags = BitIsSet(opcode, 20); 5469 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5470 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5471 if (Rd == 15 && setflags) 5472 return EmulateTSTImm(opcode, eEncodingT1); 5473 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5474 return false; 5475 break; 5476 case eEncodingA1: 5477 Rd = Bits32(opcode, 15, 12); 5478 Rn = Bits32(opcode, 19, 16); 5479 setflags = BitIsSet(opcode, 20); 5480 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5481 5482 if (Rd == 15 && setflags) 5483 return EmulateSUBSPcLrEtc (opcode, encoding); 5484 break; 5485 default: 5486 return false; 5487 } 5488 5489 // Read the first operand. 5490 uint32_t val1 = ReadCoreReg(Rn, &success); 5491 if (!success) 5492 return false; 5493 5494 uint32_t result = val1 & imm32; 5495 5496 EmulateInstruction::Context context; 5497 context.type = EmulateInstruction::eContextImmediate; 5498 context.SetNoArgs (); 5499 5500 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5501 return false; 5502 } 5503 return true; 5504 } 5505 5506 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5507 // and writes the result to the destination register. It can optionally update the condition flags 5508 // based on the result. 5509 bool 5510 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5511 { 5512 #if 0 5513 // ARM pseudo code... 5514 if ConditionPassed() then 5515 EncodingSpecificOperations(); 5516 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5517 result = R[n] AND shifted; 5518 if d == 15 then // Can only occur for ARM encoding 5519 ALUWritePC(result); // setflags is always FALSE here 5520 else 5521 R[d] = result; 5522 if setflags then 5523 APSR.N = result<31>; 5524 APSR.Z = IsZeroBit(result); 5525 APSR.C = carry; 5526 // APSR.V unchanged 5527 #endif 5528 5529 bool success = false; 5530 5531 if (ConditionPassed(opcode)) 5532 { 5533 uint32_t Rd, Rn, Rm; 5534 ARM_ShifterType shift_t; 5535 uint32_t shift_n; // the shift applied to the value read from Rm 5536 bool setflags; 5537 uint32_t carry; 5538 switch (encoding) 5539 { 5540 case eEncodingT1: 5541 Rd = Rn = Bits32(opcode, 2, 0); 5542 Rm = Bits32(opcode, 5, 3); 5543 setflags = !InITBlock(); 5544 shift_t = SRType_LSL; 5545 shift_n = 0; 5546 break; 5547 case eEncodingT2: 5548 Rd = Bits32(opcode, 11, 8); 5549 Rn = Bits32(opcode, 19, 16); 5550 Rm = Bits32(opcode, 3, 0); 5551 setflags = BitIsSet(opcode, 20); 5552 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5553 // if Rd == '1111' && S == '1' then SEE TST (register); 5554 if (Rd == 15 && setflags) 5555 return EmulateTSTReg(opcode, eEncodingT2); 5556 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5557 return false; 5558 break; 5559 case eEncodingA1: 5560 Rd = Bits32(opcode, 15, 12); 5561 Rn = Bits32(opcode, 19, 16); 5562 Rm = Bits32(opcode, 3, 0); 5563 setflags = BitIsSet(opcode, 20); 5564 shift_n = DecodeImmShiftARM(opcode, shift_t); 5565 5566 if (Rd == 15 && setflags) 5567 return EmulateSUBSPcLrEtc (opcode, encoding); 5568 break; 5569 default: 5570 return false; 5571 } 5572 5573 // Read the first operand. 5574 uint32_t val1 = ReadCoreReg(Rn, &success); 5575 if (!success) 5576 return false; 5577 5578 // Read the second operand. 5579 uint32_t val2 = ReadCoreReg(Rm, &success); 5580 if (!success) 5581 return false; 5582 5583 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5584 if (!success) 5585 return false; 5586 uint32_t result = val1 & shifted; 5587 5588 EmulateInstruction::Context context; 5589 context.type = EmulateInstruction::eContextImmediate; 5590 context.SetNoArgs (); 5591 5592 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5593 return false; 5594 } 5595 return true; 5596 } 5597 5598 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5599 // immediate value, and writes the result to the destination register. It can optionally update the 5600 // condition flags based on the result. 5601 bool 5602 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5603 { 5604 #if 0 5605 // ARM pseudo code... 5606 if ConditionPassed() then 5607 EncodingSpecificOperations(); 5608 result = R[n] AND NOT(imm32); 5609 if d == 15 then // Can only occur for ARM encoding 5610 ALUWritePC(result); // setflags is always FALSE here 5611 else 5612 R[d] = result; 5613 if setflags then 5614 APSR.N = result<31>; 5615 APSR.Z = IsZeroBit(result); 5616 APSR.C = carry; 5617 // APSR.V unchanged 5618 #endif 5619 5620 bool success = false; 5621 5622 if (ConditionPassed(opcode)) 5623 { 5624 uint32_t Rd, Rn; 5625 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5626 bool setflags; 5627 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5628 switch (encoding) 5629 { 5630 case eEncodingT1: 5631 Rd = Bits32(opcode, 11, 8); 5632 Rn = Bits32(opcode, 19, 16); 5633 setflags = BitIsSet(opcode, 20); 5634 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5635 if (BadReg(Rd) || BadReg(Rn)) 5636 return false; 5637 break; 5638 case eEncodingA1: 5639 Rd = Bits32(opcode, 15, 12); 5640 Rn = Bits32(opcode, 19, 16); 5641 setflags = BitIsSet(opcode, 20); 5642 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5643 5644 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5645 if (Rd == 15 && setflags) 5646 return EmulateSUBSPcLrEtc (opcode, encoding); 5647 break; 5648 default: 5649 return false; 5650 } 5651 5652 // Read the first operand. 5653 uint32_t val1 = ReadCoreReg(Rn, &success); 5654 if (!success) 5655 return false; 5656 5657 uint32_t result = val1 & ~imm32; 5658 5659 EmulateInstruction::Context context; 5660 context.type = EmulateInstruction::eContextImmediate; 5661 context.SetNoArgs (); 5662 5663 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5664 return false; 5665 } 5666 return true; 5667 } 5668 5669 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5670 // optionally-shifted register value, and writes the result to the destination register. 5671 // It can optionally update the condition flags based on the result. 5672 bool 5673 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5674 { 5675 #if 0 5676 // ARM pseudo code... 5677 if ConditionPassed() then 5678 EncodingSpecificOperations(); 5679 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5680 result = R[n] AND NOT(shifted); 5681 if d == 15 then // Can only occur for ARM encoding 5682 ALUWritePC(result); // setflags is always FALSE here 5683 else 5684 R[d] = result; 5685 if setflags then 5686 APSR.N = result<31>; 5687 APSR.Z = IsZeroBit(result); 5688 APSR.C = carry; 5689 // APSR.V unchanged 5690 #endif 5691 5692 bool success = false; 5693 5694 if (ConditionPassed(opcode)) 5695 { 5696 uint32_t Rd, Rn, Rm; 5697 ARM_ShifterType shift_t; 5698 uint32_t shift_n; // the shift applied to the value read from Rm 5699 bool setflags; 5700 uint32_t carry; 5701 switch (encoding) 5702 { 5703 case eEncodingT1: 5704 Rd = Rn = Bits32(opcode, 2, 0); 5705 Rm = Bits32(opcode, 5, 3); 5706 setflags = !InITBlock(); 5707 shift_t = SRType_LSL; 5708 shift_n = 0; 5709 break; 5710 case eEncodingT2: 5711 Rd = Bits32(opcode, 11, 8); 5712 Rn = Bits32(opcode, 19, 16); 5713 Rm = Bits32(opcode, 3, 0); 5714 setflags = BitIsSet(opcode, 20); 5715 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5716 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5717 return false; 5718 break; 5719 case eEncodingA1: 5720 Rd = Bits32(opcode, 15, 12); 5721 Rn = Bits32(opcode, 19, 16); 5722 Rm = Bits32(opcode, 3, 0); 5723 setflags = BitIsSet(opcode, 20); 5724 shift_n = DecodeImmShiftARM(opcode, shift_t); 5725 5726 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5727 if (Rd == 15 && setflags) 5728 return EmulateSUBSPcLrEtc (opcode, encoding); 5729 break; 5730 default: 5731 return false; 5732 } 5733 5734 // Read the first operand. 5735 uint32_t val1 = ReadCoreReg(Rn, &success); 5736 if (!success) 5737 return false; 5738 5739 // Read the second operand. 5740 uint32_t val2 = ReadCoreReg(Rm, &success); 5741 if (!success) 5742 return false; 5743 5744 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5745 if (!success) 5746 return false; 5747 uint32_t result = val1 & ~shifted; 5748 5749 EmulateInstruction::Context context; 5750 context.type = EmulateInstruction::eContextImmediate; 5751 context.SetNoArgs (); 5752 5753 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5754 return false; 5755 } 5756 return true; 5757 } 5758 5759 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5760 // from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5761 bool 5762 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5763 { 5764 #if 0 5765 if ConditionPassed() then 5766 EncodingSpecificOperations(); 5767 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5768 address = if index then offset_addr else R[n]; 5769 data = MemU[address,4]; 5770 if wback then R[n] = offset_addr; 5771 if t == 15 then 5772 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5773 elsif UnalignedSupport() || address<1:0> = '00' then 5774 R[t] = data; 5775 else // Can only apply before ARMv7 5776 R[t] = ROR(data, 8*UInt(address<1:0>)); 5777 #endif 5778 5779 bool success = false; 5780 5781 if (ConditionPassed(opcode)) 5782 { 5783 const uint32_t addr_byte_size = GetAddressByteSize(); 5784 5785 uint32_t t; 5786 uint32_t n; 5787 uint32_t imm32; 5788 bool index; 5789 bool add; 5790 bool wback; 5791 5792 switch (encoding) 5793 { 5794 case eEncodingA1: 5795 // if Rn == '1111' then SEE LDR (literal); 5796 // if P == '0' && W == '1' then SEE LDRT; 5797 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5798 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5799 t = Bits32 (opcode, 15, 12); 5800 n = Bits32 (opcode, 19, 16); 5801 imm32 = Bits32 (opcode, 11, 0); 5802 5803 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5804 index = BitIsSet (opcode, 24); 5805 add = BitIsSet (opcode, 23); 5806 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5807 5808 // if wback && n == t then UNPREDICTABLE; 5809 if (wback && (n == t)) 5810 return false; 5811 5812 break; 5813 5814 default: 5815 return false; 5816 } 5817 5818 addr_t address; 5819 addr_t offset_addr; 5820 addr_t base_address = ReadCoreReg (n, &success); 5821 if (!success) 5822 return false; 5823 5824 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5825 if (add) 5826 offset_addr = base_address + imm32; 5827 else 5828 offset_addr = base_address - imm32; 5829 5830 // address = if index then offset_addr else R[n]; 5831 if (index) 5832 address = offset_addr; 5833 else 5834 address = base_address; 5835 5836 // data = MemU[address,4]; 5837 5838 RegisterInfo base_reg; 5839 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5840 5841 EmulateInstruction::Context context; 5842 context.type = eContextRegisterLoad; 5843 context.SetRegisterPlusOffset (base_reg, address - base_address); 5844 5845 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5846 if (!success) 5847 return false; 5848 5849 // if wback then R[n] = offset_addr; 5850 if (wback) 5851 { 5852 context.type = eContextAdjustBaseRegister; 5853 context.SetAddress (offset_addr); 5854 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5855 return false; 5856 } 5857 5858 // if t == 15 then 5859 if (t == 15) 5860 { 5861 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5862 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5863 { 5864 // LoadWritePC (data); 5865 context.type = eContextRegisterLoad; 5866 context.SetRegisterPlusOffset (base_reg, address - base_address); 5867 LoadWritePC (context, data); 5868 } 5869 else 5870 return false; 5871 } 5872 // elsif UnalignedSupport() || address<1:0> = '00' then 5873 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5874 { 5875 // R[t] = data; 5876 context.type = eContextRegisterLoad; 5877 context.SetRegisterPlusOffset (base_reg, address - base_address); 5878 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5879 return false; 5880 } 5881 // else // Can only apply before ARMv7 5882 else 5883 { 5884 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5885 data = ROR (data, Bits32 (address, 1, 0), &success); 5886 if (!success) 5887 return false; 5888 context.type = eContextRegisterLoad; 5889 context.SetImmediate (data); 5890 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5891 return false; 5892 } 5893 5894 } 5895 return true; 5896 } 5897 5898 // LDR (register) calculates an address from a base register value and an offset register value, loads a word 5899 // from memory, and writes it to a resgister. The offset register value can optionally be shifted. 5900 bool 5901 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5902 { 5903 #if 0 5904 if ConditionPassed() then 5905 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5906 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5907 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5908 address = if index then offset_addr else R[n]; 5909 data = MemU[address,4]; 5910 if wback then R[n] = offset_addr; 5911 if t == 15 then 5912 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5913 elsif UnalignedSupport() || address<1:0> = '00' then 5914 R[t] = data; 5915 else // Can only apply before ARMv7 5916 if CurrentInstrSet() == InstrSet_ARM then 5917 R[t] = ROR(data, 8*UInt(address<1:0>)); 5918 else 5919 R[t] = bits(32) UNKNOWN; 5920 #endif 5921 5922 bool success = false; 5923 5924 if (ConditionPassed(opcode)) 5925 { 5926 const uint32_t addr_byte_size = GetAddressByteSize(); 5927 5928 uint32_t t; 5929 uint32_t n; 5930 uint32_t m; 5931 bool index; 5932 bool add; 5933 bool wback; 5934 ARM_ShifterType shift_t; 5935 uint32_t shift_n; 5936 5937 switch (encoding) 5938 { 5939 case eEncodingT1: 5940 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5941 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5942 t = Bits32 (opcode, 2, 0); 5943 n = Bits32 (opcode, 5, 3); 5944 m = Bits32 (opcode, 8, 6); 5945 5946 // index = TRUE; add = TRUE; wback = FALSE; 5947 index = true; 5948 add = true; 5949 wback = false; 5950 5951 // (shift_t, shift_n) = (SRType_LSL, 0); 5952 shift_t = SRType_LSL; 5953 shift_n = 0; 5954 5955 break; 5956 5957 case eEncodingT2: 5958 // if Rn == '1111' then SEE LDR (literal); 5959 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5960 t = Bits32 (opcode, 15, 12); 5961 n = Bits32 (opcode, 19, 16); 5962 m = Bits32 (opcode, 3, 0); 5963 5964 // index = TRUE; add = TRUE; wback = FALSE; 5965 index = true; 5966 add = true; 5967 wback = false; 5968 5969 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5970 shift_t = SRType_LSL; 5971 shift_n = Bits32 (opcode, 5, 4); 5972 5973 // if BadReg(m) then UNPREDICTABLE; 5974 if (BadReg (m)) 5975 return false; 5976 5977 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5978 if ((t == 15) && InITBlock() && !LastInITBlock()) 5979 return false; 5980 5981 break; 5982 5983 case eEncodingA1: 5984 { 5985 // if P == '0' && W == '1' then SEE LDRT; 5986 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5987 t = Bits32 (opcode, 15, 12); 5988 n = Bits32 (opcode, 19, 16); 5989 m = Bits32 (opcode, 3, 0); 5990 5991 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5992 index = BitIsSet (opcode, 24); 5993 add = BitIsSet (opcode, 23); 5994 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5995 5996 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5997 uint32_t type = Bits32 (opcode, 6, 5); 5998 uint32_t imm5 = Bits32 (opcode, 11, 7); 5999 shift_n = DecodeImmShift (type, imm5, shift_t); 6000 6001 // if m == 15 then UNPREDICTABLE; 6002 if (m == 15) 6003 return false; 6004 6005 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6006 if (wback && ((n == 15) || (n == t))) 6007 return false; 6008 } 6009 break; 6010 6011 6012 default: 6013 return false; 6014 } 6015 6016 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6017 if (!success) 6018 return false; 6019 6020 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6021 if (!success) 6022 return false; 6023 6024 addr_t offset_addr; 6025 addr_t address; 6026 6027 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6028 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6029 if (!success) 6030 return false; 6031 6032 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6033 if (add) 6034 offset_addr = Rn + offset; 6035 else 6036 offset_addr = Rn - offset; 6037 6038 // address = if index then offset_addr else R[n]; 6039 if (index) 6040 address = offset_addr; 6041 else 6042 address = Rn; 6043 6044 // data = MemU[address,4]; 6045 RegisterInfo base_reg; 6046 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6047 6048 EmulateInstruction::Context context; 6049 context.type = eContextRegisterLoad; 6050 context.SetRegisterPlusOffset (base_reg, address - Rn); 6051 6052 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6053 if (!success) 6054 return false; 6055 6056 // if wback then R[n] = offset_addr; 6057 if (wback) 6058 { 6059 context.type = eContextAdjustBaseRegister; 6060 context.SetAddress (offset_addr); 6061 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6062 return false; 6063 } 6064 6065 // if t == 15 then 6066 if (t == 15) 6067 { 6068 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6069 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6070 { 6071 context.type = eContextRegisterLoad; 6072 context.SetRegisterPlusOffset (base_reg, address - Rn); 6073 LoadWritePC (context, data); 6074 } 6075 else 6076 return false; 6077 } 6078 // elsif UnalignedSupport() || address<1:0> = '00' then 6079 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6080 { 6081 // R[t] = data; 6082 context.type = eContextRegisterLoad; 6083 context.SetRegisterPlusOffset (base_reg, address - Rn); 6084 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6085 return false; 6086 } 6087 else // Can only apply before ARMv7 6088 { 6089 // if CurrentInstrSet() == InstrSet_ARM then 6090 if (CurrentInstrSet () == eModeARM) 6091 { 6092 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6093 data = ROR (data, Bits32 (address, 1, 0), &success); 6094 if (!success) 6095 return false; 6096 context.type = eContextRegisterLoad; 6097 context.SetImmediate (data); 6098 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6099 return false; 6100 } 6101 else 6102 { 6103 // R[t] = bits(32) UNKNOWN; 6104 WriteBits32Unknown (t); 6105 } 6106 } 6107 } 6108 return true; 6109 } 6110 6111 // LDRB (immediate, Thumb) 6112 bool 6113 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6114 { 6115 #if 0 6116 if ConditionPassed() then 6117 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6118 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6119 address = if index then offset_addr else R[n]; 6120 R[t] = ZeroExtend(MemU[address,1], 32); 6121 if wback then R[n] = offset_addr; 6122 #endif 6123 6124 bool success = false; 6125 6126 if (ConditionPassed(opcode)) 6127 { 6128 uint32_t t; 6129 uint32_t n; 6130 uint32_t imm32; 6131 bool index; 6132 bool add; 6133 bool wback; 6134 6135 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6136 switch (encoding) 6137 { 6138 case eEncodingT1: 6139 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6140 t = Bits32 (opcode, 2, 0); 6141 n = Bits32 (opcode, 5, 3); 6142 imm32 = Bits32 (opcode, 10, 6); 6143 6144 // index = TRUE; add = TRUE; wback = FALSE; 6145 index = true; 6146 add = true; 6147 wback= false; 6148 6149 break; 6150 6151 case eEncodingT2: 6152 // if Rt == '1111' then SEE PLD; 6153 // if Rn == '1111' then SEE LDRB (literal); 6154 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6155 t = Bits32 (opcode, 15, 12); 6156 n = Bits32 (opcode, 19, 16); 6157 imm32 = Bits32 (opcode, 11, 0); 6158 6159 // index = TRUE; add = TRUE; wback = FALSE; 6160 index = true; 6161 add = true; 6162 wback = false; 6163 6164 // if t == 13 then UNPREDICTABLE; 6165 if (t == 13) 6166 return false; 6167 6168 break; 6169 6170 case eEncodingT3: 6171 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6172 // if Rn == '1111' then SEE LDRB (literal); 6173 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6174 // if P == '0' && W == '0' then UNDEFINED; 6175 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6176 return false; 6177 6178 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6179 t = Bits32 (opcode, 15, 12); 6180 n = Bits32 (opcode, 19, 16); 6181 imm32 = Bits32 (opcode, 7, 0); 6182 6183 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6184 index = BitIsSet (opcode, 10); 6185 add = BitIsSet (opcode, 9); 6186 wback = BitIsSet (opcode, 8); 6187 6188 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6189 if (BadReg (t) || (wback && (n == t))) 6190 return false; 6191 6192 break; 6193 6194 default: 6195 return false; 6196 } 6197 6198 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6199 if (!success) 6200 return false; 6201 6202 addr_t address; 6203 addr_t offset_addr; 6204 6205 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6206 if (add) 6207 offset_addr = Rn + imm32; 6208 else 6209 offset_addr = Rn - imm32; 6210 6211 // address = if index then offset_addr else R[n]; 6212 if (index) 6213 address = offset_addr; 6214 else 6215 address = Rn; 6216 6217 // R[t] = ZeroExtend(MemU[address,1], 32); 6218 RegisterInfo base_reg; 6219 RegisterInfo data_reg; 6220 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6221 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6222 6223 EmulateInstruction::Context context; 6224 context.type = eContextRegisterLoad; 6225 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6226 6227 uint64_t data = MemURead (context, address, 1, 0, &success); 6228 if (!success) 6229 return false; 6230 6231 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6232 return false; 6233 6234 // if wback then R[n] = offset_addr; 6235 if (wback) 6236 { 6237 context.type = eContextAdjustBaseRegister; 6238 context.SetAddress (offset_addr); 6239 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6240 return false; 6241 } 6242 } 6243 return true; 6244 } 6245 6246 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6247 // zero-extends it to form a 32-bit word and writes it to a register. 6248 bool 6249 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6250 { 6251 #if 0 6252 if ConditionPassed() then 6253 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6254 base = Align(PC,4); 6255 address = if add then (base + imm32) else (base - imm32); 6256 R[t] = ZeroExtend(MemU[address,1], 32); 6257 #endif 6258 6259 bool success = false; 6260 6261 if (ConditionPassed(opcode)) 6262 { 6263 uint32_t t; 6264 uint32_t imm32; 6265 bool add; 6266 switch (encoding) 6267 { 6268 case eEncodingT1: 6269 // if Rt == '1111' then SEE PLD; 6270 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6271 t = Bits32 (opcode, 15, 12); 6272 imm32 = Bits32 (opcode, 11, 0); 6273 add = BitIsSet (opcode, 23); 6274 6275 // if t == 13 then UNPREDICTABLE; 6276 if (t == 13) 6277 return false; 6278 6279 break; 6280 6281 case eEncodingA1: 6282 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6283 t = Bits32 (opcode, 15, 12); 6284 imm32 = Bits32 (opcode, 11, 0); 6285 add = BitIsSet (opcode, 23); 6286 6287 // if t == 15 then UNPREDICTABLE; 6288 if (t == 15) 6289 return false; 6290 break; 6291 6292 default: 6293 return false; 6294 } 6295 6296 // base = Align(PC,4); 6297 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6298 if (!success) 6299 return false; 6300 6301 uint32_t base = AlignPC (pc_val); 6302 6303 addr_t address; 6304 // address = if add then (base + imm32) else (base - imm32); 6305 if (add) 6306 address = base + imm32; 6307 else 6308 address = base - imm32; 6309 6310 // R[t] = ZeroExtend(MemU[address,1], 32); 6311 EmulateInstruction::Context context; 6312 context.type = eContextRelativeBranchImmediate; 6313 context.SetImmediate (address - base); 6314 6315 uint64_t data = MemURead (context, address, 1, 0, &success); 6316 if (!success) 6317 return false; 6318 6319 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6320 return false; 6321 } 6322 return true; 6323 } 6324 6325 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6326 // memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6327 // optionally be shifted. 6328 bool 6329 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6330 { 6331 #if 0 6332 if ConditionPassed() then 6333 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6334 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6335 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6336 address = if index then offset_addr else R[n]; 6337 R[t] = ZeroExtend(MemU[address,1],32); 6338 if wback then R[n] = offset_addr; 6339 #endif 6340 6341 bool success = false; 6342 6343 if (ConditionPassed(opcode)) 6344 { 6345 uint32_t t; 6346 uint32_t n; 6347 uint32_t m; 6348 bool index; 6349 bool add; 6350 bool wback; 6351 ARM_ShifterType shift_t; 6352 uint32_t shift_n; 6353 6354 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6355 switch (encoding) 6356 { 6357 case eEncodingT1: 6358 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6359 t = Bits32 (opcode, 2, 0); 6360 n = Bits32 (opcode, 5, 3); 6361 m = Bits32 (opcode, 8, 6); 6362 6363 // index = TRUE; add = TRUE; wback = FALSE; 6364 index = true; 6365 add = true; 6366 wback = false; 6367 6368 // (shift_t, shift_n) = (SRType_LSL, 0); 6369 shift_t = SRType_LSL; 6370 shift_n = 0; 6371 break; 6372 6373 case eEncodingT2: 6374 // if Rt == '1111' then SEE PLD; 6375 // if Rn == '1111' then SEE LDRB (literal); 6376 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6377 t = Bits32 (opcode, 15, 12); 6378 n = Bits32 (opcode, 19, 16); 6379 m = Bits32 (opcode, 3, 0); 6380 6381 // index = TRUE; add = TRUE; wback = FALSE; 6382 index = true; 6383 add = true; 6384 wback = false; 6385 6386 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6387 shift_t = SRType_LSL; 6388 shift_n = Bits32 (opcode, 5, 4); 6389 6390 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6391 if ((t == 13) || BadReg (m)) 6392 return false; 6393 break; 6394 6395 case eEncodingA1: 6396 { 6397 // if P == '0' && W == '1' then SEE LDRBT; 6398 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6399 t = Bits32 (opcode, 15, 12); 6400 n = Bits32 (opcode, 19, 16); 6401 m = Bits32 (opcode, 3, 0); 6402 6403 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6404 index = BitIsSet (opcode, 24); 6405 add = BitIsSet (opcode, 23); 6406 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6407 6408 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6409 uint32_t type = Bits32 (opcode, 6, 5); 6410 uint32_t imm5 = Bits32 (opcode, 11, 7); 6411 shift_n = DecodeImmShift (type, imm5, shift_t); 6412 6413 // if t == 15 || m == 15 then UNPREDICTABLE; 6414 if ((t == 15) || (m == 15)) 6415 return false; 6416 6417 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6418 if (wback && ((n == 15) || (n == t))) 6419 return false; 6420 } 6421 break; 6422 6423 default: 6424 return false; 6425 } 6426 6427 addr_t offset_addr; 6428 addr_t address; 6429 6430 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6431 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6432 if (!success) 6433 return false; 6434 6435 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6436 if (!success) 6437 return false; 6438 6439 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6440 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6441 if (!success) 6442 return false; 6443 6444 if (add) 6445 offset_addr = Rn + offset; 6446 else 6447 offset_addr = Rn - offset; 6448 6449 // address = if index then offset_addr else R[n]; 6450 if (index) 6451 address = offset_addr; 6452 else 6453 address = Rn; 6454 6455 // R[t] = ZeroExtend(MemU[address,1],32); 6456 RegisterInfo base_reg; 6457 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6458 6459 EmulateInstruction::Context context; 6460 context.type = eContextRegisterLoad; 6461 context.SetRegisterPlusOffset (base_reg, address - Rn); 6462 6463 uint64_t data = MemURead (context, address, 1, 0, &success); 6464 if (!success) 6465 return false; 6466 6467 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6468 return false; 6469 6470 // if wback then R[n] = offset_addr; 6471 if (wback) 6472 { 6473 context.type = eContextAdjustBaseRegister; 6474 context.SetAddress (offset_addr); 6475 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6476 return false; 6477 } 6478 } 6479 return true; 6480 } 6481 6482 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6483 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6484 // post-indexed, or pre-indexed addressing. 6485 bool 6486 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6487 { 6488 #if 0 6489 if ConditionPassed() then 6490 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6491 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6492 address = if index then offset_addr else R[n]; 6493 data = MemU[address,2]; 6494 if wback then R[n] = offset_addr; 6495 if UnalignedSupport() || address<0> = '0' then 6496 R[t] = ZeroExtend(data, 32); 6497 else // Can only apply before ARMv7 6498 R[t] = bits(32) UNKNOWN; 6499 #endif 6500 6501 6502 bool success = false; 6503 6504 if (ConditionPassed(opcode)) 6505 { 6506 uint32_t t; 6507 uint32_t n; 6508 uint32_t imm32; 6509 bool index; 6510 bool add; 6511 bool wback; 6512 6513 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6514 switch (encoding) 6515 { 6516 case eEncodingT1: 6517 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6518 t = Bits32 (opcode, 2, 0); 6519 n = Bits32 (opcode, 5, 3); 6520 imm32 = Bits32 (opcode, 10, 6) << 1; 6521 6522 // index = TRUE; add = TRUE; wback = FALSE; 6523 index = true; 6524 add = true; 6525 wback = false; 6526 6527 break; 6528 6529 case eEncodingT2: 6530 // if Rt == '1111' then SEE "Unallocated memory hints"; 6531 // if Rn == '1111' then SEE LDRH (literal); 6532 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6533 t = Bits32 (opcode, 15, 12); 6534 n = Bits32 (opcode, 19, 16); 6535 imm32 = Bits32 (opcode, 11, 0); 6536 6537 // index = TRUE; add = TRUE; wback = FALSE; 6538 index = true; 6539 add = true; 6540 wback = false; 6541 6542 // if t == 13 then UNPREDICTABLE; 6543 if (t == 13) 6544 return false; 6545 break; 6546 6547 case eEncodingT3: 6548 // if Rn == '1111' then SEE LDRH (literal); 6549 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6550 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6551 // if P == '0' && W == '0' then UNDEFINED; 6552 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6553 return false; 6554 6555 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6556 t = Bits32 (opcode, 15, 12); 6557 n = Bits32 (opcode, 19, 16); 6558 imm32 = Bits32 (opcode, 7, 0); 6559 6560 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6561 index = BitIsSet (opcode, 10); 6562 add = BitIsSet (opcode, 9); 6563 wback = BitIsSet (opcode, 8); 6564 6565 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6566 if (BadReg (t) || (wback && (n == t))) 6567 return false; 6568 break; 6569 6570 default: 6571 return false; 6572 } 6573 6574 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6575 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6576 if (!success) 6577 return false; 6578 6579 addr_t offset_addr; 6580 addr_t address; 6581 6582 if (add) 6583 offset_addr = Rn + imm32; 6584 else 6585 offset_addr = Rn - imm32; 6586 6587 // address = if index then offset_addr else R[n]; 6588 if (index) 6589 address = offset_addr; 6590 else 6591 address = Rn; 6592 6593 // data = MemU[address,2]; 6594 RegisterInfo base_reg; 6595 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6596 6597 EmulateInstruction::Context context; 6598 context.type = eContextRegisterLoad; 6599 context.SetRegisterPlusOffset (base_reg, address - Rn); 6600 6601 uint64_t data = MemURead (context, address, 2, 0, &success); 6602 if (!success) 6603 return false; 6604 6605 // if wback then R[n] = offset_addr; 6606 if (wback) 6607 { 6608 context.type = eContextAdjustBaseRegister; 6609 context.SetAddress (offset_addr); 6610 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6611 return false; 6612 } 6613 6614 // if UnalignedSupport() || address<0> = '0' then 6615 if (UnalignedSupport () || BitIsClear (address, 0)) 6616 { 6617 // R[t] = ZeroExtend(data, 32); 6618 context.type = eContextRegisterLoad; 6619 context.SetRegisterPlusOffset (base_reg, address - Rn); 6620 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6621 return false; 6622 } 6623 else // Can only apply before ARMv7 6624 { 6625 // R[t] = bits(32) UNKNOWN; 6626 WriteBits32Unknown (t); 6627 } 6628 } 6629 return true; 6630 } 6631 6632 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6633 // zero-extends it to form a 32-bit word, and writes it to a register. 6634 bool 6635 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6636 { 6637 #if 0 6638 if ConditionPassed() then 6639 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6640 base = Align(PC,4); 6641 address = if add then (base + imm32) else (base - imm32); 6642 data = MemU[address,2]; 6643 if UnalignedSupport() || address<0> = '0' then 6644 R[t] = ZeroExtend(data, 32); 6645 else // Can only apply before ARMv7 6646 R[t] = bits(32) UNKNOWN; 6647 #endif 6648 6649 bool success = false; 6650 6651 if (ConditionPassed(opcode)) 6652 { 6653 uint32_t t; 6654 uint32_t imm32; 6655 bool add; 6656 6657 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6658 switch (encoding) 6659 { 6660 case eEncodingT1: 6661 // if Rt == '1111' then SEE "Unallocated memory hints"; 6662 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6663 t = Bits32 (opcode, 15, 12); 6664 imm32 = Bits32 (opcode, 11, 0); 6665 add = BitIsSet (opcode, 23); 6666 6667 // if t == 13 then UNPREDICTABLE; 6668 if (t == 13) 6669 return false; 6670 6671 break; 6672 6673 case eEncodingA1: 6674 { 6675 uint32_t imm4H = Bits32 (opcode, 11, 8); 6676 uint32_t imm4L = Bits32 (opcode, 3, 0); 6677 6678 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6679 t = Bits32 (opcode, 15, 12); 6680 imm32 = (imm4H << 4) | imm4L; 6681 add = BitIsSet (opcode, 23); 6682 6683 // if t == 15 then UNPREDICTABLE; 6684 if (t == 15) 6685 return false; 6686 break; 6687 } 6688 6689 default: 6690 return false; 6691 } 6692 6693 // base = Align(PC,4); 6694 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6695 if (!success) 6696 return false; 6697 6698 addr_t base = AlignPC (pc_value); 6699 addr_t address; 6700 6701 // address = if add then (base + imm32) else (base - imm32); 6702 if (add) 6703 address = base + imm32; 6704 else 6705 address = base - imm32; 6706 6707 // data = MemU[address,2]; 6708 RegisterInfo base_reg; 6709 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6710 6711 EmulateInstruction::Context context; 6712 context.type = eContextRegisterLoad; 6713 context.SetRegisterPlusOffset (base_reg, address - base); 6714 6715 uint64_t data = MemURead (context, address, 2, 0, &success); 6716 if (!success) 6717 return false; 6718 6719 6720 // if UnalignedSupport() || address<0> = '0' then 6721 if (UnalignedSupport () || BitIsClear (address, 0)) 6722 { 6723 // R[t] = ZeroExtend(data, 32); 6724 context.type = eContextRegisterLoad; 6725 context.SetRegisterPlusOffset (base_reg, address - base); 6726 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6727 return false; 6728 6729 } 6730 else // Can only apply before ARMv7 6731 { 6732 // R[t] = bits(32) UNKNOWN; 6733 WriteBits32Unknown (t); 6734 } 6735 } 6736 return true; 6737 } 6738 6739 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6740 // from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6741 // be shifted left by 0, 1, 2, or 3 bits. 6742 bool 6743 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6744 { 6745 #if 0 6746 if ConditionPassed() then 6747 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6748 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6749 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6750 address = if index then offset_addr else R[n]; 6751 data = MemU[address,2]; 6752 if wback then R[n] = offset_addr; 6753 if UnalignedSupport() || address<0> = '0' then 6754 R[t] = ZeroExtend(data, 32); 6755 else // Can only apply before ARMv7 6756 R[t] = bits(32) UNKNOWN; 6757 #endif 6758 6759 bool success = false; 6760 6761 if (ConditionPassed(opcode)) 6762 { 6763 uint32_t t; 6764 uint32_t n; 6765 uint32_t m; 6766 bool index; 6767 bool add; 6768 bool wback; 6769 ARM_ShifterType shift_t; 6770 uint32_t shift_n; 6771 6772 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6773 switch (encoding) 6774 { 6775 case eEncodingT1: 6776 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6777 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6778 t = Bits32 (opcode, 2, 0); 6779 n = Bits32 (opcode, 5, 3); 6780 m = Bits32 (opcode, 8, 6); 6781 6782 // index = TRUE; add = TRUE; wback = FALSE; 6783 index = true; 6784 add = true; 6785 wback = false; 6786 6787 // (shift_t, shift_n) = (SRType_LSL, 0); 6788 shift_t = SRType_LSL; 6789 shift_n = 0; 6790 6791 break; 6792 6793 case eEncodingT2: 6794 // if Rn == '1111' then SEE LDRH (literal); 6795 // if Rt == '1111' then SEE "Unallocated memory hints"; 6796 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6797 t = Bits32 (opcode, 15, 12); 6798 n = Bits32 (opcode, 19, 16); 6799 m = Bits32 (opcode, 3, 0); 6800 6801 // index = TRUE; add = TRUE; wback = FALSE; 6802 index = true; 6803 add = true; 6804 wback = false; 6805 6806 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6807 shift_t = SRType_LSL; 6808 shift_n = Bits32 (opcode, 5, 4); 6809 6810 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6811 if ((t == 13) || BadReg (m)) 6812 return false; 6813 break; 6814 6815 case eEncodingA1: 6816 // if P == '0' && W == '1' then SEE LDRHT; 6817 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6818 t = Bits32 (opcode, 15, 12); 6819 n = Bits32 (opcode, 19, 16); 6820 m = Bits32 (opcode, 3, 0); 6821 6822 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6823 index = BitIsSet (opcode, 24); 6824 add = BitIsSet (opcode, 23); 6825 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6826 6827 // (shift_t, shift_n) = (SRType_LSL, 0); 6828 shift_t = SRType_LSL; 6829 shift_n = 0; 6830 6831 // if t == 15 || m == 15 then UNPREDICTABLE; 6832 if ((t == 15) || (m == 15)) 6833 return false; 6834 6835 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6836 if (wback && ((n == 15) || (n == t))) 6837 return false; 6838 6839 break; 6840 6841 default: 6842 return false; 6843 } 6844 6845 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6846 6847 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6848 if (!success) 6849 return false; 6850 6851 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6852 if (!success) 6853 return false; 6854 6855 addr_t offset_addr; 6856 addr_t address; 6857 6858 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6859 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6860 if (!success) 6861 return false; 6862 6863 if (add) 6864 offset_addr = Rn + offset; 6865 else 6866 offset_addr = Rn - offset; 6867 6868 // address = if index then offset_addr else R[n]; 6869 if (index) 6870 address = offset_addr; 6871 else 6872 address = Rn; 6873 6874 // data = MemU[address,2]; 6875 RegisterInfo base_reg; 6876 RegisterInfo offset_reg; 6877 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6878 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 6879 6880 EmulateInstruction::Context context; 6881 context.type = eContextRegisterLoad; 6882 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6883 uint64_t data = MemURead (context, address, 2, 0, &success); 6884 if (!success) 6885 return false; 6886 6887 // if wback then R[n] = offset_addr; 6888 if (wback) 6889 { 6890 context.type = eContextAdjustBaseRegister; 6891 context.SetAddress (offset_addr); 6892 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6893 return false; 6894 } 6895 6896 // if UnalignedSupport() || address<0> = '0' then 6897 if (UnalignedSupport() || BitIsClear (address, 0)) 6898 { 6899 // R[t] = ZeroExtend(data, 32); 6900 context.type = eContextRegisterLoad; 6901 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6902 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6903 return false; 6904 } 6905 else // Can only apply before ARMv7 6906 { 6907 // R[t] = bits(32) UNKNOWN; 6908 WriteBits32Unknown (t); 6909 } 6910 } 6911 return true; 6912 } 6913 6914 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6915 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6916 // or pre-indexed addressing. 6917 bool 6918 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6919 { 6920 #if 0 6921 if ConditionPassed() then 6922 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6923 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6924 address = if index then offset_addr else R[n]; 6925 R[t] = SignExtend(MemU[address,1], 32); 6926 if wback then R[n] = offset_addr; 6927 #endif 6928 6929 bool success = false; 6930 6931 if (ConditionPassed(opcode)) 6932 { 6933 uint32_t t; 6934 uint32_t n; 6935 uint32_t imm32; 6936 bool index; 6937 bool add; 6938 bool wback; 6939 6940 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6941 switch (encoding) 6942 { 6943 case eEncodingT1: 6944 // if Rt == '1111' then SEE PLI; 6945 // if Rn == '1111' then SEE LDRSB (literal); 6946 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6947 t = Bits32 (opcode, 15, 12); 6948 n = Bits32 (opcode, 19, 16); 6949 imm32 = Bits32 (opcode, 11, 0); 6950 6951 // index = TRUE; add = TRUE; wback = FALSE; 6952 index = true; 6953 add = true; 6954 wback = false; 6955 6956 // if t == 13 then UNPREDICTABLE; 6957 if (t == 13) 6958 return false; 6959 6960 break; 6961 6962 case eEncodingT2: 6963 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 6964 // if Rn == '1111' then SEE LDRSB (literal); 6965 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 6966 // if P == '0' && W == '0' then UNDEFINED; 6967 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6968 return false; 6969 6970 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6971 t = Bits32 (opcode, 15, 12); 6972 n = Bits32 (opcode, 19, 16); 6973 imm32 = Bits32 (opcode, 7, 0); 6974 6975 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6976 index = BitIsSet (opcode, 10); 6977 add = BitIsSet (opcode, 9); 6978 wback = BitIsSet (opcode, 8); 6979 6980 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6981 if (((t == 13) || ((t == 15) 6982 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 6983 || (wback && (n == t))) 6984 return false; 6985 6986 break; 6987 6988 case eEncodingA1: 6989 { 6990 // if Rn == '1111' then SEE LDRSB (literal); 6991 // if P == '0' && W == '1' then SEE LDRSBT; 6992 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 6993 t = Bits32 (opcode, 15, 12); 6994 n = Bits32 (opcode, 19, 16); 6995 6996 uint32_t imm4H = Bits32 (opcode, 11, 8); 6997 uint32_t imm4L = Bits32 (opcode, 3, 0); 6998 imm32 = (imm4H << 4) | imm4L; 6999 7000 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7001 index = BitIsSet (opcode, 24); 7002 add = BitIsSet (opcode, 23); 7003 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7004 7005 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7006 if ((t == 15) || (wback && (n == t))) 7007 return false; 7008 7009 break; 7010 } 7011 7012 default: 7013 return false; 7014 } 7015 7016 uint64_t Rn = ReadCoreReg (n, &success); 7017 if (!success) 7018 return false; 7019 7020 addr_t offset_addr; 7021 addr_t address; 7022 7023 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7024 if (add) 7025 offset_addr = Rn + imm32; 7026 else 7027 offset_addr = Rn - imm32; 7028 7029 // address = if index then offset_addr else R[n]; 7030 if (index) 7031 address = offset_addr; 7032 else 7033 address = Rn; 7034 7035 // R[t] = SignExtend(MemU[address,1], 32); 7036 RegisterInfo base_reg; 7037 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7038 7039 EmulateInstruction::Context context; 7040 context.type = eContextRegisterLoad; 7041 context.SetRegisterPlusOffset (base_reg, address - Rn); 7042 7043 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7044 if (!success) 7045 return false; 7046 7047 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7048 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7049 return false; 7050 7051 // if wback then R[n] = offset_addr; 7052 if (wback) 7053 { 7054 context.type = eContextAdjustBaseRegister; 7055 context.SetAddress (offset_addr); 7056 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7057 return false; 7058 } 7059 } 7060 7061 return true; 7062 } 7063 7064 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7065 // sign-extends it to form a 32-bit word, and writes tit to a register. 7066 bool 7067 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7068 { 7069 #if 0 7070 if ConditionPassed() then 7071 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7072 base = Align(PC,4); 7073 address = if add then (base + imm32) else (base - imm32); 7074 R[t] = SignExtend(MemU[address,1], 32); 7075 #endif 7076 7077 bool success = false; 7078 7079 if (ConditionPassed(opcode)) 7080 { 7081 uint32_t t; 7082 uint32_t imm32; 7083 bool add; 7084 7085 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7086 switch (encoding) 7087 { 7088 case eEncodingT1: 7089 // if Rt == '1111' then SEE PLI; 7090 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7091 t = Bits32 (opcode, 15, 12); 7092 imm32 = Bits32 (opcode, 11, 0); 7093 add = BitIsSet (opcode, 23); 7094 7095 // if t == 13 then UNPREDICTABLE; 7096 if (t == 13) 7097 return false; 7098 7099 break; 7100 7101 case eEncodingA1: 7102 { 7103 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7104 t = Bits32 (opcode, 15, 12); 7105 uint32_t imm4H = Bits32 (opcode, 11, 8); 7106 uint32_t imm4L = Bits32 (opcode, 3, 0); 7107 imm32 = (imm4H << 4) | imm4L; 7108 add = BitIsSet (opcode, 23); 7109 7110 // if t == 15 then UNPREDICTABLE; 7111 if (t == 15) 7112 return false; 7113 7114 break; 7115 } 7116 7117 default: 7118 return false; 7119 } 7120 7121 // base = Align(PC,4); 7122 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7123 if (!success) 7124 return false; 7125 uint64_t base = AlignPC (pc_value); 7126 7127 // address = if add then (base + imm32) else (base - imm32); 7128 addr_t address; 7129 if (add) 7130 address = base + imm32; 7131 else 7132 address = base - imm32; 7133 7134 // R[t] = SignExtend(MemU[address,1], 32); 7135 RegisterInfo base_reg; 7136 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7137 7138 EmulateInstruction::Context context; 7139 context.type = eContextRegisterLoad; 7140 context.SetRegisterPlusOffset (base_reg, address - base); 7141 7142 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7143 if (!success) 7144 return false; 7145 7146 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7147 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7148 return false; 7149 } 7150 return true; 7151 } 7152 7153 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7154 // memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7155 // shifted left by 0, 1, 2, or 3 bits. 7156 bool 7157 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7158 { 7159 #if 0 7160 if ConditionPassed() then 7161 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7162 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7163 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7164 address = if index then offset_addr else R[n]; 7165 R[t] = SignExtend(MemU[address,1], 32); 7166 if wback then R[n] = offset_addr; 7167 #endif 7168 7169 bool success = false; 7170 7171 if (ConditionPassed(opcode)) 7172 { 7173 uint32_t t; 7174 uint32_t n; 7175 uint32_t m; 7176 bool index; 7177 bool add; 7178 bool wback; 7179 ARM_ShifterType shift_t; 7180 uint32_t shift_n; 7181 7182 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7183 switch (encoding) 7184 { 7185 case eEncodingT1: 7186 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7187 t = Bits32 (opcode, 2, 0); 7188 n = Bits32 (opcode, 5, 3); 7189 m = Bits32 (opcode, 8, 6); 7190 7191 // index = TRUE; add = TRUE; wback = FALSE; 7192 index = true; 7193 add = true; 7194 wback = false; 7195 7196 // (shift_t, shift_n) = (SRType_LSL, 0); 7197 shift_t = SRType_LSL; 7198 shift_n = 0; 7199 7200 break; 7201 7202 case eEncodingT2: 7203 // if Rt == '1111' then SEE PLI; 7204 // if Rn == '1111' then SEE LDRSB (literal); 7205 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7206 t = Bits32 (opcode, 15, 12); 7207 n = Bits32 (opcode, 19, 16); 7208 m = Bits32 (opcode, 3, 0); 7209 7210 // index = TRUE; add = TRUE; wback = FALSE; 7211 index = true; 7212 add = true; 7213 wback = false; 7214 7215 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7216 shift_t = SRType_LSL; 7217 shift_n = Bits32 (opcode, 5, 4); 7218 7219 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7220 if ((t == 13) || BadReg (m)) 7221 return false; 7222 break; 7223 7224 case eEncodingA1: 7225 // if P == '0' && W == '1' then SEE LDRSBT; 7226 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7227 t = Bits32 (opcode, 15, 12); 7228 n = Bits32 (opcode, 19, 16); 7229 m = Bits32 (opcode, 3, 0); 7230 7231 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7232 index = BitIsSet (opcode, 24); 7233 add = BitIsSet (opcode, 23); 7234 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7235 7236 // (shift_t, shift_n) = (SRType_LSL, 0); 7237 shift_t = SRType_LSL; 7238 shift_n = 0; 7239 7240 // if t == 15 || m == 15 then UNPREDICTABLE; 7241 if ((t == 15) || (m == 15)) 7242 return false; 7243 7244 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7245 if (wback && ((n == 15) || (n == t))) 7246 return false; 7247 break; 7248 7249 default: 7250 return false; 7251 } 7252 7253 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7254 if (!success) 7255 return false; 7256 7257 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7258 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7259 if (!success) 7260 return false; 7261 7262 addr_t offset_addr; 7263 addr_t address; 7264 7265 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7266 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7267 if (!success) 7268 return false; 7269 7270 if (add) 7271 offset_addr = Rn + offset; 7272 else 7273 offset_addr = Rn - offset; 7274 7275 // address = if index then offset_addr else R[n]; 7276 if (index) 7277 address = offset_addr; 7278 else 7279 address = Rn; 7280 7281 // R[t] = SignExtend(MemU[address,1], 32); 7282 RegisterInfo base_reg; 7283 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7284 RegisterInfo offset_reg; 7285 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7286 7287 EmulateInstruction::Context context; 7288 context.type = eContextRegisterLoad; 7289 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7290 7291 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7292 if (!success) 7293 return false; 7294 7295 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7296 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7297 return false; 7298 7299 // if wback then R[n] = offset_addr; 7300 if (wback) 7301 { 7302 context.type = eContextAdjustBaseRegister; 7303 context.SetAddress (offset_addr); 7304 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7305 return false; 7306 } 7307 } 7308 return true; 7309 } 7310 7311 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7312 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7313 // pre-indexed addressing. 7314 bool 7315 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7316 { 7317 #if 0 7318 if ConditionPassed() then 7319 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7320 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7321 address = if index then offset_addr else R[n]; 7322 data = MemU[address,2]; 7323 if wback then R[n] = offset_addr; 7324 if UnalignedSupport() || address<0> = '0' then 7325 R[t] = SignExtend(data, 32); 7326 else // Can only apply before ARMv7 7327 R[t] = bits(32) UNKNOWN; 7328 #endif 7329 7330 bool success = false; 7331 7332 if (ConditionPassed(opcode)) 7333 { 7334 uint32_t t; 7335 uint32_t n; 7336 uint32_t imm32; 7337 bool index; 7338 bool add; 7339 bool wback; 7340 7341 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7342 switch (encoding) 7343 { 7344 case eEncodingT1: 7345 // if Rn == '1111' then SEE LDRSH (literal); 7346 // if Rt == '1111' then SEE "Unallocated memory hints"; 7347 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7348 t = Bits32 (opcode, 15, 12); 7349 n = Bits32 (opcode, 19, 16); 7350 imm32 = Bits32 (opcode, 11, 0); 7351 7352 // index = TRUE; add = TRUE; wback = FALSE; 7353 index = true; 7354 add = true; 7355 wback = false; 7356 7357 // if t == 13 then UNPREDICTABLE; 7358 if (t == 13) 7359 return false; 7360 7361 break; 7362 7363 case eEncodingT2: 7364 // if Rn == '1111' then SEE LDRSH (literal); 7365 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7366 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7367 // if P == '0' && W == '0' then UNDEFINED; 7368 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7369 return false; 7370 7371 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7372 t = Bits32 (opcode, 15, 12); 7373 n = Bits32 (opcode, 19, 16); 7374 imm32 = Bits32 (opcode, 7, 0); 7375 7376 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7377 index = BitIsSet (opcode, 10); 7378 add = BitIsSet (opcode, 9); 7379 wback = BitIsSet (opcode, 8); 7380 7381 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7382 if (BadReg (t) || (wback && (n == t))) 7383 return false; 7384 7385 break; 7386 7387 case eEncodingA1: 7388 { 7389 // if Rn == '1111' then SEE LDRSH (literal); 7390 // if P == '0' && W == '1' then SEE LDRSHT; 7391 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7392 t = Bits32 (opcode, 15, 12); 7393 n = Bits32 (opcode, 19, 16); 7394 uint32_t imm4H = Bits32 (opcode, 11,8); 7395 uint32_t imm4L = Bits32 (opcode, 3, 0); 7396 imm32 = (imm4H << 4) | imm4L; 7397 7398 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7399 index = BitIsSet (opcode, 24); 7400 add = BitIsSet (opcode, 23); 7401 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7402 7403 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7404 if ((t == 15) || (wback && (n == t))) 7405 return false; 7406 7407 break; 7408 } 7409 7410 default: 7411 return false; 7412 } 7413 7414 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7415 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7416 if (!success) 7417 return false; 7418 7419 addr_t offset_addr; 7420 if (add) 7421 offset_addr = Rn + imm32; 7422 else 7423 offset_addr = Rn - imm32; 7424 7425 // address = if index then offset_addr else R[n]; 7426 addr_t address; 7427 if (index) 7428 address = offset_addr; 7429 else 7430 address = Rn; 7431 7432 // data = MemU[address,2]; 7433 RegisterInfo base_reg; 7434 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7435 7436 EmulateInstruction::Context context; 7437 context.type = eContextRegisterLoad; 7438 context.SetRegisterPlusOffset (base_reg, address - Rn); 7439 7440 uint64_t data = MemURead (context, address, 2, 0, &success); 7441 if (!success) 7442 return false; 7443 7444 // if wback then R[n] = offset_addr; 7445 if (wback) 7446 { 7447 context.type = eContextAdjustBaseRegister; 7448 context.SetAddress (offset_addr); 7449 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7450 return false; 7451 } 7452 7453 // if UnalignedSupport() || address<0> = '0' then 7454 if (UnalignedSupport() || BitIsClear (address, 0)) 7455 { 7456 // R[t] = SignExtend(data, 32); 7457 int64_t signed_data = llvm::SignExtend64<16>(data); 7458 context.type = eContextRegisterLoad; 7459 context.SetRegisterPlusOffset (base_reg, address - Rn); 7460 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7461 return false; 7462 } 7463 else // Can only apply before ARMv7 7464 { 7465 // R[t] = bits(32) UNKNOWN; 7466 WriteBits32Unknown (t); 7467 } 7468 } 7469 return true; 7470 } 7471 7472 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7473 // sign-extends it to from a 32-bit word, and writes it to a register. 7474 bool 7475 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7476 { 7477 #if 0 7478 if ConditionPassed() then 7479 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7480 base = Align(PC,4); 7481 address = if add then (base + imm32) else (base - imm32); 7482 data = MemU[address,2]; 7483 if UnalignedSupport() || address<0> = '0' then 7484 R[t] = SignExtend(data, 32); 7485 else // Can only apply before ARMv7 7486 R[t] = bits(32) UNKNOWN; 7487 #endif 7488 7489 bool success = false; 7490 7491 if (ConditionPassed(opcode)) 7492 { 7493 uint32_t t; 7494 uint32_t imm32; 7495 bool add; 7496 7497 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7498 switch (encoding) 7499 { 7500 case eEncodingT1: 7501 // if Rt == '1111' then SEE "Unallocated memory hints"; 7502 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7503 t = Bits32 (opcode, 15, 12); 7504 imm32 = Bits32 (opcode, 11, 0); 7505 add = BitIsSet (opcode, 23); 7506 7507 // if t == 13 then UNPREDICTABLE; 7508 if (t == 13) 7509 return false; 7510 7511 break; 7512 7513 case eEncodingA1: 7514 { 7515 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7516 t = Bits32 (opcode, 15, 12); 7517 uint32_t imm4H = Bits32 (opcode, 11, 8); 7518 uint32_t imm4L = Bits32 (opcode, 3, 0); 7519 imm32 = (imm4H << 4) | imm4L; 7520 add = BitIsSet (opcode, 23); 7521 7522 // if t == 15 then UNPREDICTABLE; 7523 if (t == 15) 7524 return false; 7525 7526 break; 7527 } 7528 default: 7529 return false; 7530 } 7531 7532 // base = Align(PC,4); 7533 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7534 if (!success) 7535 return false; 7536 7537 uint64_t base = AlignPC (pc_value); 7538 7539 addr_t address; 7540 // address = if add then (base + imm32) else (base - imm32); 7541 if (add) 7542 address = base + imm32; 7543 else 7544 address = base - imm32; 7545 7546 // data = MemU[address,2]; 7547 RegisterInfo base_reg; 7548 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7549 7550 EmulateInstruction::Context context; 7551 context.type = eContextRegisterLoad; 7552 context.SetRegisterPlusOffset (base_reg, imm32); 7553 7554 uint64_t data = MemURead (context, address, 2, 0, &success); 7555 if (!success) 7556 return false; 7557 7558 // if UnalignedSupport() || address<0> = '0' then 7559 if (UnalignedSupport() || BitIsClear (address, 0)) 7560 { 7561 // R[t] = SignExtend(data, 32); 7562 int64_t signed_data = llvm::SignExtend64<16>(data); 7563 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7564 return false; 7565 } 7566 else // Can only apply before ARMv7 7567 { 7568 // R[t] = bits(32) UNKNOWN; 7569 WriteBits32Unknown (t); 7570 } 7571 } 7572 return true; 7573 } 7574 7575 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7576 // from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7577 // shifted left by 0, 1, 2, or 3 bits. 7578 bool 7579 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7580 { 7581 #if 0 7582 if ConditionPassed() then 7583 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7584 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7585 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7586 address = if index then offset_addr else R[n]; 7587 data = MemU[address,2]; 7588 if wback then R[n] = offset_addr; 7589 if UnalignedSupport() || address<0> = '0' then 7590 R[t] = SignExtend(data, 32); 7591 else // Can only apply before ARMv7 7592 R[t] = bits(32) UNKNOWN; 7593 #endif 7594 7595 bool success = false; 7596 7597 if (ConditionPassed(opcode)) 7598 { 7599 uint32_t t; 7600 uint32_t n; 7601 uint32_t m; 7602 bool index; 7603 bool add; 7604 bool wback; 7605 ARM_ShifterType shift_t; 7606 uint32_t shift_n; 7607 7608 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7609 switch (encoding) 7610 { 7611 case eEncodingT1: 7612 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7613 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7614 t = Bits32 (opcode, 2, 0); 7615 n = Bits32 (opcode, 5, 3); 7616 m = Bits32 (opcode, 8, 6); 7617 7618 // index = TRUE; add = TRUE; wback = FALSE; 7619 index = true; 7620 add = true; 7621 wback = false; 7622 7623 // (shift_t, shift_n) = (SRType_LSL, 0); 7624 shift_t = SRType_LSL; 7625 shift_n = 0; 7626 7627 break; 7628 7629 case eEncodingT2: 7630 // if Rn == '1111' then SEE LDRSH (literal); 7631 // if Rt == '1111' then SEE "Unallocated memory hints"; 7632 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7633 t = Bits32 (opcode, 15, 12); 7634 n = Bits32 (opcode, 19, 16); 7635 m = Bits32 (opcode, 3, 0); 7636 7637 // index = TRUE; add = TRUE; wback = FALSE; 7638 index = true; 7639 add = true; 7640 wback = false; 7641 7642 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7643 shift_t = SRType_LSL; 7644 shift_n = Bits32 (opcode, 5, 4); 7645 7646 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7647 if ((t == 13) || BadReg (m)) 7648 return false; 7649 7650 break; 7651 7652 case eEncodingA1: 7653 // if P == '0' && W == '1' then SEE LDRSHT; 7654 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7655 t = Bits32 (opcode, 15, 12); 7656 n = Bits32 (opcode, 19, 16); 7657 m = Bits32 (opcode, 3, 0); 7658 7659 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7660 index = BitIsSet (opcode, 24); 7661 add = BitIsSet (opcode, 23); 7662 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7663 7664 // (shift_t, shift_n) = (SRType_LSL, 0); 7665 shift_t = SRType_LSL; 7666 shift_n = 0; 7667 7668 // if t == 15 || m == 15 then UNPREDICTABLE; 7669 if ((t == 15) || (m == 15)) 7670 return false; 7671 7672 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7673 if (wback && ((n == 15) || (n == t))) 7674 return false; 7675 7676 break; 7677 7678 default: 7679 return false; 7680 } 7681 7682 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7683 if (!success) 7684 return false; 7685 7686 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7687 if (!success) 7688 return false; 7689 7690 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7691 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7692 if (!success) 7693 return false; 7694 7695 addr_t offset_addr; 7696 addr_t address; 7697 7698 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7699 if (add) 7700 offset_addr = Rn + offset; 7701 else 7702 offset_addr = Rn - offset; 7703 7704 // address = if index then offset_addr else R[n]; 7705 if (index) 7706 address = offset_addr; 7707 else 7708 address = Rn; 7709 7710 // data = MemU[address,2]; 7711 RegisterInfo base_reg; 7712 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7713 7714 RegisterInfo offset_reg; 7715 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7716 7717 EmulateInstruction::Context context; 7718 context.type = eContextRegisterLoad; 7719 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7720 7721 uint64_t data = MemURead (context, address, 2, 0, &success); 7722 if (!success) 7723 return false; 7724 7725 // if wback then R[n] = offset_addr; 7726 if (wback) 7727 { 7728 context.type = eContextAdjustBaseRegister; 7729 context.SetAddress (offset_addr); 7730 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7731 return false; 7732 } 7733 7734 // if UnalignedSupport() || address<0> = '0' then 7735 if (UnalignedSupport() || BitIsClear (address, 0)) 7736 { 7737 // R[t] = SignExtend(data, 32); 7738 context.type = eContextRegisterLoad; 7739 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7740 7741 int64_t signed_data = llvm::SignExtend64<16>(data); 7742 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7743 return false; 7744 } 7745 else // Can only apply before ARMv7 7746 { 7747 // R[t] = bits(32) UNKNOWN; 7748 WriteBits32Unknown (t); 7749 } 7750 } 7751 return true; 7752 } 7753 7754 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7755 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7756 bool 7757 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7758 { 7759 #if 0 7760 if ConditionPassed() then 7761 EncodingSpecificOperations(); 7762 rotated = ROR(R[m], rotation); 7763 R[d] = SignExtend(rotated<7:0>, 32); 7764 #endif 7765 7766 bool success = false; 7767 7768 if (ConditionPassed(opcode)) 7769 { 7770 uint32_t d; 7771 uint32_t m; 7772 uint32_t rotation; 7773 7774 // EncodingSpecificOperations(); 7775 switch (encoding) 7776 { 7777 case eEncodingT1: 7778 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7779 d = Bits32 (opcode, 2, 0); 7780 m = Bits32 (opcode, 5, 3); 7781 rotation = 0; 7782 7783 break; 7784 7785 case eEncodingT2: 7786 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7787 d = Bits32 (opcode, 11, 8); 7788 m = Bits32 (opcode, 3, 0); 7789 rotation = Bits32 (opcode, 5, 4) << 3; 7790 7791 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7792 if (BadReg (d) || BadReg (m)) 7793 return false; 7794 7795 break; 7796 7797 case eEncodingA1: 7798 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7799 d = Bits32 (opcode, 15, 12); 7800 m = Bits32 (opcode, 3, 0); 7801 rotation = Bits32 (opcode, 11, 10) << 3; 7802 7803 // if d == 15 || m == 15 then UNPREDICTABLE; 7804 if ((d == 15) || (m == 15)) 7805 return false; 7806 7807 break; 7808 7809 default: 7810 return false; 7811 } 7812 7813 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7814 if (!success) 7815 return false; 7816 7817 // rotated = ROR(R[m], rotation); 7818 uint64_t rotated = ROR (Rm, rotation, &success); 7819 if (!success) 7820 return false; 7821 7822 // R[d] = SignExtend(rotated<7:0>, 32); 7823 int64_t data = llvm::SignExtend64<8>(rotated); 7824 7825 RegisterInfo source_reg; 7826 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7827 7828 EmulateInstruction::Context context; 7829 context.type = eContextRegisterLoad; 7830 context.SetRegister (source_reg); 7831 7832 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7833 return false; 7834 } 7835 return true; 7836 } 7837 7838 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7839 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7840 bool 7841 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7842 { 7843 #if 0 7844 if ConditionPassed() then 7845 EncodingSpecificOperations(); 7846 rotated = ROR(R[m], rotation); 7847 R[d] = SignExtend(rotated<15:0>, 32); 7848 #endif 7849 7850 bool success = false; 7851 7852 if (ConditionPassed(opcode)) 7853 { 7854 uint32_t d; 7855 uint32_t m; 7856 uint32_t rotation; 7857 7858 // EncodingSpecificOperations(); 7859 switch (encoding) 7860 { 7861 case eEncodingT1: 7862 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7863 d = Bits32 (opcode, 2, 0); 7864 m = Bits32 (opcode, 5, 3); 7865 rotation = 0; 7866 7867 break; 7868 7869 case eEncodingT2: 7870 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7871 d = Bits32 (opcode, 11, 8); 7872 m = Bits32 (opcode, 3, 0); 7873 rotation = Bits32 (opcode, 5, 4) << 3; 7874 7875 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7876 if (BadReg (d) || BadReg (m)) 7877 return false; 7878 7879 break; 7880 7881 case eEncodingA1: 7882 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7883 d = Bits32 (opcode, 15, 12); 7884 m = Bits32 (opcode, 3, 0); 7885 rotation = Bits32 (opcode, 11, 10) << 3; 7886 7887 // if d == 15 || m == 15 then UNPREDICTABLE; 7888 if ((d == 15) || (m == 15)) 7889 return false; 7890 7891 break; 7892 7893 default: 7894 return false; 7895 } 7896 7897 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7898 if (!success) 7899 return false; 7900 7901 // rotated = ROR(R[m], rotation); 7902 uint64_t rotated = ROR (Rm, rotation, &success); 7903 if (!success) 7904 return false; 7905 7906 // R[d] = SignExtend(rotated<15:0>, 32); 7907 RegisterInfo source_reg; 7908 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7909 7910 EmulateInstruction::Context context; 7911 context.type = eContextRegisterLoad; 7912 context.SetRegister (source_reg); 7913 7914 int64_t data = llvm::SignExtend64<16> (rotated); 7915 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7916 return false; 7917 } 7918 7919 return true; 7920 } 7921 7922 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 7923 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7924 bool 7925 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 7926 { 7927 #if 0 7928 if ConditionPassed() then 7929 EncodingSpecificOperations(); 7930 rotated = ROR(R[m], rotation); 7931 R[d] = ZeroExtend(rotated<7:0>, 32); 7932 #endif 7933 7934 bool success = false; 7935 7936 if (ConditionPassed(opcode)) 7937 { 7938 uint32_t d; 7939 uint32_t m; 7940 uint32_t rotation; 7941 7942 // EncodingSpecificOperations(); 7943 switch (encoding) 7944 { 7945 case eEncodingT1: 7946 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7947 d = Bits32 (opcode, 2, 0); 7948 m = Bits32 (opcode, 5, 3); 7949 rotation = 0; 7950 7951 break; 7952 7953 case eEncodingT2: 7954 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7955 d = Bits32 (opcode, 11, 8); 7956 m = Bits32 (opcode, 3, 0); 7957 rotation = Bits32 (opcode, 5, 4) << 3; 7958 7959 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7960 if (BadReg (d) || BadReg (m)) 7961 return false; 7962 7963 break; 7964 7965 case eEncodingA1: 7966 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7967 d = Bits32 (opcode, 15, 12); 7968 m = Bits32 (opcode, 3, 0); 7969 rotation = Bits32 (opcode, 11, 10) << 3; 7970 7971 // if d == 15 || m == 15 then UNPREDICTABLE; 7972 if ((d == 15) || (m == 15)) 7973 return false; 7974 7975 break; 7976 7977 default: 7978 return false; 7979 } 7980 7981 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7982 if (!success) 7983 return false; 7984 7985 // rotated = ROR(R[m], rotation); 7986 uint64_t rotated = ROR (Rm, rotation, &success); 7987 if (!success) 7988 return false; 7989 7990 // R[d] = ZeroExtend(rotated<7:0>, 32); 7991 RegisterInfo source_reg; 7992 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7993 7994 EmulateInstruction::Context context; 7995 context.type = eContextRegisterLoad; 7996 context.SetRegister (source_reg); 7997 7998 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 7999 return false; 8000 } 8001 return true; 8002 } 8003 8004 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 8005 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 8006 bool 8007 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 8008 { 8009 #if 0 8010 if ConditionPassed() then 8011 EncodingSpecificOperations(); 8012 rotated = ROR(R[m], rotation); 8013 R[d] = ZeroExtend(rotated<15:0>, 32); 8014 #endif 8015 8016 bool success = false; 8017 8018 if (ConditionPassed(opcode)) 8019 { 8020 uint32_t d; 8021 uint32_t m; 8022 uint32_t rotation; 8023 8024 switch (encoding) 8025 { 8026 case eEncodingT1: 8027 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8028 d = Bits32 (opcode, 2, 0); 8029 m = Bits32 (opcode, 5, 3); 8030 rotation = 0; 8031 8032 break; 8033 8034 case eEncodingT2: 8035 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8036 d = Bits32 (opcode, 11, 8); 8037 m = Bits32 (opcode, 3, 0); 8038 rotation = Bits32 (opcode, 5, 4) << 3; 8039 8040 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8041 if (BadReg (d) || BadReg (m)) 8042 return false; 8043 8044 break; 8045 8046 case eEncodingA1: 8047 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8048 d = Bits32 (opcode, 15, 12); 8049 m = Bits32 (opcode, 3, 0); 8050 rotation = Bits32 (opcode, 11, 10) << 3; 8051 8052 // if d == 15 || m == 15 then UNPREDICTABLE; 8053 if ((d == 15) || (m == 15)) 8054 return false; 8055 8056 break; 8057 8058 default: 8059 return false; 8060 } 8061 8062 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8063 if (!success) 8064 return false; 8065 8066 // rotated = ROR(R[m], rotation); 8067 uint64_t rotated = ROR (Rm, rotation, &success); 8068 if (!success) 8069 return false; 8070 8071 // R[d] = ZeroExtend(rotated<15:0>, 32); 8072 RegisterInfo source_reg; 8073 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8074 8075 EmulateInstruction::Context context; 8076 context.type = eContextRegisterLoad; 8077 context.SetRegister (source_reg); 8078 8079 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8080 return false; 8081 } 8082 return true; 8083 } 8084 8085 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8086 // word respectively. 8087 bool 8088 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8089 { 8090 #if 0 8091 if ConditionPassed() then 8092 EncodingSpecificOperations(); 8093 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8094 UNPREDICTABLE; 8095 else 8096 address = if increment then R[n] else R[n]-8; 8097 if wordhigher then address = address+4; 8098 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8099 BranchWritePC(MemA[address,4]); 8100 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8101 #endif 8102 8103 bool success = false; 8104 8105 if (ConditionPassed(opcode)) 8106 { 8107 uint32_t n; 8108 bool wback; 8109 bool increment; 8110 bool wordhigher; 8111 8112 // EncodingSpecificOperations(); 8113 switch (encoding) 8114 { 8115 case eEncodingT1: 8116 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8117 n = Bits32 (opcode, 19, 16); 8118 wback = BitIsSet (opcode, 21); 8119 increment = false; 8120 wordhigher = false; 8121 8122 // if n == 15 then UNPREDICTABLE; 8123 if (n == 15) 8124 return false; 8125 8126 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8127 if (InITBlock() && !LastInITBlock()) 8128 return false; 8129 8130 break; 8131 8132 case eEncodingT2: 8133 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8134 n = Bits32 (opcode, 19, 16); 8135 wback = BitIsSet (opcode, 21); 8136 increment = true; 8137 wordhigher = false; 8138 8139 // if n == 15 then UNPREDICTABLE; 8140 if (n == 15) 8141 return false; 8142 8143 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8144 if (InITBlock() && !LastInITBlock()) 8145 return false; 8146 8147 break; 8148 8149 case eEncodingA1: 8150 // n = UInt(Rn); 8151 n = Bits32 (opcode, 19, 16); 8152 8153 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8154 wback = BitIsSet (opcode, 21); 8155 increment = BitIsSet (opcode, 23); 8156 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8157 8158 // if n == 15 then UNPREDICTABLE; 8159 if (n == 15) 8160 return false; 8161 8162 break; 8163 8164 default: 8165 return false; 8166 } 8167 8168 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8169 if (!CurrentModeIsPrivileged ()) 8170 // UNPREDICTABLE; 8171 return false; 8172 else 8173 { 8174 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8175 if (!success) 8176 return false; 8177 8178 addr_t address; 8179 // address = if increment then R[n] else R[n]-8; 8180 if (increment) 8181 address = Rn; 8182 else 8183 address = Rn - 8; 8184 8185 // if wordhigher then address = address+4; 8186 if (wordhigher) 8187 address = address + 4; 8188 8189 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8190 RegisterInfo base_reg; 8191 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8192 8193 EmulateInstruction::Context context; 8194 context.type = eContextReturnFromException; 8195 context.SetRegisterPlusOffset (base_reg, address - Rn); 8196 8197 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8198 if (!success) 8199 return false; 8200 8201 CPSRWriteByInstr (data, 15, true); 8202 8203 // BranchWritePC(MemA[address,4]); 8204 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8205 if (!success) 8206 return false; 8207 8208 BranchWritePC (context, data2); 8209 8210 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8211 if (wback) 8212 { 8213 context.type = eContextAdjustBaseRegister; 8214 if (increment) 8215 { 8216 context.SetOffset (8); 8217 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8218 return false; 8219 } 8220 else 8221 { 8222 context.SetOffset (-8); 8223 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8224 return false; 8225 } 8226 } // if wback 8227 } 8228 } // if ConditionPassed() 8229 return true; 8230 } 8231 8232 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8233 // and writes the result to the destination register. It can optionally update the condition flags based on 8234 // the result. 8235 bool 8236 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8237 { 8238 #if 0 8239 // ARM pseudo code... 8240 if ConditionPassed() then 8241 EncodingSpecificOperations(); 8242 result = R[n] EOR imm32; 8243 if d == 15 then // Can only occur for ARM encoding 8244 ALUWritePC(result); // setflags is always FALSE here 8245 else 8246 R[d] = result; 8247 if setflags then 8248 APSR.N = result<31>; 8249 APSR.Z = IsZeroBit(result); 8250 APSR.C = carry; 8251 // APSR.V unchanged 8252 #endif 8253 8254 bool success = false; 8255 8256 if (ConditionPassed(opcode)) 8257 { 8258 uint32_t Rd, Rn; 8259 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8260 bool setflags; 8261 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8262 switch (encoding) 8263 { 8264 case eEncodingT1: 8265 Rd = Bits32(opcode, 11, 8); 8266 Rn = Bits32(opcode, 19, 16); 8267 setflags = BitIsSet(opcode, 20); 8268 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8269 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8270 if (Rd == 15 && setflags) 8271 return EmulateTEQImm (opcode, eEncodingT1); 8272 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8273 return false; 8274 break; 8275 case eEncodingA1: 8276 Rd = Bits32(opcode, 15, 12); 8277 Rn = Bits32(opcode, 19, 16); 8278 setflags = BitIsSet(opcode, 20); 8279 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8280 8281 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8282 if (Rd == 15 && setflags) 8283 return EmulateSUBSPcLrEtc (opcode, encoding); 8284 break; 8285 default: 8286 return false; 8287 } 8288 8289 // Read the first operand. 8290 uint32_t val1 = ReadCoreReg(Rn, &success); 8291 if (!success) 8292 return false; 8293 8294 uint32_t result = val1 ^ imm32; 8295 8296 EmulateInstruction::Context context; 8297 context.type = EmulateInstruction::eContextImmediate; 8298 context.SetNoArgs (); 8299 8300 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8301 return false; 8302 } 8303 return true; 8304 } 8305 8306 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8307 // optionally-shifted register value, and writes the result to the destination register. 8308 // It can optionally update the condition flags based on the result. 8309 bool 8310 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8311 { 8312 #if 0 8313 // ARM pseudo code... 8314 if ConditionPassed() then 8315 EncodingSpecificOperations(); 8316 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8317 result = R[n] EOR shifted; 8318 if d == 15 then // Can only occur for ARM encoding 8319 ALUWritePC(result); // setflags is always FALSE here 8320 else 8321 R[d] = result; 8322 if setflags then 8323 APSR.N = result<31>; 8324 APSR.Z = IsZeroBit(result); 8325 APSR.C = carry; 8326 // APSR.V unchanged 8327 #endif 8328 8329 bool success = false; 8330 8331 if (ConditionPassed(opcode)) 8332 { 8333 uint32_t Rd, Rn, Rm; 8334 ARM_ShifterType shift_t; 8335 uint32_t shift_n; // the shift applied to the value read from Rm 8336 bool setflags; 8337 uint32_t carry; 8338 switch (encoding) 8339 { 8340 case eEncodingT1: 8341 Rd = Rn = Bits32(opcode, 2, 0); 8342 Rm = Bits32(opcode, 5, 3); 8343 setflags = !InITBlock(); 8344 shift_t = SRType_LSL; 8345 shift_n = 0; 8346 break; 8347 case eEncodingT2: 8348 Rd = Bits32(opcode, 11, 8); 8349 Rn = Bits32(opcode, 19, 16); 8350 Rm = Bits32(opcode, 3, 0); 8351 setflags = BitIsSet(opcode, 20); 8352 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8353 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8354 if (Rd == 15 && setflags) 8355 return EmulateTEQReg (opcode, eEncodingT1); 8356 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8357 return false; 8358 break; 8359 case eEncodingA1: 8360 Rd = Bits32(opcode, 15, 12); 8361 Rn = Bits32(opcode, 19, 16); 8362 Rm = Bits32(opcode, 3, 0); 8363 setflags = BitIsSet(opcode, 20); 8364 shift_n = DecodeImmShiftARM(opcode, shift_t); 8365 8366 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8367 if (Rd == 15 && setflags) 8368 return EmulateSUBSPcLrEtc (opcode, encoding); 8369 break; 8370 default: 8371 return false; 8372 } 8373 8374 // Read the first operand. 8375 uint32_t val1 = ReadCoreReg(Rn, &success); 8376 if (!success) 8377 return false; 8378 8379 // Read the second operand. 8380 uint32_t val2 = ReadCoreReg(Rm, &success); 8381 if (!success) 8382 return false; 8383 8384 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8385 if (!success) 8386 return false; 8387 uint32_t result = val1 ^ shifted; 8388 8389 EmulateInstruction::Context context; 8390 context.type = EmulateInstruction::eContextImmediate; 8391 context.SetNoArgs (); 8392 8393 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8394 return false; 8395 } 8396 return true; 8397 } 8398 8399 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8400 // writes the result to the destination register. It can optionally update the condition flags based 8401 // on the result. 8402 bool 8403 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8404 { 8405 #if 0 8406 // ARM pseudo code... 8407 if ConditionPassed() then 8408 EncodingSpecificOperations(); 8409 result = R[n] OR imm32; 8410 if d == 15 then // Can only occur for ARM encoding 8411 ALUWritePC(result); // setflags is always FALSE here 8412 else 8413 R[d] = result; 8414 if setflags then 8415 APSR.N = result<31>; 8416 APSR.Z = IsZeroBit(result); 8417 APSR.C = carry; 8418 // APSR.V unchanged 8419 #endif 8420 8421 bool success = false; 8422 8423 if (ConditionPassed(opcode)) 8424 { 8425 uint32_t Rd, Rn; 8426 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8427 bool setflags; 8428 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8429 switch (encoding) 8430 { 8431 case eEncodingT1: 8432 Rd = Bits32(opcode, 11, 8); 8433 Rn = Bits32(opcode, 19, 16); 8434 setflags = BitIsSet(opcode, 20); 8435 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8436 // if Rn == '1111' then SEE MOV (immediate); 8437 if (Rn == 15) 8438 return EmulateMOVRdImm (opcode, eEncodingT2); 8439 if (BadReg(Rd) || Rn == 13) 8440 return false; 8441 break; 8442 case eEncodingA1: 8443 Rd = Bits32(opcode, 15, 12); 8444 Rn = Bits32(opcode, 19, 16); 8445 setflags = BitIsSet(opcode, 20); 8446 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8447 8448 if (Rd == 15 && setflags) 8449 return EmulateSUBSPcLrEtc (opcode, encoding); 8450 break; 8451 default: 8452 return false; 8453 } 8454 8455 // Read the first operand. 8456 uint32_t val1 = ReadCoreReg(Rn, &success); 8457 if (!success) 8458 return false; 8459 8460 uint32_t result = val1 | imm32; 8461 8462 EmulateInstruction::Context context; 8463 context.type = EmulateInstruction::eContextImmediate; 8464 context.SetNoArgs (); 8465 8466 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8467 return false; 8468 } 8469 return true; 8470 } 8471 8472 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8473 // value, and writes the result to the destination register. It can optionally update the condition flags based 8474 // on the result. 8475 bool 8476 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8477 { 8478 #if 0 8479 // ARM pseudo code... 8480 if ConditionPassed() then 8481 EncodingSpecificOperations(); 8482 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8483 result = R[n] OR shifted; 8484 if d == 15 then // Can only occur for ARM encoding 8485 ALUWritePC(result); // setflags is always FALSE here 8486 else 8487 R[d] = result; 8488 if setflags then 8489 APSR.N = result<31>; 8490 APSR.Z = IsZeroBit(result); 8491 APSR.C = carry; 8492 // APSR.V unchanged 8493 #endif 8494 8495 bool success = false; 8496 8497 if (ConditionPassed(opcode)) 8498 { 8499 uint32_t Rd, Rn, Rm; 8500 ARM_ShifterType shift_t; 8501 uint32_t shift_n; // the shift applied to the value read from Rm 8502 bool setflags; 8503 uint32_t carry; 8504 switch (encoding) 8505 { 8506 case eEncodingT1: 8507 Rd = Rn = Bits32(opcode, 2, 0); 8508 Rm = Bits32(opcode, 5, 3); 8509 setflags = !InITBlock(); 8510 shift_t = SRType_LSL; 8511 shift_n = 0; 8512 break; 8513 case eEncodingT2: 8514 Rd = Bits32(opcode, 11, 8); 8515 Rn = Bits32(opcode, 19, 16); 8516 Rm = Bits32(opcode, 3, 0); 8517 setflags = BitIsSet(opcode, 20); 8518 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8519 // if Rn == '1111' then SEE MOV (register); 8520 if (Rn == 15) 8521 return EmulateMOVRdRm (opcode, eEncodingT3); 8522 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8523 return false; 8524 break; 8525 case eEncodingA1: 8526 Rd = Bits32(opcode, 15, 12); 8527 Rn = Bits32(opcode, 19, 16); 8528 Rm = Bits32(opcode, 3, 0); 8529 setflags = BitIsSet(opcode, 20); 8530 shift_n = DecodeImmShiftARM(opcode, shift_t); 8531 8532 if (Rd == 15 && setflags) 8533 return EmulateSUBSPcLrEtc (opcode, encoding); 8534 break; 8535 default: 8536 return false; 8537 } 8538 8539 // Read the first operand. 8540 uint32_t val1 = ReadCoreReg(Rn, &success); 8541 if (!success) 8542 return false; 8543 8544 // Read the second operand. 8545 uint32_t val2 = ReadCoreReg(Rm, &success); 8546 if (!success) 8547 return false; 8548 8549 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8550 if (!success) 8551 return false; 8552 uint32_t result = val1 | shifted; 8553 8554 EmulateInstruction::Context context; 8555 context.type = EmulateInstruction::eContextImmediate; 8556 context.SetNoArgs (); 8557 8558 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8559 return false; 8560 } 8561 return true; 8562 } 8563 8564 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8565 // the destination register. It can optionally update the condition flags based on the result. 8566 bool 8567 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8568 { 8569 #if 0 8570 // ARM pseudo code... 8571 if ConditionPassed() then 8572 EncodingSpecificOperations(); 8573 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8574 if d == 15 then // Can only occur for ARM encoding 8575 ALUWritePC(result); // setflags is always FALSE here 8576 else 8577 R[d] = result; 8578 if setflags then 8579 APSR.N = result<31>; 8580 APSR.Z = IsZeroBit(result); 8581 APSR.C = carry; 8582 APSR.V = overflow; 8583 #endif 8584 8585 bool success = false; 8586 8587 uint32_t Rd; // the destination register 8588 uint32_t Rn; // the first operand 8589 bool setflags; 8590 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8591 switch (encoding) { 8592 case eEncodingT1: 8593 Rd = Bits32(opcode, 2, 0); 8594 Rn = Bits32(opcode, 5, 3); 8595 setflags = !InITBlock(); 8596 imm32 = 0; 8597 break; 8598 case eEncodingT2: 8599 Rd = Bits32(opcode, 11, 8); 8600 Rn = Bits32(opcode, 19, 16); 8601 setflags = BitIsSet(opcode, 20); 8602 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8603 if (BadReg(Rd) || BadReg(Rn)) 8604 return false; 8605 break; 8606 case eEncodingA1: 8607 Rd = Bits32(opcode, 15, 12); 8608 Rn = Bits32(opcode, 19, 16); 8609 setflags = BitIsSet(opcode, 20); 8610 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8611 8612 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8613 if (Rd == 15 && setflags) 8614 return EmulateSUBSPcLrEtc (opcode, encoding); 8615 break; 8616 default: 8617 return false; 8618 } 8619 // Read the register value from the operand register Rn. 8620 uint32_t reg_val = ReadCoreReg(Rn, &success); 8621 if (!success) 8622 return false; 8623 8624 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8625 8626 EmulateInstruction::Context context; 8627 context.type = EmulateInstruction::eContextImmediate; 8628 context.SetNoArgs (); 8629 8630 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8631 return false; 8632 8633 return true; 8634 } 8635 8636 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8637 // result to the destination register. It can optionally update the condition flags based on the result. 8638 bool 8639 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8640 { 8641 #if 0 8642 // ARM pseudo code... 8643 if ConditionPassed() then 8644 EncodingSpecificOperations(); 8645 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8646 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8647 if d == 15 then // Can only occur for ARM encoding 8648 ALUWritePC(result); // setflags is always FALSE here 8649 else 8650 R[d] = result; 8651 if setflags then 8652 APSR.N = result<31>; 8653 APSR.Z = IsZeroBit(result); 8654 APSR.C = carry; 8655 APSR.V = overflow; 8656 #endif 8657 8658 bool success = false; 8659 8660 uint32_t Rd; // the destination register 8661 uint32_t Rn; // the first operand 8662 uint32_t Rm; // the second operand 8663 bool setflags; 8664 ARM_ShifterType shift_t; 8665 uint32_t shift_n; // the shift applied to the value read from Rm 8666 switch (encoding) { 8667 case eEncodingT1: 8668 Rd = Bits32(opcode, 11, 8); 8669 Rn = Bits32(opcode, 19, 16); 8670 Rm = Bits32(opcode, 3, 0); 8671 setflags = BitIsSet(opcode, 20); 8672 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8673 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8674 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8675 return false; 8676 break; 8677 case eEncodingA1: 8678 Rd = Bits32(opcode, 15, 12); 8679 Rn = Bits32(opcode, 19, 16); 8680 Rm = Bits32(opcode, 3, 0); 8681 setflags = BitIsSet(opcode, 20); 8682 shift_n = DecodeImmShiftARM(opcode, shift_t); 8683 8684 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8685 if (Rd == 15 && setflags) 8686 return EmulateSUBSPcLrEtc (opcode, encoding); 8687 break; 8688 default: 8689 return false; 8690 } 8691 // Read the register value from register Rn. 8692 uint32_t val1 = ReadCoreReg(Rn, &success); 8693 if (!success) 8694 return false; 8695 8696 // Read the register value from register Rm. 8697 uint32_t val2 = ReadCoreReg(Rm, &success); 8698 if (!success) 8699 return false; 8700 8701 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8702 if (!success) 8703 return false; 8704 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8705 8706 EmulateInstruction::Context context; 8707 context.type = EmulateInstruction::eContextImmediate; 8708 context.SetNoArgs(); 8709 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8710 return false; 8711 8712 return true; 8713 } 8714 8715 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8716 // an immediate value, and writes the result to the destination register. It can optionally update the condition 8717 // flags based on the result. 8718 bool 8719 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8720 { 8721 #if 0 8722 // ARM pseudo code... 8723 if ConditionPassed() then 8724 EncodingSpecificOperations(); 8725 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8726 if d == 15 then 8727 ALUWritePC(result); // setflags is always FALSE here 8728 else 8729 R[d] = result; 8730 if setflags then 8731 APSR.N = result<31>; 8732 APSR.Z = IsZeroBit(result); 8733 APSR.C = carry; 8734 APSR.V = overflow; 8735 #endif 8736 8737 bool success = false; 8738 8739 uint32_t Rd; // the destination register 8740 uint32_t Rn; // the first operand 8741 bool setflags; 8742 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8743 switch (encoding) { 8744 case eEncodingA1: 8745 Rd = Bits32(opcode, 15, 12); 8746 Rn = Bits32(opcode, 19, 16); 8747 setflags = BitIsSet(opcode, 20); 8748 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8749 8750 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8751 if (Rd == 15 && setflags) 8752 return EmulateSUBSPcLrEtc (opcode, encoding); 8753 break; 8754 default: 8755 return false; 8756 } 8757 // Read the register value from the operand register Rn. 8758 uint32_t reg_val = ReadCoreReg(Rn, &success); 8759 if (!success) 8760 return false; 8761 8762 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8763 8764 EmulateInstruction::Context context; 8765 context.type = EmulateInstruction::eContextImmediate; 8766 context.SetNoArgs (); 8767 8768 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8769 return false; 8770 8771 return true; 8772 } 8773 8774 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8775 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8776 // condition flags based on the result. 8777 bool 8778 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8779 { 8780 #if 0 8781 // ARM pseudo code... 8782 if ConditionPassed() then 8783 EncodingSpecificOperations(); 8784 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8785 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8786 if d == 15 then 8787 ALUWritePC(result); // setflags is always FALSE here 8788 else 8789 R[d] = result; 8790 if setflags then 8791 APSR.N = result<31>; 8792 APSR.Z = IsZeroBit(result); 8793 APSR.C = carry; 8794 APSR.V = overflow; 8795 #endif 8796 8797 bool success = false; 8798 8799 uint32_t Rd; // the destination register 8800 uint32_t Rn; // the first operand 8801 uint32_t Rm; // the second operand 8802 bool setflags; 8803 ARM_ShifterType shift_t; 8804 uint32_t shift_n; // the shift applied to the value read from Rm 8805 switch (encoding) { 8806 case eEncodingA1: 8807 Rd = Bits32(opcode, 15, 12); 8808 Rn = Bits32(opcode, 19, 16); 8809 Rm = Bits32(opcode, 3, 0); 8810 setflags = BitIsSet(opcode, 20); 8811 shift_n = DecodeImmShiftARM(opcode, shift_t); 8812 8813 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8814 if (Rd == 15 && setflags) 8815 return EmulateSUBSPcLrEtc (opcode, encoding); 8816 break; 8817 default: 8818 return false; 8819 } 8820 // Read the register value from register Rn. 8821 uint32_t val1 = ReadCoreReg(Rn, &success); 8822 if (!success) 8823 return false; 8824 8825 // Read the register value from register Rm. 8826 uint32_t val2 = ReadCoreReg(Rm, &success); 8827 if (!success) 8828 return false; 8829 8830 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8831 if (!success) 8832 return false; 8833 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8834 8835 EmulateInstruction::Context context; 8836 context.type = EmulateInstruction::eContextImmediate; 8837 context.SetNoArgs(); 8838 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8839 return false; 8840 8841 return true; 8842 } 8843 8844 // Subtract with Carry (immediate) subtracts an immediate value and the value of 8845 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8846 // It can optionally update the condition flags based on the result. 8847 bool 8848 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8849 { 8850 #if 0 8851 // ARM pseudo code... 8852 if ConditionPassed() then 8853 EncodingSpecificOperations(); 8854 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8855 if d == 15 then // Can only occur for ARM encoding 8856 ALUWritePC(result); // setflags is always FALSE here 8857 else 8858 R[d] = result; 8859 if setflags then 8860 APSR.N = result<31>; 8861 APSR.Z = IsZeroBit(result); 8862 APSR.C = carry; 8863 APSR.V = overflow; 8864 #endif 8865 8866 bool success = false; 8867 8868 uint32_t Rd; // the destination register 8869 uint32_t Rn; // the first operand 8870 bool setflags; 8871 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8872 switch (encoding) { 8873 case eEncodingT1: 8874 Rd = Bits32(opcode, 11, 8); 8875 Rn = Bits32(opcode, 19, 16); 8876 setflags = BitIsSet(opcode, 20); 8877 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8878 if (BadReg(Rd) || BadReg(Rn)) 8879 return false; 8880 break; 8881 case eEncodingA1: 8882 Rd = Bits32(opcode, 15, 12); 8883 Rn = Bits32(opcode, 19, 16); 8884 setflags = BitIsSet(opcode, 20); 8885 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8886 8887 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8888 if (Rd == 15 && setflags) 8889 return EmulateSUBSPcLrEtc (opcode, encoding); 8890 break; 8891 default: 8892 return false; 8893 } 8894 // Read the register value from the operand register Rn. 8895 uint32_t reg_val = ReadCoreReg(Rn, &success); 8896 if (!success) 8897 return false; 8898 8899 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 8900 8901 EmulateInstruction::Context context; 8902 context.type = EmulateInstruction::eContextImmediate; 8903 context.SetNoArgs (); 8904 8905 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8906 return false; 8907 8908 return true; 8909 } 8910 8911 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 8912 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8913 // It can optionally update the condition flags based on the result. 8914 bool 8915 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 8916 { 8917 #if 0 8918 // ARM pseudo code... 8919 if ConditionPassed() then 8920 EncodingSpecificOperations(); 8921 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8922 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 8923 if d == 15 then // Can only occur for ARM encoding 8924 ALUWritePC(result); // setflags is always FALSE here 8925 else 8926 R[d] = result; 8927 if setflags then 8928 APSR.N = result<31>; 8929 APSR.Z = IsZeroBit(result); 8930 APSR.C = carry; 8931 APSR.V = overflow; 8932 #endif 8933 8934 bool success = false; 8935 8936 uint32_t Rd; // the destination register 8937 uint32_t Rn; // the first operand 8938 uint32_t Rm; // the second operand 8939 bool setflags; 8940 ARM_ShifterType shift_t; 8941 uint32_t shift_n; // the shift applied to the value read from Rm 8942 switch (encoding) { 8943 case eEncodingT1: 8944 Rd = Rn = Bits32(opcode, 2, 0); 8945 Rm = Bits32(opcode, 5, 3); 8946 setflags = !InITBlock(); 8947 shift_t = SRType_LSL; 8948 shift_n = 0; 8949 break; 8950 case eEncodingT2: 8951 Rd = Bits32(opcode, 11, 8); 8952 Rn = Bits32(opcode, 19, 16); 8953 Rm = Bits32(opcode, 3, 0); 8954 setflags = BitIsSet(opcode, 20); 8955 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8956 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8957 return false; 8958 break; 8959 case eEncodingA1: 8960 Rd = Bits32(opcode, 15, 12); 8961 Rn = Bits32(opcode, 19, 16); 8962 Rm = Bits32(opcode, 3, 0); 8963 setflags = BitIsSet(opcode, 20); 8964 shift_n = DecodeImmShiftARM(opcode, shift_t); 8965 8966 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8967 if (Rd == 15 && setflags) 8968 return EmulateSUBSPcLrEtc (opcode, encoding); 8969 break; 8970 default: 8971 return false; 8972 } 8973 // Read the register value from register Rn. 8974 uint32_t val1 = ReadCoreReg(Rn, &success); 8975 if (!success) 8976 return false; 8977 8978 // Read the register value from register Rm. 8979 uint32_t val2 = ReadCoreReg(Rm, &success); 8980 if (!success) 8981 return false; 8982 8983 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8984 if (!success) 8985 return false; 8986 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 8987 8988 EmulateInstruction::Context context; 8989 context.type = EmulateInstruction::eContextImmediate; 8990 context.SetNoArgs(); 8991 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8992 return false; 8993 8994 return true; 8995 } 8996 8997 // This instruction subtracts an immediate value from a register value, and writes the result 8998 // to the destination register. It can optionally update the condition flags based on the result. 8999 bool 9000 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9001 { 9002 #if 0 9003 // ARM pseudo code... 9004 if ConditionPassed() then 9005 EncodingSpecificOperations(); 9006 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9007 R[d] = result; 9008 if setflags then 9009 APSR.N = result<31>; 9010 APSR.Z = IsZeroBit(result); 9011 APSR.C = carry; 9012 APSR.V = overflow; 9013 #endif 9014 9015 bool success = false; 9016 9017 uint32_t Rd; // the destination register 9018 uint32_t Rn; // the first operand 9019 bool setflags; 9020 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9021 switch (encoding) { 9022 case eEncodingT1: 9023 Rd = Bits32(opcode, 2, 0); 9024 Rn = Bits32(opcode, 5, 3); 9025 setflags = !InITBlock(); 9026 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9027 break; 9028 case eEncodingT2: 9029 Rd = Rn = Bits32(opcode, 10, 8); 9030 setflags = !InITBlock(); 9031 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9032 break; 9033 case eEncodingT3: 9034 Rd = Bits32(opcode, 11, 8); 9035 Rn = Bits32(opcode, 19, 16); 9036 setflags = BitIsSet(opcode, 20); 9037 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9038 9039 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9040 if (Rd == 15 && setflags) 9041 return EmulateCMPImm (opcode, eEncodingT2); 9042 9043 // if Rn == '1101' then SEE SUB (SP minus immediate); 9044 if (Rn == 13) 9045 return EmulateSUBSPImm (opcode, eEncodingT2); 9046 9047 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9048 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9049 return false; 9050 break; 9051 case eEncodingT4: 9052 Rd = Bits32(opcode, 11, 8); 9053 Rn = Bits32(opcode, 19, 16); 9054 setflags = BitIsSet(opcode, 20); 9055 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9056 9057 // if Rn == '1111' then SEE ADR; 9058 if (Rn == 15) 9059 return EmulateADR (opcode, eEncodingT2); 9060 9061 // if Rn == '1101' then SEE SUB (SP minus immediate); 9062 if (Rn == 13) 9063 return EmulateSUBSPImm (opcode, eEncodingT3); 9064 9065 if (BadReg(Rd)) 9066 return false; 9067 break; 9068 default: 9069 return false; 9070 } 9071 // Read the register value from the operand register Rn. 9072 uint32_t reg_val = ReadCoreReg(Rn, &success); 9073 if (!success) 9074 return false; 9075 9076 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9077 9078 EmulateInstruction::Context context; 9079 context.type = EmulateInstruction::eContextImmediate; 9080 context.SetNoArgs (); 9081 9082 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9083 return false; 9084 9085 return true; 9086 } 9087 9088 // This instruction subtracts an immediate value from a register value, and writes the result 9089 // to the destination register. It can optionally update the condition flags based on the result. 9090 bool 9091 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9092 { 9093 #if 0 9094 // ARM pseudo code... 9095 if ConditionPassed() then 9096 EncodingSpecificOperations(); 9097 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9098 if d == 15 then 9099 ALUWritePC(result); // setflags is always FALSE here 9100 else 9101 R[d] = result; 9102 if setflags then 9103 APSR.N = result<31>; 9104 APSR.Z = IsZeroBit(result); 9105 APSR.C = carry; 9106 APSR.V = overflow; 9107 #endif 9108 9109 bool success = false; 9110 9111 uint32_t Rd; // the destination register 9112 uint32_t Rn; // the first operand 9113 bool setflags; 9114 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9115 switch (encoding) { 9116 case eEncodingA1: 9117 Rd = Bits32(opcode, 15, 12); 9118 Rn = Bits32(opcode, 19, 16); 9119 setflags = BitIsSet(opcode, 20); 9120 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9121 9122 // if Rn == '1111' && S == '0' then SEE ADR; 9123 if (Rn == 15 && !setflags) 9124 return EmulateADR (opcode, eEncodingA2); 9125 9126 // if Rn == '1101' then SEE SUB (SP minus immediate); 9127 if (Rn == 13) 9128 return EmulateSUBSPImm (opcode, eEncodingA1); 9129 9130 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9131 if (Rd == 15 && setflags) 9132 return EmulateSUBSPcLrEtc (opcode, encoding); 9133 break; 9134 default: 9135 return false; 9136 } 9137 // Read the register value from the operand register Rn. 9138 uint32_t reg_val = ReadCoreReg(Rn, &success); 9139 if (!success) 9140 return false; 9141 9142 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9143 9144 EmulateInstruction::Context context; 9145 context.type = EmulateInstruction::eContextImmediate; 9146 context.SetNoArgs (); 9147 9148 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9149 return false; 9150 9151 return true; 9152 } 9153 9154 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9155 // immediate value. It updates the condition flags based on the result, and discards the result. 9156 bool 9157 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9158 { 9159 #if 0 9160 // ARM pseudo code... 9161 if ConditionPassed() then 9162 EncodingSpecificOperations(); 9163 result = R[n] EOR imm32; 9164 APSR.N = result<31>; 9165 APSR.Z = IsZeroBit(result); 9166 APSR.C = carry; 9167 // APSR.V unchanged 9168 #endif 9169 9170 bool success = false; 9171 9172 if (ConditionPassed(opcode)) 9173 { 9174 uint32_t Rn; 9175 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9176 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9177 switch (encoding) 9178 { 9179 case eEncodingT1: 9180 Rn = Bits32(opcode, 19, 16); 9181 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9182 if (BadReg(Rn)) 9183 return false; 9184 break; 9185 case eEncodingA1: 9186 Rn = Bits32(opcode, 19, 16); 9187 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9188 break; 9189 default: 9190 return false; 9191 } 9192 9193 // Read the first operand. 9194 uint32_t val1 = ReadCoreReg(Rn, &success); 9195 if (!success) 9196 return false; 9197 9198 uint32_t result = val1 ^ imm32; 9199 9200 EmulateInstruction::Context context; 9201 context.type = EmulateInstruction::eContextImmediate; 9202 context.SetNoArgs (); 9203 9204 if (!WriteFlags(context, result, carry)) 9205 return false; 9206 } 9207 return true; 9208 } 9209 9210 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9211 // optionally-shifted register value. It updates the condition flags based on the result, and discards 9212 // the result. 9213 bool 9214 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9215 { 9216 #if 0 9217 // ARM pseudo code... 9218 if ConditionPassed() then 9219 EncodingSpecificOperations(); 9220 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9221 result = R[n] EOR shifted; 9222 APSR.N = result<31>; 9223 APSR.Z = IsZeroBit(result); 9224 APSR.C = carry; 9225 // APSR.V unchanged 9226 #endif 9227 9228 bool success = false; 9229 9230 if (ConditionPassed(opcode)) 9231 { 9232 uint32_t Rn, Rm; 9233 ARM_ShifterType shift_t; 9234 uint32_t shift_n; // the shift applied to the value read from Rm 9235 uint32_t carry; 9236 switch (encoding) 9237 { 9238 case eEncodingT1: 9239 Rn = Bits32(opcode, 19, 16); 9240 Rm = Bits32(opcode, 3, 0); 9241 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9242 if (BadReg(Rn) || BadReg(Rm)) 9243 return false; 9244 break; 9245 case eEncodingA1: 9246 Rn = Bits32(opcode, 19, 16); 9247 Rm = Bits32(opcode, 3, 0); 9248 shift_n = DecodeImmShiftARM(opcode, shift_t); 9249 break; 9250 default: 9251 return false; 9252 } 9253 9254 // Read the first operand. 9255 uint32_t val1 = ReadCoreReg(Rn, &success); 9256 if (!success) 9257 return false; 9258 9259 // Read the second operand. 9260 uint32_t val2 = ReadCoreReg(Rm, &success); 9261 if (!success) 9262 return false; 9263 9264 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9265 if (!success) 9266 return false; 9267 uint32_t result = val1 ^ shifted; 9268 9269 EmulateInstruction::Context context; 9270 context.type = EmulateInstruction::eContextImmediate; 9271 context.SetNoArgs (); 9272 9273 if (!WriteFlags(context, result, carry)) 9274 return false; 9275 } 9276 return true; 9277 } 9278 9279 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9280 // It updates the condition flags based on the result, and discards the result. 9281 bool 9282 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9283 { 9284 #if 0 9285 // ARM pseudo code... 9286 if ConditionPassed() then 9287 EncodingSpecificOperations(); 9288 result = R[n] AND imm32; 9289 APSR.N = result<31>; 9290 APSR.Z = IsZeroBit(result); 9291 APSR.C = carry; 9292 // APSR.V unchanged 9293 #endif 9294 9295 bool success = false; 9296 9297 if (ConditionPassed(opcode)) 9298 { 9299 uint32_t Rn; 9300 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9301 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9302 switch (encoding) 9303 { 9304 case eEncodingT1: 9305 Rn = Bits32(opcode, 19, 16); 9306 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9307 if (BadReg(Rn)) 9308 return false; 9309 break; 9310 case eEncodingA1: 9311 Rn = Bits32(opcode, 19, 16); 9312 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9313 break; 9314 default: 9315 return false; 9316 } 9317 9318 // Read the first operand. 9319 uint32_t val1 = ReadCoreReg(Rn, &success); 9320 if (!success) 9321 return false; 9322 9323 uint32_t result = val1 & imm32; 9324 9325 EmulateInstruction::Context context; 9326 context.type = EmulateInstruction::eContextImmediate; 9327 context.SetNoArgs (); 9328 9329 if (!WriteFlags(context, result, carry)) 9330 return false; 9331 } 9332 return true; 9333 } 9334 9335 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9336 // It updates the condition flags based on the result, and discards the result. 9337 bool 9338 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9339 { 9340 #if 0 9341 // ARM pseudo code... 9342 if ConditionPassed() then 9343 EncodingSpecificOperations(); 9344 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9345 result = R[n] AND shifted; 9346 APSR.N = result<31>; 9347 APSR.Z = IsZeroBit(result); 9348 APSR.C = carry; 9349 // APSR.V unchanged 9350 #endif 9351 9352 bool success = false; 9353 9354 if (ConditionPassed(opcode)) 9355 { 9356 uint32_t Rn, Rm; 9357 ARM_ShifterType shift_t; 9358 uint32_t shift_n; // the shift applied to the value read from Rm 9359 uint32_t carry; 9360 switch (encoding) 9361 { 9362 case eEncodingT1: 9363 Rn = Bits32(opcode, 2, 0); 9364 Rm = Bits32(opcode, 5, 3); 9365 shift_t = SRType_LSL; 9366 shift_n = 0; 9367 break; 9368 case eEncodingT2: 9369 Rn = Bits32(opcode, 19, 16); 9370 Rm = Bits32(opcode, 3, 0); 9371 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9372 if (BadReg(Rn) || BadReg(Rm)) 9373 return false; 9374 break; 9375 case eEncodingA1: 9376 Rn = Bits32(opcode, 19, 16); 9377 Rm = Bits32(opcode, 3, 0); 9378 shift_n = DecodeImmShiftARM(opcode, shift_t); 9379 break; 9380 default: 9381 return false; 9382 } 9383 9384 // Read the first operand. 9385 uint32_t val1 = ReadCoreReg(Rn, &success); 9386 if (!success) 9387 return false; 9388 9389 // Read the second operand. 9390 uint32_t val2 = ReadCoreReg(Rm, &success); 9391 if (!success) 9392 return false; 9393 9394 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9395 if (!success) 9396 return false; 9397 uint32_t result = val1 & shifted; 9398 9399 EmulateInstruction::Context context; 9400 context.type = EmulateInstruction::eContextImmediate; 9401 context.SetNoArgs (); 9402 9403 if (!WriteFlags(context, result, carry)) 9404 return false; 9405 } 9406 return true; 9407 } 9408 9409 // A8.6.216 SUB (SP minus register) 9410 bool 9411 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9412 { 9413 #if 0 9414 if ConditionPassed() then 9415 EncodingSpecificOperations(); 9416 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9417 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9418 if d == 15 then // Can only occur for ARM encoding 9419 ALUWritePC(result); // setflags is always FALSE here 9420 else 9421 R[d] = result; 9422 if setflags then 9423 APSR.N = result<31>; 9424 APSR.Z = IsZeroBit(result); 9425 APSR.C = carry; 9426 APSR.V = overflow; 9427 #endif 9428 9429 bool success = false; 9430 9431 if (ConditionPassed(opcode)) 9432 { 9433 uint32_t d; 9434 uint32_t m; 9435 bool setflags; 9436 ARM_ShifterType shift_t; 9437 uint32_t shift_n; 9438 9439 switch (encoding) 9440 { 9441 case eEncodingT1: 9442 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9443 d = Bits32 (opcode, 11, 8); 9444 m = Bits32 (opcode, 3, 0); 9445 setflags = BitIsSet (opcode, 20); 9446 9447 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9448 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9449 9450 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9451 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9452 return false; 9453 9454 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9455 if ((d == 15) || BadReg (m)) 9456 return false; 9457 break; 9458 9459 case eEncodingA1: 9460 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9461 d = Bits32 (opcode, 15, 12); 9462 m = Bits32 (opcode, 3, 0); 9463 setflags = BitIsSet (opcode, 20); 9464 9465 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9466 if (d == 15 && setflags) 9467 EmulateSUBSPcLrEtc (opcode, encoding); 9468 9469 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9470 shift_n = DecodeImmShiftARM (opcode, shift_t); 9471 break; 9472 9473 default: 9474 return false; 9475 } 9476 9477 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9478 uint32_t Rm = ReadCoreReg (m, &success); 9479 if (!success) 9480 return false; 9481 9482 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9483 if (!success) 9484 return false; 9485 9486 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9487 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9488 if (!success) 9489 return false; 9490 9491 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9492 9493 EmulateInstruction::Context context; 9494 context.type = eContextArithmetic; 9495 RegisterInfo sp_reg; 9496 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9497 RegisterInfo dwarf_reg; 9498 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9499 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9500 9501 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9502 return false; 9503 } 9504 return true; 9505 } 9506 9507 9508 // A8.6.7 ADD (register-shifted register) 9509 bool 9510 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9511 { 9512 #if 0 9513 if ConditionPassed() then 9514 EncodingSpecificOperations(); 9515 shift_n = UInt(R[s]<7:0>); 9516 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9517 (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9518 R[d] = result; 9519 if setflags then 9520 APSR.N = result<31>; 9521 APSR.Z = IsZeroBit(result); 9522 APSR.C = carry; 9523 APSR.V = overflow; 9524 #endif 9525 9526 bool success = false; 9527 9528 if (ConditionPassed(opcode)) 9529 { 9530 uint32_t d; 9531 uint32_t n; 9532 uint32_t m; 9533 uint32_t s; 9534 bool setflags; 9535 ARM_ShifterType shift_t; 9536 9537 switch (encoding) 9538 { 9539 case eEncodingA1: 9540 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9541 d = Bits32 (opcode, 15, 12); 9542 n = Bits32 (opcode, 19, 16); 9543 m = Bits32 (opcode, 3, 0); 9544 s = Bits32 (opcode, 11, 8); 9545 9546 // setflags = (S == �1�); shift_t = DecodeRegShift(type); 9547 setflags = BitIsSet (opcode, 20); 9548 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9549 9550 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9551 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9552 return false; 9553 break; 9554 9555 default: 9556 return false; 9557 } 9558 9559 // shift_n = UInt(R[s]<7:0>); 9560 uint32_t Rs = ReadCoreReg (s, &success); 9561 if (!success) 9562 return false; 9563 9564 uint32_t shift_n = Bits32 (Rs, 7, 0); 9565 9566 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9567 uint32_t Rm = ReadCoreReg (m, &success); 9568 if (!success) 9569 return false; 9570 9571 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9572 if (!success) 9573 return false; 9574 9575 // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9576 uint32_t Rn = ReadCoreReg (n, &success); 9577 if (!success) 9578 return false; 9579 9580 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9581 9582 // R[d] = result; 9583 EmulateInstruction::Context context; 9584 context.type = eContextArithmetic; 9585 RegisterInfo reg_n; 9586 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9587 RegisterInfo reg_m; 9588 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9589 9590 context.SetRegisterRegisterOperands (reg_n, reg_m); 9591 9592 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9593 return false; 9594 9595 // if setflags then 9596 // APSR.N = result<31>; 9597 // APSR.Z = IsZeroBit(result); 9598 // APSR.C = carry; 9599 // APSR.V = overflow; 9600 if (setflags) 9601 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9602 } 9603 return true; 9604 } 9605 9606 // A8.6.213 SUB (register) 9607 bool 9608 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9609 { 9610 #if 0 9611 if ConditionPassed() then 9612 EncodingSpecificOperations(); 9613 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9614 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9615 if d == 15 then // Can only occur for ARM encoding 9616 ALUWritePC(result); // setflags is always FALSE here 9617 else 9618 R[d] = result; 9619 if setflags then 9620 APSR.N = result<31>; 9621 APSR.Z = IsZeroBit(result); 9622 APSR.C = carry; 9623 APSR.V = overflow; 9624 #endif 9625 9626 bool success = false; 9627 9628 if (ConditionPassed(opcode)) 9629 { 9630 uint32_t d; 9631 uint32_t n; 9632 uint32_t m; 9633 bool setflags; 9634 ARM_ShifterType shift_t; 9635 uint32_t shift_n; 9636 9637 switch (encoding) 9638 { 9639 case eEncodingT1: 9640 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9641 d = Bits32 (opcode, 2, 0); 9642 n = Bits32 (opcode, 5, 3); 9643 m = Bits32 (opcode, 8, 6); 9644 setflags = !InITBlock(); 9645 9646 // (shift_t, shift_n) = (SRType_LSL, 0); 9647 shift_t = SRType_LSL; 9648 shift_n = 0; 9649 9650 break; 9651 9652 case eEncodingT2: 9653 // if Rd == �1111� && S == �1� then SEE CMP (register); 9654 // if Rn == �1101� then SEE SUB (SP minus register); 9655 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9656 d = Bits32 (opcode, 11, 8); 9657 n = Bits32 (opcode, 19, 16); 9658 m = Bits32 (opcode, 3, 0); 9659 setflags = BitIsSet (opcode, 20); 9660 9661 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9662 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9663 9664 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9665 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9666 return false; 9667 9668 break; 9669 9670 case eEncodingA1: 9671 // if Rn == �1101� then SEE SUB (SP minus register); 9672 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9673 d = Bits32 (opcode, 15, 12); 9674 n = Bits32 (opcode, 19, 16); 9675 m = Bits32 (opcode, 3, 0); 9676 setflags = BitIsSet (opcode, 20); 9677 9678 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9679 if ((d == 15) && setflags) 9680 EmulateSUBSPcLrEtc (opcode, encoding); 9681 9682 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9683 shift_n = DecodeImmShiftARM (opcode, shift_t); 9684 9685 break; 9686 9687 default: 9688 return false; 9689 } 9690 9691 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9692 uint32_t Rm = ReadCoreReg (m, &success); 9693 if (!success) 9694 return false; 9695 9696 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9697 if (!success) 9698 return false; 9699 9700 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9701 uint32_t Rn = ReadCoreReg (n, &success); 9702 if (!success) 9703 return false; 9704 9705 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9706 9707 // if d == 15 then // Can only occur for ARM encoding 9708 // ALUWritePC(result); // setflags is always FALSE here 9709 // else 9710 // R[d] = result; 9711 // if setflags then 9712 // APSR.N = result<31>; 9713 // APSR.Z = IsZeroBit(result); 9714 // APSR.C = carry; 9715 // APSR.V = overflow; 9716 9717 EmulateInstruction::Context context; 9718 context.type = eContextArithmetic; 9719 RegisterInfo reg_n; 9720 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9721 RegisterInfo reg_m; 9722 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9723 context.SetRegisterRegisterOperands (reg_n, reg_m); 9724 9725 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9726 return false; 9727 } 9728 return true; 9729 } 9730 9731 // A8.6.202 STREX 9732 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9733 // word from a register to memory if the executing processor has exclusive access to the memory addressed. 9734 bool 9735 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9736 { 9737 #if 0 9738 if ConditionPassed() then 9739 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9740 address = R[n] + imm32; 9741 if ExclusiveMonitorsPass(address,4) then 9742 MemA[address,4] = R[t]; 9743 R[d] = 0; 9744 else 9745 R[d] = 1; 9746 #endif 9747 9748 bool success = false; 9749 9750 if (ConditionPassed(opcode)) 9751 { 9752 uint32_t d; 9753 uint32_t t; 9754 uint32_t n; 9755 uint32_t imm32; 9756 const uint32_t addr_byte_size = GetAddressByteSize(); 9757 9758 switch (encoding) 9759 { 9760 case eEncodingT1: 9761 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 9762 d = Bits32 (opcode, 11, 8); 9763 t = Bits32 (opcode, 15, 12); 9764 n = Bits32 (opcode, 19, 16); 9765 imm32 = Bits32 (opcode, 7, 0) << 2; 9766 9767 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9768 if (BadReg (d) || BadReg (t) || (n == 15)) 9769 return false; 9770 9771 // if d == n || d == t then UNPREDICTABLE; 9772 if ((d == n) || (d == t)) 9773 return false; 9774 9775 break; 9776 9777 case eEncodingA1: 9778 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9779 d = Bits32 (opcode, 15, 12); 9780 t = Bits32 (opcode, 3, 0); 9781 n = Bits32 (opcode, 19, 16); 9782 imm32 = 0; 9783 9784 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9785 if ((d == 15) || (t == 15) || (n == 15)) 9786 return false; 9787 9788 // if d == n || d == t then UNPREDICTABLE; 9789 if ((d == n) || (d == t)) 9790 return false; 9791 9792 break; 9793 9794 default: 9795 return false; 9796 } 9797 9798 // address = R[n] + imm32; 9799 uint32_t Rn = ReadCoreReg (n, &success); 9800 if (!success) 9801 return false; 9802 9803 addr_t address = Rn + imm32; 9804 9805 RegisterInfo base_reg; 9806 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9807 RegisterInfo data_reg; 9808 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9809 EmulateInstruction::Context context; 9810 context.type = eContextRegisterStore; 9811 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9812 9813 // if ExclusiveMonitorsPass(address,4) then 9814 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9815 // always return true. 9816 if (true) 9817 { 9818 // MemA[address,4] = R[t]; 9819 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9820 if (!success) 9821 return false; 9822 9823 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9824 return false; 9825 9826 // R[d] = 0; 9827 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9828 return false; 9829 } 9830 else 9831 { 9832 // R[d] = 1; 9833 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9834 return false; 9835 } 9836 } 9837 return true; 9838 } 9839 9840 // A8.6.197 STRB (immediate, ARM) 9841 bool 9842 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9843 { 9844 #if 0 9845 if ConditionPassed() then 9846 EncodingSpecificOperations(); 9847 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9848 address = if index then offset_addr else R[n]; 9849 MemU[address,1] = R[t]<7:0>; 9850 if wback then R[n] = offset_addr; 9851 #endif 9852 9853 bool success = false; 9854 9855 if (ConditionPassed(opcode)) 9856 { 9857 uint32_t t; 9858 uint32_t n; 9859 uint32_t imm32; 9860 bool index; 9861 bool add; 9862 bool wback; 9863 9864 switch (encoding) 9865 { 9866 case eEncodingA1: 9867 // if P == �0� && W == �1� then SEE STRBT; 9868 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9869 t = Bits32 (opcode, 15, 12); 9870 n = Bits32 (opcode, 19, 16); 9871 imm32 = Bits32 (opcode, 11, 0); 9872 9873 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9874 index = BitIsSet (opcode, 24); 9875 add = BitIsSet (opcode, 23); 9876 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9877 9878 // if t == 15 then UNPREDICTABLE; 9879 if (t == 15) 9880 return false; 9881 9882 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9883 if (wback && ((n == 15) || (n == t))) 9884 return false; 9885 9886 break; 9887 9888 default: 9889 return false; 9890 } 9891 9892 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9893 uint32_t Rn = ReadCoreReg (n, &success); 9894 if (!success) 9895 return false; 9896 9897 addr_t offset_addr; 9898 if (add) 9899 offset_addr = Rn + imm32; 9900 else 9901 offset_addr = Rn - imm32; 9902 9903 // address = if index then offset_addr else R[n]; 9904 addr_t address; 9905 if (index) 9906 address = offset_addr; 9907 else 9908 address = Rn; 9909 9910 // MemU[address,1] = R[t]<7:0>; 9911 uint32_t Rt = ReadCoreReg (t, &success); 9912 if (!success) 9913 return false; 9914 9915 RegisterInfo base_reg; 9916 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9917 RegisterInfo data_reg; 9918 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9919 EmulateInstruction::Context context; 9920 context.type = eContextRegisterStore; 9921 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9922 9923 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 9924 return false; 9925 9926 // if wback then R[n] = offset_addr; 9927 if (wback) 9928 { 9929 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9930 return false; 9931 } 9932 } 9933 return true; 9934 } 9935 9936 // A8.6.194 STR (immediate, ARM) 9937 bool 9938 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9939 { 9940 #if 0 9941 if ConditionPassed() then 9942 EncodingSpecificOperations(); 9943 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9944 address = if index then offset_addr else R[n]; 9945 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9946 if wback then R[n] = offset_addr; 9947 #endif 9948 9949 bool success = false; 9950 9951 if (ConditionPassed(opcode)) 9952 { 9953 uint32_t t; 9954 uint32_t n; 9955 uint32_t imm32; 9956 bool index; 9957 bool add; 9958 bool wback; 9959 9960 const uint32_t addr_byte_size = GetAddressByteSize(); 9961 9962 switch (encoding) 9963 { 9964 case eEncodingA1: 9965 // if P == �0� && W == �1� then SEE STRT; 9966 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH; 9967 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9968 t = Bits32 (opcode, 15, 12); 9969 n = Bits32 (opcode, 19, 16); 9970 imm32 = Bits32 (opcode, 11, 0); 9971 9972 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9973 index = BitIsSet (opcode, 24); 9974 add = BitIsSet (opcode, 23); 9975 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9976 9977 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9978 if (wback && ((n == 15) || (n == t))) 9979 return false; 9980 9981 break; 9982 9983 default: 9984 return false; 9985 } 9986 9987 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9988 uint32_t Rn = ReadCoreReg (n, &success); 9989 if (!success) 9990 return false; 9991 9992 addr_t offset_addr; 9993 if (add) 9994 offset_addr = Rn + imm32; 9995 else 9996 offset_addr = Rn - imm32; 9997 9998 // address = if index then offset_addr else R[n]; 9999 addr_t address; 10000 if (index) 10001 address = offset_addr; 10002 else 10003 address = Rn; 10004 10005 RegisterInfo base_reg; 10006 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10007 RegisterInfo data_reg; 10008 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10009 EmulateInstruction::Context context; 10010 context.type = eContextRegisterStore; 10011 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10012 10013 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10014 uint32_t Rt = ReadCoreReg (t, &success); 10015 if (!success) 10016 return false; 10017 10018 if (t == 15) 10019 { 10020 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10021 if (!success) 10022 return false; 10023 10024 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10025 return false; 10026 } 10027 else 10028 { 10029 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10030 return false; 10031 } 10032 10033 // if wback then R[n] = offset_addr; 10034 if (wback) 10035 { 10036 context.type = eContextAdjustBaseRegister; 10037 context.SetImmediate (offset_addr); 10038 10039 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10040 return false; 10041 } 10042 } 10043 return true; 10044 } 10045 10046 // A8.6.66 LDRD (immediate) 10047 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10048 // words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10049 bool 10050 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10051 { 10052 #if 0 10053 if ConditionPassed() then 10054 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10055 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10056 address = if index then offset_addr else R[n]; 10057 R[t] = MemA[address,4]; 10058 R[t2] = MemA[address+4,4]; 10059 if wback then R[n] = offset_addr; 10060 #endif 10061 10062 bool success = false; 10063 10064 if (ConditionPassed(opcode)) 10065 { 10066 uint32_t t; 10067 uint32_t t2; 10068 uint32_t n; 10069 uint32_t imm32; 10070 bool index; 10071 bool add; 10072 bool wback; 10073 10074 switch (encoding) 10075 { 10076 case eEncodingT1: 10077 //if P == �0� && W == �0� then SEE �Related encodings�; 10078 //if Rn == �1111� then SEE LDRD (literal); 10079 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10080 t = Bits32 (opcode, 15, 12); 10081 t2 = Bits32 (opcode, 11, 8); 10082 n = Bits32 (opcode, 19, 16); 10083 imm32 = Bits32 (opcode, 7, 0) << 2; 10084 10085 //index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10086 index = BitIsSet (opcode, 24); 10087 add = BitIsSet (opcode, 23); 10088 wback = BitIsSet (opcode, 21); 10089 10090 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10091 if (wback && ((n == t) || (n == t2))) 10092 return false; 10093 10094 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10095 if (BadReg (t) || BadReg (t2) || (t == t2)) 10096 return false; 10097 10098 break; 10099 10100 case eEncodingA1: 10101 //if Rn == �1111� then SEE LDRD (literal); 10102 //if Rt<0> == �1� then UNPREDICTABLE; 10103 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10104 t = Bits32 (opcode, 15, 12); 10105 if (BitIsSet (t, 0)) 10106 return false; 10107 t2 = t + 1; 10108 n = Bits32 (opcode, 19, 16); 10109 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10110 10111 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10112 index = BitIsSet (opcode, 24); 10113 add = BitIsSet (opcode, 23); 10114 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10115 10116 //if P == �0� && W == �1� then UNPREDICTABLE; 10117 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10118 return false; 10119 10120 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10121 if (wback && ((n == t) || (n == t2))) 10122 return false; 10123 10124 //if t2 == 15 then UNPREDICTABLE; 10125 if (t2 == 15) 10126 return false; 10127 10128 break; 10129 10130 default: 10131 return false; 10132 } 10133 10134 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10135 uint32_t Rn = ReadCoreReg (n, &success); 10136 if (!success) 10137 return false; 10138 10139 addr_t offset_addr; 10140 if (add) 10141 offset_addr = Rn + imm32; 10142 else 10143 offset_addr = Rn - imm32; 10144 10145 //address = if index then offset_addr else R[n]; 10146 addr_t address; 10147 if (index) 10148 address = offset_addr; 10149 else 10150 address = Rn; 10151 10152 //R[t] = MemA[address,4]; 10153 RegisterInfo base_reg; 10154 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10155 10156 EmulateInstruction::Context context; 10157 context.type = eContextRegisterLoad; 10158 context.SetRegisterPlusOffset (base_reg, address - Rn); 10159 10160 const uint32_t addr_byte_size = GetAddressByteSize(); 10161 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10162 if (!success) 10163 return false; 10164 10165 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10166 return false; 10167 10168 //R[t2] = MemA[address+4,4]; 10169 10170 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10171 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10172 if (!success) 10173 return false; 10174 10175 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10176 return false; 10177 10178 //if wback then R[n] = offset_addr; 10179 if (wback) 10180 { 10181 context.type = eContextAdjustBaseRegister; 10182 context.SetAddress (offset_addr); 10183 10184 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10185 return false; 10186 } 10187 } 10188 return true; 10189 } 10190 10191 // A8.6.68 LDRD (register) 10192 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10193 // words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10194 bool 10195 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10196 { 10197 #if 0 10198 if ConditionPassed() then 10199 EncodingSpecificOperations(); 10200 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10201 address = if index then offset_addr else R[n]; 10202 R[t] = MemA[address,4]; 10203 R[t2] = MemA[address+4,4]; 10204 if wback then R[n] = offset_addr; 10205 #endif 10206 10207 bool success = false; 10208 10209 if (ConditionPassed(opcode)) 10210 { 10211 uint32_t t; 10212 uint32_t t2; 10213 uint32_t n; 10214 uint32_t m; 10215 bool index; 10216 bool add; 10217 bool wback; 10218 10219 switch (encoding) 10220 { 10221 case eEncodingA1: 10222 // if Rt<0> == �1� then UNPREDICTABLE; 10223 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10224 t = Bits32 (opcode, 15, 12); 10225 if (BitIsSet (t, 0)) 10226 return false; 10227 t2 = t + 1; 10228 n = Bits32 (opcode, 19, 16); 10229 m = Bits32 (opcode, 3, 0); 10230 10231 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10232 index = BitIsSet (opcode, 24); 10233 add = BitIsSet (opcode, 23); 10234 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10235 10236 // if P == �0� && W == �1� then UNPREDICTABLE; 10237 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10238 return false; 10239 10240 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10241 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10242 return false; 10243 10244 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10245 if (wback && ((n == 15) || (n == t) || (n == t2))) 10246 return false; 10247 10248 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10249 if ((ArchVersion() < 6) && wback && (m == n)) 10250 return false; 10251 break; 10252 10253 default: 10254 return false; 10255 } 10256 10257 uint32_t Rn = ReadCoreReg (n, &success); 10258 if (!success) 10259 return false; 10260 RegisterInfo base_reg; 10261 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10262 10263 uint32_t Rm = ReadCoreReg (m, &success); 10264 if (!success) 10265 return false; 10266 RegisterInfo offset_reg; 10267 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10268 10269 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10270 addr_t offset_addr; 10271 if (add) 10272 offset_addr = Rn + Rm; 10273 else 10274 offset_addr = Rn - Rm; 10275 10276 // address = if index then offset_addr else R[n]; 10277 addr_t address; 10278 if (index) 10279 address = offset_addr; 10280 else 10281 address = Rn; 10282 10283 EmulateInstruction::Context context; 10284 context.type = eContextRegisterLoad; 10285 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10286 10287 // R[t] = MemA[address,4]; 10288 const uint32_t addr_byte_size = GetAddressByteSize(); 10289 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10290 if (!success) 10291 return false; 10292 10293 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10294 return false; 10295 10296 // R[t2] = MemA[address+4,4]; 10297 10298 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10299 if (!success) 10300 return false; 10301 10302 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10303 return false; 10304 10305 // if wback then R[n] = offset_addr; 10306 if (wback) 10307 { 10308 context.type = eContextAdjustBaseRegister; 10309 context.SetAddress (offset_addr); 10310 10311 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10312 return false; 10313 } 10314 } 10315 return true; 10316 } 10317 10318 // A8.6.200 STRD (immediate) 10319 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10320 // stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10321 bool 10322 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10323 { 10324 #if 0 10325 if ConditionPassed() then 10326 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10327 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10328 address = if index then offset_addr else R[n]; 10329 MemA[address,4] = R[t]; 10330 MemA[address+4,4] = R[t2]; 10331 if wback then R[n] = offset_addr; 10332 #endif 10333 10334 bool success = false; 10335 10336 if (ConditionPassed(opcode)) 10337 { 10338 uint32_t t; 10339 uint32_t t2; 10340 uint32_t n; 10341 uint32_t imm32; 10342 bool index; 10343 bool add; 10344 bool wback; 10345 10346 switch (encoding) 10347 { 10348 case eEncodingT1: 10349 // if P == �0� && W == �0� then SEE �Related encodings�; 10350 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10351 t = Bits32 (opcode, 15, 12); 10352 t2 = Bits32 (opcode, 11, 8); 10353 n = Bits32 (opcode, 19, 16); 10354 imm32 = Bits32 (opcode, 7, 0) << 2; 10355 10356 // index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10357 index = BitIsSet (opcode, 24); 10358 add = BitIsSet (opcode, 23); 10359 wback = BitIsSet (opcode, 21); 10360 10361 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10362 if (wback && ((n == t) || (n == t2))) 10363 return false; 10364 10365 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10366 if ((n == 15) || BadReg (t) || BadReg (t2)) 10367 return false; 10368 10369 break; 10370 10371 case eEncodingA1: 10372 // if Rt<0> == �1� then UNPREDICTABLE; 10373 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10374 t = Bits32 (opcode, 15, 12); 10375 if (BitIsSet (t, 0)) 10376 return false; 10377 10378 t2 = t + 1; 10379 n = Bits32 (opcode, 19, 16); 10380 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10381 10382 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10383 index = BitIsSet (opcode, 24); 10384 add = BitIsSet (opcode, 23); 10385 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10386 10387 // if P == �0� && W == �1� then UNPREDICTABLE; 10388 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10389 return false; 10390 10391 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10392 if (wback && ((n == 15) || (n == t) || (n == t2))) 10393 return false; 10394 10395 // if t2 == 15 then UNPREDICTABLE; 10396 if (t2 == 15) 10397 return false; 10398 10399 break; 10400 10401 default: 10402 return false; 10403 } 10404 10405 RegisterInfo base_reg; 10406 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10407 10408 uint32_t Rn = ReadCoreReg (n, &success); 10409 if (!success) 10410 return false; 10411 10412 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10413 addr_t offset_addr; 10414 if (add) 10415 offset_addr = Rn + imm32; 10416 else 10417 offset_addr = Rn - imm32; 10418 10419 //address = if index then offset_addr else R[n]; 10420 addr_t address; 10421 if (index) 10422 address = offset_addr; 10423 else 10424 address = Rn; 10425 10426 //MemA[address,4] = R[t]; 10427 RegisterInfo data_reg; 10428 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10429 10430 uint32_t data = ReadCoreReg (t, &success); 10431 if (!success) 10432 return false; 10433 10434 EmulateInstruction::Context context; 10435 context.type = eContextRegisterStore; 10436 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10437 10438 const uint32_t addr_byte_size = GetAddressByteSize(); 10439 10440 if (!MemAWrite (context, address, data, addr_byte_size)) 10441 return false; 10442 10443 //MemA[address+4,4] = R[t2]; 10444 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10445 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10446 10447 data = ReadCoreReg (t2, &success); 10448 if (!success) 10449 return false; 10450 10451 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10452 return false; 10453 10454 //if wback then R[n] = offset_addr; 10455 if (wback) 10456 { 10457 context.type = eContextAdjustBaseRegister; 10458 context.SetAddress (offset_addr); 10459 10460 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10461 return false; 10462 } 10463 } 10464 return true; 10465 } 10466 10467 10468 // A8.6.201 STRD (register) 10469 bool 10470 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10471 { 10472 #if 0 10473 if ConditionPassed() then 10474 EncodingSpecificOperations(); 10475 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10476 address = if index then offset_addr else R[n]; 10477 MemA[address,4] = R[t]; 10478 MemA[address+4,4] = R[t2]; 10479 if wback then R[n] = offset_addr; 10480 #endif 10481 10482 bool success = false; 10483 10484 if (ConditionPassed(opcode)) 10485 { 10486 uint32_t t; 10487 uint32_t t2; 10488 uint32_t n; 10489 uint32_t m; 10490 bool index; 10491 bool add; 10492 bool wback; 10493 10494 switch (encoding) 10495 { 10496 case eEncodingA1: 10497 // if Rt<0> == �1� then UNPREDICTABLE; 10498 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10499 t = Bits32 (opcode, 15, 12); 10500 if (BitIsSet (t, 0)) 10501 return false; 10502 10503 t2 = t+1; 10504 n = Bits32 (opcode, 19, 16); 10505 m = Bits32 (opcode, 3, 0); 10506 10507 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10508 index = BitIsSet (opcode, 24); 10509 add = BitIsSet (opcode, 23); 10510 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10511 10512 // if P == �0� && W == �1� then UNPREDICTABLE; 10513 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10514 return false; 10515 10516 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10517 if ((t2 == 15) || (m == 15)) 10518 return false; 10519 10520 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10521 if (wback && ((n == 15) || (n == t) || (n == t2))) 10522 return false; 10523 10524 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10525 if ((ArchVersion() < 6) && wback && (m == n)) 10526 return false; 10527 10528 break; 10529 10530 default: 10531 return false; 10532 } 10533 10534 RegisterInfo base_reg; 10535 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10536 RegisterInfo offset_reg; 10537 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10538 RegisterInfo data_reg; 10539 10540 uint32_t Rn = ReadCoreReg (n, &success); 10541 if (!success) 10542 return false; 10543 10544 uint32_t Rm = ReadCoreReg (m, &success); 10545 if (!success) 10546 return false; 10547 10548 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10549 addr_t offset_addr; 10550 if (add) 10551 offset_addr = Rn + Rm; 10552 else 10553 offset_addr = Rn - Rm; 10554 10555 // address = if index then offset_addr else R[n]; 10556 addr_t address; 10557 if (index) 10558 address = offset_addr; 10559 else 10560 address = Rn; 10561 // MemA[address,4] = R[t]; 10562 uint32_t Rt = ReadCoreReg (t, &success); 10563 if (!success) 10564 return false; 10565 10566 EmulateInstruction::Context context; 10567 context.type = eContextRegisterStore; 10568 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10569 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10570 10571 const uint32_t addr_byte_size = GetAddressByteSize(); 10572 10573 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10574 return false; 10575 10576 // MemA[address+4,4] = R[t2]; 10577 uint32_t Rt2 = ReadCoreReg (t2, &success); 10578 if (!success) 10579 return false; 10580 10581 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10582 10583 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10584 10585 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10586 return false; 10587 10588 // if wback then R[n] = offset_addr; 10589 if (wback) 10590 { 10591 context.type = eContextAdjustBaseRegister; 10592 context.SetAddress (offset_addr); 10593 10594 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10595 return false; 10596 10597 } 10598 } 10599 return true; 10600 } 10601 10602 // A8.6.319 VLDM 10603 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10604 // an ARM core register. 10605 bool 10606 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10607 { 10608 #if 0 10609 if ConditionPassed() then 10610 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10611 address = if add then R[n] else R[n]-imm32; 10612 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10613 for r = 0 to regs-1 10614 if single_regs then 10615 S[d+r] = MemA[address,4]; address = address+4; 10616 else 10617 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10618 // Combine the word-aligned words in the correct order for current endianness. 10619 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10620 #endif 10621 10622 bool success = false; 10623 10624 if (ConditionPassed(opcode)) 10625 { 10626 bool single_regs; 10627 bool add; 10628 bool wback; 10629 uint32_t d; 10630 uint32_t n; 10631 uint32_t imm32; 10632 uint32_t regs; 10633 10634 switch (encoding) 10635 { 10636 case eEncodingT1: 10637 case eEncodingA1: 10638 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10639 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10640 // if P == �1� && W == �0� then SEE VLDR; 10641 // if P == U && W == �1� then UNDEFINED; 10642 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10643 return false; 10644 10645 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10646 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10647 single_regs = false; 10648 add = BitIsSet (opcode, 23); 10649 wback = BitIsSet (opcode, 21); 10650 10651 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10652 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10653 n = Bits32 (opcode, 19, 16); 10654 imm32 = Bits32 (opcode, 7, 0) << 2; 10655 10656 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�. 10657 regs = Bits32 (opcode, 7, 0) / 2; 10658 10659 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10660 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10661 return false; 10662 10663 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10664 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10665 return false; 10666 10667 break; 10668 10669 case eEncodingT2: 10670 case eEncodingA2: 10671 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10672 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10673 // if P == �1� && W == �0� then SEE VLDR; 10674 // if P == U && W == �1� then UNDEFINED; 10675 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10676 return false; 10677 10678 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10679 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10680 single_regs = true; 10681 add = BitIsSet (opcode, 23); 10682 wback = BitIsSet (opcode, 21); 10683 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10684 n = Bits32 (opcode, 19, 16); 10685 10686 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10687 imm32 = Bits32 (opcode, 7, 0) << 2; 10688 regs = Bits32 (opcode, 7, 0); 10689 10690 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10691 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10692 return false; 10693 10694 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10695 if ((regs == 0) || ((d + regs) > 32)) 10696 return false; 10697 break; 10698 10699 default: 10700 return false; 10701 } 10702 10703 RegisterInfo base_reg; 10704 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10705 10706 uint32_t Rn = ReadCoreReg (n, &success); 10707 if (!success) 10708 return false; 10709 10710 // address = if add then R[n] else R[n]-imm32; 10711 addr_t address; 10712 if (add) 10713 address = Rn; 10714 else 10715 address = Rn - imm32; 10716 10717 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10718 EmulateInstruction::Context context; 10719 10720 if (wback) 10721 { 10722 uint32_t value; 10723 if (add) 10724 value = Rn + imm32; 10725 else 10726 value = Rn - imm32; 10727 10728 context.type = eContextAdjustBaseRegister; 10729 context.SetImmediateSigned (value - Rn); 10730 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10731 return false; 10732 10733 } 10734 10735 const uint32_t addr_byte_size = GetAddressByteSize(); 10736 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10737 10738 context.type = eContextRegisterLoad; 10739 10740 // for r = 0 to regs-1 10741 for (uint32_t r = 0; r < regs; ++r) 10742 { 10743 if (single_regs) 10744 { 10745 // S[d+r] = MemA[address,4]; address = address+4; 10746 context.SetRegisterPlusOffset (base_reg, address - Rn); 10747 10748 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10749 if (!success) 10750 return false; 10751 10752 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10753 return false; 10754 10755 address = address + 4; 10756 } 10757 else 10758 { 10759 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10760 context.SetRegisterPlusOffset (base_reg, address - Rn); 10761 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10762 if (!success) 10763 return false; 10764 10765 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10766 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10767 if (!success) 10768 return false; 10769 10770 address = address + 8; 10771 // // Combine the word-aligned words in the correct order for current endianness. 10772 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10773 uint64_t data; 10774 if (GetByteOrder() == eByteOrderBig) 10775 { 10776 data = word1; 10777 data = (data << 32) | word2; 10778 } 10779 else 10780 { 10781 data = word2; 10782 data = (data << 32) | word1; 10783 } 10784 10785 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10786 return false; 10787 } 10788 } 10789 } 10790 return true; 10791 } 10792 10793 // A8.6.399 VSTM 10794 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10795 // ARM core register. 10796 bool 10797 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10798 { 10799 #if 0 10800 if ConditionPassed() then 10801 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10802 address = if add then R[n] else R[n]-imm32; 10803 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10804 for r = 0 to regs-1 10805 if single_regs then 10806 MemA[address,4] = S[d+r]; address = address+4; 10807 else 10808 // Store as two word-aligned words in the correct order for current endianness. 10809 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10810 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10811 address = address+8; 10812 #endif 10813 10814 bool success = false; 10815 10816 if (ConditionPassed (opcode)) 10817 { 10818 bool single_regs; 10819 bool add; 10820 bool wback; 10821 uint32_t d; 10822 uint32_t n; 10823 uint32_t imm32; 10824 uint32_t regs; 10825 10826 switch (encoding) 10827 { 10828 case eEncodingT1: 10829 case eEncodingA1: 10830 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10831 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10832 // if P == �1� && W == �0� then SEE VSTR; 10833 // if P == U && W == �1� then UNDEFINED; 10834 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10835 return false; 10836 10837 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10838 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10839 single_regs = false; 10840 add = BitIsSet (opcode, 23); 10841 wback = BitIsSet (opcode, 21); 10842 10843 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10844 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10845 n = Bits32 (opcode, 19, 16); 10846 imm32 = Bits32 (opcode, 7, 0) << 2; 10847 10848 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�. 10849 regs = Bits32 (opcode, 7, 0) / 2; 10850 10851 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10852 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10853 return false; 10854 10855 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10856 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10857 return false; 10858 10859 break; 10860 10861 case eEncodingT2: 10862 case eEncodingA2: 10863 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10864 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10865 // if P == �1� && W == �0� then SEE VSTR; 10866 // if P == U && W == �1� then UNDEFINED; 10867 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10868 return false; 10869 10870 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10871 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10872 single_regs = true; 10873 add = BitIsSet (opcode, 23); 10874 wback = BitIsSet (opcode, 21); 10875 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10876 n = Bits32 (opcode, 19, 16); 10877 10878 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10879 imm32 = Bits32 (opcode, 7, 0) << 2; 10880 regs = Bits32 (opcode, 7, 0); 10881 10882 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10883 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 10884 return false; 10885 10886 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10887 if ((regs == 0) || ((d + regs) > 32)) 10888 return false; 10889 10890 break; 10891 10892 default: 10893 return false; 10894 } 10895 10896 RegisterInfo base_reg; 10897 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10898 10899 uint32_t Rn = ReadCoreReg (n, &success); 10900 if (!success) 10901 return false; 10902 10903 // address = if add then R[n] else R[n]-imm32; 10904 addr_t address; 10905 if (add) 10906 address = Rn; 10907 else 10908 address = Rn - imm32; 10909 10910 EmulateInstruction::Context context; 10911 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10912 if (wback) 10913 { 10914 uint32_t value; 10915 if (add) 10916 value = Rn + imm32; 10917 else 10918 value = Rn - imm32; 10919 10920 context.type = eContextAdjustBaseRegister; 10921 context.SetRegisterPlusOffset (base_reg, value - Rn); 10922 10923 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10924 return false; 10925 } 10926 10927 const uint32_t addr_byte_size = GetAddressByteSize(); 10928 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10929 10930 context.type = eContextRegisterStore; 10931 // for r = 0 to regs-1 10932 for (int r = 0; r < regs; ++r) 10933 { 10934 10935 if (single_regs) 10936 { 10937 // MemA[address,4] = S[d+r]; address = address+4; 10938 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10939 if (!success) 10940 return false; 10941 10942 RegisterInfo data_reg; 10943 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10944 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10945 if (!MemAWrite (context, address, data, addr_byte_size)) 10946 return false; 10947 10948 address = address + 4; 10949 } 10950 else 10951 { 10952 // // Store as two word-aligned words in the correct order for current endianness. 10953 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10954 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10955 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10956 if (!success) 10957 return false; 10958 10959 RegisterInfo data_reg; 10960 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10961 10962 if (GetByteOrder() == eByteOrderBig) 10963 { 10964 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10965 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 10966 return false; 10967 10968 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10969 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 10970 return false; 10971 } 10972 else 10973 { 10974 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10975 if (!MemAWrite (context, address, Bits64 (data, 31, 0), 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, 63, 32), addr_byte_size)) 10980 return false; 10981 } 10982 // address = address+8; 10983 address = address + 8; 10984 } 10985 } 10986 } 10987 return true; 10988 } 10989 10990 // A8.6.320 10991 // This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with 10992 // an optional offset. 10993 bool 10994 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 10995 { 10996 #if 0 10997 if ConditionPassed() then 10998 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10999 base = if n == 15 then Align(PC,4) else R[n]; 11000 address = if add then (base + imm32) else (base - imm32); 11001 if single_reg then 11002 S[d] = MemA[address,4]; 11003 else 11004 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11005 // Combine the word-aligned words in the correct order for current endianness. 11006 D[d] = if BigEndian() then word1:word2 else word2:word1; 11007 #endif 11008 11009 bool success = false; 11010 11011 if (ConditionPassed (opcode)) 11012 { 11013 bool single_reg; 11014 bool add; 11015 uint32_t imm32; 11016 uint32_t d; 11017 uint32_t n; 11018 11019 switch (encoding) 11020 { 11021 case eEncodingT1: 11022 case eEncodingA1: 11023 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11024 single_reg = false; 11025 add = BitIsSet (opcode, 23); 11026 imm32 = Bits32 (opcode, 7, 0) << 2; 11027 11028 // d = UInt(D:Vd); n = UInt(Rn); 11029 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11030 n = Bits32 (opcode, 19, 16); 11031 11032 break; 11033 11034 case eEncodingT2: 11035 case eEncodingA2: 11036 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11037 single_reg = true; 11038 add = BitIsSet (opcode, 23); 11039 imm32 = Bits32 (opcode, 7, 0) << 2; 11040 11041 // d = UInt(Vd:D); n = UInt(Rn); 11042 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11043 n = Bits32 (opcode, 19, 16); 11044 11045 break; 11046 11047 default: 11048 return false; 11049 } 11050 RegisterInfo base_reg; 11051 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11052 11053 uint32_t Rn = ReadCoreReg (n, &success); 11054 if (!success) 11055 return false; 11056 11057 // base = if n == 15 then Align(PC,4) else R[n]; 11058 uint32_t base; 11059 if (n == 15) 11060 base = AlignPC (Rn); 11061 else 11062 base = Rn; 11063 11064 // address = if add then (base + imm32) else (base - imm32); 11065 addr_t address; 11066 if (add) 11067 address = base + imm32; 11068 else 11069 address = base - imm32; 11070 11071 const uint32_t addr_byte_size = GetAddressByteSize(); 11072 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11073 11074 EmulateInstruction::Context context; 11075 context.type = eContextRegisterLoad; 11076 context.SetRegisterPlusOffset (base_reg, address - base); 11077 11078 if (single_reg) 11079 { 11080 // S[d] = MemA[address,4]; 11081 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11082 if (!success) 11083 return false; 11084 11085 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11086 return false; 11087 } 11088 else 11089 { 11090 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11091 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11092 if (!success) 11093 return false; 11094 11095 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11096 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11097 if (!success) 11098 return false; 11099 // // Combine the word-aligned words in the correct order for current endianness. 11100 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11101 uint64_t data64; 11102 if (GetByteOrder() == eByteOrderBig) 11103 { 11104 data64 = word1; 11105 data64 = (data64 << 32) | word2; 11106 } 11107 else 11108 { 11109 data64 = word2; 11110 data64 = (data64 << 32) | word1; 11111 } 11112 11113 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11114 return false; 11115 } 11116 } 11117 return true; 11118 } 11119 11120 // A8.6.400 VSTR 11121 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11122 // optional offset. 11123 bool 11124 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11125 { 11126 #if 0 11127 if ConditionPassed() then 11128 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11129 address = if add then (R[n] + imm32) else (R[n] - imm32); 11130 if single_reg then 11131 MemA[address,4] = S[d]; 11132 else 11133 // Store as two word-aligned words in the correct order for current endianness. 11134 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11135 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11136 #endif 11137 11138 bool success = false; 11139 11140 if (ConditionPassed (opcode)) 11141 { 11142 bool single_reg; 11143 bool add; 11144 uint32_t imm32; 11145 uint32_t d; 11146 uint32_t n; 11147 11148 switch (encoding) 11149 { 11150 case eEncodingT1: 11151 case eEncodingA1: 11152 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11153 single_reg = false; 11154 add = BitIsSet (opcode, 23); 11155 imm32 = Bits32 (opcode, 7, 0) << 2; 11156 11157 // d = UInt(D:Vd); n = UInt(Rn); 11158 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11159 n = Bits32 (opcode, 19, 16); 11160 11161 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11162 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11163 return false; 11164 11165 break; 11166 11167 case eEncodingT2: 11168 case eEncodingA2: 11169 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11170 single_reg = true; 11171 add = BitIsSet (opcode, 23); 11172 imm32 = Bits32 (opcode, 7, 0) << 2; 11173 11174 // d = UInt(Vd:D); n = UInt(Rn); 11175 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11176 n = Bits32 (opcode, 19, 16); 11177 11178 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11179 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11180 return false; 11181 11182 break; 11183 11184 default: 11185 return false; 11186 } 11187 11188 RegisterInfo base_reg; 11189 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11190 11191 uint32_t Rn = ReadCoreReg (n, &success); 11192 if (!success) 11193 return false; 11194 11195 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11196 addr_t address; 11197 if (add) 11198 address = Rn + imm32; 11199 else 11200 address = Rn - imm32; 11201 11202 const uint32_t addr_byte_size = GetAddressByteSize(); 11203 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11204 11205 RegisterInfo data_reg; 11206 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11207 EmulateInstruction::Context context; 11208 context.type = eContextRegisterStore; 11209 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11210 11211 if (single_reg) 11212 { 11213 // MemA[address,4] = S[d]; 11214 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11215 if (!success) 11216 return false; 11217 11218 if (!MemAWrite (context, address, data, addr_byte_size)) 11219 return false; 11220 } 11221 else 11222 { 11223 // // Store as two word-aligned words in the correct order for current endianness. 11224 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11225 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11226 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11227 if (!success) 11228 return false; 11229 11230 if (GetByteOrder() == eByteOrderBig) 11231 { 11232 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11233 return false; 11234 11235 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11236 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11237 return false; 11238 } 11239 else 11240 { 11241 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11242 return false; 11243 11244 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11245 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11246 return false; 11247 } 11248 } 11249 } 11250 return true; 11251 } 11252 11253 // A8.6.307 VLDI1 (multiple single elements) 11254 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11255 // element of each register is loaded. 11256 bool 11257 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11258 { 11259 #if 0 11260 if ConditionPassed() then 11261 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11262 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11263 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11264 for r = 0 to regs-1 11265 for e = 0 to elements-1 11266 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11267 address = address + ebytes; 11268 #endif 11269 11270 bool success = false; 11271 11272 if (ConditionPassed (opcode)) 11273 { 11274 uint32_t regs; 11275 uint32_t alignment; 11276 uint32_t ebytes; 11277 uint32_t esize; 11278 uint32_t elements; 11279 uint32_t d; 11280 uint32_t n; 11281 uint32_t m; 11282 bool wback; 11283 bool register_index; 11284 11285 switch (encoding) 11286 { 11287 case eEncodingT1: 11288 case eEncodingA1: 11289 { 11290 // case type of 11291 // when �0111� 11292 // regs = 1; if align<1> == �1� then UNDEFINED; 11293 // when �1010� 11294 // regs = 2; if align == �11� then UNDEFINED; 11295 // when �0110� 11296 // regs = 3; if align<1> == �1� then UNDEFINED; 11297 // when �0010� 11298 // regs = 4; 11299 // otherwise 11300 // SEE �Related encodings�; 11301 uint32_t type = Bits32 (opcode, 11, 8); 11302 uint32_t align = Bits32 (opcode, 5, 4); 11303 if (type == 7) // '0111' 11304 { 11305 regs = 1; 11306 if (BitIsSet (align, 1)) 11307 return false; 11308 } 11309 else if (type == 10) // '1010' 11310 { 11311 regs = 2; 11312 if (align == 3) 11313 return false; 11314 11315 } 11316 else if (type == 6) // '0110' 11317 { 11318 regs = 3; 11319 if (BitIsSet (align, 1)) 11320 return false; 11321 } 11322 else if (type == 2) // '0010' 11323 { 11324 regs = 4; 11325 } 11326 else 11327 return false; 11328 11329 // alignment = if align == �00� then 1 else 4 << UInt(align); 11330 if (align == 0) 11331 alignment = 1; 11332 else 11333 alignment = 4 << align; 11334 11335 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11336 ebytes = 1 << Bits32 (opcode, 7, 6); 11337 esize = 8 * ebytes; 11338 elements = 8 / ebytes; 11339 11340 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11341 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11342 n = Bits32 (opcode, 19, 15); 11343 m = Bits32 (opcode, 3, 0); 11344 11345 // wback = (m != 15); register_index = (m != 15 && m != 13); 11346 wback = (m != 15); 11347 register_index = ((m != 15) && (m != 13)); 11348 11349 // if d+regs > 32 then UNPREDICTABLE; 11350 if ((d + regs) > 32) 11351 return false; 11352 } 11353 break; 11354 11355 default: 11356 return false; 11357 } 11358 11359 RegisterInfo base_reg; 11360 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11361 11362 uint32_t Rn = ReadCoreReg (n, &success); 11363 if (!success) 11364 return false; 11365 11366 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11367 addr_t address = Rn; 11368 if ((address % alignment) != 0) 11369 return false; 11370 11371 EmulateInstruction::Context context; 11372 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11373 if (wback) 11374 { 11375 uint32_t Rm = ReadCoreReg (m, &success); 11376 if (!success) 11377 return false; 11378 11379 uint32_t offset; 11380 if (register_index) 11381 offset = Rm; 11382 else 11383 offset = 8 * regs; 11384 11385 uint32_t value = Rn + offset; 11386 context.type = eContextAdjustBaseRegister; 11387 context.SetRegisterPlusOffset (base_reg, offset); 11388 11389 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11390 return false; 11391 11392 } 11393 11394 // for r = 0 to regs-1 11395 for (int r = 0; r < regs; ++r) 11396 { 11397 // for e = 0 to elements-1 11398 uint64_t assembled_data = 0; 11399 for (int e = 0; e < elements; ++e) 11400 { 11401 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11402 context.type = eContextRegisterLoad; 11403 context.SetRegisterPlusOffset (base_reg, address - Rn); 11404 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11405 if (!success) 11406 return false; 11407 11408 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11409 11410 // address = address + ebytes; 11411 address = address + ebytes; 11412 } 11413 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11414 return false; 11415 } 11416 } 11417 return true; 11418 } 11419 11420 // A8.6.308 VLD1 (single element to one lane) 11421 // 11422 bool 11423 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11424 { 11425 #if 0 11426 if ConditionPassed() then 11427 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11428 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11429 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11430 Elem[D[d],index,esize] = MemU[address,ebytes]; 11431 #endif 11432 11433 bool success = false; 11434 11435 if (ConditionPassed (opcode)) 11436 { 11437 uint32_t ebytes; 11438 uint32_t esize; 11439 uint32_t index; 11440 uint32_t alignment; 11441 uint32_t d; 11442 uint32_t n; 11443 uint32_t m; 11444 bool wback; 11445 bool register_index; 11446 11447 switch (encoding) 11448 { 11449 case eEncodingT1: 11450 case eEncodingA1: 11451 { 11452 uint32_t size = Bits32 (opcode, 11, 10); 11453 uint32_t index_align = Bits32 (opcode, 7, 4); 11454 // if size == �11� then SEE VLD1 (single element to all lanes); 11455 if (size == 3) 11456 return EmulateVLD1SingleAll (opcode, encoding); 11457 // case size of 11458 if (size == 0) // when '00' 11459 { 11460 // if index_align<0> != �0� then UNDEFINED; 11461 if (BitIsClear (index_align, 0)) 11462 return false; 11463 11464 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11465 ebytes = 1; 11466 esize = 8; 11467 index = Bits32 (index_align, 3, 1); 11468 alignment = 1; 11469 } 11470 else if (size == 1) // when �01� 11471 { 11472 // if index_align<1> != �0� then UNDEFINED; 11473 if (BitIsClear (index_align, 1)) 11474 return false; 11475 11476 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11477 ebytes = 2; 11478 esize = 16; 11479 index = Bits32 (index_align, 3, 2); 11480 11481 // alignment = if index_align<0> == �0� then 1 else 2; 11482 if (BitIsClear (index_align, 0)) 11483 alignment = 1; 11484 else 11485 alignment = 2; 11486 } 11487 else if (size == 2) // when �10� 11488 { 11489 // if index_align<2> != �0� then UNDEFINED; 11490 if (BitIsClear (index_align, 2)) 11491 return false; 11492 11493 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11494 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11495 return false; 11496 11497 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11498 ebytes = 4; 11499 esize = 32; 11500 index = Bit32 (index_align, 3); 11501 11502 // alignment = if index_align<1:0> == �00� then 1 else 4; 11503 if (Bits32 (index_align, 1, 0) == 0) 11504 alignment = 1; 11505 else 11506 alignment = 4; 11507 } 11508 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11509 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11510 n = Bits32 (opcode, 19, 16); 11511 m = Bits32 (opcode, 3, 0); 11512 11513 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11514 wback = (m != 15); 11515 register_index = ((m != 15) && (m != 13)); 11516 11517 if (n == 15) 11518 return false; 11519 11520 } 11521 break; 11522 11523 default: 11524 return false; 11525 } 11526 11527 RegisterInfo base_reg; 11528 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11529 11530 uint32_t Rn = ReadCoreReg (n, &success); 11531 if (!success) 11532 return false; 11533 11534 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11535 addr_t address = Rn; 11536 if ((address % alignment) != 0) 11537 return false; 11538 11539 EmulateInstruction::Context context; 11540 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11541 if (wback) 11542 { 11543 uint32_t Rm = ReadCoreReg (m, &success); 11544 if (!success) 11545 return false; 11546 11547 uint32_t offset; 11548 if (register_index) 11549 offset = Rm; 11550 else 11551 offset = ebytes; 11552 11553 uint32_t value = Rn + offset; 11554 11555 context.type = eContextAdjustBaseRegister; 11556 context.SetRegisterPlusOffset (base_reg, offset); 11557 11558 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11559 return false; 11560 } 11561 11562 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11563 uint32_t element = MemURead (context, address, esize, 0, &success); 11564 if (!success) 11565 return false; 11566 11567 element = element << (index * esize); 11568 11569 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11570 if (!success) 11571 return false; 11572 11573 uint64_t all_ones = -1; 11574 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11575 // at element & to the right of element. 11576 if (index > 0) 11577 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11578 // now mask should be 0's where element goes & 1's 11579 // everywhere else. 11580 11581 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11582 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11583 11584 context.type = eContextRegisterLoad; 11585 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11586 return false; 11587 } 11588 return true; 11589 } 11590 11591 // A8.6.391 VST1 (multiple single elements) 11592 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without 11593 // interleaving. Every element of each register is stored. 11594 bool 11595 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11596 { 11597 #if 0 11598 if ConditionPassed() then 11599 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11600 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11601 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11602 for r = 0 to regs-1 11603 for e = 0 to elements-1 11604 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11605 address = address + ebytes; 11606 #endif 11607 11608 bool success = false; 11609 11610 if (ConditionPassed (opcode)) 11611 { 11612 uint32_t regs; 11613 uint32_t alignment; 11614 uint32_t ebytes; 11615 uint32_t esize; 11616 uint32_t elements; 11617 uint32_t d; 11618 uint32_t n; 11619 uint32_t m; 11620 bool wback; 11621 bool register_index; 11622 11623 switch (encoding) 11624 { 11625 case eEncodingT1: 11626 case eEncodingA1: 11627 { 11628 uint32_t type = Bits32 (opcode, 11, 8); 11629 uint32_t align = Bits32 (opcode, 5, 4); 11630 11631 // case type of 11632 if (type == 7) // when �0111� 11633 { 11634 // regs = 1; if align<1> == �1� then UNDEFINED; 11635 regs = 1; 11636 if (BitIsSet (align, 1)) 11637 return false; 11638 } 11639 else if (type == 10) // when �1010� 11640 { 11641 // regs = 2; if align == �11� then UNDEFINED; 11642 regs = 2; 11643 if (align == 3) 11644 return false; 11645 } 11646 else if (type == 6) // when �0110� 11647 { 11648 // regs = 3; if align<1> == �1� then UNDEFINED; 11649 regs = 3; 11650 if (BitIsSet (align, 1)) 11651 return false; 11652 } 11653 else if (type == 2) // when �0010� 11654 // regs = 4; 11655 regs = 4; 11656 else // otherwise 11657 // SEE �Related encodings�; 11658 return false; 11659 11660 // alignment = if align == �00� then 1 else 4 << UInt(align); 11661 if (align == 0) 11662 alignment = 1; 11663 else 11664 alignment = 4 << align; 11665 11666 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11667 ebytes = 1 << Bits32 (opcode,7, 6); 11668 esize = 8 * ebytes; 11669 elements = 8 / ebytes; 11670 11671 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11672 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11673 n = Bits32 (opcode, 19, 16); 11674 m = Bits32 (opcode, 3, 0); 11675 11676 // wback = (m != 15); register_index = (m != 15 && m != 13); 11677 wback = (m != 15); 11678 register_index = ((m != 15) && (m != 13)); 11679 11680 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11681 if ((d + regs) > 32) 11682 return false; 11683 11684 if (n == 15) 11685 return false; 11686 11687 } 11688 break; 11689 11690 default: 11691 return false; 11692 } 11693 11694 RegisterInfo base_reg; 11695 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11696 11697 uint32_t Rn = ReadCoreReg (n, &success); 11698 if (!success) 11699 return false; 11700 11701 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11702 addr_t address = Rn; 11703 if ((address % alignment) != 0) 11704 return false; 11705 11706 EmulateInstruction::Context context; 11707 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11708 if (wback) 11709 { 11710 uint32_t Rm = ReadCoreReg (m, &success); 11711 if (!success) 11712 return false; 11713 11714 uint32_t offset; 11715 if (register_index) 11716 offset = Rm; 11717 else 11718 offset = 8 * regs; 11719 11720 context.type = eContextAdjustBaseRegister; 11721 context.SetRegisterPlusOffset (base_reg, offset); 11722 11723 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11724 return false; 11725 } 11726 11727 RegisterInfo data_reg; 11728 context.type = eContextRegisterStore; 11729 // for r = 0 to regs-1 11730 for (int r = 0; r < regs; ++r) 11731 { 11732 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11733 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11734 if (!success) 11735 return false; 11736 11737 // for e = 0 to elements-1 11738 for (int e = 0; e < elements; ++e) 11739 { 11740 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11741 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11742 11743 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11744 if (!MemUWrite (context, address, word, ebytes)) 11745 return false; 11746 11747 // address = address + ebytes; 11748 address = address + ebytes; 11749 } 11750 } 11751 } 11752 return true; 11753 } 11754 11755 // A8.6.392 VST1 (single element from one lane) 11756 // This instruction stores one element to memory from one element of a register. 11757 bool 11758 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11759 { 11760 #if 0 11761 if ConditionPassed() then 11762 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11763 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11764 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11765 MemU[address,ebytes] = Elem[D[d],index,esize]; 11766 #endif 11767 11768 bool success = false; 11769 11770 if (ConditionPassed (opcode)) 11771 { 11772 uint32_t ebytes; 11773 uint32_t esize; 11774 uint32_t index; 11775 uint32_t alignment; 11776 uint32_t d; 11777 uint32_t n; 11778 uint32_t m; 11779 bool wback; 11780 bool register_index; 11781 11782 switch (encoding) 11783 { 11784 case eEncodingT1: 11785 case eEncodingA1: 11786 { 11787 uint32_t size = Bits32 (opcode, 11, 10); 11788 uint32_t index_align = Bits32 (opcode, 7, 4); 11789 11790 // if size == �11� then UNDEFINED; 11791 if (size == 3) 11792 return false; 11793 11794 // case size of 11795 if (size == 0) // when �00� 11796 { 11797 // if index_align<0> != �0� then UNDEFINED; 11798 if (BitIsClear (index_align, 0)) 11799 return false; 11800 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11801 ebytes = 1; 11802 esize = 8; 11803 index = Bits32 (index_align, 3, 1); 11804 alignment = 1; 11805 } 11806 else if (size == 1) // when �01� 11807 { 11808 // if index_align<1> != �0� then UNDEFINED; 11809 if (BitIsClear (index_align, 1)) 11810 return false; 11811 11812 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11813 ebytes = 2; 11814 esize = 16; 11815 index = Bits32 (index_align, 3, 2); 11816 11817 // alignment = if index_align<0> == �0� then 1 else 2; 11818 if (BitIsClear (index_align, 0)) 11819 alignment = 1; 11820 else 11821 alignment = 2; 11822 } 11823 else if (size == 2) // when �10� 11824 { 11825 // if index_align<2> != �0� then UNDEFINED; 11826 if (BitIsClear (index_align, 2)) 11827 return false; 11828 11829 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11830 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11831 return false; 11832 11833 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11834 ebytes = 4; 11835 esize = 32; 11836 index = Bit32 (index_align, 3); 11837 11838 // alignment = if index_align<1:0> == �00� then 1 else 4; 11839 if (Bits32 (index_align, 1, 0) == 0) 11840 alignment = 1; 11841 else 11842 alignment = 4; 11843 } 11844 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11845 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11846 n = Bits32 (opcode, 19, 16); 11847 m = Bits32 (opcode, 3, 0); 11848 11849 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11850 wback = (m != 15); 11851 register_index = ((m != 15) && (m != 13)); 11852 11853 if (n == 15) 11854 return false; 11855 } 11856 break; 11857 11858 default: 11859 return false; 11860 } 11861 11862 RegisterInfo base_reg; 11863 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11864 11865 uint32_t Rn = ReadCoreReg (n, &success); 11866 if (!success) 11867 return false; 11868 11869 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11870 addr_t address = Rn; 11871 if ((address % alignment) != 0) 11872 return false; 11873 11874 EmulateInstruction::Context context; 11875 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11876 if (wback) 11877 { 11878 uint32_t Rm = ReadCoreReg (m, &success); 11879 if (!success) 11880 return false; 11881 11882 uint32_t offset; 11883 if (register_index) 11884 offset = Rm; 11885 else 11886 offset = ebytes; 11887 11888 context.type = eContextAdjustBaseRegister; 11889 context.SetRegisterPlusOffset (base_reg, offset); 11890 11891 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11892 return false; 11893 } 11894 11895 // MemU[address,ebytes] = Elem[D[d],index,esize]; 11896 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11897 if (!success) 11898 return false; 11899 11900 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 11901 11902 RegisterInfo data_reg; 11903 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 11904 context.type = eContextRegisterStore; 11905 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11906 11907 if (!MemUWrite (context, address, word, ebytes)) 11908 return false; 11909 } 11910 return true; 11911 } 11912 11913 // A8.6.309 VLD1 (single element to all lanes) 11914 // This instruction loads one element from memory into every element of one or two vectors. 11915 bool 11916 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 11917 { 11918 #if 0 11919 if ConditionPassed() then 11920 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11921 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11922 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11923 replicated_element = Replicate(MemU[address,ebytes], elements); 11924 for r = 0 to regs-1 11925 D[d+r] = replicated_element; 11926 #endif 11927 11928 bool success = false; 11929 11930 if (ConditionPassed (opcode)) 11931 { 11932 uint32_t ebytes; 11933 uint32_t elements; 11934 uint32_t regs; 11935 uint32_t alignment; 11936 uint32_t d; 11937 uint32_t n; 11938 uint32_t m; 11939 bool wback; 11940 bool register_index; 11941 11942 switch (encoding) 11943 { 11944 case eEncodingT1: 11945 case eEncodingA1: 11946 { 11947 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED; 11948 uint32_t size = Bits32 (opcode, 7, 6); 11949 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 11950 return false; 11951 11952 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2; 11953 ebytes = 1 << size; 11954 elements = 8 / ebytes; 11955 if (BitIsClear (opcode, 5)) 11956 regs = 1; 11957 else 11958 regs = 2; 11959 11960 //alignment = if a == �0� then 1 else ebytes; 11961 if (BitIsClear (opcode, 4)) 11962 alignment = 1; 11963 else 11964 alignment = ebytes; 11965 11966 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11967 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11968 n = Bits32 (opcode, 19, 16); 11969 m = Bits32 (opcode, 3, 0); 11970 11971 //wback = (m != 15); register_index = (m != 15 && m != 13); 11972 wback = (m != 15); 11973 register_index = ((m != 15) && (m != 13)); 11974 11975 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11976 if ((d + regs) > 32) 11977 return false; 11978 11979 if (n == 15) 11980 return false; 11981 } 11982 break; 11983 11984 default: 11985 return false; 11986 } 11987 11988 RegisterInfo base_reg; 11989 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11990 11991 uint32_t Rn = ReadCoreReg (n, &success); 11992 if (!success) 11993 return false; 11994 11995 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11996 addr_t address = Rn; 11997 if ((address % alignment) != 0) 11998 return false; 11999 12000 EmulateInstruction::Context context; 12001 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12002 if (wback) 12003 { 12004 uint32_t Rm = ReadCoreReg (m, &success); 12005 if (!success) 12006 return false; 12007 12008 uint32_t offset; 12009 if (register_index) 12010 offset = Rm; 12011 else 12012 offset = ebytes; 12013 12014 context.type = eContextAdjustBaseRegister; 12015 context.SetRegisterPlusOffset (base_reg, offset); 12016 12017 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12018 return false; 12019 } 12020 12021 // replicated_element = Replicate(MemU[address,ebytes], elements); 12022 12023 context.type = eContextRegisterLoad; 12024 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12025 if (!success) 12026 return false; 12027 12028 uint64_t replicated_element = 0; 12029 uint32_t esize = ebytes * 8; 12030 for (int e = 0; e < elements; ++e) 12031 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12032 12033 // for r = 0 to regs-1 12034 for (int r = 0; r < regs; ++r) 12035 { 12036 // D[d+r] = replicated_element; 12037 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12038 return false; 12039 } 12040 } 12041 return true; 12042 } 12043 12044 // B6.2.13 SUBS PC, LR and related instructions 12045 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12046 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12047 bool 12048 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12049 { 12050 #if 0 12051 if ConditionPassed() then 12052 EncodingSpecificOperations(); 12053 if CurrentInstrSet() == InstrSet_ThumbEE then 12054 UNPREDICTABLE; 12055 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12056 case opcode of 12057 when �0000� result = R[n] AND operand2; // AND 12058 when �0001� result = R[n] EOR operand2; // EOR 12059 when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12060 when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12061 when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12062 when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12063 when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12064 when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12065 when �1100� result = R[n] OR operand2; // ORR 12066 when �1101� result = operand2; // MOV 12067 when �1110� result = R[n] AND NOT(operand2); // BIC 12068 when �1111� result = NOT(operand2); // MVN 12069 CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12070 BranchWritePC(result); 12071 #endif 12072 12073 bool success = false; 12074 12075 if (ConditionPassed (opcode)) 12076 { 12077 uint32_t n; 12078 uint32_t m; 12079 uint32_t imm32; 12080 bool register_form; 12081 ARM_ShifterType shift_t; 12082 uint32_t shift_n; 12083 uint32_t code; 12084 12085 switch (encoding) 12086 { 12087 case eEncodingT1: 12088 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12089 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB 12090 n = 14; 12091 imm32 = Bits32 (opcode, 7, 0); 12092 register_form = false; 12093 code = 2; 12094 12095 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12096 if (InITBlock() && !LastInITBlock()) 12097 return false; 12098 12099 break; 12100 12101 case eEncodingA1: 12102 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12103 n = Bits32 (opcode, 19, 16); 12104 imm32 = ARMExpandImm (opcode); 12105 register_form = false; 12106 code = Bits32 (opcode, 24, 21); 12107 12108 break; 12109 12110 case eEncodingA2: 12111 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12112 n = Bits32 (opcode, 19, 16); 12113 m = Bits32 (opcode, 3, 0); 12114 register_form = true; 12115 12116 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12117 shift_n = DecodeImmShiftARM (opcode, shift_t); 12118 12119 break; 12120 12121 default: 12122 return false; 12123 } 12124 12125 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12126 uint32_t operand2; 12127 if (register_form) 12128 { 12129 uint32_t Rm = ReadCoreReg (m, &success); 12130 if (!success) 12131 return false; 12132 12133 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12134 if (!success) 12135 return false; 12136 } 12137 else 12138 { 12139 operand2 = imm32; 12140 } 12141 12142 uint32_t Rn = ReadCoreReg (n, &success); 12143 if (!success) 12144 return false; 12145 12146 AddWithCarryResult result; 12147 12148 // case opcode of 12149 switch (code) 12150 { 12151 case 0: // when �0000� 12152 // result = R[n] AND operand2; // AND 12153 result.result = Rn & operand2; 12154 break; 12155 12156 case 1: // when �0001� 12157 // result = R[n] EOR operand2; // EOR 12158 result.result = Rn ^ operand2; 12159 break; 12160 12161 case 2: // when �0010� 12162 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12163 result = AddWithCarry (Rn, ~(operand2), 1); 12164 break; 12165 12166 case 3: // when �0011� 12167 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12168 result = AddWithCarry (~(Rn), operand2, 1); 12169 break; 12170 12171 case 4: // when �0100� 12172 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12173 result = AddWithCarry (Rn, operand2, 0); 12174 break; 12175 12176 case 5: // when �0101� 12177 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12178 result = AddWithCarry (Rn, operand2, APSR_C); 12179 break; 12180 12181 case 6: // when �0110� 12182 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12183 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12184 break; 12185 12186 case 7: // when �0111� 12187 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12188 result = AddWithCarry (~(Rn), operand2, APSR_C); 12189 break; 12190 12191 case 10: // when �1100� 12192 // result = R[n] OR operand2; // ORR 12193 result.result = Rn | operand2; 12194 break; 12195 12196 case 11: // when �1101� 12197 // result = operand2; // MOV 12198 result.result = operand2; 12199 break; 12200 12201 case 12: // when �1110� 12202 // result = R[n] AND NOT(operand2); // BIC 12203 result.result = Rn & ~(operand2); 12204 break; 12205 12206 case 15: // when �1111� 12207 // result = NOT(operand2); // MVN 12208 result.result = ~(operand2); 12209 break; 12210 12211 default: 12212 return false; 12213 } 12214 // CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12215 12216 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12217 // the best. 12218 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12219 if (!success) 12220 return false; 12221 12222 CPSRWriteByInstr (spsr, 15, true); 12223 12224 // BranchWritePC(result); 12225 EmulateInstruction::Context context; 12226 context.type = eContextAdjustPC; 12227 context.SetImmediate (result.result); 12228 12229 BranchWritePC (context, result.result); 12230 } 12231 return true; 12232 } 12233 12234 EmulateInstructionARM::ARMOpcode* 12235 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12236 { 12237 static ARMOpcode 12238 g_arm_opcodes[] = 12239 { 12240 //---------------------------------------------------------------------- 12241 // Prologue instructions 12242 //---------------------------------------------------------------------- 12243 12244 // push register(s) 12245 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12246 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12247 12248 // set r7 to point to a stack offset 12249 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12250 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12251 // copy the stack pointer to ip 12252 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12253 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12254 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12255 12256 // adjust the stack pointer 12257 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12258 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12259 12260 // push one register 12261 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12262 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12263 12264 // vector push consecutive extension register(s) 12265 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12266 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12267 12268 //---------------------------------------------------------------------- 12269 // Epilogue instructions 12270 //---------------------------------------------------------------------- 12271 12272 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12273 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12274 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12275 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12276 12277 //---------------------------------------------------------------------- 12278 // Supervisor Call (previously Software Interrupt) 12279 //---------------------------------------------------------------------- 12280 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12281 12282 //---------------------------------------------------------------------- 12283 // Branch instructions 12284 //---------------------------------------------------------------------- 12285 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12286 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 12287 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12288 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12289 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12290 // for example, "bx lr" 12291 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12292 // bxj 12293 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12294 12295 //---------------------------------------------------------------------- 12296 // Data-processing instructions 12297 //---------------------------------------------------------------------- 12298 // adc (immediate) 12299 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12300 // adc (register) 12301 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12302 // add (immediate) 12303 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12304 // add (register) 12305 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12306 // add (register-shifted register) 12307 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12308 // adr 12309 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12310 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12311 // and (immediate) 12312 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12313 // and (register) 12314 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12315 // bic (immediate) 12316 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12317 // bic (register) 12318 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12319 // eor (immediate) 12320 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12321 // eor (register) 12322 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12323 // orr (immediate) 12324 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12325 // orr (register) 12326 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12327 // rsb (immediate) 12328 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12329 // rsb (register) 12330 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12331 // rsc (immediate) 12332 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12333 // rsc (register) 12334 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12335 // sbc (immediate) 12336 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12337 // sbc (register) 12338 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12339 // sub (immediate, ARM) 12340 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12341 // sub (sp minus immediate) 12342 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12343 // sub (register) 12344 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12345 // teq (immediate) 12346 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12347 // teq (register) 12348 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12349 // tst (immediate) 12350 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12351 // tst (register) 12352 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12353 12354 // mov (immediate) 12355 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12356 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12357 // mov (register) 12358 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12359 // mvn (immediate) 12360 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12361 // mvn (register) 12362 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12363 // cmn (immediate) 12364 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12365 // cmn (register) 12366 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12367 // cmp (immediate) 12368 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12369 // cmp (register) 12370 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12371 // asr (immediate) 12372 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12373 // asr (register) 12374 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12375 // lsl (immediate) 12376 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12377 // lsl (register) 12378 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12379 // lsr (immediate) 12380 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12381 // lsr (register) 12382 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12383 // rrx is a special case encoding of ror (immediate) 12384 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12385 // ror (immediate) 12386 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12387 // ror (register) 12388 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12389 // mul 12390 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12391 12392 // subs pc, lr and related instructions 12393 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12394 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12395 12396 //---------------------------------------------------------------------- 12397 // Load instructions 12398 //---------------------------------------------------------------------- 12399 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12400 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12401 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12402 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12403 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12404 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12405 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12406 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12407 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12408 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12409 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12410 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12411 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12412 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12413 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12414 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12415 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12416 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12417 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12418 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12419 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12420 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12421 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12422 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12423 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12424 12425 //---------------------------------------------------------------------- 12426 // Store instructions 12427 //---------------------------------------------------------------------- 12428 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12429 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12430 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12431 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12432 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12433 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12434 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12435 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12436 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12437 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12438 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12439 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12440 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12441 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12442 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12443 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12444 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12445 12446 //---------------------------------------------------------------------- 12447 // Other instructions 12448 //---------------------------------------------------------------------- 12449 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12450 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12451 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12452 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12453 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12454 12455 }; 12456 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 12457 12458 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12459 { 12460 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12461 (g_arm_opcodes[i].variants & arm_isa) != 0) 12462 return &g_arm_opcodes[i]; 12463 } 12464 return NULL; 12465 } 12466 12467 12468 EmulateInstructionARM::ARMOpcode* 12469 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12470 { 12471 12472 static ARMOpcode 12473 g_thumb_opcodes[] = 12474 { 12475 //---------------------------------------------------------------------- 12476 // Prologue instructions 12477 //---------------------------------------------------------------------- 12478 12479 // push register(s) 12480 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12481 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12482 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12483 12484 // set r7 to point to a stack offset 12485 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12486 // copy the stack pointer to r7 12487 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12488 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12489 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12490 12491 // PC-relative load into register (see also EmulateADDSPRm) 12492 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12493 12494 // adjust the stack pointer 12495 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12496 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12497 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12498 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12499 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12500 12501 // vector push consecutive extension register(s) 12502 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12503 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12504 12505 //---------------------------------------------------------------------- 12506 // Epilogue instructions 12507 //---------------------------------------------------------------------- 12508 12509 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12510 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12511 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12512 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12513 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12514 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12515 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12516 12517 //---------------------------------------------------------------------- 12518 // Supervisor Call (previously Software Interrupt) 12519 //---------------------------------------------------------------------- 12520 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12521 12522 //---------------------------------------------------------------------- 12523 // If Then makes up to four following instructions conditional. 12524 //---------------------------------------------------------------------- 12525 // The next 5 opcode _must_ come before the if then instruction 12526 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12527 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12528 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12529 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12530 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12531 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12532 12533 //---------------------------------------------------------------------- 12534 // Branch instructions 12535 //---------------------------------------------------------------------- 12536 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12537 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12538 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12539 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12540 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12541 // J1 == J2 == 1 12542 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12543 // J1 == J2 == 1 12544 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12545 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12546 // for example, "bx lr" 12547 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12548 // bxj 12549 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12550 // compare and branch 12551 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12552 // table branch byte 12553 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12554 // table branch halfword 12555 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12556 12557 //---------------------------------------------------------------------- 12558 // Data-processing instructions 12559 //---------------------------------------------------------------------- 12560 // adc (immediate) 12561 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12562 // adc (register) 12563 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12564 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12565 // add (register) 12566 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12567 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12568 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12569 // adr 12570 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12571 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12572 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12573 // and (immediate) 12574 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12575 // and (register) 12576 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12577 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12578 // bic (immediate) 12579 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12580 // bic (register) 12581 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12582 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12583 // eor (immediate) 12584 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12585 // eor (register) 12586 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12587 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12588 // orr (immediate) 12589 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12590 // orr (register) 12591 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12592 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12593 // rsb (immediate) 12594 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12595 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12596 // rsb (register) 12597 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12598 // sbc (immediate) 12599 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12600 // sbc (register) 12601 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12602 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12603 // add (immediate, Thumb) 12604 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12605 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12606 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12607 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12608 // sub (immediate, Thumb) 12609 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12610 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12611 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12612 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12613 // sub (sp minus immediate) 12614 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12615 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12616 // sub (register) 12617 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12618 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12619 // teq (immediate) 12620 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12621 // teq (register) 12622 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12623 // tst (immediate) 12624 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12625 // tst (register) 12626 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12627 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12628 12629 12630 // move from high register to high register 12631 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12632 // move from low register to low register 12633 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12634 // mov{s}<c>.w <Rd>, <Rm> 12635 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12636 // move immediate 12637 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12638 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12639 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12640 // mvn (immediate) 12641 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12642 // mvn (register) 12643 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12644 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12645 // cmn (immediate) 12646 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12647 // cmn (register) 12648 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12649 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12650 // cmp (immediate) 12651 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12652 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12653 // cmp (register) (Rn and Rm both from r0-r7) 12654 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12655 // cmp (register) (Rn and Rm not both from r0-r7) 12656 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12657 // asr (immediate) 12658 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12659 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12660 // asr (register) 12661 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12662 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12663 // lsl (immediate) 12664 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12665 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12666 // lsl (register) 12667 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12668 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12669 // lsr (immediate) 12670 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12671 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12672 // lsr (register) 12673 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12674 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12675 // rrx is a special case encoding of ror (immediate) 12676 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12677 // ror (immediate) 12678 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12679 // ror (register) 12680 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12681 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12682 // mul 12683 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12684 // mul 12685 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12686 12687 // subs pc, lr and related instructions 12688 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12689 12690 //---------------------------------------------------------------------- 12691 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12692 // otherwise the wrong instructions will be selected. 12693 //---------------------------------------------------------------------- 12694 12695 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12696 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12697 12698 //---------------------------------------------------------------------- 12699 // Load instructions 12700 //---------------------------------------------------------------------- 12701 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12702 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12703 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12704 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12705 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12706 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12707 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12708 // Thumb2 PC-relative load into register 12709 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12710 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12711 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12712 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12713 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12714 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12715 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12716 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12717 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12718 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12719 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12720 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12721 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12722 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12723 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12724 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12725 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12726 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12727 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12728 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12729 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12730 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12731 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12732 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12733 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12734 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12735 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12736 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12737 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12738 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12739 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12740 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12741 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12742 12743 //---------------------------------------------------------------------- 12744 // Store instructions 12745 //---------------------------------------------------------------------- 12746 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12747 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12748 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12749 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12750 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12751 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12752 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12753 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12754 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12755 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12756 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12757 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12758 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12759 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12760 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12761 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12762 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12763 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12764 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12765 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12766 { 0xffb00000, 0xfa000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12767 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12768 12769 //---------------------------------------------------------------------- 12770 // Other instructions 12771 //---------------------------------------------------------------------- 12772 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12773 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12774 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12775 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12776 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12777 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12778 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12779 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12780 }; 12781 12782 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 12783 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12784 { 12785 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12786 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12787 return &g_thumb_opcodes[i]; 12788 } 12789 return NULL; 12790 } 12791 12792 bool 12793 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12794 { 12795 m_arch = arch; 12796 m_arm_isa = 0; 12797 const char *arch_cstr = arch.GetArchitectureName (); 12798 if (arch_cstr) 12799 { 12800 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12801 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12802 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12803 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12804 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12805 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12806 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12807 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12808 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12809 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12810 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12811 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12812 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12813 } 12814 return m_arm_isa != 0; 12815 } 12816 12817 bool 12818 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12819 { 12820 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12821 { 12822 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12823 m_opcode_mode = eModeThumb; 12824 else 12825 { 12826 AddressClass addr_class = inst_addr.GetAddressClass(); 12827 12828 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 12829 m_opcode_mode = eModeARM; 12830 else if (addr_class == eAddressClassCodeAlternateISA) 12831 m_opcode_mode = eModeThumb; 12832 else 12833 return false; 12834 } 12835 if (m_opcode_mode == eModeThumb) 12836 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 12837 else 12838 m_opcode_cpsr = CPSR_MODE_USR; 12839 return true; 12840 } 12841 return false; 12842 } 12843 12844 bool 12845 EmulateInstructionARM::ReadInstruction () 12846 { 12847 bool success = false; 12848 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 12849 if (success) 12850 { 12851 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 12852 if (success) 12853 { 12854 Context read_inst_context; 12855 read_inst_context.type = eContextReadOpcode; 12856 read_inst_context.SetNoArgs (); 12857 12858 if (m_opcode_cpsr & MASK_CPSR_T) 12859 { 12860 m_opcode_mode = eModeThumb; 12861 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 12862 12863 if (success) 12864 { 12865 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 12866 { 12867 m_opcode.SetOpcode16 (thumb_opcode); 12868 } 12869 else 12870 { 12871 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success)); 12872 } 12873 } 12874 } 12875 else 12876 { 12877 m_opcode_mode = eModeARM; 12878 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success)); 12879 } 12880 } 12881 } 12882 if (!success) 12883 { 12884 m_opcode_mode = eModeInvalid; 12885 m_addr = LLDB_INVALID_ADDRESS; 12886 } 12887 return success; 12888 } 12889 12890 uint32_t 12891 EmulateInstructionARM::ArchVersion () 12892 { 12893 return m_arm_isa; 12894 } 12895 12896 bool 12897 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) 12898 { 12899 // If we are ignoring conditions, then always return true. 12900 // this allows us to iterate over disassembly code and still 12901 // emulate an instruction even if we don't have all the right 12902 // bits set in the CPSR register... 12903 if (m_ignore_conditions) 12904 return true; 12905 12906 if (is_conditional) 12907 *is_conditional = true; 12908 12909 const uint32_t cond = CurrentCond (opcode); 12910 12911 if (cond == UINT32_MAX) 12912 return false; 12913 12914 bool result = false; 12915 switch (UnsignedBits(cond, 3, 1)) 12916 { 12917 case 0: 12918 if (m_opcode_cpsr == 0) 12919 result = true; 12920 else 12921 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 12922 break; 12923 case 1: 12924 if (m_opcode_cpsr == 0) 12925 result = true; 12926 else 12927 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 12928 break; 12929 case 2: 12930 if (m_opcode_cpsr == 0) 12931 result = true; 12932 else 12933 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 12934 break; 12935 case 3: 12936 if (m_opcode_cpsr == 0) 12937 result = true; 12938 else 12939 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 12940 break; 12941 case 4: 12942 if (m_opcode_cpsr == 0) 12943 result = true; 12944 else 12945 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12946 break; 12947 case 5: 12948 if (m_opcode_cpsr == 0) 12949 result = true; 12950 else 12951 { 12952 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12953 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12954 result = n == v; 12955 } 12956 break; 12957 case 6: 12958 if (m_opcode_cpsr == 0) 12959 result = true; 12960 else 12961 { 12962 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12963 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12964 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12965 } 12966 break; 12967 case 7: 12968 // Always execute (cond == 0b1110, or the special 0b1111 which gives 12969 // opcodes different meanings, but always means execution happpens. 12970 if (is_conditional) 12971 *is_conditional = false; 12972 result = true; 12973 break; 12974 } 12975 12976 if (cond & 1) 12977 result = !result; 12978 return result; 12979 } 12980 12981 uint32_t 12982 EmulateInstructionARM::CurrentCond (const uint32_t opcode) 12983 { 12984 switch (m_opcode_mode) 12985 { 12986 default: 12987 case eModeInvalid: 12988 break; 12989 12990 case eModeARM: 12991 return UnsignedBits(opcode, 31, 28); 12992 12993 case eModeThumb: 12994 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 12995 // 'cond' field of the encoding. 12996 { 12997 const uint32_t byte_size = m_opcode.GetByteSize(); 12998 if (byte_size == 2) 12999 { 13000 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 13001 return Bits32(opcode, 11, 7); 13002 } 13003 else if (byte_size == 4) 13004 { 13005 if (Bits32(opcode, 31, 27) == 0x1e && 13006 Bits32(opcode, 15, 14) == 0x02 && 13007 Bits32(opcode, 12, 12) == 0x00 && 13008 Bits32(opcode, 25, 22) <= 0x0d) 13009 { 13010 return Bits32(opcode, 25, 22); 13011 } 13012 } 13013 else 13014 // We have an invalid thumb instruction, let's bail out. 13015 break; 13016 13017 return m_it_session.GetCond(); 13018 } 13019 } 13020 return UINT32_MAX; // Return invalid value 13021 } 13022 13023 bool 13024 EmulateInstructionARM::InITBlock() 13025 { 13026 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13027 } 13028 13029 bool 13030 EmulateInstructionARM::LastInITBlock() 13031 { 13032 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13033 } 13034 13035 bool 13036 EmulateInstructionARM::BadMode (uint32_t mode) 13037 { 13038 13039 switch (mode) 13040 { 13041 case 16: return false; // '10000' 13042 case 17: return false; // '10001' 13043 case 18: return false; // '10010' 13044 case 19: return false; // '10011' 13045 case 22: return false; // '10110' 13046 case 23: return false; // '10111' 13047 case 27: return false; // '11011' 13048 case 31: return false; // '11111' 13049 default: return true; 13050 } 13051 return true; 13052 } 13053 13054 bool 13055 EmulateInstructionARM::CurrentModeIsPrivileged () 13056 { 13057 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13058 13059 if (BadMode (mode)) 13060 return false; 13061 13062 if (mode == 16) 13063 return false; 13064 13065 return true; 13066 } 13067 13068 void 13069 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13070 { 13071 bool privileged = CurrentModeIsPrivileged(); 13072 13073 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13074 13075 if (BitIsSet (bytemask, 3)) 13076 { 13077 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13078 if (affect_execstate) 13079 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13080 } 13081 13082 if (BitIsSet (bytemask, 2)) 13083 { 13084 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13085 } 13086 13087 if (BitIsSet (bytemask, 1)) 13088 { 13089 if (affect_execstate) 13090 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13091 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13092 if (privileged) 13093 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13094 } 13095 13096 if (BitIsSet (bytemask, 0)) 13097 { 13098 if (privileged) 13099 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13100 if (affect_execstate) 13101 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13102 if (privileged) 13103 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13104 } 13105 13106 m_opcode_cpsr = tmp_cpsr; 13107 } 13108 13109 13110 bool 13111 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13112 { 13113 addr_t target; 13114 13115 // Check the current instruction set. 13116 if (CurrentInstrSet() == eModeARM) 13117 target = addr & 0xfffffffc; 13118 else 13119 target = addr & 0xfffffffe; 13120 13121 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13122 return false; 13123 13124 return true; 13125 } 13126 13127 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13128 bool 13129 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13130 { 13131 addr_t target; 13132 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13133 // we want to record it and issue a WriteRegister callback so the clients 13134 // can track the mode changes accordingly. 13135 bool cpsr_changed = false; 13136 13137 if (BitIsSet(addr, 0)) 13138 { 13139 if (CurrentInstrSet() != eModeThumb) 13140 { 13141 SelectInstrSet(eModeThumb); 13142 cpsr_changed = true; 13143 } 13144 target = addr & 0xfffffffe; 13145 context.SetISA (eModeThumb); 13146 } 13147 else if (BitIsClear(addr, 1)) 13148 { 13149 if (CurrentInstrSet() != eModeARM) 13150 { 13151 SelectInstrSet(eModeARM); 13152 cpsr_changed = true; 13153 } 13154 target = addr & 0xfffffffc; 13155 context.SetISA (eModeARM); 13156 } 13157 else 13158 return false; // address<1:0> == '10' => UNPREDICTABLE 13159 13160 if (cpsr_changed) 13161 { 13162 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13163 return false; 13164 } 13165 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13166 return false; 13167 13168 return true; 13169 } 13170 13171 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13172 bool 13173 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13174 { 13175 if (ArchVersion() >= ARMv5T) 13176 return BXWritePC(context, addr); 13177 else 13178 return BranchWritePC((const Context)context, addr); 13179 } 13180 13181 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13182 bool 13183 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13184 { 13185 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13186 return BXWritePC(context, addr); 13187 else 13188 return BranchWritePC((const Context)context, addr); 13189 } 13190 13191 EmulateInstructionARM::Mode 13192 EmulateInstructionARM::CurrentInstrSet () 13193 { 13194 return m_opcode_mode; 13195 } 13196 13197 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13198 // ReadInstruction() is performed. This function has a side effect of updating 13199 // the m_new_inst_cpsr member variable if necessary. 13200 bool 13201 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13202 { 13203 m_new_inst_cpsr = m_opcode_cpsr; 13204 switch (arm_or_thumb) 13205 { 13206 default: 13207 return false; 13208 case eModeARM: 13209 // Clear the T bit. 13210 m_new_inst_cpsr &= ~MASK_CPSR_T; 13211 break; 13212 case eModeThumb: 13213 // Set the T bit. 13214 m_new_inst_cpsr |= MASK_CPSR_T; 13215 break; 13216 } 13217 return true; 13218 } 13219 13220 // This function returns TRUE if the processor currently provides support for 13221 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13222 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13223 bool 13224 EmulateInstructionARM::UnalignedSupport() 13225 { 13226 return (ArchVersion() >= ARMv7); 13227 } 13228 13229 // The main addition and subtraction instructions can produce status information 13230 // about both unsigned carry and signed overflow conditions. This status 13231 // information can be used to synthesize multi-word additions and subtractions. 13232 EmulateInstructionARM::AddWithCarryResult 13233 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13234 { 13235 uint32_t result; 13236 uint8_t carry_out; 13237 uint8_t overflow; 13238 13239 uint64_t unsigned_sum = x + y + carry_in; 13240 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13241 13242 result = UnsignedBits(unsigned_sum, 31, 0); 13243 // carry_out = (result == unsigned_sum ? 0 : 1); 13244 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13245 13246 if (carry_in) 13247 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13248 else 13249 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13250 13251 AddWithCarryResult res = { result, carry_out, overflow }; 13252 return res; 13253 } 13254 13255 uint32_t 13256 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13257 { 13258 uint32_t reg_kind, reg_num; 13259 switch (num) 13260 { 13261 case SP_REG: 13262 reg_kind = eRegisterKindGeneric; 13263 reg_num = LLDB_REGNUM_GENERIC_SP; 13264 break; 13265 case LR_REG: 13266 reg_kind = eRegisterKindGeneric; 13267 reg_num = LLDB_REGNUM_GENERIC_RA; 13268 break; 13269 case PC_REG: 13270 reg_kind = eRegisterKindGeneric; 13271 reg_num = LLDB_REGNUM_GENERIC_PC; 13272 break; 13273 default: 13274 if (num < SP_REG) 13275 { 13276 reg_kind = eRegisterKindDWARF; 13277 reg_num = dwarf_r0 + num; 13278 } 13279 else 13280 { 13281 //assert(0 && "Invalid register number"); 13282 *success = false; 13283 return UINT32_MAX; 13284 } 13285 break; 13286 } 13287 13288 // Read our register. 13289 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13290 13291 // When executing an ARM instruction , PC reads as the address of the current 13292 // instruction plus 8. 13293 // When executing a Thumb instruction , PC reads as the address of the current 13294 // instruction plus 4. 13295 if (num == 15) 13296 { 13297 if (CurrentInstrSet() == eModeARM) 13298 val += 8; 13299 else 13300 val += 4; 13301 } 13302 13303 return val; 13304 } 13305 13306 // Write the result to the ARM core register Rd, and optionally update the 13307 // condition flags based on the result. 13308 // 13309 // This helper method tries to encapsulate the following pseudocode from the 13310 // ARM Architecture Reference Manual: 13311 // 13312 // if d == 15 then // Can only occur for encoding A1 13313 // ALUWritePC(result); // setflags is always FALSE here 13314 // else 13315 // R[d] = result; 13316 // if setflags then 13317 // APSR.N = result<31>; 13318 // APSR.Z = IsZeroBit(result); 13319 // APSR.C = carry; 13320 // // APSR.V unchanged 13321 // 13322 // In the above case, the API client does not pass in the overflow arg, which 13323 // defaults to ~0u. 13324 bool 13325 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13326 const uint32_t result, 13327 const uint32_t Rd, 13328 bool setflags, 13329 const uint32_t carry, 13330 const uint32_t overflow) 13331 { 13332 if (Rd == 15) 13333 { 13334 if (!ALUWritePC (context, result)) 13335 return false; 13336 } 13337 else 13338 { 13339 uint32_t reg_kind, reg_num; 13340 switch (Rd) 13341 { 13342 case SP_REG: 13343 reg_kind = eRegisterKindGeneric; 13344 reg_num = LLDB_REGNUM_GENERIC_SP; 13345 break; 13346 case LR_REG: 13347 reg_kind = eRegisterKindGeneric; 13348 reg_num = LLDB_REGNUM_GENERIC_RA; 13349 break; 13350 default: 13351 reg_kind = eRegisterKindDWARF; 13352 reg_num = dwarf_r0 + Rd; 13353 } 13354 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13355 return false; 13356 if (setflags) 13357 return WriteFlags (context, result, carry, overflow); 13358 } 13359 return true; 13360 } 13361 13362 // This helper method tries to encapsulate the following pseudocode from the 13363 // ARM Architecture Reference Manual: 13364 // 13365 // APSR.N = result<31>; 13366 // APSR.Z = IsZeroBit(result); 13367 // APSR.C = carry; 13368 // APSR.V = overflow 13369 // 13370 // Default arguments can be specified for carry and overflow parameters, which means 13371 // not to update the respective flags. 13372 bool 13373 EmulateInstructionARM::WriteFlags (Context &context, 13374 const uint32_t result, 13375 const uint32_t carry, 13376 const uint32_t overflow) 13377 { 13378 m_new_inst_cpsr = m_opcode_cpsr; 13379 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13380 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13381 if (carry != ~0u) 13382 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13383 if (overflow != ~0u) 13384 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13385 if (m_new_inst_cpsr != m_opcode_cpsr) 13386 { 13387 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13388 return false; 13389 } 13390 return true; 13391 } 13392 13393 bool 13394 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13395 { 13396 // Advance the ITSTATE bits to their values for the next instruction. 13397 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13398 m_it_session.ITAdvance(); 13399 13400 ARMOpcode *opcode_data = NULL; 13401 13402 if (m_opcode_mode == eModeThumb) 13403 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13404 else if (m_opcode_mode == eModeARM) 13405 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13406 13407 if (opcode_data == NULL) 13408 return false; 13409 13410 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13411 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13412 13413 bool success = false; 13414 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13415 { 13416 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13417 dwarf_cpsr, 13418 0, 13419 &success); 13420 } 13421 13422 // Only return false if we are unable to read the CPSR if we care about conditions 13423 if (success == false && m_ignore_conditions == false) 13424 return false; 13425 13426 uint32_t orig_pc_value = 0; 13427 if (auto_advance_pc) 13428 { 13429 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13430 if (!success) 13431 return false; 13432 } 13433 13434 // Call the Emulate... function. 13435 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13436 if (!success) 13437 return false; 13438 13439 if (auto_advance_pc) 13440 { 13441 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13442 if (!success) 13443 return false; 13444 13445 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13446 { 13447 if (opcode_data->size == eSize32) 13448 after_pc_value += 4; 13449 else if (opcode_data->size == eSize16) 13450 after_pc_value += 2; 13451 13452 EmulateInstruction::Context context; 13453 context.type = eContextAdvancePC; 13454 context.SetNoArgs(); 13455 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13456 return false; 13457 13458 } 13459 } 13460 return true; 13461 } 13462 13463 bool 13464 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13465 { 13466 if (!test_data) 13467 { 13468 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13469 return false; 13470 } 13471 13472 static ConstString opcode_key ("opcode"); 13473 static ConstString before_key ("before_state"); 13474 static ConstString after_key ("after_state"); 13475 13476 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13477 13478 uint32_t test_opcode; 13479 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13480 { 13481 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13482 return false; 13483 } 13484 test_opcode = value_sp->GetUInt64Value (); 13485 13486 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13487 { 13488 m_opcode_mode = eModeARM; 13489 m_opcode.SetOpcode32 (test_opcode); 13490 } 13491 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13492 { 13493 m_opcode_mode = eModeThumb; 13494 if (test_opcode < 0x10000) 13495 m_opcode.SetOpcode16 (test_opcode); 13496 else 13497 m_opcode.SetOpcode32 (test_opcode); 13498 13499 } 13500 else 13501 { 13502 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13503 return false; 13504 } 13505 13506 EmulationStateARM before_state; 13507 EmulationStateARM after_state; 13508 13509 value_sp = test_data->GetValueForKey (before_key); 13510 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13511 { 13512 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13513 return false; 13514 } 13515 13516 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13517 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13518 { 13519 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13520 return false; 13521 } 13522 13523 value_sp = test_data->GetValueForKey (after_key); 13524 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13525 { 13526 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13527 return false; 13528 } 13529 13530 state_dictionary = value_sp->GetAsDictionary (); 13531 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13532 { 13533 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13534 return false; 13535 } 13536 13537 SetBaton ((void *) &before_state); 13538 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13539 &EmulationStateARM::WritePseudoMemory, 13540 &EmulationStateARM::ReadPseudoRegister, 13541 &EmulationStateARM::WritePseudoRegister); 13542 13543 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13544 if (!success) 13545 { 13546 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13547 return false; 13548 } 13549 13550 success = before_state.CompareState (after_state); 13551 if (!success) 13552 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13553 13554 return success; 13555 } 13556 // 13557 // 13558 //const char * 13559 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13560 //{ 13561 // if (reg_kind == eRegisterKindGeneric) 13562 // { 13563 // switch (reg_num) 13564 // { 13565 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 13566 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 13567 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 13568 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 13569 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13570 // default: return NULL; 13571 // } 13572 // } 13573 // else if (reg_kind == eRegisterKindDWARF) 13574 // { 13575 // return GetARMDWARFRegisterName (reg_num); 13576 // } 13577 // return NULL; 13578 //} 13579 // 13580 bool 13581 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13582 { 13583 unwind_plan.Clear(); 13584 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13585 13586 UnwindPlan::Row row; 13587 13588 // Our previous Call Frame Address is the stack pointer 13589 row.SetCFARegister (dwarf_sp); 13590 13591 // Our previous PC is in the LR 13592 row.SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true); 13593 unwind_plan.AppendRow (row); 13594 13595 // All other registers are the same. 13596 13597 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13598 return true; 13599 } 13600 13601 13602 13603 13604