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 || m_arch.GetTriple().getOS() == llvm::Triple::Darwin) 284 return 7; 285 else 286 return 11; 287 } 288 289 uint32_t 290 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 291 { 292 if (m_opcode_mode == eModeThumb || m_arch.GetTriple().getOS() == llvm::Triple::Darwin) 293 return dwarf_r7; 294 else 295 return dwarf_r11; 296 } 297 298 // Push Multiple Registers stores multiple registers to the stack, storing to 299 // consecutive memory locations ending just below the address in SP, and updates 300 // SP to point to the start of the stored data. 301 bool 302 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 303 { 304 #if 0 305 // ARM pseudo code... 306 if (ConditionPassed()) 307 { 308 EncodingSpecificOperations(); 309 NullCheckIfThumbEE(13); 310 address = SP - 4*BitCount(registers); 311 312 for (i = 0 to 14) 313 { 314 if (registers<i> == '1') 315 { 316 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 317 MemA[address,4] = bits(32) UNKNOWN; 318 else 319 MemA[address,4] = R[i]; 320 address = address + 4; 321 } 322 } 323 324 if (registers<15> == '1') // Only possible for encoding A1 or A2 325 MemA[address,4] = PCStoreValue(); 326 327 SP = SP - 4*BitCount(registers); 328 } 329 #endif 330 331 bool conditional = false; 332 bool success = false; 333 if (ConditionPassed(opcode, &conditional)) 334 { 335 const uint32_t addr_byte_size = GetAddressByteSize(); 336 const addr_t sp = ReadCoreReg (SP_REG, &success); 337 if (!success) 338 return false; 339 uint32_t registers = 0; 340 uint32_t Rt; // the source register 341 switch (encoding) { 342 case eEncodingT1: 343 registers = Bits32(opcode, 7, 0); 344 // The M bit represents LR. 345 if (Bit32(opcode, 8)) 346 registers |= (1u << 14); 347 // if BitCount(registers) < 1 then UNPREDICTABLE; 348 if (BitCount(registers) < 1) 349 return false; 350 break; 351 case eEncodingT2: 352 // Ignore bits 15 & 13. 353 registers = Bits32(opcode, 15, 0) & ~0xa000; 354 // if BitCount(registers) < 2 then UNPREDICTABLE; 355 if (BitCount(registers) < 2) 356 return false; 357 break; 358 case eEncodingT3: 359 Rt = Bits32(opcode, 15, 12); 360 // if BadReg(t) then UNPREDICTABLE; 361 if (BadReg(Rt)) 362 return false; 363 registers = (1u << Rt); 364 break; 365 case eEncodingA1: 366 registers = Bits32(opcode, 15, 0); 367 // Instead of return false, let's handle the following case as well, 368 // which amounts to pushing one reg onto the full descending stacks. 369 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 370 break; 371 case eEncodingA2: 372 Rt = Bits32(opcode, 15, 12); 373 // if t == 13 then UNPREDICTABLE; 374 if (Rt == dwarf_sp) 375 return false; 376 registers = (1u << Rt); 377 break; 378 default: 379 return false; 380 } 381 addr_t sp_offset = addr_byte_size * BitCount (registers); 382 addr_t addr = sp - sp_offset; 383 uint32_t i; 384 385 EmulateInstruction::Context context; 386 if (conditional) 387 context.type = EmulateInstruction::eContextRegisterStore; 388 else 389 context.type = EmulateInstruction::eContextPushRegisterOnStack; 390 RegisterInfo reg_info; 391 RegisterInfo sp_reg; 392 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 393 for (i=0; i<15; ++i) 394 { 395 if (BitIsSet (registers, i)) 396 { 397 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 398 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 399 uint32_t reg_value = ReadCoreReg(i, &success); 400 if (!success) 401 return false; 402 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 403 return false; 404 addr += addr_byte_size; 405 } 406 } 407 408 if (BitIsSet (registers, 15)) 409 { 410 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 411 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 412 const uint32_t pc = ReadCoreReg(PC_REG, &success); 413 if (!success) 414 return false; 415 if (!MemAWrite (context, addr, pc, addr_byte_size)) 416 return false; 417 } 418 419 context.type = EmulateInstruction::eContextAdjustStackPointer; 420 context.SetImmediateSigned (-sp_offset); 421 422 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 423 return false; 424 } 425 return true; 426 } 427 428 // Pop Multiple Registers loads multiple registers from the stack, loading from 429 // consecutive memory locations staring at the address in SP, and updates 430 // SP to point just above the loaded data. 431 bool 432 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 433 { 434 #if 0 435 // ARM pseudo code... 436 if (ConditionPassed()) 437 { 438 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 439 address = SP; 440 for i = 0 to 14 441 if registers<i> == '1' then 442 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 443 if registers<15> == '1' then 444 if UnalignedAllowed then 445 LoadWritePC(MemU[address,4]); 446 else 447 LoadWritePC(MemA[address,4]); 448 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 449 if registers<13> == '1' then SP = bits(32) UNKNOWN; 450 } 451 #endif 452 453 bool success = false; 454 455 bool conditional = false; 456 if (ConditionPassed(opcode, &conditional)) 457 { 458 const uint32_t addr_byte_size = GetAddressByteSize(); 459 const addr_t sp = ReadCoreReg (SP_REG, &success); 460 if (!success) 461 return false; 462 uint32_t registers = 0; 463 uint32_t Rt; // the destination register 464 switch (encoding) { 465 case eEncodingT1: 466 registers = Bits32(opcode, 7, 0); 467 // The P bit represents PC. 468 if (Bit32(opcode, 8)) 469 registers |= (1u << 15); 470 // if BitCount(registers) < 1 then UNPREDICTABLE; 471 if (BitCount(registers) < 1) 472 return false; 473 break; 474 case eEncodingT2: 475 // Ignore bit 13. 476 registers = Bits32(opcode, 15, 0) & ~0x2000; 477 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 478 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 479 return false; 480 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 481 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 482 return false; 483 break; 484 case eEncodingT3: 485 Rt = Bits32(opcode, 15, 12); 486 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 487 if (Rt == 13) 488 return false; 489 if (Rt == 15 && InITBlock() && !LastInITBlock()) 490 return false; 491 registers = (1u << Rt); 492 break; 493 case eEncodingA1: 494 registers = Bits32(opcode, 15, 0); 495 // Instead of return false, let's handle the following case as well, 496 // which amounts to popping one reg from the full descending stacks. 497 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 498 499 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 500 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 501 return false; 502 break; 503 case eEncodingA2: 504 Rt = Bits32(opcode, 15, 12); 505 // if t == 13 then UNPREDICTABLE; 506 if (Rt == dwarf_sp) 507 return false; 508 registers = (1u << Rt); 509 break; 510 default: 511 return false; 512 } 513 addr_t sp_offset = addr_byte_size * BitCount (registers); 514 addr_t addr = sp; 515 uint32_t i, data; 516 517 EmulateInstruction::Context context; 518 if (conditional) 519 context.type = EmulateInstruction::eContextRegisterLoad; 520 else 521 context.type = EmulateInstruction::eContextPopRegisterOffStack; 522 523 RegisterInfo sp_reg; 524 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 525 526 for (i=0; i<15; ++i) 527 { 528 if (BitIsSet (registers, i)) 529 { 530 context.SetRegisterPlusOffset (sp_reg, addr - sp); 531 data = MemARead(context, addr, 4, 0, &success); 532 if (!success) 533 return false; 534 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 535 return false; 536 addr += addr_byte_size; 537 } 538 } 539 540 if (BitIsSet (registers, 15)) 541 { 542 context.SetRegisterPlusOffset (sp_reg, addr - sp); 543 data = MemARead(context, addr, 4, 0, &success); 544 if (!success) 545 return false; 546 // In ARMv5T and above, this is an interworking branch. 547 if (!LoadWritePC(context, data)) 548 return false; 549 addr += addr_byte_size; 550 } 551 552 context.type = EmulateInstruction::eContextAdjustStackPointer; 553 context.SetImmediateSigned (sp_offset); 554 555 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 556 return false; 557 } 558 return true; 559 } 560 561 // Set r7 or ip to point to saved value residing within the stack. 562 // ADD (SP plus immediate) 563 bool 564 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 565 { 566 #if 0 567 // ARM pseudo code... 568 if (ConditionPassed()) 569 { 570 EncodingSpecificOperations(); 571 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 572 if d == 15 then 573 ALUWritePC(result); // setflags is always FALSE here 574 else 575 R[d] = result; 576 if setflags then 577 APSR.N = result<31>; 578 APSR.Z = IsZeroBit(result); 579 APSR.C = carry; 580 APSR.V = overflow; 581 } 582 #endif 583 584 bool success = false; 585 586 if (ConditionPassed(opcode)) 587 { 588 const addr_t sp = ReadCoreReg (SP_REG, &success); 589 if (!success) 590 return false; 591 uint32_t Rd; // the destination register 592 uint32_t imm32; 593 switch (encoding) { 594 case eEncodingT1: 595 Rd = 7; 596 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 597 break; 598 case eEncodingA1: 599 Rd = Bits32(opcode, 15, 12); 600 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 601 break; 602 default: 603 return false; 604 } 605 addr_t sp_offset = imm32; 606 addr_t addr = sp + sp_offset; // a pointer to the stack area 607 608 EmulateInstruction::Context context; 609 context.type = eContextSetFramePointer; 610 RegisterInfo sp_reg; 611 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 612 context.SetRegisterPlusOffset (sp_reg, sp_offset); 613 614 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 615 return false; 616 } 617 return true; 618 } 619 620 // Set r7 or ip to the current stack pointer. 621 // MOV (register) 622 bool 623 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 624 { 625 #if 0 626 // ARM pseudo code... 627 if (ConditionPassed()) 628 { 629 EncodingSpecificOperations(); 630 result = R[m]; 631 if d == 15 then 632 ALUWritePC(result); // setflags is always FALSE here 633 else 634 R[d] = result; 635 if setflags then 636 APSR.N = result<31>; 637 APSR.Z = IsZeroBit(result); 638 // APSR.C unchanged 639 // APSR.V unchanged 640 } 641 #endif 642 643 bool success = false; 644 645 if (ConditionPassed(opcode)) 646 { 647 const addr_t sp = ReadCoreReg (SP_REG, &success); 648 if (!success) 649 return false; 650 uint32_t Rd; // the destination register 651 switch (encoding) { 652 case eEncodingT1: 653 Rd = 7; 654 break; 655 case eEncodingA1: 656 Rd = 12; 657 break; 658 default: 659 return false; 660 } 661 662 EmulateInstruction::Context context; 663 if (Rd == GetFramePointerRegisterNumber()) 664 context.type = EmulateInstruction::eContextSetFramePointer; 665 else 666 context.type = EmulateInstruction::eContextRegisterPlusOffset; 667 RegisterInfo sp_reg; 668 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 669 context.SetRegisterPlusOffset (sp_reg, 0); 670 671 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 672 return false; 673 } 674 return true; 675 } 676 677 // Move from high register (r8-r15) to low register (r0-r7). 678 // MOV (register) 679 bool 680 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 681 { 682 return EmulateMOVRdRm (opcode, encoding); 683 } 684 685 // Move from register to register. 686 // MOV (register) 687 bool 688 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 689 { 690 #if 0 691 // ARM pseudo code... 692 if (ConditionPassed()) 693 { 694 EncodingSpecificOperations(); 695 result = R[m]; 696 if d == 15 then 697 ALUWritePC(result); // setflags is always FALSE here 698 else 699 R[d] = result; 700 if setflags then 701 APSR.N = result<31>; 702 APSR.Z = IsZeroBit(result); 703 // APSR.C unchanged 704 // APSR.V unchanged 705 } 706 #endif 707 708 bool success = false; 709 710 if (ConditionPassed(opcode)) 711 { 712 uint32_t Rm; // the source register 713 uint32_t Rd; // the destination register 714 bool setflags; 715 switch (encoding) { 716 case eEncodingT1: 717 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 718 Rm = Bits32(opcode, 6, 3); 719 setflags = false; 720 if (Rd == 15 && InITBlock() && !LastInITBlock()) 721 return false; 722 break; 723 case eEncodingT2: 724 Rd = Bits32(opcode, 2, 0); 725 Rm = Bits32(opcode, 5, 3); 726 setflags = true; 727 if (InITBlock()) 728 return false; 729 break; 730 case eEncodingT3: 731 Rd = Bits32(opcode, 11, 8); 732 Rm = Bits32(opcode, 3, 0); 733 setflags = BitIsSet(opcode, 20); 734 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 735 if (setflags && (BadReg(Rd) || BadReg(Rm))) 736 return false; 737 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 738 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 739 return false; 740 break; 741 case eEncodingA1: 742 Rd = Bits32(opcode, 15, 12); 743 Rm = Bits32(opcode, 3, 0); 744 setflags = BitIsSet(opcode, 20); 745 746 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 747 if (Rd == 15 && setflags) 748 return EmulateSUBSPcLrEtc (opcode, encoding); 749 break; 750 default: 751 return false; 752 } 753 uint32_t result = ReadCoreReg(Rm, &success); 754 if (!success) 755 return false; 756 757 // The context specifies that Rm is to be moved into Rd. 758 EmulateInstruction::Context context; 759 context.type = EmulateInstruction::eContextRegisterLoad; 760 RegisterInfo dwarf_reg; 761 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 762 context.SetRegister (dwarf_reg); 763 764 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 765 return false; 766 } 767 return true; 768 } 769 770 // Move (immediate) writes an immediate value to the destination register. It 771 // can optionally update the condition flags based on the value. 772 // MOV (immediate) 773 bool 774 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 775 { 776 #if 0 777 // ARM pseudo code... 778 if (ConditionPassed()) 779 { 780 EncodingSpecificOperations(); 781 result = imm32; 782 if d == 15 then // Can only occur for ARM encoding 783 ALUWritePC(result); // setflags is always FALSE here 784 else 785 R[d] = result; 786 if setflags then 787 APSR.N = result<31>; 788 APSR.Z = IsZeroBit(result); 789 APSR.C = carry; 790 // APSR.V unchanged 791 } 792 #endif 793 794 if (ConditionPassed(opcode)) 795 { 796 uint32_t Rd; // the destination register 797 uint32_t imm32; // the immediate value to be written to Rd 798 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 799 // for setflags == false, this value is a don't care 800 // initialized to 0 to silence the static analyzer 801 bool setflags; 802 switch (encoding) { 803 case eEncodingT1: 804 Rd = Bits32(opcode, 10, 8); 805 setflags = !InITBlock(); 806 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 807 carry = APSR_C; 808 809 break; 810 811 case eEncodingT2: 812 Rd = Bits32(opcode, 11, 8); 813 setflags = BitIsSet(opcode, 20); 814 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 815 if (BadReg(Rd)) 816 return false; 817 818 break; 819 820 case eEncodingT3: 821 { 822 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 823 Rd = Bits32 (opcode, 11, 8); 824 setflags = false; 825 uint32_t imm4 = Bits32 (opcode, 19, 16); 826 uint32_t imm3 = Bits32 (opcode, 14, 12); 827 uint32_t i = Bit32 (opcode, 26); 828 uint32_t imm8 = Bits32 (opcode, 7, 0); 829 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 830 831 // if BadReg(d) then UNPREDICTABLE; 832 if (BadReg (Rd)) 833 return false; 834 } 835 break; 836 837 case eEncodingA1: 838 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 839 Rd = Bits32 (opcode, 15, 12); 840 setflags = BitIsSet (opcode, 20); 841 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 842 843 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 844 if ((Rd == 15) && setflags) 845 return EmulateSUBSPcLrEtc (opcode, encoding); 846 847 break; 848 849 case eEncodingA2: 850 { 851 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 852 Rd = Bits32 (opcode, 15, 12); 853 setflags = false; 854 uint32_t imm4 = Bits32 (opcode, 19, 16); 855 uint32_t imm12 = Bits32 (opcode, 11, 0); 856 imm32 = (imm4 << 12) | imm12; 857 858 // if d == 15 then UNPREDICTABLE; 859 if (Rd == 15) 860 return false; 861 } 862 break; 863 864 default: 865 return false; 866 } 867 uint32_t result = imm32; 868 869 // The context specifies that an immediate is to be moved into Rd. 870 EmulateInstruction::Context context; 871 context.type = EmulateInstruction::eContextImmediate; 872 context.SetNoArgs (); 873 874 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 875 return false; 876 } 877 return true; 878 } 879 880 // MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 881 // register. These 32 bits do not depend on whether the source register values are considered to be signed values or 882 // unsigned values. 883 // 884 // Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 885 // limited to only a few forms of the instruction. 886 bool 887 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 888 { 889 #if 0 890 if ConditionPassed() then 891 EncodingSpecificOperations(); 892 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 893 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 894 result = operand1 * operand2; 895 R[d] = result<31:0>; 896 if setflags then 897 APSR.N = result<31>; 898 APSR.Z = IsZeroBit(result); 899 if ArchVersion() == 4 then 900 APSR.C = bit UNKNOWN; 901 // else APSR.C unchanged 902 // APSR.V always unchanged 903 #endif 904 905 if (ConditionPassed(opcode)) 906 { 907 uint32_t d; 908 uint32_t n; 909 uint32_t m; 910 bool setflags; 911 912 // EncodingSpecificOperations(); 913 switch (encoding) 914 { 915 case eEncodingT1: 916 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 917 d = Bits32 (opcode, 2, 0); 918 n = Bits32 (opcode, 5, 3); 919 m = Bits32 (opcode, 2, 0); 920 setflags = !InITBlock(); 921 922 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 923 if ((ArchVersion() < ARMv6) && (d == n)) 924 return false; 925 926 break; 927 928 case eEncodingT2: 929 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 930 d = Bits32 (opcode, 11, 8); 931 n = Bits32 (opcode, 19, 16); 932 m = Bits32 (opcode, 3, 0); 933 setflags = false; 934 935 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 936 if (BadReg (d) || BadReg (n) || BadReg (m)) 937 return false; 938 939 break; 940 941 case eEncodingA1: 942 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 943 d = Bits32 (opcode, 19, 16); 944 n = Bits32 (opcode, 3, 0); 945 m = Bits32 (opcode, 11, 8); 946 setflags = BitIsSet (opcode, 20); 947 948 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 949 if ((d == 15) || (n == 15) || (m == 15)) 950 return false; 951 952 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 953 if ((ArchVersion() < ARMv6) && (d == n)) 954 return false; 955 956 break; 957 958 default: 959 return false; 960 } 961 962 bool success = false; 963 964 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 965 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 966 if (!success) 967 return false; 968 969 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 970 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 971 if (!success) 972 return false; 973 974 // result = operand1 * operand2; 975 uint64_t result = operand1 * operand2; 976 977 // R[d] = result<31:0>; 978 RegisterInfo op1_reg; 979 RegisterInfo op2_reg; 980 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 981 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 982 983 EmulateInstruction::Context context; 984 context.type = eContextArithmetic; 985 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 986 987 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 988 return false; 989 990 // if setflags then 991 if (setflags) 992 { 993 // APSR.N = result<31>; 994 // APSR.Z = IsZeroBit(result); 995 m_new_inst_cpsr = m_opcode_cpsr; 996 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 997 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 998 if (m_new_inst_cpsr != m_opcode_cpsr) 999 { 1000 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1001 return false; 1002 } 1003 1004 // if ArchVersion() == 4 then 1005 // APSR.C = bit UNKNOWN; 1006 } 1007 } 1008 return true; 1009 } 1010 1011 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1012 // It can optionally update the condition flags based on the value. 1013 bool 1014 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1015 { 1016 #if 0 1017 // ARM pseudo code... 1018 if (ConditionPassed()) 1019 { 1020 EncodingSpecificOperations(); 1021 result = NOT(imm32); 1022 if d == 15 then // Can only occur for ARM encoding 1023 ALUWritePC(result); // setflags is always FALSE here 1024 else 1025 R[d] = result; 1026 if setflags then 1027 APSR.N = result<31>; 1028 APSR.Z = IsZeroBit(result); 1029 APSR.C = carry; 1030 // APSR.V unchanged 1031 } 1032 #endif 1033 1034 if (ConditionPassed(opcode)) 1035 { 1036 uint32_t Rd; // the destination register 1037 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1038 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1039 bool setflags; 1040 switch (encoding) { 1041 case eEncodingT1: 1042 Rd = Bits32(opcode, 11, 8); 1043 setflags = BitIsSet(opcode, 20); 1044 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1045 break; 1046 case eEncodingA1: 1047 Rd = Bits32(opcode, 15, 12); 1048 setflags = BitIsSet(opcode, 20); 1049 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1050 1051 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1052 if (Rd == 15 && setflags) 1053 return EmulateSUBSPcLrEtc (opcode, encoding); 1054 break; 1055 default: 1056 return false; 1057 } 1058 uint32_t result = ~imm32; 1059 1060 // The context specifies that an immediate is to be moved into Rd. 1061 EmulateInstruction::Context context; 1062 context.type = EmulateInstruction::eContextImmediate; 1063 context.SetNoArgs (); 1064 1065 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1066 return false; 1067 } 1068 return true; 1069 } 1070 1071 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1072 // It can optionally update the condition flags based on the result. 1073 bool 1074 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1075 { 1076 #if 0 1077 // ARM pseudo code... 1078 if (ConditionPassed()) 1079 { 1080 EncodingSpecificOperations(); 1081 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1082 result = NOT(shifted); 1083 if d == 15 then // Can only occur for ARM encoding 1084 ALUWritePC(result); // setflags is always FALSE here 1085 else 1086 R[d] = result; 1087 if setflags then 1088 APSR.N = result<31>; 1089 APSR.Z = IsZeroBit(result); 1090 APSR.C = carry; 1091 // APSR.V unchanged 1092 } 1093 #endif 1094 1095 if (ConditionPassed(opcode)) 1096 { 1097 uint32_t Rm; // the source register 1098 uint32_t Rd; // the destination register 1099 ARM_ShifterType shift_t; 1100 uint32_t shift_n; // the shift applied to the value read from Rm 1101 bool setflags; 1102 uint32_t carry; // the carry bit after the shift operation 1103 switch (encoding) { 1104 case eEncodingT1: 1105 Rd = Bits32(opcode, 2, 0); 1106 Rm = Bits32(opcode, 5, 3); 1107 setflags = !InITBlock(); 1108 shift_t = SRType_LSL; 1109 shift_n = 0; 1110 if (InITBlock()) 1111 return false; 1112 break; 1113 case eEncodingT2: 1114 Rd = Bits32(opcode, 11, 8); 1115 Rm = Bits32(opcode, 3, 0); 1116 setflags = BitIsSet(opcode, 20); 1117 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1118 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1119 if (BadReg(Rd) || BadReg(Rm)) 1120 return false; 1121 break; 1122 case eEncodingA1: 1123 Rd = Bits32(opcode, 15, 12); 1124 Rm = Bits32(opcode, 3, 0); 1125 setflags = BitIsSet(opcode, 20); 1126 shift_n = DecodeImmShiftARM(opcode, shift_t); 1127 break; 1128 default: 1129 return false; 1130 } 1131 bool success = false; 1132 uint32_t value = ReadCoreReg(Rm, &success); 1133 if (!success) 1134 return false; 1135 1136 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1137 if (!success) 1138 return false; 1139 uint32_t result = ~shifted; 1140 1141 // The context specifies that an immediate is to be moved into Rd. 1142 EmulateInstruction::Context context; 1143 context.type = EmulateInstruction::eContextImmediate; 1144 context.SetNoArgs (); 1145 1146 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1147 return false; 1148 } 1149 return true; 1150 } 1151 1152 // PC relative immediate load into register, possibly followed by ADD (SP plus register). 1153 // LDR (literal) 1154 bool 1155 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1156 { 1157 #if 0 1158 // ARM pseudo code... 1159 if (ConditionPassed()) 1160 { 1161 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1162 base = Align(PC,4); 1163 address = if add then (base + imm32) else (base - imm32); 1164 data = MemU[address,4]; 1165 if t == 15 then 1166 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1167 elsif UnalignedSupport() || address<1:0> = '00' then 1168 R[t] = data; 1169 else // Can only apply before ARMv7 1170 if CurrentInstrSet() == InstrSet_ARM then 1171 R[t] = ROR(data, 8*UInt(address<1:0>)); 1172 else 1173 R[t] = bits(32) UNKNOWN; 1174 } 1175 #endif 1176 1177 if (ConditionPassed(opcode)) 1178 { 1179 bool success = false; 1180 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1181 if (!success) 1182 return false; 1183 1184 // PC relative immediate load context 1185 EmulateInstruction::Context context; 1186 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1187 RegisterInfo pc_reg; 1188 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1189 context.SetRegisterPlusOffset (pc_reg, 0); 1190 1191 uint32_t Rt; // the destination register 1192 uint32_t imm32; // immediate offset from the PC 1193 bool add; // +imm32 or -imm32? 1194 addr_t base; // the base address 1195 addr_t address; // the PC relative address 1196 uint32_t data; // the literal data value from the PC relative load 1197 switch (encoding) { 1198 case eEncodingT1: 1199 Rt = Bits32(opcode, 10, 8); 1200 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1201 add = true; 1202 break; 1203 case eEncodingT2: 1204 Rt = Bits32(opcode, 15, 12); 1205 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1206 add = BitIsSet(opcode, 23); 1207 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1208 return false; 1209 break; 1210 default: 1211 return false; 1212 } 1213 1214 base = Align(pc, 4); 1215 if (add) 1216 address = base + imm32; 1217 else 1218 address = base - imm32; 1219 1220 context.SetRegisterPlusOffset(pc_reg, address - base); 1221 data = MemURead(context, address, 4, 0, &success); 1222 if (!success) 1223 return false; 1224 1225 if (Rt == 15) 1226 { 1227 if (Bits32(address, 1, 0) == 0) 1228 { 1229 // In ARMv5T and above, this is an interworking branch. 1230 if (!LoadWritePC(context, data)) 1231 return false; 1232 } 1233 else 1234 return false; 1235 } 1236 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1237 { 1238 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1239 return false; 1240 } 1241 else // We don't handle ARM for now. 1242 return false; 1243 1244 } 1245 return true; 1246 } 1247 1248 // An add operation to adjust the SP. 1249 // ADD (SP plus immediate) 1250 bool 1251 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1252 { 1253 #if 0 1254 // ARM pseudo code... 1255 if (ConditionPassed()) 1256 { 1257 EncodingSpecificOperations(); 1258 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1259 if d == 15 then // Can only occur for ARM encoding 1260 ALUWritePC(result); // setflags is always FALSE here 1261 else 1262 R[d] = result; 1263 if setflags then 1264 APSR.N = result<31>; 1265 APSR.Z = IsZeroBit(result); 1266 APSR.C = carry; 1267 APSR.V = overflow; 1268 } 1269 #endif 1270 1271 bool success = false; 1272 1273 if (ConditionPassed(opcode)) 1274 { 1275 const addr_t sp = ReadCoreReg (SP_REG, &success); 1276 if (!success) 1277 return false; 1278 uint32_t imm32; // the immediate operand 1279 uint32_t d; 1280 bool setflags; 1281 switch (encoding) 1282 { 1283 case eEncodingT1: 1284 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1285 d = Bits32 (opcode, 10, 8); 1286 setflags = false; 1287 imm32 = (Bits32 (opcode, 7, 0) << 2); 1288 1289 break; 1290 1291 case eEncodingT2: 1292 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1293 d = 13; 1294 setflags = false; 1295 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1296 1297 break; 1298 1299 default: 1300 return false; 1301 } 1302 addr_t sp_offset = imm32; 1303 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 1304 1305 EmulateInstruction::Context context; 1306 context.type = EmulateInstruction::eContextAdjustStackPointer; 1307 RegisterInfo sp_reg; 1308 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1309 context.SetRegisterPlusOffset (sp_reg, sp_offset); 1310 1311 if (d == 15) 1312 { 1313 if (!ALUWritePC (context, addr)) 1314 return false; 1315 } 1316 else 1317 { 1318 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr)) 1319 return false; 1320 } 1321 } 1322 return true; 1323 } 1324 1325 // An add operation to adjust the SP. 1326 // ADD (SP plus register) 1327 bool 1328 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1329 { 1330 #if 0 1331 // ARM pseudo code... 1332 if (ConditionPassed()) 1333 { 1334 EncodingSpecificOperations(); 1335 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1336 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1337 if d == 15 then 1338 ALUWritePC(result); // setflags is always FALSE here 1339 else 1340 R[d] = result; 1341 if setflags then 1342 APSR.N = result<31>; 1343 APSR.Z = IsZeroBit(result); 1344 APSR.C = carry; 1345 APSR.V = overflow; 1346 } 1347 #endif 1348 1349 bool success = false; 1350 1351 if (ConditionPassed(opcode)) 1352 { 1353 const addr_t sp = ReadCoreReg (SP_REG, &success); 1354 if (!success) 1355 return false; 1356 uint32_t Rm; // the second operand 1357 switch (encoding) { 1358 case eEncodingT2: 1359 Rm = Bits32(opcode, 6, 3); 1360 break; 1361 default: 1362 return false; 1363 } 1364 int32_t reg_value = ReadCoreReg(Rm, &success); 1365 if (!success) 1366 return false; 1367 1368 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1369 1370 EmulateInstruction::Context context; 1371 context.type = eContextArithmetic; 1372 RegisterInfo sp_reg; 1373 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1374 1375 RegisterInfo other_reg; 1376 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1377 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1378 1379 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1380 return false; 1381 } 1382 return true; 1383 } 1384 1385 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1386 // at a PC-relative address, and changes instruction set from ARM to Thumb, or 1387 // from Thumb to ARM. 1388 // BLX (immediate) 1389 bool 1390 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1391 { 1392 #if 0 1393 // ARM pseudo code... 1394 if (ConditionPassed()) 1395 { 1396 EncodingSpecificOperations(); 1397 if CurrentInstrSet() == InstrSet_ARM then 1398 LR = PC - 4; 1399 else 1400 LR = PC<31:1> : '1'; 1401 if targetInstrSet == InstrSet_ARM then 1402 targetAddress = Align(PC,4) + imm32; 1403 else 1404 targetAddress = PC + imm32; 1405 SelectInstrSet(targetInstrSet); 1406 BranchWritePC(targetAddress); 1407 } 1408 #endif 1409 1410 bool success = true; 1411 1412 if (ConditionPassed(opcode)) 1413 { 1414 EmulateInstruction::Context context; 1415 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1416 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1417 if (!success) 1418 return false; 1419 addr_t lr; // next instruction address 1420 addr_t target; // target address 1421 int32_t imm32; // PC-relative offset 1422 switch (encoding) { 1423 case eEncodingT1: 1424 { 1425 lr = pc | 1u; // return address 1426 uint32_t S = Bit32(opcode, 26); 1427 uint32_t imm10 = Bits32(opcode, 25, 16); 1428 uint32_t J1 = Bit32(opcode, 13); 1429 uint32_t J2 = Bit32(opcode, 11); 1430 uint32_t imm11 = Bits32(opcode, 10, 0); 1431 uint32_t I1 = !(J1 ^ S); 1432 uint32_t I2 = !(J2 ^ S); 1433 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1434 imm32 = llvm::SignExtend32<25>(imm25); 1435 target = pc + imm32; 1436 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1437 if (InITBlock() && !LastInITBlock()) 1438 return false; 1439 break; 1440 } 1441 case eEncodingT2: 1442 { 1443 lr = pc | 1u; // return address 1444 uint32_t S = Bit32(opcode, 26); 1445 uint32_t imm10H = Bits32(opcode, 25, 16); 1446 uint32_t J1 = Bit32(opcode, 13); 1447 uint32_t J2 = Bit32(opcode, 11); 1448 uint32_t imm10L = Bits32(opcode, 10, 1); 1449 uint32_t I1 = !(J1 ^ S); 1450 uint32_t I2 = !(J2 ^ S); 1451 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1452 imm32 = llvm::SignExtend32<25>(imm25); 1453 target = Align(pc, 4) + imm32; 1454 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1455 if (InITBlock() && !LastInITBlock()) 1456 return false; 1457 break; 1458 } 1459 case eEncodingA1: 1460 lr = pc - 4; // return address 1461 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1462 target = Align(pc, 4) + imm32; 1463 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1464 break; 1465 case eEncodingA2: 1466 lr = pc - 4; // return address 1467 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1468 target = pc + imm32; 1469 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1470 break; 1471 default: 1472 return false; 1473 } 1474 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1475 return false; 1476 if (!BranchWritePC(context, target)) 1477 return false; 1478 } 1479 return true; 1480 } 1481 1482 // Branch with Link and Exchange (register) calls a subroutine at an address and 1483 // instruction set specified by a register. 1484 // BLX (register) 1485 bool 1486 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1487 { 1488 #if 0 1489 // ARM pseudo code... 1490 if (ConditionPassed()) 1491 { 1492 EncodingSpecificOperations(); 1493 target = R[m]; 1494 if CurrentInstrSet() == InstrSet_ARM then 1495 next_instr_addr = PC - 4; 1496 LR = next_instr_addr; 1497 else 1498 next_instr_addr = PC - 2; 1499 LR = next_instr_addr<31:1> : '1'; 1500 BXWritePC(target); 1501 } 1502 #endif 1503 1504 bool success = false; 1505 1506 if (ConditionPassed(opcode)) 1507 { 1508 EmulateInstruction::Context context; 1509 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1510 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1511 addr_t lr; // next instruction address 1512 if (!success) 1513 return false; 1514 uint32_t Rm; // the register with the target address 1515 switch (encoding) { 1516 case eEncodingT1: 1517 lr = (pc - 2) | 1u; // return address 1518 Rm = Bits32(opcode, 6, 3); 1519 // if m == 15 then UNPREDICTABLE; 1520 if (Rm == 15) 1521 return false; 1522 if (InITBlock() && !LastInITBlock()) 1523 return false; 1524 break; 1525 case eEncodingA1: 1526 lr = pc - 4; // return address 1527 Rm = Bits32(opcode, 3, 0); 1528 // if m == 15 then UNPREDICTABLE; 1529 if (Rm == 15) 1530 return false; 1531 break; 1532 default: 1533 return false; 1534 } 1535 addr_t target = ReadCoreReg (Rm, &success); 1536 if (!success) 1537 return false; 1538 RegisterInfo dwarf_reg; 1539 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1540 context.SetRegister (dwarf_reg); 1541 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1542 return false; 1543 if (!BXWritePC(context, target)) 1544 return false; 1545 } 1546 return true; 1547 } 1548 1549 // Branch and Exchange causes a branch to an address and instruction set specified by a register. 1550 bool 1551 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1552 { 1553 #if 0 1554 // ARM pseudo code... 1555 if (ConditionPassed()) 1556 { 1557 EncodingSpecificOperations(); 1558 BXWritePC(R[m]); 1559 } 1560 #endif 1561 1562 if (ConditionPassed(opcode)) 1563 { 1564 EmulateInstruction::Context context; 1565 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1566 uint32_t Rm; // the register with the target address 1567 switch (encoding) { 1568 case eEncodingT1: 1569 Rm = Bits32(opcode, 6, 3); 1570 if (InITBlock() && !LastInITBlock()) 1571 return false; 1572 break; 1573 case eEncodingA1: 1574 Rm = Bits32(opcode, 3, 0); 1575 break; 1576 default: 1577 return false; 1578 } 1579 bool success = false; 1580 addr_t target = ReadCoreReg (Rm, &success); 1581 if (!success) 1582 return false; 1583 1584 RegisterInfo dwarf_reg; 1585 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1586 context.SetRegister (dwarf_reg); 1587 if (!BXWritePC(context, target)) 1588 return false; 1589 } 1590 return true; 1591 } 1592 1593 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1594 // address and instruction set specified by a register as though it were a BX instruction. 1595 // 1596 // TODO: Emulate Jazelle architecture? 1597 // We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1598 bool 1599 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1600 { 1601 #if 0 1602 // ARM pseudo code... 1603 if (ConditionPassed()) 1604 { 1605 EncodingSpecificOperations(); 1606 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1607 BXWritePC(R[m]); 1608 else 1609 if JazelleAcceptsExecution() then 1610 SwitchToJazelleExecution(); 1611 else 1612 SUBARCHITECTURE_DEFINED handler call; 1613 } 1614 #endif 1615 1616 if (ConditionPassed(opcode)) 1617 { 1618 EmulateInstruction::Context context; 1619 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1620 uint32_t Rm; // the register with the target address 1621 switch (encoding) { 1622 case eEncodingT1: 1623 Rm = Bits32(opcode, 19, 16); 1624 if (BadReg(Rm)) 1625 return false; 1626 if (InITBlock() && !LastInITBlock()) 1627 return false; 1628 break; 1629 case eEncodingA1: 1630 Rm = Bits32(opcode, 3, 0); 1631 if (Rm == 15) 1632 return false; 1633 break; 1634 default: 1635 return false; 1636 } 1637 bool success = false; 1638 addr_t target = ReadCoreReg (Rm, &success); 1639 if (!success) 1640 return false; 1641 1642 RegisterInfo dwarf_reg; 1643 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1644 context.SetRegister (dwarf_reg); 1645 if (!BXWritePC(context, target)) 1646 return false; 1647 } 1648 return true; 1649 } 1650 1651 // Set r7 to point to some ip offset. 1652 // SUB (immediate) 1653 bool 1654 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1655 { 1656 #if 0 1657 // ARM pseudo code... 1658 if (ConditionPassed()) 1659 { 1660 EncodingSpecificOperations(); 1661 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1662 if d == 15 then // Can only occur for ARM encoding 1663 ALUWritePC(result); // setflags is always FALSE here 1664 else 1665 R[d] = result; 1666 if setflags then 1667 APSR.N = result<31>; 1668 APSR.Z = IsZeroBit(result); 1669 APSR.C = carry; 1670 APSR.V = overflow; 1671 } 1672 #endif 1673 1674 if (ConditionPassed(opcode)) 1675 { 1676 bool success = false; 1677 const addr_t ip = ReadCoreReg (12, &success); 1678 if (!success) 1679 return false; 1680 uint32_t imm32; 1681 switch (encoding) { 1682 case eEncodingA1: 1683 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1684 break; 1685 default: 1686 return false; 1687 } 1688 addr_t ip_offset = imm32; 1689 addr_t addr = ip - ip_offset; // the adjusted ip value 1690 1691 EmulateInstruction::Context context; 1692 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1693 RegisterInfo dwarf_reg; 1694 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1695 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1696 1697 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1698 return false; 1699 } 1700 return true; 1701 } 1702 1703 // Set ip to point to some stack offset. 1704 // SUB (SP minus immediate) 1705 bool 1706 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1707 { 1708 #if 0 1709 // ARM pseudo code... 1710 if (ConditionPassed()) 1711 { 1712 EncodingSpecificOperations(); 1713 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1714 if d == 15 then // Can only occur for ARM encoding 1715 ALUWritePC(result); // setflags is always FALSE here 1716 else 1717 R[d] = result; 1718 if setflags then 1719 APSR.N = result<31>; 1720 APSR.Z = IsZeroBit(result); 1721 APSR.C = carry; 1722 APSR.V = overflow; 1723 } 1724 #endif 1725 1726 if (ConditionPassed(opcode)) 1727 { 1728 bool success = false; 1729 const addr_t sp = ReadCoreReg (SP_REG, &success); 1730 if (!success) 1731 return false; 1732 uint32_t imm32; 1733 switch (encoding) { 1734 case eEncodingA1: 1735 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1736 break; 1737 default: 1738 return false; 1739 } 1740 addr_t sp_offset = imm32; 1741 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1742 1743 EmulateInstruction::Context context; 1744 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1745 RegisterInfo dwarf_reg; 1746 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1747 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1748 1749 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1750 return false; 1751 } 1752 return true; 1753 } 1754 1755 // This instruction subtracts an immediate value from the SP value, and writes 1756 // the result to the destination register. 1757 // 1758 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1759 bool 1760 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1761 { 1762 #if 0 1763 // ARM pseudo code... 1764 if (ConditionPassed()) 1765 { 1766 EncodingSpecificOperations(); 1767 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1768 if d == 15 then // Can only occur for ARM encoding 1769 ALUWritePC(result); // setflags is always FALSE here 1770 else 1771 R[d] = result; 1772 if setflags then 1773 APSR.N = result<31>; 1774 APSR.Z = IsZeroBit(result); 1775 APSR.C = carry; 1776 APSR.V = overflow; 1777 } 1778 #endif 1779 1780 bool success = false; 1781 if (ConditionPassed(opcode)) 1782 { 1783 const addr_t sp = ReadCoreReg (SP_REG, &success); 1784 if (!success) 1785 return false; 1786 1787 uint32_t Rd; 1788 bool setflags; 1789 uint32_t imm32; 1790 switch (encoding) { 1791 case eEncodingT1: 1792 Rd = 13; 1793 setflags = false; 1794 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1795 break; 1796 case eEncodingT2: 1797 Rd = Bits32(opcode, 11, 8); 1798 setflags = BitIsSet(opcode, 20); 1799 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1800 if (Rd == 15 && setflags) 1801 return EmulateCMPImm(opcode, eEncodingT2); 1802 if (Rd == 15 && !setflags) 1803 return false; 1804 break; 1805 case eEncodingT3: 1806 Rd = Bits32(opcode, 11, 8); 1807 setflags = false; 1808 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1809 if (Rd == 15) 1810 return false; 1811 break; 1812 case eEncodingA1: 1813 Rd = Bits32(opcode, 15, 12); 1814 setflags = BitIsSet(opcode, 20); 1815 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1816 1817 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1818 if (Rd == 15 && setflags) 1819 return EmulateSUBSPcLrEtc (opcode, encoding); 1820 break; 1821 default: 1822 return false; 1823 } 1824 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1825 1826 EmulateInstruction::Context context; 1827 if (Rd == 13) 1828 { 1829 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1830 // value gets passed down to context.SetImmediateSigned. 1831 context.type = EmulateInstruction::eContextAdjustStackPointer; 1832 context.SetImmediateSigned (-imm64); // the stack pointer offset 1833 } 1834 else 1835 { 1836 context.type = EmulateInstruction::eContextImmediate; 1837 context.SetNoArgs (); 1838 } 1839 1840 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1841 return false; 1842 } 1843 return true; 1844 } 1845 1846 // A store operation to the stack that also updates the SP. 1847 bool 1848 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1849 { 1850 #if 0 1851 // ARM pseudo code... 1852 if (ConditionPassed()) 1853 { 1854 EncodingSpecificOperations(); 1855 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1856 address = if index then offset_addr else R[n]; 1857 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1858 if wback then R[n] = offset_addr; 1859 } 1860 #endif 1861 1862 bool conditional = false; 1863 bool success = false; 1864 if (ConditionPassed(opcode, &conditional)) 1865 { 1866 const uint32_t addr_byte_size = GetAddressByteSize(); 1867 const addr_t sp = ReadCoreReg (SP_REG, &success); 1868 if (!success) 1869 return false; 1870 uint32_t Rt; // the source register 1871 uint32_t imm12; 1872 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1873 1874 bool index; 1875 bool add; 1876 bool wback; 1877 switch (encoding) { 1878 case eEncodingA1: 1879 Rt = Bits32(opcode, 15, 12); 1880 imm12 = Bits32(opcode, 11, 0); 1881 Rn = Bits32 (opcode, 19, 16); 1882 1883 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1884 return false; 1885 1886 index = BitIsSet (opcode, 24); 1887 add = BitIsSet (opcode, 23); 1888 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1889 1890 if (wback && ((Rn == 15) || (Rn == Rt))) 1891 return false; 1892 break; 1893 default: 1894 return false; 1895 } 1896 addr_t offset_addr; 1897 if (add) 1898 offset_addr = sp + imm12; 1899 else 1900 offset_addr = sp - imm12; 1901 1902 addr_t addr; 1903 if (index) 1904 addr = offset_addr; 1905 else 1906 addr = sp; 1907 1908 EmulateInstruction::Context context; 1909 if (conditional) 1910 context.type = EmulateInstruction::eContextRegisterStore; 1911 else 1912 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1913 RegisterInfo sp_reg; 1914 RegisterInfo dwarf_reg; 1915 1916 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1917 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 1918 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 1919 if (Rt != 15) 1920 { 1921 uint32_t reg_value = ReadCoreReg(Rt, &success); 1922 if (!success) 1923 return false; 1924 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 1925 return false; 1926 } 1927 else 1928 { 1929 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1930 if (!success) 1931 return false; 1932 if (!MemUWrite (context, addr, pc, addr_byte_size)) 1933 return false; 1934 } 1935 1936 1937 if (wback) 1938 { 1939 context.type = EmulateInstruction::eContextAdjustStackPointer; 1940 context.SetImmediateSigned (addr - sp); 1941 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 1942 return false; 1943 } 1944 } 1945 return true; 1946 } 1947 1948 // Vector Push stores multiple extension registers to the stack. 1949 // It also updates SP to point to the start of the stored data. 1950 bool 1951 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 1952 { 1953 #if 0 1954 // ARM pseudo code... 1955 if (ConditionPassed()) 1956 { 1957 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1958 address = SP - imm32; 1959 SP = SP - imm32; 1960 if single_regs then 1961 for r = 0 to regs-1 1962 MemA[address,4] = S[d+r]; address = address+4; 1963 else 1964 for r = 0 to regs-1 1965 // Store as two word-aligned words in the correct order for current endianness. 1966 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1967 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1968 address = address+8; 1969 } 1970 #endif 1971 1972 bool success = false; 1973 bool conditional = false; 1974 if (ConditionPassed(opcode, &conditional)) 1975 { 1976 const uint32_t addr_byte_size = GetAddressByteSize(); 1977 const addr_t sp = ReadCoreReg (SP_REG, &success); 1978 if (!success) 1979 return false; 1980 bool single_regs; 1981 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1982 uint32_t imm32; // stack offset 1983 uint32_t regs; // number of registers 1984 switch (encoding) { 1985 case eEncodingT1: 1986 case eEncodingA1: 1987 single_regs = false; 1988 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1989 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1990 // If UInt(imm8) is odd, see "FSTMX". 1991 regs = Bits32(opcode, 7, 0) / 2; 1992 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1993 if (regs == 0 || regs > 16 || (d + regs) > 32) 1994 return false; 1995 break; 1996 case eEncodingT2: 1997 case eEncodingA2: 1998 single_regs = true; 1999 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2000 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2001 regs = Bits32(opcode, 7, 0); 2002 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2003 if (regs == 0 || regs > 16 || (d + regs) > 32) 2004 return false; 2005 break; 2006 default: 2007 return false; 2008 } 2009 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2010 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2011 addr_t sp_offset = imm32; 2012 addr_t addr = sp - sp_offset; 2013 uint32_t i; 2014 2015 EmulateInstruction::Context context; 2016 if (conditional) 2017 context.type = EmulateInstruction::eContextRegisterStore; 2018 else 2019 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2020 RegisterInfo dwarf_reg; 2021 RegisterInfo sp_reg; 2022 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2023 for (i=0; i<regs; ++i) 2024 { 2025 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2026 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2027 // uint64_t to accommodate 64-bit registers. 2028 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2029 if (!success) 2030 return false; 2031 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2032 return false; 2033 addr += reg_byte_size; 2034 } 2035 2036 context.type = EmulateInstruction::eContextAdjustStackPointer; 2037 context.SetImmediateSigned (-sp_offset); 2038 2039 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2040 return false; 2041 } 2042 return true; 2043 } 2044 2045 // Vector Pop loads multiple extension registers from the stack. 2046 // It also updates SP to point just above the loaded data. 2047 bool 2048 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2049 { 2050 #if 0 2051 // ARM pseudo code... 2052 if (ConditionPassed()) 2053 { 2054 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2055 address = SP; 2056 SP = SP + imm32; 2057 if single_regs then 2058 for r = 0 to regs-1 2059 S[d+r] = MemA[address,4]; address = address+4; 2060 else 2061 for r = 0 to regs-1 2062 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2063 // Combine the word-aligned words in the correct order for current endianness. 2064 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2065 } 2066 #endif 2067 2068 bool success = false; 2069 bool conditional = false; 2070 if (ConditionPassed(opcode, &conditional)) 2071 { 2072 const uint32_t addr_byte_size = GetAddressByteSize(); 2073 const addr_t sp = ReadCoreReg (SP_REG, &success); 2074 if (!success) 2075 return false; 2076 bool single_regs; 2077 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2078 uint32_t imm32; // stack offset 2079 uint32_t regs; // number of registers 2080 switch (encoding) { 2081 case eEncodingT1: 2082 case eEncodingA1: 2083 single_regs = false; 2084 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2085 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2086 // If UInt(imm8) is odd, see "FLDMX". 2087 regs = Bits32(opcode, 7, 0) / 2; 2088 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2089 if (regs == 0 || regs > 16 || (d + regs) > 32) 2090 return false; 2091 break; 2092 case eEncodingT2: 2093 case eEncodingA2: 2094 single_regs = true; 2095 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2096 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2097 regs = Bits32(opcode, 7, 0); 2098 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2099 if (regs == 0 || regs > 16 || (d + regs) > 32) 2100 return false; 2101 break; 2102 default: 2103 return false; 2104 } 2105 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2106 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2107 addr_t sp_offset = imm32; 2108 addr_t addr = sp; 2109 uint32_t i; 2110 uint64_t data; // uint64_t to accomodate 64-bit registers. 2111 2112 EmulateInstruction::Context context; 2113 if (conditional) 2114 context.type = EmulateInstruction::eContextRegisterLoad; 2115 else 2116 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2117 RegisterInfo dwarf_reg; 2118 RegisterInfo sp_reg; 2119 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2120 for (i=0; i<regs; ++i) 2121 { 2122 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2123 context.SetRegisterPlusOffset (sp_reg, addr - sp); 2124 data = MemARead(context, addr, reg_byte_size, 0, &success); 2125 if (!success) 2126 return false; 2127 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2128 return false; 2129 addr += reg_byte_size; 2130 } 2131 2132 context.type = EmulateInstruction::eContextAdjustStackPointer; 2133 context.SetImmediateSigned (sp_offset); 2134 2135 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2136 return false; 2137 } 2138 return true; 2139 } 2140 2141 // SVC (previously SWI) 2142 bool 2143 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2144 { 2145 #if 0 2146 // ARM pseudo code... 2147 if (ConditionPassed()) 2148 { 2149 EncodingSpecificOperations(); 2150 CallSupervisor(); 2151 } 2152 #endif 2153 2154 bool success = false; 2155 2156 if (ConditionPassed(opcode)) 2157 { 2158 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2159 addr_t lr; // next instruction address 2160 if (!success) 2161 return false; 2162 uint32_t imm32; // the immediate constant 2163 uint32_t mode; // ARM or Thumb mode 2164 switch (encoding) { 2165 case eEncodingT1: 2166 lr = (pc + 2) | 1u; // return address 2167 imm32 = Bits32(opcode, 7, 0); 2168 mode = eModeThumb; 2169 break; 2170 case eEncodingA1: 2171 lr = pc + 4; // return address 2172 imm32 = Bits32(opcode, 23, 0); 2173 mode = eModeARM; 2174 break; 2175 default: 2176 return false; 2177 } 2178 2179 EmulateInstruction::Context context; 2180 context.type = EmulateInstruction::eContextSupervisorCall; 2181 context.SetISAAndImmediate (mode, imm32); 2182 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2183 return false; 2184 } 2185 return true; 2186 } 2187 2188 // If Then makes up to four following instructions (the IT block) conditional. 2189 bool 2190 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2191 { 2192 #if 0 2193 // ARM pseudo code... 2194 EncodingSpecificOperations(); 2195 ITSTATE.IT<7:0> = firstcond:mask; 2196 #endif 2197 2198 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2199 return true; 2200 } 2201 2202 bool 2203 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2204 { 2205 // NOP, nothing to do... 2206 return true; 2207 } 2208 2209 // Branch causes a branch to a target address. 2210 bool 2211 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2212 { 2213 #if 0 2214 // ARM pseudo code... 2215 if (ConditionPassed()) 2216 { 2217 EncodingSpecificOperations(); 2218 BranchWritePC(PC + imm32); 2219 } 2220 #endif 2221 2222 bool success = false; 2223 2224 if (ConditionPassed(opcode)) 2225 { 2226 EmulateInstruction::Context context; 2227 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2228 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2229 if (!success) 2230 return false; 2231 addr_t target; // target address 2232 int32_t imm32; // PC-relative offset 2233 switch (encoding) { 2234 case eEncodingT1: 2235 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2236 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2237 target = pc + imm32; 2238 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2239 break; 2240 case eEncodingT2: 2241 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 2242 target = pc + imm32; 2243 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2244 break; 2245 case eEncodingT3: 2246 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2247 { 2248 uint32_t S = Bit32(opcode, 26); 2249 uint32_t imm6 = Bits32(opcode, 21, 16); 2250 uint32_t J1 = Bit32(opcode, 13); 2251 uint32_t J2 = Bit32(opcode, 11); 2252 uint32_t imm11 = Bits32(opcode, 10, 0); 2253 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2254 imm32 = llvm::SignExtend32<21>(imm21); 2255 target = pc + imm32; 2256 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2257 break; 2258 } 2259 case eEncodingT4: 2260 { 2261 uint32_t S = Bit32(opcode, 26); 2262 uint32_t imm10 = Bits32(opcode, 25, 16); 2263 uint32_t J1 = Bit32(opcode, 13); 2264 uint32_t J2 = Bit32(opcode, 11); 2265 uint32_t imm11 = Bits32(opcode, 10, 0); 2266 uint32_t I1 = !(J1 ^ S); 2267 uint32_t I2 = !(J2 ^ S); 2268 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2269 imm32 = llvm::SignExtend32<25>(imm25); 2270 target = pc + imm32; 2271 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2272 break; 2273 } 2274 case eEncodingA1: 2275 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2276 target = pc + imm32; 2277 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2278 break; 2279 default: 2280 return false; 2281 } 2282 if (!BranchWritePC(context, target)) 2283 return false; 2284 } 2285 return true; 2286 } 2287 2288 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2289 // zero and conditionally branch forward a constant value. They do not affect the condition flags. 2290 // CBNZ, CBZ 2291 bool 2292 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2293 { 2294 #if 0 2295 // ARM pseudo code... 2296 EncodingSpecificOperations(); 2297 if nonzero ^ IsZero(R[n]) then 2298 BranchWritePC(PC + imm32); 2299 #endif 2300 2301 bool success = false; 2302 2303 // Read the register value from the operand register Rn. 2304 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2305 if (!success) 2306 return false; 2307 2308 EmulateInstruction::Context context; 2309 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2310 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2311 if (!success) 2312 return false; 2313 2314 addr_t target; // target address 2315 uint32_t imm32; // PC-relative offset to branch forward 2316 bool nonzero; 2317 switch (encoding) { 2318 case eEncodingT1: 2319 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2320 nonzero = BitIsSet(opcode, 11); 2321 target = pc + imm32; 2322 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2323 break; 2324 default: 2325 return false; 2326 } 2327 if (nonzero ^ (reg_val == 0)) 2328 if (!BranchWritePC(context, target)) 2329 return false; 2330 2331 return true; 2332 } 2333 2334 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2335 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2336 // The branch length is twice the value of the byte returned from the table. 2337 // 2338 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2339 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2340 // The branch length is twice the value of the halfword returned from the table. 2341 // TBB, TBH 2342 bool 2343 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2344 { 2345 #if 0 2346 // ARM pseudo code... 2347 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2348 if is_tbh then 2349 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2350 else 2351 halfwords = UInt(MemU[R[n]+R[m], 1]); 2352 BranchWritePC(PC + 2*halfwords); 2353 #endif 2354 2355 bool success = false; 2356 2357 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2358 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2359 bool is_tbh; // true if table branch halfword 2360 switch (encoding) { 2361 case eEncodingT1: 2362 Rn = Bits32(opcode, 19, 16); 2363 Rm = Bits32(opcode, 3, 0); 2364 is_tbh = BitIsSet(opcode, 4); 2365 if (Rn == 13 || BadReg(Rm)) 2366 return false; 2367 if (InITBlock() && !LastInITBlock()) 2368 return false; 2369 break; 2370 default: 2371 return false; 2372 } 2373 2374 // Read the address of the table from the operand register Rn. 2375 // The PC can be used, in which case the table immediately follows this instruction. 2376 uint32_t base = ReadCoreReg(Rm, &success); 2377 if (!success) 2378 return false; 2379 2380 // the table index 2381 uint32_t index = ReadCoreReg(Rm, &success); 2382 if (!success) 2383 return false; 2384 2385 // the offsetted table address 2386 addr_t addr = base + (is_tbh ? index*2 : index); 2387 2388 // PC-relative offset to branch forward 2389 EmulateInstruction::Context context; 2390 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2391 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2392 if (!success) 2393 return false; 2394 2395 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2396 if (!success) 2397 return false; 2398 2399 // target address 2400 addr_t target = pc + offset; 2401 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2402 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2403 2404 if (!BranchWritePC(context, target)) 2405 return false; 2406 2407 return true; 2408 } 2409 2410 // This instruction adds an immediate value to a register value, and writes the result to the destination register. 2411 // It can optionally update the condition flags based on the result. 2412 bool 2413 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2414 { 2415 #if 0 2416 if ConditionPassed() then 2417 EncodingSpecificOperations(); 2418 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2419 R[d] = result; 2420 if setflags then 2421 APSR.N = result<31>; 2422 APSR.Z = IsZeroBit(result); 2423 APSR.C = carry; 2424 APSR.V = overflow; 2425 #endif 2426 2427 bool success = false; 2428 2429 if (ConditionPassed(opcode)) 2430 { 2431 uint32_t d; 2432 uint32_t n; 2433 bool setflags; 2434 uint32_t imm32; 2435 uint32_t carry_out; 2436 2437 //EncodingSpecificOperations(); 2438 switch (encoding) 2439 { 2440 case eEncodingT1: 2441 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2442 d = Bits32 (opcode, 2, 0); 2443 n = Bits32 (opcode, 5, 3); 2444 setflags = !InITBlock(); 2445 imm32 = Bits32 (opcode, 8,6); 2446 2447 break; 2448 2449 case eEncodingT2: 2450 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2451 d = Bits32 (opcode, 10, 8); 2452 n = Bits32 (opcode, 10, 8); 2453 setflags = !InITBlock(); 2454 imm32 = Bits32 (opcode, 7, 0); 2455 2456 break; 2457 2458 case eEncodingT3: 2459 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2460 // if Rn == '1101' then SEE ADD (SP plus immediate); 2461 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2462 d = Bits32 (opcode, 11, 8); 2463 n = Bits32 (opcode, 19, 16); 2464 setflags = BitIsSet (opcode, 20); 2465 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2466 2467 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2468 if (BadReg (d) || (n == 15)) 2469 return false; 2470 2471 break; 2472 2473 case eEncodingT4: 2474 { 2475 // if Rn == '1111' then SEE ADR; 2476 // if Rn == '1101' then SEE ADD (SP plus immediate); 2477 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2478 d = Bits32 (opcode, 11, 8); 2479 n = Bits32 (opcode, 19, 16); 2480 setflags = false; 2481 uint32_t i = Bit32 (opcode, 26); 2482 uint32_t imm3 = Bits32 (opcode, 14, 12); 2483 uint32_t imm8 = Bits32 (opcode, 7, 0); 2484 imm32 = (i << 11) | (imm3 << 8) | imm8; 2485 2486 // if BadReg(d) then UNPREDICTABLE; 2487 if (BadReg (d)) 2488 return false; 2489 2490 break; 2491 } 2492 default: 2493 return false; 2494 } 2495 2496 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2497 if (!success) 2498 return false; 2499 2500 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2501 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2502 2503 RegisterInfo reg_n; 2504 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2505 2506 EmulateInstruction::Context context; 2507 context.type = eContextArithmetic; 2508 context.SetRegisterPlusOffset (reg_n, imm32); 2509 2510 //R[d] = result; 2511 //if setflags then 2512 //APSR.N = result<31>; 2513 //APSR.Z = IsZeroBit(result); 2514 //APSR.C = carry; 2515 //APSR.V = overflow; 2516 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2517 return false; 2518 2519 } 2520 return true; 2521 } 2522 2523 // This instruction adds an immediate value to a register value, and writes the result to the destination 2524 // register. It can optionally update the condition flags based on the result. 2525 bool 2526 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2527 { 2528 #if 0 2529 // ARM pseudo code... 2530 if ConditionPassed() then 2531 EncodingSpecificOperations(); 2532 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2533 if d == 15 then 2534 ALUWritePC(result); // setflags is always FALSE here 2535 else 2536 R[d] = result; 2537 if setflags then 2538 APSR.N = result<31>; 2539 APSR.Z = IsZeroBit(result); 2540 APSR.C = carry; 2541 APSR.V = overflow; 2542 #endif 2543 2544 bool success = false; 2545 2546 if (ConditionPassed(opcode)) 2547 { 2548 uint32_t Rd, Rn; 2549 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2550 bool setflags; 2551 switch (encoding) 2552 { 2553 case eEncodingA1: 2554 Rd = Bits32(opcode, 15, 12); 2555 Rn = Bits32(opcode, 19, 16); 2556 setflags = BitIsSet(opcode, 20); 2557 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2558 break; 2559 default: 2560 return false; 2561 } 2562 2563 // Read the first operand. 2564 uint32_t val1 = ReadCoreReg(Rn, &success); 2565 if (!success) 2566 return false; 2567 2568 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2569 2570 EmulateInstruction::Context context; 2571 context.type = eContextArithmetic; 2572 RegisterInfo dwarf_reg; 2573 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2574 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2575 2576 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2577 return false; 2578 } 2579 return true; 2580 } 2581 2582 // This instruction adds a register value and an optionally-shifted register value, and writes the result 2583 // to the destination register. It can optionally update the condition flags based on the result. 2584 bool 2585 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2586 { 2587 #if 0 2588 // ARM pseudo code... 2589 if ConditionPassed() then 2590 EncodingSpecificOperations(); 2591 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2592 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2593 if d == 15 then 2594 ALUWritePC(result); // setflags is always FALSE here 2595 else 2596 R[d] = result; 2597 if setflags then 2598 APSR.N = result<31>; 2599 APSR.Z = IsZeroBit(result); 2600 APSR.C = carry; 2601 APSR.V = overflow; 2602 #endif 2603 2604 bool success = false; 2605 2606 if (ConditionPassed(opcode)) 2607 { 2608 uint32_t Rd, Rn, Rm; 2609 ARM_ShifterType shift_t; 2610 uint32_t shift_n; // the shift applied to the value read from Rm 2611 bool setflags; 2612 switch (encoding) 2613 { 2614 case eEncodingT1: 2615 Rd = Bits32(opcode, 2, 0); 2616 Rn = Bits32(opcode, 5, 3); 2617 Rm = Bits32(opcode, 8, 6); 2618 setflags = !InITBlock(); 2619 shift_t = SRType_LSL; 2620 shift_n = 0; 2621 break; 2622 case eEncodingT2: 2623 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2624 Rm = Bits32(opcode, 6, 3); 2625 setflags = false; 2626 shift_t = SRType_LSL; 2627 shift_n = 0; 2628 if (Rn == 15 && Rm == 15) 2629 return false; 2630 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2631 return false; 2632 break; 2633 case eEncodingA1: 2634 Rd = Bits32(opcode, 15, 12); 2635 Rn = Bits32(opcode, 19, 16); 2636 Rm = Bits32(opcode, 3, 0); 2637 setflags = BitIsSet(opcode, 20); 2638 shift_n = DecodeImmShiftARM(opcode, shift_t); 2639 break; 2640 default: 2641 return false; 2642 } 2643 2644 // Read the first operand. 2645 uint32_t val1 = ReadCoreReg(Rn, &success); 2646 if (!success) 2647 return false; 2648 2649 // Read the second operand. 2650 uint32_t val2 = ReadCoreReg(Rm, &success); 2651 if (!success) 2652 return false; 2653 2654 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2655 if (!success) 2656 return false; 2657 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2658 2659 EmulateInstruction::Context context; 2660 context.type = eContextArithmetic; 2661 RegisterInfo op1_reg; 2662 RegisterInfo op2_reg; 2663 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2664 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2665 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2666 2667 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2668 return false; 2669 } 2670 return true; 2671 } 2672 2673 // Compare Negative (immediate) adds a register value and an immediate value. 2674 // It updates the condition flags based on the result, and discards the result. 2675 bool 2676 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2677 { 2678 #if 0 2679 // ARM pseudo code... 2680 if ConditionPassed() then 2681 EncodingSpecificOperations(); 2682 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2683 APSR.N = result<31>; 2684 APSR.Z = IsZeroBit(result); 2685 APSR.C = carry; 2686 APSR.V = overflow; 2687 #endif 2688 2689 bool success = false; 2690 2691 uint32_t Rn; // the first operand 2692 uint32_t imm32; // the immediate value to be compared with 2693 switch (encoding) { 2694 case eEncodingT1: 2695 Rn = Bits32(opcode, 19, 16); 2696 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2697 if (Rn == 15) 2698 return false; 2699 break; 2700 case eEncodingA1: 2701 Rn = Bits32(opcode, 19, 16); 2702 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2703 break; 2704 default: 2705 return false; 2706 } 2707 // Read the register value from the operand register Rn. 2708 uint32_t reg_val = ReadCoreReg(Rn, &success); 2709 if (!success) 2710 return false; 2711 2712 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2713 2714 EmulateInstruction::Context context; 2715 context.type = EmulateInstruction::eContextImmediate; 2716 context.SetNoArgs (); 2717 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2718 return false; 2719 2720 return true; 2721 } 2722 2723 // Compare Negative (register) adds a register value and an optionally-shifted register value. 2724 // It updates the condition flags based on the result, and discards the result. 2725 bool 2726 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2727 { 2728 #if 0 2729 // ARM pseudo code... 2730 if ConditionPassed() then 2731 EncodingSpecificOperations(); 2732 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2733 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2734 APSR.N = result<31>; 2735 APSR.Z = IsZeroBit(result); 2736 APSR.C = carry; 2737 APSR.V = overflow; 2738 #endif 2739 2740 bool success = false; 2741 2742 uint32_t Rn; // the first operand 2743 uint32_t Rm; // the second operand 2744 ARM_ShifterType shift_t; 2745 uint32_t shift_n; // the shift applied to the value read from Rm 2746 switch (encoding) { 2747 case eEncodingT1: 2748 Rn = Bits32(opcode, 2, 0); 2749 Rm = Bits32(opcode, 5, 3); 2750 shift_t = SRType_LSL; 2751 shift_n = 0; 2752 break; 2753 case eEncodingT2: 2754 Rn = Bits32(opcode, 19, 16); 2755 Rm = Bits32(opcode, 3, 0); 2756 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2757 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2758 if (Rn == 15 || BadReg(Rm)) 2759 return false; 2760 break; 2761 case eEncodingA1: 2762 Rn = Bits32(opcode, 19, 16); 2763 Rm = Bits32(opcode, 3, 0); 2764 shift_n = DecodeImmShiftARM(opcode, shift_t); 2765 break; 2766 default: 2767 return false; 2768 } 2769 // Read the register value from register Rn. 2770 uint32_t val1 = ReadCoreReg(Rn, &success); 2771 if (!success) 2772 return false; 2773 2774 // Read the register value from register Rm. 2775 uint32_t val2 = ReadCoreReg(Rm, &success); 2776 if (!success) 2777 return false; 2778 2779 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2780 if (!success) 2781 return false; 2782 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2783 2784 EmulateInstruction::Context context; 2785 context.type = EmulateInstruction::eContextImmediate; 2786 context.SetNoArgs(); 2787 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2788 return false; 2789 2790 return true; 2791 } 2792 2793 // Compare (immediate) subtracts an immediate value from a register value. 2794 // It updates the condition flags based on the result, and discards the result. 2795 bool 2796 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2797 { 2798 #if 0 2799 // ARM pseudo code... 2800 if ConditionPassed() then 2801 EncodingSpecificOperations(); 2802 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2803 APSR.N = result<31>; 2804 APSR.Z = IsZeroBit(result); 2805 APSR.C = carry; 2806 APSR.V = overflow; 2807 #endif 2808 2809 bool success = false; 2810 2811 uint32_t Rn; // the first operand 2812 uint32_t imm32; // the immediate value to be compared with 2813 switch (encoding) { 2814 case eEncodingT1: 2815 Rn = Bits32(opcode, 10, 8); 2816 imm32 = Bits32(opcode, 7, 0); 2817 break; 2818 case eEncodingT2: 2819 Rn = Bits32(opcode, 19, 16); 2820 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2821 if (Rn == 15) 2822 return false; 2823 break; 2824 case eEncodingA1: 2825 Rn = Bits32(opcode, 19, 16); 2826 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2827 break; 2828 default: 2829 return false; 2830 } 2831 // Read the register value from the operand register Rn. 2832 uint32_t reg_val = ReadCoreReg(Rn, &success); 2833 if (!success) 2834 return false; 2835 2836 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2837 2838 EmulateInstruction::Context context; 2839 context.type = EmulateInstruction::eContextImmediate; 2840 context.SetNoArgs (); 2841 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2842 return false; 2843 2844 return true; 2845 } 2846 2847 // Compare (register) subtracts an optionally-shifted register value from a register value. 2848 // It updates the condition flags based on the result, and discards the result. 2849 bool 2850 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2851 { 2852 #if 0 2853 // ARM pseudo code... 2854 if ConditionPassed() then 2855 EncodingSpecificOperations(); 2856 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2857 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2858 APSR.N = result<31>; 2859 APSR.Z = IsZeroBit(result); 2860 APSR.C = carry; 2861 APSR.V = overflow; 2862 #endif 2863 2864 bool success = false; 2865 2866 uint32_t Rn; // the first operand 2867 uint32_t Rm; // the second operand 2868 ARM_ShifterType shift_t; 2869 uint32_t shift_n; // the shift applied to the value read from Rm 2870 switch (encoding) { 2871 case eEncodingT1: 2872 Rn = Bits32(opcode, 2, 0); 2873 Rm = Bits32(opcode, 5, 3); 2874 shift_t = SRType_LSL; 2875 shift_n = 0; 2876 break; 2877 case eEncodingT2: 2878 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2879 Rm = Bits32(opcode, 6, 3); 2880 shift_t = SRType_LSL; 2881 shift_n = 0; 2882 if (Rn < 8 && Rm < 8) 2883 return false; 2884 if (Rn == 15 || Rm == 15) 2885 return false; 2886 break; 2887 case eEncodingA1: 2888 Rn = Bits32(opcode, 19, 16); 2889 Rm = Bits32(opcode, 3, 0); 2890 shift_n = DecodeImmShiftARM(opcode, shift_t); 2891 break; 2892 default: 2893 return false; 2894 } 2895 // Read the register value from register Rn. 2896 uint32_t val1 = ReadCoreReg(Rn, &success); 2897 if (!success) 2898 return false; 2899 2900 // Read the register value from register Rm. 2901 uint32_t val2 = ReadCoreReg(Rm, &success); 2902 if (!success) 2903 return false; 2904 2905 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2906 if (!success) 2907 return false; 2908 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 2909 2910 EmulateInstruction::Context context; 2911 context.type = EmulateInstruction::eContextImmediate; 2912 context.SetNoArgs(); 2913 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2914 return false; 2915 2916 return true; 2917 } 2918 2919 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2920 // shifting in copies of its sign bit, and writes the result to the destination register. It can 2921 // optionally update the condition flags based on the result. 2922 bool 2923 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 2924 { 2925 #if 0 2926 // ARM pseudo code... 2927 if ConditionPassed() then 2928 EncodingSpecificOperations(); 2929 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2930 if d == 15 then // Can only occur for ARM encoding 2931 ALUWritePC(result); // setflags is always FALSE here 2932 else 2933 R[d] = result; 2934 if setflags then 2935 APSR.N = result<31>; 2936 APSR.Z = IsZeroBit(result); 2937 APSR.C = carry; 2938 // APSR.V unchanged 2939 #endif 2940 2941 return EmulateShiftImm (opcode, encoding, SRType_ASR); 2942 } 2943 2944 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 2945 // shifting in copies of its sign bit, and writes the result to the destination register. 2946 // The variable number of bits is read from the bottom byte of a register. It can optionally update 2947 // the condition flags based on the result. 2948 bool 2949 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 2950 { 2951 #if 0 2952 // ARM pseudo code... 2953 if ConditionPassed() then 2954 EncodingSpecificOperations(); 2955 shift_n = UInt(R[m]<7:0>); 2956 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2957 R[d] = result; 2958 if setflags then 2959 APSR.N = result<31>; 2960 APSR.Z = IsZeroBit(result); 2961 APSR.C = carry; 2962 // APSR.V unchanged 2963 #endif 2964 2965 return EmulateShiftReg (opcode, encoding, SRType_ASR); 2966 } 2967 2968 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 2969 // shifting in zeros, and writes the result to the destination register. It can optionally 2970 // update the condition flags based on the result. 2971 bool 2972 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 2973 { 2974 #if 0 2975 // ARM pseudo code... 2976 if ConditionPassed() then 2977 EncodingSpecificOperations(); 2978 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 2979 if d == 15 then // Can only occur for ARM encoding 2980 ALUWritePC(result); // setflags is always FALSE here 2981 else 2982 R[d] = result; 2983 if setflags then 2984 APSR.N = result<31>; 2985 APSR.Z = IsZeroBit(result); 2986 APSR.C = carry; 2987 // APSR.V unchanged 2988 #endif 2989 2990 return EmulateShiftImm (opcode, encoding, SRType_LSL); 2991 } 2992 2993 // Logical Shift Left (register) shifts a register value left by a variable number of bits, 2994 // shifting in zeros, and writes the result to the destination register. The variable number 2995 // of bits is read from the bottom byte of a register. It can optionally update the condition 2996 // flags based on the result. 2997 bool 2998 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 2999 { 3000 #if 0 3001 // ARM pseudo code... 3002 if ConditionPassed() then 3003 EncodingSpecificOperations(); 3004 shift_n = UInt(R[m]<7:0>); 3005 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3006 R[d] = result; 3007 if setflags then 3008 APSR.N = result<31>; 3009 APSR.Z = IsZeroBit(result); 3010 APSR.C = carry; 3011 // APSR.V unchanged 3012 #endif 3013 3014 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3015 } 3016 3017 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3018 // shifting in zeros, and writes the result to the destination register. It can optionally 3019 // update the condition flags based on the result. 3020 bool 3021 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3022 { 3023 #if 0 3024 // ARM pseudo code... 3025 if ConditionPassed() then 3026 EncodingSpecificOperations(); 3027 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3028 if d == 15 then // Can only occur for ARM encoding 3029 ALUWritePC(result); // setflags is always FALSE here 3030 else 3031 R[d] = result; 3032 if setflags then 3033 APSR.N = result<31>; 3034 APSR.Z = IsZeroBit(result); 3035 APSR.C = carry; 3036 // APSR.V unchanged 3037 #endif 3038 3039 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3040 } 3041 3042 // Logical Shift Right (register) shifts a register value right by a variable number of bits, 3043 // shifting in zeros, and writes the result to the destination register. The variable number 3044 // of bits is read from the bottom byte of a register. It can optionally update the condition 3045 // flags based on the result. 3046 bool 3047 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3048 { 3049 #if 0 3050 // ARM pseudo code... 3051 if ConditionPassed() then 3052 EncodingSpecificOperations(); 3053 shift_n = UInt(R[m]<7:0>); 3054 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3055 R[d] = result; 3056 if setflags then 3057 APSR.N = result<31>; 3058 APSR.Z = IsZeroBit(result); 3059 APSR.C = carry; 3060 // APSR.V unchanged 3061 #endif 3062 3063 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3064 } 3065 3066 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3067 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3068 // It can optionally update the condition flags based on the result. 3069 bool 3070 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3071 { 3072 #if 0 3073 // ARM pseudo code... 3074 if ConditionPassed() then 3075 EncodingSpecificOperations(); 3076 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3077 if d == 15 then // Can only occur for ARM encoding 3078 ALUWritePC(result); // setflags is always FALSE here 3079 else 3080 R[d] = result; 3081 if setflags then 3082 APSR.N = result<31>; 3083 APSR.Z = IsZeroBit(result); 3084 APSR.C = carry; 3085 // APSR.V unchanged 3086 #endif 3087 3088 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3089 } 3090 3091 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3092 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3093 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3094 // flags based on the result. 3095 bool 3096 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3097 { 3098 #if 0 3099 // ARM pseudo code... 3100 if ConditionPassed() then 3101 EncodingSpecificOperations(); 3102 shift_n = UInt(R[m]<7:0>); 3103 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3104 R[d] = result; 3105 if setflags then 3106 APSR.N = result<31>; 3107 APSR.Z = IsZeroBit(result); 3108 APSR.C = carry; 3109 // APSR.V unchanged 3110 #endif 3111 3112 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3113 } 3114 3115 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3116 // with the carry flag shifted into bit [31]. 3117 // 3118 // RRX can optionally update the condition flags based on the result. 3119 // In that case, bit [0] is shifted into the carry flag. 3120 bool 3121 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3122 { 3123 #if 0 3124 // ARM pseudo code... 3125 if ConditionPassed() then 3126 EncodingSpecificOperations(); 3127 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3128 if d == 15 then // Can only occur for ARM encoding 3129 ALUWritePC(result); // setflags is always FALSE here 3130 else 3131 R[d] = result; 3132 if setflags then 3133 APSR.N = result<31>; 3134 APSR.Z = IsZeroBit(result); 3135 APSR.C = carry; 3136 // APSR.V unchanged 3137 #endif 3138 3139 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3140 } 3141 3142 bool 3143 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3144 { 3145 // assert(shift_type == SRType_ASR 3146 // || shift_type == SRType_LSL 3147 // || shift_type == SRType_LSR 3148 // || shift_type == SRType_ROR 3149 // || shift_type == SRType_RRX); 3150 3151 bool success = false; 3152 3153 if (ConditionPassed(opcode)) 3154 { 3155 uint32_t Rd; // the destination register 3156 uint32_t Rm; // the first operand register 3157 uint32_t imm5; // encoding for the shift amount 3158 uint32_t carry; // the carry bit after the shift operation 3159 bool setflags; 3160 3161 // Special case handling! 3162 // A8.6.139 ROR (immediate) -- Encoding T1 3163 ARMEncoding use_encoding = encoding; 3164 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3165 { 3166 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3167 // have the same decoding of bit fields as the other Thumb2 shift operations. 3168 use_encoding = eEncodingT2; 3169 } 3170 3171 switch (use_encoding) { 3172 case eEncodingT1: 3173 // Due to the above special case handling! 3174 if (shift_type == SRType_ROR) 3175 return false; 3176 3177 Rd = Bits32(opcode, 2, 0); 3178 Rm = Bits32(opcode, 5, 3); 3179 setflags = !InITBlock(); 3180 imm5 = Bits32(opcode, 10, 6); 3181 break; 3182 case eEncodingT2: 3183 // A8.6.141 RRX 3184 // There's no imm form of RRX instructions. 3185 if (shift_type == SRType_RRX) 3186 return false; 3187 3188 Rd = Bits32(opcode, 11, 8); 3189 Rm = Bits32(opcode, 3, 0); 3190 setflags = BitIsSet(opcode, 20); 3191 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3192 if (BadReg(Rd) || BadReg(Rm)) 3193 return false; 3194 break; 3195 case eEncodingA1: 3196 Rd = Bits32(opcode, 15, 12); 3197 Rm = Bits32(opcode, 3, 0); 3198 setflags = BitIsSet(opcode, 20); 3199 imm5 = Bits32(opcode, 11, 7); 3200 break; 3201 default: 3202 return false; 3203 } 3204 3205 // A8.6.139 ROR (immediate) 3206 if (shift_type == SRType_ROR && imm5 == 0) 3207 shift_type = SRType_RRX; 3208 3209 // Get the first operand. 3210 uint32_t value = ReadCoreReg (Rm, &success); 3211 if (!success) 3212 return false; 3213 3214 // Decode the shift amount if not RRX. 3215 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3216 3217 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3218 if (!success) 3219 return false; 3220 3221 // The context specifies that an immediate is to be moved into Rd. 3222 EmulateInstruction::Context context; 3223 context.type = EmulateInstruction::eContextImmediate; 3224 context.SetNoArgs (); 3225 3226 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3227 return false; 3228 } 3229 return true; 3230 } 3231 3232 bool 3233 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3234 { 3235 // assert(shift_type == SRType_ASR 3236 // || shift_type == SRType_LSL 3237 // || shift_type == SRType_LSR 3238 // || shift_type == SRType_ROR); 3239 3240 bool success = false; 3241 3242 if (ConditionPassed(opcode)) 3243 { 3244 uint32_t Rd; // the destination register 3245 uint32_t Rn; // the first operand register 3246 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3247 uint32_t carry; // the carry bit after the shift operation 3248 bool setflags; 3249 switch (encoding) { 3250 case eEncodingT1: 3251 Rd = Bits32(opcode, 2, 0); 3252 Rn = Rd; 3253 Rm = Bits32(opcode, 5, 3); 3254 setflags = !InITBlock(); 3255 break; 3256 case eEncodingT2: 3257 Rd = Bits32(opcode, 11, 8); 3258 Rn = Bits32(opcode, 19, 16); 3259 Rm = Bits32(opcode, 3, 0); 3260 setflags = BitIsSet(opcode, 20); 3261 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3262 return false; 3263 break; 3264 case eEncodingA1: 3265 Rd = Bits32(opcode, 15, 12); 3266 Rn = Bits32(opcode, 3, 0); 3267 Rm = Bits32(opcode, 11, 8); 3268 setflags = BitIsSet(opcode, 20); 3269 if (Rd == 15 || Rn == 15 || Rm == 15) 3270 return false; 3271 break; 3272 default: 3273 return false; 3274 } 3275 3276 // Get the first operand. 3277 uint32_t value = ReadCoreReg (Rn, &success); 3278 if (!success) 3279 return false; 3280 // Get the Rm register content. 3281 uint32_t val = ReadCoreReg (Rm, &success); 3282 if (!success) 3283 return false; 3284 3285 // Get the shift amount. 3286 uint32_t amt = Bits32(val, 7, 0); 3287 3288 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3289 if (!success) 3290 return false; 3291 3292 // The context specifies that an immediate is to be moved into Rd. 3293 EmulateInstruction::Context context; 3294 context.type = EmulateInstruction::eContextImmediate; 3295 context.SetNoArgs (); 3296 3297 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3298 return false; 3299 } 3300 return true; 3301 } 3302 3303 // LDM loads multiple registers from consecutive memory locations, using an 3304 // address from a base register. Optionally the address just above the highest of those locations 3305 // can be written back to the base register. 3306 bool 3307 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3308 { 3309 #if 0 3310 // ARM pseudo code... 3311 if ConditionPassed() 3312 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3313 address = R[n]; 3314 3315 for i = 0 to 14 3316 if registers<i> == '1' then 3317 R[i] = MemA[address, 4]; address = address + 4; 3318 if registers<15> == '1' then 3319 LoadWritePC (MemA[address, 4]); 3320 3321 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3322 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3323 3324 #endif 3325 3326 bool success = false; 3327 bool conditional = false; 3328 if (ConditionPassed(opcode, &conditional)) 3329 { 3330 uint32_t n; 3331 uint32_t registers = 0; 3332 bool wback; 3333 const uint32_t addr_byte_size = GetAddressByteSize(); 3334 switch (encoding) 3335 { 3336 case eEncodingT1: 3337 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3338 n = Bits32 (opcode, 10, 8); 3339 registers = Bits32 (opcode, 7, 0); 3340 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3341 wback = BitIsClear (registers, n); 3342 // if BitCount(registers) < 1 then UNPREDICTABLE; 3343 if (BitCount(registers) < 1) 3344 return false; 3345 break; 3346 case eEncodingT2: 3347 // if W == '1' && Rn == '1101' then SEE POP; 3348 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3349 n = Bits32 (opcode, 19, 16); 3350 registers = Bits32 (opcode, 15, 0); 3351 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3352 wback = BitIsSet (opcode, 21); 3353 3354 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3355 if ((n == 15) 3356 || (BitCount (registers) < 2) 3357 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3358 return false; 3359 3360 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3361 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3362 return false; 3363 3364 // if wback && registers<n> == '1' then UNPREDICTABLE; 3365 if (wback 3366 && BitIsSet (registers, n)) 3367 return false; 3368 break; 3369 3370 case eEncodingA1: 3371 n = Bits32 (opcode, 19, 16); 3372 registers = Bits32 (opcode, 15, 0); 3373 wback = BitIsSet (opcode, 21); 3374 if ((n == 15) 3375 || (BitCount (registers) < 1)) 3376 return false; 3377 break; 3378 default: 3379 return false; 3380 } 3381 3382 int32_t offset = 0; 3383 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3384 if (!success) 3385 return false; 3386 3387 EmulateInstruction::Context context; 3388 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3389 RegisterInfo dwarf_reg; 3390 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3391 context.SetRegisterPlusOffset (dwarf_reg, offset); 3392 3393 for (int i = 0; i < 14; ++i) 3394 { 3395 if (BitIsSet (registers, i)) 3396 { 3397 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3398 context.SetRegisterPlusOffset (dwarf_reg, offset); 3399 if (wback && (n == 13)) // Pop Instruction 3400 { 3401 if (conditional) 3402 context.type = EmulateInstruction::eContextRegisterLoad; 3403 else 3404 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3405 } 3406 3407 // R[i] = MemA [address, 4]; address = address + 4; 3408 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3409 if (!success) 3410 return false; 3411 3412 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3413 return false; 3414 3415 offset += addr_byte_size; 3416 } 3417 } 3418 3419 if (BitIsSet (registers, 15)) 3420 { 3421 //LoadWritePC (MemA [address, 4]); 3422 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3423 context.SetRegisterPlusOffset (dwarf_reg, offset); 3424 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3425 if (!success) 3426 return false; 3427 // In ARMv5T and above, this is an interworking branch. 3428 if (!LoadWritePC(context, data)) 3429 return false; 3430 } 3431 3432 if (wback && BitIsClear (registers, n)) 3433 { 3434 // R[n] = R[n] + 4 * BitCount (registers) 3435 int32_t offset = addr_byte_size * BitCount (registers); 3436 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3437 context.SetRegisterPlusOffset (dwarf_reg, offset); 3438 3439 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3440 return false; 3441 } 3442 if (wback && BitIsSet (registers, n)) 3443 // R[n] bits(32) UNKNOWN; 3444 return WriteBits32Unknown (n); 3445 } 3446 return true; 3447 } 3448 3449 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3450 // The consecutive memory locations end at this address and the address just below the lowest of those locations 3451 // can optionally be written back to the base register. 3452 bool 3453 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3454 { 3455 #if 0 3456 // ARM pseudo code... 3457 if ConditionPassed() then 3458 EncodingSpecificOperations(); 3459 address = R[n] - 4*BitCount(registers) + 4; 3460 3461 for i = 0 to 14 3462 if registers<i> == '1' then 3463 R[i] = MemA[address,4]; address = address + 4; 3464 3465 if registers<15> == '1' then 3466 LoadWritePC(MemA[address,4]); 3467 3468 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3469 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3470 #endif 3471 3472 bool success = false; 3473 3474 if (ConditionPassed(opcode)) 3475 { 3476 uint32_t n; 3477 uint32_t registers = 0; 3478 bool wback; 3479 const uint32_t addr_byte_size = GetAddressByteSize(); 3480 3481 // EncodingSpecificOperations(); 3482 switch (encoding) 3483 { 3484 case eEncodingA1: 3485 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3486 n = Bits32 (opcode, 19, 16); 3487 registers = Bits32 (opcode, 15, 0); 3488 wback = BitIsSet (opcode, 21); 3489 3490 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3491 if ((n == 15) || (BitCount (registers) < 1)) 3492 return false; 3493 3494 break; 3495 3496 default: 3497 return false; 3498 } 3499 // address = R[n] - 4*BitCount(registers) + 4; 3500 3501 int32_t offset = 0; 3502 addr_t Rn = ReadCoreReg (n, &success); 3503 3504 if (!success) 3505 return false; 3506 3507 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3508 3509 EmulateInstruction::Context context; 3510 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3511 RegisterInfo dwarf_reg; 3512 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3513 context.SetRegisterPlusOffset (dwarf_reg, offset); 3514 3515 // for i = 0 to 14 3516 for (int i = 0; i < 14; ++i) 3517 { 3518 // if registers<i> == '1' then 3519 if (BitIsSet (registers, i)) 3520 { 3521 // R[i] = MemA[address,4]; address = address + 4; 3522 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3523 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3524 if (!success) 3525 return false; 3526 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3527 return false; 3528 offset += addr_byte_size; 3529 } 3530 } 3531 3532 // if registers<15> == '1' then 3533 // LoadWritePC(MemA[address,4]); 3534 if (BitIsSet (registers, 15)) 3535 { 3536 context.SetRegisterPlusOffset (dwarf_reg, offset); 3537 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3538 if (!success) 3539 return false; 3540 // In ARMv5T and above, this is an interworking branch. 3541 if (!LoadWritePC(context, data)) 3542 return false; 3543 } 3544 3545 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3546 if (wback && BitIsClear (registers, n)) 3547 { 3548 if (!success) 3549 return false; 3550 3551 offset = (addr_byte_size * BitCount (registers)) * -1; 3552 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3553 context.SetImmediateSigned (offset); 3554 addr_t addr = Rn + offset; 3555 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3556 return false; 3557 } 3558 3559 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3560 if (wback && BitIsSet (registers, n)) 3561 return WriteBits32Unknown (n); 3562 } 3563 return true; 3564 } 3565 3566 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3567 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 3568 // be optionally written back to the base register. 3569 bool 3570 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3571 { 3572 #if 0 3573 // ARM pseudo code... 3574 if ConditionPassed() then 3575 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3576 address = R[n] - 4*BitCount(registers); 3577 3578 for i = 0 to 14 3579 if registers<i> == '1' then 3580 R[i] = MemA[address,4]; address = address + 4; 3581 if registers<15> == '1' then 3582 LoadWritePC(MemA[address,4]); 3583 3584 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3585 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3586 #endif 3587 3588 bool success = false; 3589 3590 if (ConditionPassed(opcode)) 3591 { 3592 uint32_t n; 3593 uint32_t registers = 0; 3594 bool wback; 3595 const uint32_t addr_byte_size = GetAddressByteSize(); 3596 switch (encoding) 3597 { 3598 case eEncodingT1: 3599 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3600 n = Bits32 (opcode, 19, 16); 3601 registers = Bits32 (opcode, 15, 0); 3602 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3603 wback = BitIsSet (opcode, 21); 3604 3605 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3606 if ((n == 15) 3607 || (BitCount (registers) < 2) 3608 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3609 return false; 3610 3611 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3612 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3613 return false; 3614 3615 // if wback && registers<n> == '1' then UNPREDICTABLE; 3616 if (wback && BitIsSet (registers, n)) 3617 return false; 3618 3619 break; 3620 3621 case eEncodingA1: 3622 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3623 n = Bits32 (opcode, 19, 16); 3624 registers = Bits32 (opcode, 15, 0); 3625 wback = BitIsSet (opcode, 21); 3626 3627 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3628 if ((n == 15) || (BitCount (registers) < 1)) 3629 return false; 3630 3631 break; 3632 3633 default: 3634 return false; 3635 } 3636 3637 // address = R[n] - 4*BitCount(registers); 3638 3639 int32_t offset = 0; 3640 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3641 3642 if (!success) 3643 return false; 3644 3645 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3646 EmulateInstruction::Context context; 3647 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3648 RegisterInfo dwarf_reg; 3649 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3650 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3651 3652 for (int i = 0; i < 14; ++i) 3653 { 3654 if (BitIsSet (registers, i)) 3655 { 3656 // R[i] = MemA[address,4]; address = address + 4; 3657 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3658 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3659 if (!success) 3660 return false; 3661 3662 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3663 return false; 3664 3665 offset += addr_byte_size; 3666 } 3667 } 3668 3669 // if registers<15> == '1' then 3670 // LoadWritePC(MemA[address,4]); 3671 if (BitIsSet (registers, 15)) 3672 { 3673 context.SetRegisterPlusOffset (dwarf_reg, offset); 3674 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3675 if (!success) 3676 return false; 3677 // In ARMv5T and above, this is an interworking branch. 3678 if (!LoadWritePC(context, data)) 3679 return false; 3680 } 3681 3682 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3683 if (wback && BitIsClear (registers, n)) 3684 { 3685 if (!success) 3686 return false; 3687 3688 offset = (addr_byte_size * BitCount (registers)) * -1; 3689 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3690 context.SetImmediateSigned (offset); 3691 addr_t addr = Rn + offset; 3692 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3693 return false; 3694 } 3695 3696 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3697 if (wback && BitIsSet (registers, n)) 3698 return WriteBits32Unknown (n); 3699 } 3700 return true; 3701 } 3702 3703 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3704 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3705 // optinoally be written back to the base register. 3706 bool 3707 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3708 { 3709 #if 0 3710 if ConditionPassed() then 3711 EncodingSpecificOperations(); 3712 address = R[n] + 4; 3713 3714 for i = 0 to 14 3715 if registers<i> == '1' then 3716 R[i] = MemA[address,4]; address = address + 4; 3717 if registers<15> == '1' then 3718 LoadWritePC(MemA[address,4]); 3719 3720 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3721 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3722 #endif 3723 3724 bool success = false; 3725 3726 if (ConditionPassed(opcode)) 3727 { 3728 uint32_t n; 3729 uint32_t registers = 0; 3730 bool wback; 3731 const uint32_t addr_byte_size = GetAddressByteSize(); 3732 switch (encoding) 3733 { 3734 case eEncodingA1: 3735 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3736 n = Bits32 (opcode, 19, 16); 3737 registers = Bits32 (opcode, 15, 0); 3738 wback = BitIsSet (opcode, 21); 3739 3740 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3741 if ((n == 15) || (BitCount (registers) < 1)) 3742 return false; 3743 3744 break; 3745 default: 3746 return false; 3747 } 3748 // address = R[n] + 4; 3749 3750 int32_t offset = 0; 3751 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3752 3753 if (!success) 3754 return false; 3755 3756 addr_t address = Rn + addr_byte_size; 3757 3758 EmulateInstruction::Context context; 3759 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3760 RegisterInfo dwarf_reg; 3761 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3762 context.SetRegisterPlusOffset (dwarf_reg, offset); 3763 3764 for (int i = 0; i < 14; ++i) 3765 { 3766 if (BitIsSet (registers, i)) 3767 { 3768 // R[i] = MemA[address,4]; address = address + 4; 3769 3770 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3771 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3772 if (!success) 3773 return false; 3774 3775 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3776 return false; 3777 3778 offset += addr_byte_size; 3779 } 3780 } 3781 3782 // if registers<15> == '1' then 3783 // LoadWritePC(MemA[address,4]); 3784 if (BitIsSet (registers, 15)) 3785 { 3786 context.SetRegisterPlusOffset (dwarf_reg, offset); 3787 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3788 if (!success) 3789 return false; 3790 // In ARMv5T and above, this is an interworking branch. 3791 if (!LoadWritePC(context, data)) 3792 return false; 3793 } 3794 3795 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3796 if (wback && BitIsClear (registers, n)) 3797 { 3798 if (!success) 3799 return false; 3800 3801 offset = addr_byte_size * BitCount (registers); 3802 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3803 context.SetImmediateSigned (offset); 3804 addr_t addr = Rn + offset; 3805 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3806 return false; 3807 } 3808 3809 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3810 if (wback && BitIsSet (registers, n)) 3811 return WriteBits32Unknown (n); 3812 } 3813 return true; 3814 } 3815 3816 // Load Register (immediate) calculates an address from a base register value and 3817 // an immediate offset, loads a word from memory, and writes to a register. 3818 // LDR (immediate, Thumb) 3819 bool 3820 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3821 { 3822 #if 0 3823 // ARM pseudo code... 3824 if (ConditionPassed()) 3825 { 3826 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3827 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3828 address = if index then offset_addr else R[n]; 3829 data = MemU[address,4]; 3830 if wback then R[n] = offset_addr; 3831 if t == 15 then 3832 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3833 elsif UnalignedSupport() || address<1:0> = '00' then 3834 R[t] = data; 3835 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3836 } 3837 #endif 3838 3839 bool success = false; 3840 3841 if (ConditionPassed(opcode)) 3842 { 3843 uint32_t Rt; // the destination register 3844 uint32_t Rn; // the base register 3845 uint32_t imm32; // the immediate offset used to form the address 3846 addr_t offset_addr; // the offset address 3847 addr_t address; // the calculated address 3848 uint32_t data; // the literal data value from memory load 3849 bool add, index, wback; 3850 switch (encoding) { 3851 case eEncodingT1: 3852 Rt = Bits32(opcode, 2, 0); 3853 Rn = Bits32(opcode, 5, 3); 3854 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3855 // index = TRUE; add = TRUE; wback = FALSE 3856 add = true; 3857 index = true; 3858 wback = false; 3859 3860 break; 3861 3862 case eEncodingT2: 3863 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3864 Rt = Bits32 (opcode, 10, 8); 3865 Rn = 13; 3866 imm32 = Bits32 (opcode, 7, 0) << 2; 3867 3868 // index = TRUE; add = TRUE; wback = FALSE; 3869 index = true; 3870 add = true; 3871 wback = false; 3872 3873 break; 3874 3875 case eEncodingT3: 3876 // if Rn == '1111' then SEE LDR (literal); 3877 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3878 Rt = Bits32 (opcode, 15, 12); 3879 Rn = Bits32 (opcode, 19, 16); 3880 imm32 = Bits32 (opcode, 11, 0); 3881 3882 // index = TRUE; add = TRUE; wback = FALSE; 3883 index = true; 3884 add = true; 3885 wback = false; 3886 3887 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3888 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 3889 return false; 3890 3891 break; 3892 3893 case eEncodingT4: 3894 // if Rn == '1111' then SEE LDR (literal); 3895 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 3896 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 3897 // if P == '0' && W == '0' then UNDEFINED; 3898 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 3899 return false; 3900 3901 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3902 Rt = Bits32 (opcode, 15, 12); 3903 Rn = Bits32 (opcode, 19, 16); 3904 imm32 = Bits32 (opcode, 7, 0); 3905 3906 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 3907 index = BitIsSet (opcode, 10); 3908 add = BitIsSet (opcode, 9); 3909 wback = BitIsSet (opcode, 8); 3910 3911 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 3912 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 3913 return false; 3914 3915 break; 3916 3917 default: 3918 return false; 3919 } 3920 uint32_t base = ReadCoreReg (Rn, &success); 3921 if (!success) 3922 return false; 3923 if (add) 3924 offset_addr = base + imm32; 3925 else 3926 offset_addr = base - imm32; 3927 3928 address = (index ? offset_addr : base); 3929 3930 RegisterInfo base_reg; 3931 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 3932 if (wback) 3933 { 3934 EmulateInstruction::Context ctx; 3935 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 3936 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3937 3938 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 3939 return false; 3940 } 3941 3942 // Prepare to write to the Rt register. 3943 EmulateInstruction::Context context; 3944 context.type = EmulateInstruction::eContextRegisterLoad; 3945 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 3946 3947 // Read memory from the address. 3948 data = MemURead(context, address, 4, 0, &success); 3949 if (!success) 3950 return false; 3951 3952 if (Rt == 15) 3953 { 3954 if (Bits32(address, 1, 0) == 0) 3955 { 3956 if (!LoadWritePC(context, data)) 3957 return false; 3958 } 3959 else 3960 return false; 3961 } 3962 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 3963 { 3964 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 3965 return false; 3966 } 3967 else 3968 WriteBits32Unknown (Rt); 3969 } 3970 return true; 3971 } 3972 3973 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 3974 // from a base register. The consecutive memory locations start at this address, and teh address just above the last 3975 // of those locations can optionally be written back to the base register. 3976 bool 3977 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 3978 { 3979 #if 0 3980 if ConditionPassed() then 3981 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3982 address = R[n]; 3983 3984 for i = 0 to 14 3985 if registers<i> == '1' then 3986 if i == n && wback && i != LowestSetBit(registers) then 3987 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3988 else 3989 MemA[address,4] = R[i]; 3990 address = address + 4; 3991 3992 if registers<15> == '1' then // Only possible for encoding A1 3993 MemA[address,4] = PCStoreValue(); 3994 if wback then R[n] = R[n] + 4*BitCount(registers); 3995 #endif 3996 3997 bool success = false; 3998 3999 if (ConditionPassed(opcode)) 4000 { 4001 uint32_t n; 4002 uint32_t registers = 0; 4003 bool wback; 4004 const uint32_t addr_byte_size = GetAddressByteSize(); 4005 4006 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4007 switch (encoding) 4008 { 4009 case eEncodingT1: 4010 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4011 n = Bits32 (opcode, 10, 8); 4012 registers = Bits32 (opcode, 7, 0); 4013 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4014 wback = true; 4015 4016 // if BitCount(registers) < 1 then UNPREDICTABLE; 4017 if (BitCount (registers) < 1) 4018 return false; 4019 4020 break; 4021 4022 case eEncodingT2: 4023 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4024 n = Bits32 (opcode, 19, 16); 4025 registers = Bits32 (opcode, 15, 0); 4026 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4027 wback = BitIsSet (opcode, 21); 4028 4029 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4030 if ((n == 15) || (BitCount (registers) < 2)) 4031 return false; 4032 4033 // if wback && registers<n> == '1' then UNPREDICTABLE; 4034 if (wback && BitIsSet (registers, n)) 4035 return false; 4036 4037 break; 4038 4039 case eEncodingA1: 4040 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4041 n = Bits32 (opcode, 19, 16); 4042 registers = Bits32 (opcode, 15, 0); 4043 wback = BitIsSet (opcode, 21); 4044 4045 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4046 if ((n == 15) || (BitCount (registers) < 1)) 4047 return false; 4048 4049 break; 4050 4051 default: 4052 return false; 4053 } 4054 4055 // address = R[n]; 4056 int32_t offset = 0; 4057 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4058 if (!success) 4059 return false; 4060 4061 EmulateInstruction::Context context; 4062 context.type = EmulateInstruction::eContextRegisterStore; 4063 RegisterInfo base_reg; 4064 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4065 4066 // for i = 0 to 14 4067 int lowest_set_bit = 14; 4068 for (int i = 0; i < 14; ++i) 4069 { 4070 // if registers<i> == '1' then 4071 if (BitIsSet (registers, i)) 4072 { 4073 if (i < lowest_set_bit) 4074 lowest_set_bit = i; 4075 // if i == n && wback && i != LowestSetBit(registers) then 4076 if ((i == n) && wback && (i != lowest_set_bit)) 4077 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4078 WriteBits32UnknownToMemory (address + offset); 4079 else 4080 { 4081 // MemA[address,4] = R[i]; 4082 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4083 if (!success) 4084 return false; 4085 4086 RegisterInfo data_reg; 4087 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4088 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4089 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4090 return false; 4091 } 4092 4093 // address = address + 4; 4094 offset += addr_byte_size; 4095 } 4096 } 4097 4098 // if registers<15> == '1' then // Only possible for encoding A1 4099 // MemA[address,4] = PCStoreValue(); 4100 if (BitIsSet (registers, 15)) 4101 { 4102 RegisterInfo pc_reg; 4103 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4104 context.SetRegisterPlusOffset (pc_reg, 8); 4105 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4106 if (!success) 4107 return false; 4108 4109 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4110 return false; 4111 } 4112 4113 // if wback then R[n] = R[n] + 4*BitCount(registers); 4114 if (wback) 4115 { 4116 offset = addr_byte_size * BitCount (registers); 4117 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4118 context.SetImmediateSigned (offset); 4119 addr_t data = address + offset; 4120 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4121 return false; 4122 } 4123 } 4124 return true; 4125 } 4126 4127 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4128 // from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4129 // of those locations can optionally be written back to the base register. 4130 bool 4131 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4132 { 4133 #if 0 4134 if ConditionPassed() then 4135 EncodingSpecificOperations(); 4136 address = R[n] - 4*BitCount(registers) + 4; 4137 4138 for i = 0 to 14 4139 if registers<i> == '1' then 4140 if i == n && wback && i != LowestSetBit(registers) then 4141 MemA[address,4] = bits(32) UNKNOWN; 4142 else 4143 MemA[address,4] = R[i]; 4144 address = address + 4; 4145 4146 if registers<15> == '1' then 4147 MemA[address,4] = PCStoreValue(); 4148 4149 if wback then R[n] = R[n] - 4*BitCount(registers); 4150 #endif 4151 4152 bool success = false; 4153 4154 if (ConditionPassed(opcode)) 4155 { 4156 uint32_t n; 4157 uint32_t registers = 0; 4158 bool wback; 4159 const uint32_t addr_byte_size = GetAddressByteSize(); 4160 4161 // EncodingSpecificOperations(); 4162 switch (encoding) 4163 { 4164 case eEncodingA1: 4165 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4166 n = Bits32 (opcode, 19, 16); 4167 registers = Bits32 (opcode, 15, 0); 4168 wback = BitIsSet (opcode, 21); 4169 4170 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4171 if ((n == 15) || (BitCount (registers) < 1)) 4172 return false; 4173 break; 4174 default: 4175 return false; 4176 } 4177 4178 // address = R[n] - 4*BitCount(registers) + 4; 4179 int32_t offset = 0; 4180 addr_t Rn = ReadCoreReg (n, &success); 4181 if (!success) 4182 return false; 4183 4184 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4185 4186 EmulateInstruction::Context context; 4187 context.type = EmulateInstruction::eContextRegisterStore; 4188 RegisterInfo base_reg; 4189 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4190 4191 // for i = 0 to 14 4192 int lowest_bit_set = 14; 4193 for (int i = 0; i < 14; ++i) 4194 { 4195 // if registers<i> == '1' then 4196 if (BitIsSet (registers, i)) 4197 { 4198 if (i < lowest_bit_set) 4199 lowest_bit_set = i; 4200 //if i == n && wback && i != LowestSetBit(registers) then 4201 if ((i == n) && wback && (i != lowest_bit_set)) 4202 // MemA[address,4] = bits(32) UNKNOWN; 4203 WriteBits32UnknownToMemory (address + offset); 4204 else 4205 { 4206 // MemA[address,4] = R[i]; 4207 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4208 if (!success) 4209 return false; 4210 4211 RegisterInfo data_reg; 4212 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4213 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4214 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4215 return false; 4216 } 4217 4218 // address = address + 4; 4219 offset += addr_byte_size; 4220 } 4221 } 4222 4223 // if registers<15> == '1' then 4224 // MemA[address,4] = PCStoreValue(); 4225 if (BitIsSet (registers, 15)) 4226 { 4227 RegisterInfo pc_reg; 4228 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4229 context.SetRegisterPlusOffset (pc_reg, 8); 4230 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4231 if (!success) 4232 return false; 4233 4234 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4235 return false; 4236 } 4237 4238 // if wback then R[n] = R[n] - 4*BitCount(registers); 4239 if (wback) 4240 { 4241 offset = (addr_byte_size * BitCount (registers)) * -1; 4242 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4243 context.SetImmediateSigned (offset); 4244 addr_t data = Rn + offset; 4245 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4246 return false; 4247 } 4248 } 4249 return true; 4250 } 4251 4252 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4253 // from a base register. The consecutive memory locations end just below this address, and the address of the first of 4254 // those locations can optionally be written back to the base register. 4255 bool 4256 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4257 { 4258 #if 0 4259 if ConditionPassed() then 4260 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4261 address = R[n] - 4*BitCount(registers); 4262 4263 for i = 0 to 14 4264 if registers<i> == '1' then 4265 if i == n && wback && i != LowestSetBit(registers) then 4266 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4267 else 4268 MemA[address,4] = R[i]; 4269 address = address + 4; 4270 4271 if registers<15> == '1' then // Only possible for encoding A1 4272 MemA[address,4] = PCStoreValue(); 4273 4274 if wback then R[n] = R[n] - 4*BitCount(registers); 4275 #endif 4276 4277 4278 bool success = false; 4279 4280 if (ConditionPassed(opcode)) 4281 { 4282 uint32_t n; 4283 uint32_t registers = 0; 4284 bool wback; 4285 const uint32_t addr_byte_size = GetAddressByteSize(); 4286 4287 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4288 switch (encoding) 4289 { 4290 case eEncodingT1: 4291 // if W == '1' && Rn == '1101' then SEE PUSH; 4292 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4293 { 4294 // See PUSH 4295 } 4296 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4297 n = Bits32 (opcode, 19, 16); 4298 registers = Bits32 (opcode, 15, 0); 4299 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4300 wback = BitIsSet (opcode, 21); 4301 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4302 if ((n == 15) || BitCount (registers) < 2) 4303 return false; 4304 // if wback && registers<n> == '1' then UNPREDICTABLE; 4305 if (wback && BitIsSet (registers, n)) 4306 return false; 4307 break; 4308 4309 case eEncodingA1: 4310 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH; 4311 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4312 { 4313 // See Push 4314 } 4315 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4316 n = Bits32 (opcode, 19, 16); 4317 registers = Bits32 (opcode, 15, 0); 4318 wback = BitIsSet (opcode, 21); 4319 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4320 if ((n == 15) || BitCount (registers) < 1) 4321 return false; 4322 break; 4323 4324 default: 4325 return false; 4326 } 4327 4328 // address = R[n] - 4*BitCount(registers); 4329 4330 int32_t offset = 0; 4331 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4332 if (!success) 4333 return false; 4334 4335 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4336 4337 EmulateInstruction::Context context; 4338 context.type = EmulateInstruction::eContextRegisterStore; 4339 RegisterInfo base_reg; 4340 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4341 4342 // for i = 0 to 14 4343 uint32_t lowest_set_bit = 14; 4344 for (int i = 0; i < 14; ++i) 4345 { 4346 // if registers<i> == '1' then 4347 if (BitIsSet (registers, i)) 4348 { 4349 if (i < lowest_set_bit) 4350 lowest_set_bit = i; 4351 // if i == n && wback && i != LowestSetBit(registers) then 4352 if ((i == n) && wback && (i != lowest_set_bit)) 4353 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4354 WriteBits32UnknownToMemory (address + offset); 4355 else 4356 { 4357 // MemA[address,4] = R[i]; 4358 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4359 if (!success) 4360 return false; 4361 4362 RegisterInfo data_reg; 4363 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4364 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4365 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4366 return false; 4367 } 4368 4369 // address = address + 4; 4370 offset += addr_byte_size; 4371 } 4372 } 4373 4374 // if registers<15> == '1' then // Only possible for encoding A1 4375 // MemA[address,4] = PCStoreValue(); 4376 if (BitIsSet (registers, 15)) 4377 { 4378 RegisterInfo pc_reg; 4379 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4380 context.SetRegisterPlusOffset (pc_reg, 8); 4381 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4382 if (!success) 4383 return false; 4384 4385 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4386 return false; 4387 } 4388 4389 // if wback then R[n] = R[n] - 4*BitCount(registers); 4390 if (wback) 4391 { 4392 offset = (addr_byte_size * BitCount (registers)) * -1; 4393 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4394 context.SetImmediateSigned (offset); 4395 addr_t data = Rn + offset; 4396 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4397 return false; 4398 } 4399 } 4400 return true; 4401 } 4402 4403 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4404 // from a base register. The consecutive memory locations start just above this address, and the address of the last 4405 // of those locations can optionally be written back to the base register. 4406 bool 4407 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4408 { 4409 #if 0 4410 if ConditionPassed() then 4411 EncodingSpecificOperations(); 4412 address = R[n] + 4; 4413 4414 for i = 0 to 14 4415 if registers<i> == '1' then 4416 if i == n && wback && i != LowestSetBit(registers) then 4417 MemA[address,4] = bits(32) UNKNOWN; 4418 else 4419 MemA[address,4] = R[i]; 4420 address = address + 4; 4421 4422 if registers<15> == '1' then 4423 MemA[address,4] = PCStoreValue(); 4424 4425 if wback then R[n] = R[n] + 4*BitCount(registers); 4426 #endif 4427 4428 bool success = false; 4429 4430 if (ConditionPassed(opcode)) 4431 { 4432 uint32_t n; 4433 uint32_t registers = 0; 4434 bool wback; 4435 const uint32_t addr_byte_size = GetAddressByteSize(); 4436 4437 // EncodingSpecificOperations(); 4438 switch (encoding) 4439 { 4440 case eEncodingA1: 4441 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4442 n = Bits32 (opcode, 19, 16); 4443 registers = Bits32 (opcode, 15, 0); 4444 wback = BitIsSet (opcode, 21); 4445 4446 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4447 if ((n == 15) && (BitCount (registers) < 1)) 4448 return false; 4449 break; 4450 default: 4451 return false; 4452 } 4453 // address = R[n] + 4; 4454 4455 int32_t offset = 0; 4456 addr_t Rn = ReadCoreReg (n, &success); 4457 if (!success) 4458 return false; 4459 4460 addr_t address = Rn + addr_byte_size; 4461 4462 EmulateInstruction::Context context; 4463 context.type = EmulateInstruction::eContextRegisterStore; 4464 RegisterInfo base_reg; 4465 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4466 4467 uint32_t lowest_set_bit = 14; 4468 // for i = 0 to 14 4469 for (int i = 0; i < 14; ++i) 4470 { 4471 // if registers<i> == '1' then 4472 if (BitIsSet (registers, i)) 4473 { 4474 if (i < lowest_set_bit) 4475 lowest_set_bit = i; 4476 // if i == n && wback && i != LowestSetBit(registers) then 4477 if ((i == n) && wback && (i != lowest_set_bit)) 4478 // MemA[address,4] = bits(32) UNKNOWN; 4479 WriteBits32UnknownToMemory (address + offset); 4480 // else 4481 else 4482 { 4483 // MemA[address,4] = R[i]; 4484 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4485 if (!success) 4486 return false; 4487 4488 RegisterInfo data_reg; 4489 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4490 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4491 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4492 return false; 4493 } 4494 4495 // address = address + 4; 4496 offset += addr_byte_size; 4497 } 4498 } 4499 4500 // if registers<15> == '1' then 4501 // MemA[address,4] = PCStoreValue(); 4502 if (BitIsSet (registers, 15)) 4503 { 4504 RegisterInfo pc_reg; 4505 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4506 context.SetRegisterPlusOffset (pc_reg, 8); 4507 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4508 if (!success) 4509 return false; 4510 4511 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4512 return false; 4513 } 4514 4515 // if wback then R[n] = R[n] + 4*BitCount(registers); 4516 if (wback) 4517 { 4518 offset = addr_byte_size * BitCount (registers); 4519 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4520 context.SetImmediateSigned (offset); 4521 addr_t data = Rn + offset; 4522 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4523 return false; 4524 } 4525 } 4526 return true; 4527 } 4528 4529 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 4530 // from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4531 bool 4532 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4533 { 4534 #if 0 4535 if ConditionPassed() then 4536 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4537 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4538 address = if index then offset_addr else R[n]; 4539 if UnalignedSupport() || address<1:0> == '00' then 4540 MemU[address,4] = R[t]; 4541 else // Can only occur before ARMv7 4542 MemU[address,4] = bits(32) UNKNOWN; 4543 if wback then R[n] = offset_addr; 4544 #endif 4545 4546 bool success = false; 4547 4548 if (ConditionPassed(opcode)) 4549 { 4550 const uint32_t addr_byte_size = GetAddressByteSize(); 4551 4552 uint32_t t; 4553 uint32_t n; 4554 uint32_t imm32; 4555 bool index; 4556 bool add; 4557 bool wback; 4558 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4559 switch (encoding) 4560 { 4561 case eEncodingT1: 4562 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4563 t = Bits32 (opcode, 2, 0); 4564 n = Bits32 (opcode, 5, 3); 4565 imm32 = Bits32 (opcode, 10, 6) << 2; 4566 4567 // index = TRUE; add = TRUE; wback = FALSE; 4568 index = true; 4569 add = false; 4570 wback = false; 4571 break; 4572 4573 case eEncodingT2: 4574 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4575 t = Bits32 (opcode, 10, 8); 4576 n = 13; 4577 imm32 = Bits32 (opcode, 7, 0) << 2; 4578 4579 // index = TRUE; add = TRUE; wback = FALSE; 4580 index = true; 4581 add = true; 4582 wback = false; 4583 break; 4584 4585 case eEncodingT3: 4586 // if Rn == '1111' then UNDEFINED; 4587 if (Bits32 (opcode, 19, 16) == 15) 4588 return false; 4589 4590 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4591 t = Bits32 (opcode, 15, 12); 4592 n = Bits32 (opcode, 19, 16); 4593 imm32 = Bits32 (opcode, 11, 0); 4594 4595 // index = TRUE; add = TRUE; wback = FALSE; 4596 index = true; 4597 add = true; 4598 wback = false; 4599 4600 // if t == 15 then UNPREDICTABLE; 4601 if (t == 15) 4602 return false; 4603 break; 4604 4605 case eEncodingT4: 4606 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4607 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4608 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4609 if ((Bits32 (opcode, 19, 16) == 15) 4610 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4611 return false; 4612 4613 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4614 t = Bits32 (opcode, 15, 12); 4615 n = Bits32 (opcode, 19, 16); 4616 imm32 = Bits32 (opcode, 7, 0); 4617 4618 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4619 index = BitIsSet (opcode, 10); 4620 add = BitIsSet (opcode, 9); 4621 wback = BitIsSet (opcode, 8); 4622 4623 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4624 if ((t == 15) || (wback && (n == t))) 4625 return false; 4626 break; 4627 4628 default: 4629 return false; 4630 } 4631 4632 addr_t offset_addr; 4633 addr_t address; 4634 4635 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4636 uint32_t base_address = ReadCoreReg (n, &success); 4637 if (!success) 4638 return false; 4639 4640 if (add) 4641 offset_addr = base_address + imm32; 4642 else 4643 offset_addr = base_address - imm32; 4644 4645 // address = if index then offset_addr else R[n]; 4646 if (index) 4647 address = offset_addr; 4648 else 4649 address = base_address; 4650 4651 EmulateInstruction::Context context; 4652 context.type = eContextRegisterStore; 4653 RegisterInfo base_reg; 4654 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4655 4656 // if UnalignedSupport() || address<1:0> == '00' then 4657 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4658 { 4659 // MemU[address,4] = R[t]; 4660 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4661 if (!success) 4662 return false; 4663 4664 RegisterInfo data_reg; 4665 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4666 int32_t offset = address - base_address; 4667 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4668 if (!MemUWrite (context, address, data, addr_byte_size)) 4669 return false; 4670 } 4671 else 4672 { 4673 // MemU[address,4] = bits(32) UNKNOWN; 4674 WriteBits32UnknownToMemory (address); 4675 } 4676 4677 // if wback then R[n] = offset_addr; 4678 if (wback) 4679 { 4680 context.type = eContextRegisterLoad; 4681 context.SetAddress (offset_addr); 4682 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4683 return false; 4684 } 4685 } 4686 return true; 4687 } 4688 4689 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4690 // word from a register to memory. The offset register value can optionally be shifted. 4691 bool 4692 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4693 { 4694 #if 0 4695 if ConditionPassed() then 4696 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4697 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4698 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4699 address = if index then offset_addr else R[n]; 4700 if t == 15 then // Only possible for encoding A1 4701 data = PCStoreValue(); 4702 else 4703 data = R[t]; 4704 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4705 MemU[address,4] = data; 4706 else // Can only occur before ARMv7 4707 MemU[address,4] = bits(32) UNKNOWN; 4708 if wback then R[n] = offset_addr; 4709 #endif 4710 4711 bool success = false; 4712 4713 if (ConditionPassed(opcode)) 4714 { 4715 const uint32_t addr_byte_size = GetAddressByteSize(); 4716 4717 uint32_t t; 4718 uint32_t n; 4719 uint32_t m; 4720 ARM_ShifterType shift_t; 4721 uint32_t shift_n; 4722 bool index; 4723 bool add; 4724 bool wback; 4725 4726 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4727 switch (encoding) 4728 { 4729 case eEncodingT1: 4730 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4731 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4732 t = Bits32 (opcode, 2, 0); 4733 n = Bits32 (opcode, 5, 3); 4734 m = Bits32 (opcode, 8, 6); 4735 4736 // index = TRUE; add = TRUE; wback = FALSE; 4737 index = true; 4738 add = true; 4739 wback = false; 4740 4741 // (shift_t, shift_n) = (SRType_LSL, 0); 4742 shift_t = SRType_LSL; 4743 shift_n = 0; 4744 break; 4745 4746 case eEncodingT2: 4747 // if Rn == '1111' then UNDEFINED; 4748 if (Bits32 (opcode, 19, 16) == 15) 4749 return false; 4750 4751 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4752 t = Bits32 (opcode, 15, 12); 4753 n = Bits32 (opcode, 19, 16); 4754 m = Bits32 (opcode, 3, 0); 4755 4756 // index = TRUE; add = TRUE; wback = FALSE; 4757 index = true; 4758 add = true; 4759 wback = false; 4760 4761 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4762 shift_t = SRType_LSL; 4763 shift_n = Bits32 (opcode, 5, 4); 4764 4765 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4766 if ((t == 15) || (BadReg (m))) 4767 return false; 4768 break; 4769 4770 case eEncodingA1: 4771 { 4772 // if P == '0' && W == '1' then SEE STRT; 4773 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4774 t = Bits32 (opcode, 15, 12); 4775 n = Bits32 (opcode, 19, 16); 4776 m = Bits32 (opcode, 3, 0); 4777 4778 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4779 index = BitIsSet (opcode, 24); 4780 add = BitIsSet (opcode, 23); 4781 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4782 4783 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4784 uint32_t typ = Bits32 (opcode, 6, 5); 4785 uint32_t imm5 = Bits32 (opcode, 11, 7); 4786 shift_n = DecodeImmShift(typ, imm5, shift_t); 4787 4788 // if m == 15 then UNPREDICTABLE; 4789 if (m == 15) 4790 return false; 4791 4792 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4793 if (wback && ((n == 15) || (n == t))) 4794 return false; 4795 4796 break; 4797 } 4798 default: 4799 return false; 4800 } 4801 4802 addr_t offset_addr; 4803 addr_t address; 4804 int32_t offset = 0; 4805 4806 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4807 if (!success) 4808 return false; 4809 4810 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4811 if (!success) 4812 return false; 4813 4814 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4815 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4816 if (!success) 4817 return false; 4818 4819 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4820 if (add) 4821 offset_addr = base_address + offset; 4822 else 4823 offset_addr = base_address - offset; 4824 4825 // address = if index then offset_addr else R[n]; 4826 if (index) 4827 address = offset_addr; 4828 else 4829 address = base_address; 4830 4831 uint32_t data; 4832 // if t == 15 then // Only possible for encoding A1 4833 if (t == 15) 4834 // data = PCStoreValue(); 4835 data = ReadCoreReg (PC_REG, &success); 4836 else 4837 // data = R[t]; 4838 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4839 4840 if (!success) 4841 return false; 4842 4843 EmulateInstruction::Context context; 4844 context.type = eContextRegisterStore; 4845 4846 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4847 if (UnalignedSupport () 4848 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4849 || CurrentInstrSet() == eModeARM) 4850 { 4851 // MemU[address,4] = data; 4852 4853 RegisterInfo base_reg; 4854 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4855 4856 RegisterInfo data_reg; 4857 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4858 4859 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4860 if (!MemUWrite (context, address, data, addr_byte_size)) 4861 return false; 4862 4863 } 4864 else 4865 // MemU[address,4] = bits(32) UNKNOWN; 4866 WriteBits32UnknownToMemory (address); 4867 4868 // if wback then R[n] = offset_addr; 4869 if (wback) 4870 { 4871 context.type = eContextRegisterLoad; 4872 context.SetAddress (offset_addr); 4873 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4874 return false; 4875 } 4876 4877 } 4878 return true; 4879 } 4880 4881 bool 4882 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 4883 { 4884 #if 0 4885 if ConditionPassed() then 4886 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4887 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4888 address = if index then offset_addr else R[n]; 4889 MemU[address,1] = R[t]<7:0>; 4890 if wback then R[n] = offset_addr; 4891 #endif 4892 4893 4894 bool success = false; 4895 4896 if (ConditionPassed(opcode)) 4897 { 4898 uint32_t t; 4899 uint32_t n; 4900 uint32_t imm32; 4901 bool index; 4902 bool add; 4903 bool wback; 4904 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4905 switch (encoding) 4906 { 4907 case eEncodingT1: 4908 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 4909 t = Bits32 (opcode, 2, 0); 4910 n = Bits32 (opcode, 5, 3); 4911 imm32 = Bits32 (opcode, 10, 6); 4912 4913 // index = TRUE; add = TRUE; wback = FALSE; 4914 index = true; 4915 add = true; 4916 wback = false; 4917 break; 4918 4919 case eEncodingT2: 4920 // if Rn == '1111' then UNDEFINED; 4921 if (Bits32 (opcode, 19, 16) == 15) 4922 return false; 4923 4924 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4925 t = Bits32 (opcode, 15, 12); 4926 n = Bits32 (opcode, 19, 16); 4927 imm32 = Bits32 (opcode, 11, 0); 4928 4929 // index = TRUE; add = TRUE; wback = FALSE; 4930 index = true; 4931 add = true; 4932 wback = false; 4933 4934 // if BadReg(t) then UNPREDICTABLE; 4935 if (BadReg (t)) 4936 return false; 4937 break; 4938 4939 case eEncodingT3: 4940 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 4941 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4942 if (Bits32 (opcode, 19, 16) == 15) 4943 return false; 4944 4945 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4946 t = Bits32 (opcode, 15, 12); 4947 n = Bits32 (opcode, 19, 16); 4948 imm32 = Bits32 (opcode, 7, 0); 4949 4950 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4951 index = BitIsSet (opcode, 10); 4952 add = BitIsSet (opcode, 9); 4953 wback = BitIsSet (opcode, 8); 4954 4955 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 4956 if ((BadReg (t)) || (wback && (n == t))) 4957 return false; 4958 break; 4959 4960 default: 4961 return false; 4962 } 4963 4964 addr_t offset_addr; 4965 addr_t address; 4966 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4967 if (!success) 4968 return false; 4969 4970 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4971 if (add) 4972 offset_addr = base_address + imm32; 4973 else 4974 offset_addr = base_address - imm32; 4975 4976 // address = if index then offset_addr else R[n]; 4977 if (index) 4978 address = offset_addr; 4979 else 4980 address = base_address; 4981 4982 // MemU[address,1] = R[t]<7:0> 4983 RegisterInfo base_reg; 4984 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4985 4986 RegisterInfo data_reg; 4987 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4988 4989 EmulateInstruction::Context context; 4990 context.type = eContextRegisterStore; 4991 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4992 4993 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4994 if (!success) 4995 return false; 4996 4997 data = Bits32 (data, 7, 0); 4998 4999 if (!MemUWrite (context, address, data, 1)) 5000 return false; 5001 5002 // if wback then R[n] = offset_addr; 5003 if (wback) 5004 { 5005 context.type = eContextRegisterLoad; 5006 context.SetAddress (offset_addr); 5007 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5008 return false; 5009 } 5010 5011 } 5012 5013 return true; 5014 } 5015 5016 // STRH (register) calculates an address from a base register value and an offset register value, and stores a 5017 // halfword from a register to memory. The offset register alue can be shifted left by 0, 1, 2, or 3 bits. 5018 bool 5019 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5020 { 5021 #if 0 5022 if ConditionPassed() then 5023 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5024 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5025 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5026 address = if index then offset_addr else R[n]; 5027 if UnalignedSupport() || address<0> == '0' then 5028 MemU[address,2] = R[t]<15:0>; 5029 else // Can only occur before ARMv7 5030 MemU[address,2] = bits(16) UNKNOWN; 5031 if wback then R[n] = offset_addr; 5032 #endif 5033 5034 bool success = false; 5035 5036 if (ConditionPassed(opcode)) 5037 { 5038 uint32_t t; 5039 uint32_t n; 5040 uint32_t m; 5041 bool index; 5042 bool add; 5043 bool wback; 5044 ARM_ShifterType shift_t; 5045 uint32_t shift_n; 5046 5047 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5048 switch (encoding) 5049 { 5050 case eEncodingT1: 5051 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5052 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5053 t = Bits32 (opcode, 2, 0); 5054 n = Bits32 (opcode, 5, 3); 5055 m = Bits32 (opcode, 8, 6); 5056 5057 // index = TRUE; add = TRUE; wback = FALSE; 5058 index = true; 5059 add = true; 5060 wback = false; 5061 5062 // (shift_t, shift_n) = (SRType_LSL, 0); 5063 shift_t = SRType_LSL; 5064 shift_n = 0; 5065 5066 break; 5067 5068 case eEncodingT2: 5069 // if Rn == '1111' then UNDEFINED; 5070 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5071 t = Bits32 (opcode, 15, 12); 5072 n = Bits32 (opcode, 19, 16); 5073 m = Bits32 (opcode, 3, 0); 5074 if (n == 15) 5075 return false; 5076 5077 // index = TRUE; add = TRUE; wback = FALSE; 5078 index = true; 5079 add = true; 5080 wback = false; 5081 5082 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5083 shift_t = SRType_LSL; 5084 shift_n = Bits32 (opcode, 5, 4); 5085 5086 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5087 if (BadReg (t) || BadReg (m)) 5088 return false; 5089 5090 break; 5091 5092 case eEncodingA1: 5093 // if P == '0' && W == '1' then SEE STRHT; 5094 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5095 t = Bits32 (opcode, 15, 12); 5096 n = Bits32 (opcode, 19, 16); 5097 m = Bits32 (opcode, 3, 0); 5098 5099 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5100 index = BitIsSet (opcode, 24); 5101 add = BitIsSet (opcode, 23); 5102 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5103 5104 // (shift_t, shift_n) = (SRType_LSL, 0); 5105 shift_t = SRType_LSL; 5106 shift_n = 0; 5107 5108 // if t == 15 || m == 15 then UNPREDICTABLE; 5109 if ((t == 15) || (m == 15)) 5110 return false; 5111 5112 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5113 if (wback && ((n == 15) || (n == t))) 5114 return false; 5115 5116 break; 5117 5118 default: 5119 return false; 5120 } 5121 5122 uint32_t Rm = ReadCoreReg (m, &success); 5123 if (!success) 5124 return false; 5125 5126 uint32_t Rn = ReadCoreReg (n, &success); 5127 if (!success) 5128 return false; 5129 5130 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5131 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5132 if (!success) 5133 return false; 5134 5135 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5136 addr_t offset_addr; 5137 if (add) 5138 offset_addr = Rn + offset; 5139 else 5140 offset_addr = Rn - offset; 5141 5142 // address = if index then offset_addr else R[n]; 5143 addr_t address; 5144 if (index) 5145 address = offset_addr; 5146 else 5147 address = Rn; 5148 5149 EmulateInstruction::Context context; 5150 context.type = eContextRegisterStore; 5151 RegisterInfo base_reg; 5152 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5153 RegisterInfo offset_reg; 5154 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5155 5156 // if UnalignedSupport() || address<0> == '0' then 5157 if (UnalignedSupport() || BitIsClear (address, 0)) 5158 { 5159 // MemU[address,2] = R[t]<15:0>; 5160 uint32_t Rt = ReadCoreReg (t, &success); 5161 if (!success) 5162 return false; 5163 5164 EmulateInstruction::Context context; 5165 context.type = eContextRegisterStore; 5166 RegisterInfo base_reg; 5167 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5168 RegisterInfo offset_reg; 5169 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5170 RegisterInfo data_reg; 5171 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5172 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5173 5174 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5175 return false; 5176 } 5177 else // Can only occur before ARMv7 5178 { 5179 // MemU[address,2] = bits(16) UNKNOWN; 5180 } 5181 5182 // if wback then R[n] = offset_addr; 5183 if (wback) 5184 { 5185 context.type = eContextAdjustBaseRegister; 5186 context.SetAddress (offset_addr); 5187 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5188 return false; 5189 } 5190 } 5191 5192 return true; 5193 } 5194 5195 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5196 // and writes the result to the destination register. It can optionally update the condition flags 5197 // based on the result. 5198 bool 5199 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5200 { 5201 #if 0 5202 // ARM pseudo code... 5203 if ConditionPassed() then 5204 EncodingSpecificOperations(); 5205 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5206 if d == 15 then // Can only occur for ARM encoding 5207 ALUWritePC(result); // setflags is always FALSE here 5208 else 5209 R[d] = result; 5210 if setflags then 5211 APSR.N = result<31>; 5212 APSR.Z = IsZeroBit(result); 5213 APSR.C = carry; 5214 APSR.V = overflow; 5215 #endif 5216 5217 bool success = false; 5218 5219 if (ConditionPassed(opcode)) 5220 { 5221 uint32_t Rd, Rn; 5222 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5223 bool setflags; 5224 switch (encoding) 5225 { 5226 case eEncodingT1: 5227 Rd = Bits32(opcode, 11, 8); 5228 Rn = Bits32(opcode, 19, 16); 5229 setflags = BitIsSet(opcode, 20); 5230 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5231 if (BadReg(Rd) || BadReg(Rn)) 5232 return false; 5233 break; 5234 case eEncodingA1: 5235 Rd = Bits32(opcode, 15, 12); 5236 Rn = Bits32(opcode, 19, 16); 5237 setflags = BitIsSet(opcode, 20); 5238 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5239 5240 if (Rd == 15 && setflags) 5241 return EmulateSUBSPcLrEtc (opcode, encoding); 5242 break; 5243 default: 5244 return false; 5245 } 5246 5247 // Read the first operand. 5248 int32_t val1 = ReadCoreReg(Rn, &success); 5249 if (!success) 5250 return false; 5251 5252 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5253 5254 EmulateInstruction::Context context; 5255 context.type = EmulateInstruction::eContextImmediate; 5256 context.SetNoArgs (); 5257 5258 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5259 return false; 5260 } 5261 return true; 5262 } 5263 5264 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5265 // register value, and writes the result to the destination register. It can optionally update the 5266 // condition flags based on the result. 5267 bool 5268 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5269 { 5270 #if 0 5271 // ARM pseudo code... 5272 if ConditionPassed() then 5273 EncodingSpecificOperations(); 5274 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5275 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5276 if d == 15 then // Can only occur for ARM encoding 5277 ALUWritePC(result); // setflags is always FALSE here 5278 else 5279 R[d] = result; 5280 if setflags then 5281 APSR.N = result<31>; 5282 APSR.Z = IsZeroBit(result); 5283 APSR.C = carry; 5284 APSR.V = overflow; 5285 #endif 5286 5287 bool success = false; 5288 5289 if (ConditionPassed(opcode)) 5290 { 5291 uint32_t Rd, Rn, Rm; 5292 ARM_ShifterType shift_t; 5293 uint32_t shift_n; // the shift applied to the value read from Rm 5294 bool setflags; 5295 switch (encoding) 5296 { 5297 case eEncodingT1: 5298 Rd = Rn = Bits32(opcode, 2, 0); 5299 Rm = Bits32(opcode, 5, 3); 5300 setflags = !InITBlock(); 5301 shift_t = SRType_LSL; 5302 shift_n = 0; 5303 break; 5304 case eEncodingT2: 5305 Rd = Bits32(opcode, 11, 8); 5306 Rn = Bits32(opcode, 19, 16); 5307 Rm = Bits32(opcode, 3, 0); 5308 setflags = BitIsSet(opcode, 20); 5309 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5310 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5311 return false; 5312 break; 5313 case eEncodingA1: 5314 Rd = Bits32(opcode, 15, 12); 5315 Rn = Bits32(opcode, 19, 16); 5316 Rm = Bits32(opcode, 3, 0); 5317 setflags = BitIsSet(opcode, 20); 5318 shift_n = DecodeImmShiftARM(opcode, shift_t); 5319 5320 if (Rd == 15 && setflags) 5321 return EmulateSUBSPcLrEtc (opcode, encoding); 5322 break; 5323 default: 5324 return false; 5325 } 5326 5327 // Read the first operand. 5328 int32_t val1 = ReadCoreReg(Rn, &success); 5329 if (!success) 5330 return false; 5331 5332 // Read the second operand. 5333 int32_t val2 = ReadCoreReg(Rm, &success); 5334 if (!success) 5335 return false; 5336 5337 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5338 if (!success) 5339 return false; 5340 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5341 5342 EmulateInstruction::Context context; 5343 context.type = EmulateInstruction::eContextImmediate; 5344 context.SetNoArgs (); 5345 5346 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5347 return false; 5348 } 5349 return true; 5350 } 5351 5352 // This instruction adds an immediate value to the PC value to form a PC-relative address, 5353 // and writes the result to the destination register. 5354 bool 5355 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5356 { 5357 #if 0 5358 // ARM pseudo code... 5359 if ConditionPassed() then 5360 EncodingSpecificOperations(); 5361 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5362 if d == 15 then // Can only occur for ARM encodings 5363 ALUWritePC(result); 5364 else 5365 R[d] = result; 5366 #endif 5367 5368 bool success = false; 5369 5370 if (ConditionPassed(opcode)) 5371 { 5372 uint32_t Rd; 5373 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5374 bool add; 5375 switch (encoding) 5376 { 5377 case eEncodingT1: 5378 Rd = Bits32(opcode, 10, 8); 5379 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5380 break; 5381 case eEncodingT2: 5382 case eEncodingT3: 5383 Rd = Bits32(opcode, 11, 8); 5384 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5385 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5386 if (BadReg(Rd)) 5387 return false; 5388 break; 5389 case eEncodingA1: 5390 case eEncodingA2: 5391 Rd = Bits32(opcode, 15, 12); 5392 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5393 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5394 break; 5395 default: 5396 return false; 5397 } 5398 5399 // Read the PC value. 5400 uint32_t pc = ReadCoreReg(PC_REG, &success); 5401 if (!success) 5402 return false; 5403 5404 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5405 5406 EmulateInstruction::Context context; 5407 context.type = EmulateInstruction::eContextImmediate; 5408 context.SetNoArgs (); 5409 5410 if (!WriteCoreReg(context, result, Rd)) 5411 return false; 5412 } 5413 return true; 5414 } 5415 5416 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5417 // to the destination register. It can optionally update the condition flags based on the result. 5418 bool 5419 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5420 { 5421 #if 0 5422 // ARM pseudo code... 5423 if ConditionPassed() then 5424 EncodingSpecificOperations(); 5425 result = R[n] AND imm32; 5426 if d == 15 then // Can only occur for ARM encoding 5427 ALUWritePC(result); // setflags is always FALSE here 5428 else 5429 R[d] = result; 5430 if setflags then 5431 APSR.N = result<31>; 5432 APSR.Z = IsZeroBit(result); 5433 APSR.C = carry; 5434 // APSR.V unchanged 5435 #endif 5436 5437 bool success = false; 5438 5439 if (ConditionPassed(opcode)) 5440 { 5441 uint32_t Rd, Rn; 5442 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5443 bool setflags; 5444 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5445 switch (encoding) 5446 { 5447 case eEncodingT1: 5448 Rd = Bits32(opcode, 11, 8); 5449 Rn = Bits32(opcode, 19, 16); 5450 setflags = BitIsSet(opcode, 20); 5451 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5452 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5453 if (Rd == 15 && setflags) 5454 return EmulateTSTImm(opcode, eEncodingT1); 5455 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5456 return false; 5457 break; 5458 case eEncodingA1: 5459 Rd = Bits32(opcode, 15, 12); 5460 Rn = Bits32(opcode, 19, 16); 5461 setflags = BitIsSet(opcode, 20); 5462 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5463 5464 if (Rd == 15 && setflags) 5465 return EmulateSUBSPcLrEtc (opcode, encoding); 5466 break; 5467 default: 5468 return false; 5469 } 5470 5471 // Read the first operand. 5472 uint32_t val1 = ReadCoreReg(Rn, &success); 5473 if (!success) 5474 return false; 5475 5476 uint32_t result = val1 & imm32; 5477 5478 EmulateInstruction::Context context; 5479 context.type = EmulateInstruction::eContextImmediate; 5480 context.SetNoArgs (); 5481 5482 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5483 return false; 5484 } 5485 return true; 5486 } 5487 5488 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5489 // and writes the result to the destination register. It can optionally update the condition flags 5490 // based on the result. 5491 bool 5492 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5493 { 5494 #if 0 5495 // ARM pseudo code... 5496 if ConditionPassed() then 5497 EncodingSpecificOperations(); 5498 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5499 result = R[n] AND shifted; 5500 if d == 15 then // Can only occur for ARM encoding 5501 ALUWritePC(result); // setflags is always FALSE here 5502 else 5503 R[d] = result; 5504 if setflags then 5505 APSR.N = result<31>; 5506 APSR.Z = IsZeroBit(result); 5507 APSR.C = carry; 5508 // APSR.V unchanged 5509 #endif 5510 5511 bool success = false; 5512 5513 if (ConditionPassed(opcode)) 5514 { 5515 uint32_t Rd, Rn, Rm; 5516 ARM_ShifterType shift_t; 5517 uint32_t shift_n; // the shift applied to the value read from Rm 5518 bool setflags; 5519 uint32_t carry; 5520 switch (encoding) 5521 { 5522 case eEncodingT1: 5523 Rd = Rn = Bits32(opcode, 2, 0); 5524 Rm = Bits32(opcode, 5, 3); 5525 setflags = !InITBlock(); 5526 shift_t = SRType_LSL; 5527 shift_n = 0; 5528 break; 5529 case eEncodingT2: 5530 Rd = Bits32(opcode, 11, 8); 5531 Rn = Bits32(opcode, 19, 16); 5532 Rm = Bits32(opcode, 3, 0); 5533 setflags = BitIsSet(opcode, 20); 5534 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5535 // if Rd == '1111' && S == '1' then SEE TST (register); 5536 if (Rd == 15 && setflags) 5537 return EmulateTSTReg(opcode, eEncodingT2); 5538 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5539 return false; 5540 break; 5541 case eEncodingA1: 5542 Rd = Bits32(opcode, 15, 12); 5543 Rn = Bits32(opcode, 19, 16); 5544 Rm = Bits32(opcode, 3, 0); 5545 setflags = BitIsSet(opcode, 20); 5546 shift_n = DecodeImmShiftARM(opcode, shift_t); 5547 5548 if (Rd == 15 && setflags) 5549 return EmulateSUBSPcLrEtc (opcode, encoding); 5550 break; 5551 default: 5552 return false; 5553 } 5554 5555 // Read the first operand. 5556 uint32_t val1 = ReadCoreReg(Rn, &success); 5557 if (!success) 5558 return false; 5559 5560 // Read the second operand. 5561 uint32_t val2 = ReadCoreReg(Rm, &success); 5562 if (!success) 5563 return false; 5564 5565 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5566 if (!success) 5567 return false; 5568 uint32_t result = val1 & shifted; 5569 5570 EmulateInstruction::Context context; 5571 context.type = EmulateInstruction::eContextImmediate; 5572 context.SetNoArgs (); 5573 5574 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5575 return false; 5576 } 5577 return true; 5578 } 5579 5580 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5581 // immediate value, and writes the result to the destination register. It can optionally update the 5582 // condition flags based on the result. 5583 bool 5584 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5585 { 5586 #if 0 5587 // ARM pseudo code... 5588 if ConditionPassed() then 5589 EncodingSpecificOperations(); 5590 result = R[n] AND NOT(imm32); 5591 if d == 15 then // Can only occur for ARM encoding 5592 ALUWritePC(result); // setflags is always FALSE here 5593 else 5594 R[d] = result; 5595 if setflags then 5596 APSR.N = result<31>; 5597 APSR.Z = IsZeroBit(result); 5598 APSR.C = carry; 5599 // APSR.V unchanged 5600 #endif 5601 5602 bool success = false; 5603 5604 if (ConditionPassed(opcode)) 5605 { 5606 uint32_t Rd, Rn; 5607 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5608 bool setflags; 5609 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5610 switch (encoding) 5611 { 5612 case eEncodingT1: 5613 Rd = Bits32(opcode, 11, 8); 5614 Rn = Bits32(opcode, 19, 16); 5615 setflags = BitIsSet(opcode, 20); 5616 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5617 if (BadReg(Rd) || BadReg(Rn)) 5618 return false; 5619 break; 5620 case eEncodingA1: 5621 Rd = Bits32(opcode, 15, 12); 5622 Rn = Bits32(opcode, 19, 16); 5623 setflags = BitIsSet(opcode, 20); 5624 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5625 5626 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5627 if (Rd == 15 && setflags) 5628 return EmulateSUBSPcLrEtc (opcode, encoding); 5629 break; 5630 default: 5631 return false; 5632 } 5633 5634 // Read the first operand. 5635 uint32_t val1 = ReadCoreReg(Rn, &success); 5636 if (!success) 5637 return false; 5638 5639 uint32_t result = val1 & ~imm32; 5640 5641 EmulateInstruction::Context context; 5642 context.type = EmulateInstruction::eContextImmediate; 5643 context.SetNoArgs (); 5644 5645 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5646 return false; 5647 } 5648 return true; 5649 } 5650 5651 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5652 // optionally-shifted register value, and writes the result to the destination register. 5653 // It can optionally update the condition flags based on the result. 5654 bool 5655 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5656 { 5657 #if 0 5658 // ARM pseudo code... 5659 if ConditionPassed() then 5660 EncodingSpecificOperations(); 5661 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5662 result = R[n] AND NOT(shifted); 5663 if d == 15 then // Can only occur for ARM encoding 5664 ALUWritePC(result); // setflags is always FALSE here 5665 else 5666 R[d] = result; 5667 if setflags then 5668 APSR.N = result<31>; 5669 APSR.Z = IsZeroBit(result); 5670 APSR.C = carry; 5671 // APSR.V unchanged 5672 #endif 5673 5674 bool success = false; 5675 5676 if (ConditionPassed(opcode)) 5677 { 5678 uint32_t Rd, Rn, Rm; 5679 ARM_ShifterType shift_t; 5680 uint32_t shift_n; // the shift applied to the value read from Rm 5681 bool setflags; 5682 uint32_t carry; 5683 switch (encoding) 5684 { 5685 case eEncodingT1: 5686 Rd = Rn = Bits32(opcode, 2, 0); 5687 Rm = Bits32(opcode, 5, 3); 5688 setflags = !InITBlock(); 5689 shift_t = SRType_LSL; 5690 shift_n = 0; 5691 break; 5692 case eEncodingT2: 5693 Rd = Bits32(opcode, 11, 8); 5694 Rn = Bits32(opcode, 19, 16); 5695 Rm = Bits32(opcode, 3, 0); 5696 setflags = BitIsSet(opcode, 20); 5697 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5698 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5699 return false; 5700 break; 5701 case eEncodingA1: 5702 Rd = Bits32(opcode, 15, 12); 5703 Rn = Bits32(opcode, 19, 16); 5704 Rm = Bits32(opcode, 3, 0); 5705 setflags = BitIsSet(opcode, 20); 5706 shift_n = DecodeImmShiftARM(opcode, shift_t); 5707 5708 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5709 if (Rd == 15 && setflags) 5710 return EmulateSUBSPcLrEtc (opcode, encoding); 5711 break; 5712 default: 5713 return false; 5714 } 5715 5716 // Read the first operand. 5717 uint32_t val1 = ReadCoreReg(Rn, &success); 5718 if (!success) 5719 return false; 5720 5721 // Read the second operand. 5722 uint32_t val2 = ReadCoreReg(Rm, &success); 5723 if (!success) 5724 return false; 5725 5726 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5727 if (!success) 5728 return false; 5729 uint32_t result = val1 & ~shifted; 5730 5731 EmulateInstruction::Context context; 5732 context.type = EmulateInstruction::eContextImmediate; 5733 context.SetNoArgs (); 5734 5735 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5736 return false; 5737 } 5738 return true; 5739 } 5740 5741 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5742 // from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5743 bool 5744 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5745 { 5746 #if 0 5747 if ConditionPassed() then 5748 EncodingSpecificOperations(); 5749 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5750 address = if index then offset_addr else R[n]; 5751 data = MemU[address,4]; 5752 if wback then R[n] = offset_addr; 5753 if t == 15 then 5754 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5755 elsif UnalignedSupport() || address<1:0> = '00' then 5756 R[t] = data; 5757 else // Can only apply before ARMv7 5758 R[t] = ROR(data, 8*UInt(address<1:0>)); 5759 #endif 5760 5761 bool success = false; 5762 5763 if (ConditionPassed(opcode)) 5764 { 5765 const uint32_t addr_byte_size = GetAddressByteSize(); 5766 5767 uint32_t t; 5768 uint32_t n; 5769 uint32_t imm32; 5770 bool index; 5771 bool add; 5772 bool wback; 5773 5774 switch (encoding) 5775 { 5776 case eEncodingA1: 5777 // if Rn == '1111' then SEE LDR (literal); 5778 // if P == '0' && W == '1' then SEE LDRT; 5779 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5780 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5781 t = Bits32 (opcode, 15, 12); 5782 n = Bits32 (opcode, 19, 16); 5783 imm32 = Bits32 (opcode, 11, 0); 5784 5785 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5786 index = BitIsSet (opcode, 24); 5787 add = BitIsSet (opcode, 23); 5788 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5789 5790 // if wback && n == t then UNPREDICTABLE; 5791 if (wback && (n == t)) 5792 return false; 5793 5794 break; 5795 5796 default: 5797 return false; 5798 } 5799 5800 addr_t address; 5801 addr_t offset_addr; 5802 addr_t base_address = ReadCoreReg (n, &success); 5803 if (!success) 5804 return false; 5805 5806 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5807 if (add) 5808 offset_addr = base_address + imm32; 5809 else 5810 offset_addr = base_address - imm32; 5811 5812 // address = if index then offset_addr else R[n]; 5813 if (index) 5814 address = offset_addr; 5815 else 5816 address = base_address; 5817 5818 // data = MemU[address,4]; 5819 5820 RegisterInfo base_reg; 5821 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5822 5823 EmulateInstruction::Context context; 5824 context.type = eContextRegisterLoad; 5825 context.SetRegisterPlusOffset (base_reg, address - base_address); 5826 5827 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5828 if (!success) 5829 return false; 5830 5831 // if wback then R[n] = offset_addr; 5832 if (wback) 5833 { 5834 context.type = eContextAdjustBaseRegister; 5835 context.SetAddress (offset_addr); 5836 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5837 return false; 5838 } 5839 5840 // if t == 15 then 5841 if (t == 15) 5842 { 5843 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5844 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5845 { 5846 // LoadWritePC (data); 5847 context.type = eContextRegisterLoad; 5848 context.SetRegisterPlusOffset (base_reg, address - base_address); 5849 LoadWritePC (context, data); 5850 } 5851 else 5852 return false; 5853 } 5854 // elsif UnalignedSupport() || address<1:0> = '00' then 5855 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5856 { 5857 // R[t] = data; 5858 context.type = eContextRegisterLoad; 5859 context.SetRegisterPlusOffset (base_reg, address - base_address); 5860 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5861 return false; 5862 } 5863 // else // Can only apply before ARMv7 5864 else 5865 { 5866 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5867 data = ROR (data, Bits32 (address, 1, 0), &success); 5868 if (!success) 5869 return false; 5870 context.type = eContextRegisterLoad; 5871 context.SetImmediate (data); 5872 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5873 return false; 5874 } 5875 5876 } 5877 return true; 5878 } 5879 5880 // LDR (register) calculates an address from a base register value and an offset register value, loads a word 5881 // from memory, and writes it to a resgister. The offset register value can optionally be shifted. 5882 bool 5883 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 5884 { 5885 #if 0 5886 if ConditionPassed() then 5887 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5888 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5889 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5890 address = if index then offset_addr else R[n]; 5891 data = MemU[address,4]; 5892 if wback then R[n] = offset_addr; 5893 if t == 15 then 5894 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5895 elsif UnalignedSupport() || address<1:0> = '00' then 5896 R[t] = data; 5897 else // Can only apply before ARMv7 5898 if CurrentInstrSet() == InstrSet_ARM then 5899 R[t] = ROR(data, 8*UInt(address<1:0>)); 5900 else 5901 R[t] = bits(32) UNKNOWN; 5902 #endif 5903 5904 bool success = false; 5905 5906 if (ConditionPassed(opcode)) 5907 { 5908 const uint32_t addr_byte_size = GetAddressByteSize(); 5909 5910 uint32_t t; 5911 uint32_t n; 5912 uint32_t m; 5913 bool index; 5914 bool add; 5915 bool wback; 5916 ARM_ShifterType shift_t; 5917 uint32_t shift_n; 5918 5919 switch (encoding) 5920 { 5921 case eEncodingT1: 5922 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5923 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5924 t = Bits32 (opcode, 2, 0); 5925 n = Bits32 (opcode, 5, 3); 5926 m = Bits32 (opcode, 8, 6); 5927 5928 // index = TRUE; add = TRUE; wback = FALSE; 5929 index = true; 5930 add = true; 5931 wback = false; 5932 5933 // (shift_t, shift_n) = (SRType_LSL, 0); 5934 shift_t = SRType_LSL; 5935 shift_n = 0; 5936 5937 break; 5938 5939 case eEncodingT2: 5940 // if Rn == '1111' then SEE LDR (literal); 5941 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5942 t = Bits32 (opcode, 15, 12); 5943 n = Bits32 (opcode, 19, 16); 5944 m = Bits32 (opcode, 3, 0); 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, UInt(imm2)); 5952 shift_t = SRType_LSL; 5953 shift_n = Bits32 (opcode, 5, 4); 5954 5955 // if BadReg(m) then UNPREDICTABLE; 5956 if (BadReg (m)) 5957 return false; 5958 5959 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 5960 if ((t == 15) && InITBlock() && !LastInITBlock()) 5961 return false; 5962 5963 break; 5964 5965 case eEncodingA1: 5966 { 5967 // if P == '0' && W == '1' then SEE LDRT; 5968 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5969 t = Bits32 (opcode, 15, 12); 5970 n = Bits32 (opcode, 19, 16); 5971 m = Bits32 (opcode, 3, 0); 5972 5973 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5974 index = BitIsSet (opcode, 24); 5975 add = BitIsSet (opcode, 23); 5976 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5977 5978 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5979 uint32_t type = Bits32 (opcode, 6, 5); 5980 uint32_t imm5 = Bits32 (opcode, 11, 7); 5981 shift_n = DecodeImmShift (type, imm5, shift_t); 5982 5983 // if m == 15 then UNPREDICTABLE; 5984 if (m == 15) 5985 return false; 5986 5987 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5988 if (wback && ((n == 15) || (n == t))) 5989 return false; 5990 } 5991 break; 5992 5993 5994 default: 5995 return false; 5996 } 5997 5998 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5999 if (!success) 6000 return false; 6001 6002 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6003 if (!success) 6004 return false; 6005 6006 addr_t offset_addr; 6007 addr_t address; 6008 6009 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6010 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6011 if (!success) 6012 return false; 6013 6014 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6015 if (add) 6016 offset_addr = Rn + offset; 6017 else 6018 offset_addr = Rn - offset; 6019 6020 // address = if index then offset_addr else R[n]; 6021 if (index) 6022 address = offset_addr; 6023 else 6024 address = Rn; 6025 6026 // data = MemU[address,4]; 6027 RegisterInfo base_reg; 6028 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6029 6030 EmulateInstruction::Context context; 6031 context.type = eContextRegisterLoad; 6032 context.SetRegisterPlusOffset (base_reg, address - Rn); 6033 6034 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6035 if (!success) 6036 return false; 6037 6038 // if wback then R[n] = offset_addr; 6039 if (wback) 6040 { 6041 context.type = eContextAdjustBaseRegister; 6042 context.SetAddress (offset_addr); 6043 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6044 return false; 6045 } 6046 6047 // if t == 15 then 6048 if (t == 15) 6049 { 6050 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6051 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6052 { 6053 context.type = eContextRegisterLoad; 6054 context.SetRegisterPlusOffset (base_reg, address - Rn); 6055 LoadWritePC (context, data); 6056 } 6057 else 6058 return false; 6059 } 6060 // elsif UnalignedSupport() || address<1:0> = '00' then 6061 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6062 { 6063 // R[t] = data; 6064 context.type = eContextRegisterLoad; 6065 context.SetRegisterPlusOffset (base_reg, address - Rn); 6066 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6067 return false; 6068 } 6069 else // Can only apply before ARMv7 6070 { 6071 // if CurrentInstrSet() == InstrSet_ARM then 6072 if (CurrentInstrSet () == eModeARM) 6073 { 6074 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6075 data = ROR (data, Bits32 (address, 1, 0), &success); 6076 if (!success) 6077 return false; 6078 context.type = eContextRegisterLoad; 6079 context.SetImmediate (data); 6080 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6081 return false; 6082 } 6083 else 6084 { 6085 // R[t] = bits(32) UNKNOWN; 6086 WriteBits32Unknown (t); 6087 } 6088 } 6089 } 6090 return true; 6091 } 6092 6093 // LDRB (immediate, Thumb) 6094 bool 6095 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6096 { 6097 #if 0 6098 if ConditionPassed() then 6099 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6100 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6101 address = if index then offset_addr else R[n]; 6102 R[t] = ZeroExtend(MemU[address,1], 32); 6103 if wback then R[n] = offset_addr; 6104 #endif 6105 6106 bool success = false; 6107 6108 if (ConditionPassed(opcode)) 6109 { 6110 uint32_t t; 6111 uint32_t n; 6112 uint32_t imm32; 6113 bool index; 6114 bool add; 6115 bool wback; 6116 6117 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6118 switch (encoding) 6119 { 6120 case eEncodingT1: 6121 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6122 t = Bits32 (opcode, 2, 0); 6123 n = Bits32 (opcode, 5, 3); 6124 imm32 = Bits32 (opcode, 10, 6); 6125 6126 // index = TRUE; add = TRUE; wback = FALSE; 6127 index = true; 6128 add = true; 6129 wback= false; 6130 6131 break; 6132 6133 case eEncodingT2: 6134 // if Rt == '1111' then SEE PLD; 6135 // if Rn == '1111' then SEE LDRB (literal); 6136 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6137 t = Bits32 (opcode, 15, 12); 6138 n = Bits32 (opcode, 19, 16); 6139 imm32 = Bits32 (opcode, 11, 0); 6140 6141 // index = TRUE; add = TRUE; wback = FALSE; 6142 index = true; 6143 add = true; 6144 wback = false; 6145 6146 // if t == 13 then UNPREDICTABLE; 6147 if (t == 13) 6148 return false; 6149 6150 break; 6151 6152 case eEncodingT3: 6153 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6154 // if Rn == '1111' then SEE LDRB (literal); 6155 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6156 // if P == '0' && W == '0' then UNDEFINED; 6157 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6158 return false; 6159 6160 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6161 t = Bits32 (opcode, 15, 12); 6162 n = Bits32 (opcode, 19, 16); 6163 imm32 = Bits32 (opcode, 7, 0); 6164 6165 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6166 index = BitIsSet (opcode, 10); 6167 add = BitIsSet (opcode, 9); 6168 wback = BitIsSet (opcode, 8); 6169 6170 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6171 if (BadReg (t) || (wback && (n == t))) 6172 return false; 6173 6174 break; 6175 6176 default: 6177 return false; 6178 } 6179 6180 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6181 if (!success) 6182 return false; 6183 6184 addr_t address; 6185 addr_t offset_addr; 6186 6187 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6188 if (add) 6189 offset_addr = Rn + imm32; 6190 else 6191 offset_addr = Rn - imm32; 6192 6193 // address = if index then offset_addr else R[n]; 6194 if (index) 6195 address = offset_addr; 6196 else 6197 address = Rn; 6198 6199 // R[t] = ZeroExtend(MemU[address,1], 32); 6200 RegisterInfo base_reg; 6201 RegisterInfo data_reg; 6202 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6203 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6204 6205 EmulateInstruction::Context context; 6206 context.type = eContextRegisterLoad; 6207 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6208 6209 uint64_t data = MemURead (context, address, 1, 0, &success); 6210 if (!success) 6211 return false; 6212 6213 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6214 return false; 6215 6216 // if wback then R[n] = offset_addr; 6217 if (wback) 6218 { 6219 context.type = eContextAdjustBaseRegister; 6220 context.SetAddress (offset_addr); 6221 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6222 return false; 6223 } 6224 } 6225 return true; 6226 } 6227 6228 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6229 // zero-extends it to form a 32-bit word and writes it to a register. 6230 bool 6231 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6232 { 6233 #if 0 6234 if ConditionPassed() then 6235 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6236 base = Align(PC,4); 6237 address = if add then (base + imm32) else (base - imm32); 6238 R[t] = ZeroExtend(MemU[address,1], 32); 6239 #endif 6240 6241 bool success = false; 6242 6243 if (ConditionPassed(opcode)) 6244 { 6245 uint32_t t; 6246 uint32_t imm32; 6247 bool add; 6248 switch (encoding) 6249 { 6250 case eEncodingT1: 6251 // if Rt == '1111' then SEE PLD; 6252 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6253 t = Bits32 (opcode, 15, 12); 6254 imm32 = Bits32 (opcode, 11, 0); 6255 add = BitIsSet (opcode, 23); 6256 6257 // if t == 13 then UNPREDICTABLE; 6258 if (t == 13) 6259 return false; 6260 6261 break; 6262 6263 case eEncodingA1: 6264 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6265 t = Bits32 (opcode, 15, 12); 6266 imm32 = Bits32 (opcode, 11, 0); 6267 add = BitIsSet (opcode, 23); 6268 6269 // if t == 15 then UNPREDICTABLE; 6270 if (t == 15) 6271 return false; 6272 break; 6273 6274 default: 6275 return false; 6276 } 6277 6278 // base = Align(PC,4); 6279 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6280 if (!success) 6281 return false; 6282 6283 uint32_t base = AlignPC (pc_val); 6284 6285 addr_t address; 6286 // address = if add then (base + imm32) else (base - imm32); 6287 if (add) 6288 address = base + imm32; 6289 else 6290 address = base - imm32; 6291 6292 // R[t] = ZeroExtend(MemU[address,1], 32); 6293 EmulateInstruction::Context context; 6294 context.type = eContextRelativeBranchImmediate; 6295 context.SetImmediate (address - base); 6296 6297 uint64_t data = MemURead (context, address, 1, 0, &success); 6298 if (!success) 6299 return false; 6300 6301 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6302 return false; 6303 } 6304 return true; 6305 } 6306 6307 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6308 // memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6309 // optionally be shifted. 6310 bool 6311 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6312 { 6313 #if 0 6314 if ConditionPassed() then 6315 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6316 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6317 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6318 address = if index then offset_addr else R[n]; 6319 R[t] = ZeroExtend(MemU[address,1],32); 6320 if wback then R[n] = offset_addr; 6321 #endif 6322 6323 bool success = false; 6324 6325 if (ConditionPassed(opcode)) 6326 { 6327 uint32_t t; 6328 uint32_t n; 6329 uint32_t m; 6330 bool index; 6331 bool add; 6332 bool wback; 6333 ARM_ShifterType shift_t; 6334 uint32_t shift_n; 6335 6336 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6337 switch (encoding) 6338 { 6339 case eEncodingT1: 6340 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6341 t = Bits32 (opcode, 2, 0); 6342 n = Bits32 (opcode, 5, 3); 6343 m = Bits32 (opcode, 8, 6); 6344 6345 // index = TRUE; add = TRUE; wback = FALSE; 6346 index = true; 6347 add = true; 6348 wback = false; 6349 6350 // (shift_t, shift_n) = (SRType_LSL, 0); 6351 shift_t = SRType_LSL; 6352 shift_n = 0; 6353 break; 6354 6355 case eEncodingT2: 6356 // if Rt == '1111' then SEE PLD; 6357 // if Rn == '1111' then SEE LDRB (literal); 6358 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6359 t = Bits32 (opcode, 15, 12); 6360 n = Bits32 (opcode, 19, 16); 6361 m = Bits32 (opcode, 3, 0); 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, UInt(imm2)); 6369 shift_t = SRType_LSL; 6370 shift_n = Bits32 (opcode, 5, 4); 6371 6372 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6373 if ((t == 13) || BadReg (m)) 6374 return false; 6375 break; 6376 6377 case eEncodingA1: 6378 { 6379 // if P == '0' && W == '1' then SEE LDRBT; 6380 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6381 t = Bits32 (opcode, 15, 12); 6382 n = Bits32 (opcode, 19, 16); 6383 m = Bits32 (opcode, 3, 0); 6384 6385 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6386 index = BitIsSet (opcode, 24); 6387 add = BitIsSet (opcode, 23); 6388 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6389 6390 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6391 uint32_t type = Bits32 (opcode, 6, 5); 6392 uint32_t imm5 = Bits32 (opcode, 11, 7); 6393 shift_n = DecodeImmShift (type, imm5, shift_t); 6394 6395 // if t == 15 || m == 15 then UNPREDICTABLE; 6396 if ((t == 15) || (m == 15)) 6397 return false; 6398 6399 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6400 if (wback && ((n == 15) || (n == t))) 6401 return false; 6402 } 6403 break; 6404 6405 default: 6406 return false; 6407 } 6408 6409 addr_t offset_addr; 6410 addr_t address; 6411 6412 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6413 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6414 if (!success) 6415 return false; 6416 6417 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6418 if (!success) 6419 return false; 6420 6421 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6422 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6423 if (!success) 6424 return false; 6425 6426 if (add) 6427 offset_addr = Rn + offset; 6428 else 6429 offset_addr = Rn - offset; 6430 6431 // address = if index then offset_addr else R[n]; 6432 if (index) 6433 address = offset_addr; 6434 else 6435 address = Rn; 6436 6437 // R[t] = ZeroExtend(MemU[address,1],32); 6438 RegisterInfo base_reg; 6439 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6440 6441 EmulateInstruction::Context context; 6442 context.type = eContextRegisterLoad; 6443 context.SetRegisterPlusOffset (base_reg, address - Rn); 6444 6445 uint64_t data = MemURead (context, address, 1, 0, &success); 6446 if (!success) 6447 return false; 6448 6449 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6450 return false; 6451 6452 // if wback then R[n] = offset_addr; 6453 if (wback) 6454 { 6455 context.type = eContextAdjustBaseRegister; 6456 context.SetAddress (offset_addr); 6457 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6458 return false; 6459 } 6460 } 6461 return true; 6462 } 6463 6464 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6465 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6466 // post-indexed, or pre-indexed addressing. 6467 bool 6468 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6469 { 6470 #if 0 6471 if ConditionPassed() then 6472 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6473 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6474 address = if index then offset_addr else R[n]; 6475 data = MemU[address,2]; 6476 if wback then R[n] = offset_addr; 6477 if UnalignedSupport() || address<0> = '0' then 6478 R[t] = ZeroExtend(data, 32); 6479 else // Can only apply before ARMv7 6480 R[t] = bits(32) UNKNOWN; 6481 #endif 6482 6483 6484 bool success = false; 6485 6486 if (ConditionPassed(opcode)) 6487 { 6488 uint32_t t; 6489 uint32_t n; 6490 uint32_t imm32; 6491 bool index; 6492 bool add; 6493 bool wback; 6494 6495 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6496 switch (encoding) 6497 { 6498 case eEncodingT1: 6499 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6500 t = Bits32 (opcode, 2, 0); 6501 n = Bits32 (opcode, 5, 3); 6502 imm32 = Bits32 (opcode, 10, 6) << 1; 6503 6504 // index = TRUE; add = TRUE; wback = FALSE; 6505 index = true; 6506 add = true; 6507 wback = false; 6508 6509 break; 6510 6511 case eEncodingT2: 6512 // if Rt == '1111' then SEE "Unallocated memory hints"; 6513 // if Rn == '1111' then SEE LDRH (literal); 6514 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6515 t = Bits32 (opcode, 15, 12); 6516 n = Bits32 (opcode, 19, 16); 6517 imm32 = Bits32 (opcode, 11, 0); 6518 6519 // index = TRUE; add = TRUE; wback = FALSE; 6520 index = true; 6521 add = true; 6522 wback = false; 6523 6524 // if t == 13 then UNPREDICTABLE; 6525 if (t == 13) 6526 return false; 6527 break; 6528 6529 case eEncodingT3: 6530 // if Rn == '1111' then SEE LDRH (literal); 6531 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6532 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6533 // if P == '0' && W == '0' then UNDEFINED; 6534 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6535 return false; 6536 6537 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6538 t = Bits32 (opcode, 15, 12); 6539 n = Bits32 (opcode, 19, 16); 6540 imm32 = Bits32 (opcode, 7, 0); 6541 6542 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6543 index = BitIsSet (opcode, 10); 6544 add = BitIsSet (opcode, 9); 6545 wback = BitIsSet (opcode, 8); 6546 6547 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6548 if (BadReg (t) || (wback && (n == t))) 6549 return false; 6550 break; 6551 6552 default: 6553 return false; 6554 } 6555 6556 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6557 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6558 if (!success) 6559 return false; 6560 6561 addr_t offset_addr; 6562 addr_t address; 6563 6564 if (add) 6565 offset_addr = Rn + imm32; 6566 else 6567 offset_addr = Rn - imm32; 6568 6569 // address = if index then offset_addr else R[n]; 6570 if (index) 6571 address = offset_addr; 6572 else 6573 address = Rn; 6574 6575 // data = MemU[address,2]; 6576 RegisterInfo base_reg; 6577 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6578 6579 EmulateInstruction::Context context; 6580 context.type = eContextRegisterLoad; 6581 context.SetRegisterPlusOffset (base_reg, address - Rn); 6582 6583 uint64_t data = MemURead (context, address, 2, 0, &success); 6584 if (!success) 6585 return false; 6586 6587 // if wback then R[n] = offset_addr; 6588 if (wback) 6589 { 6590 context.type = eContextAdjustBaseRegister; 6591 context.SetAddress (offset_addr); 6592 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6593 return false; 6594 } 6595 6596 // if UnalignedSupport() || address<0> = '0' then 6597 if (UnalignedSupport () || BitIsClear (address, 0)) 6598 { 6599 // R[t] = ZeroExtend(data, 32); 6600 context.type = eContextRegisterLoad; 6601 context.SetRegisterPlusOffset (base_reg, address - Rn); 6602 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6603 return false; 6604 } 6605 else // Can only apply before ARMv7 6606 { 6607 // R[t] = bits(32) UNKNOWN; 6608 WriteBits32Unknown (t); 6609 } 6610 } 6611 return true; 6612 } 6613 6614 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6615 // zero-extends it to form a 32-bit word, and writes it to a register. 6616 bool 6617 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6618 { 6619 #if 0 6620 if ConditionPassed() then 6621 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6622 base = Align(PC,4); 6623 address = if add then (base + imm32) else (base - imm32); 6624 data = MemU[address,2]; 6625 if UnalignedSupport() || address<0> = '0' then 6626 R[t] = ZeroExtend(data, 32); 6627 else // Can only apply before ARMv7 6628 R[t] = bits(32) UNKNOWN; 6629 #endif 6630 6631 bool success = false; 6632 6633 if (ConditionPassed(opcode)) 6634 { 6635 uint32_t t; 6636 uint32_t imm32; 6637 bool add; 6638 6639 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6640 switch (encoding) 6641 { 6642 case eEncodingT1: 6643 // if Rt == '1111' then SEE "Unallocated memory hints"; 6644 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6645 t = Bits32 (opcode, 15, 12); 6646 imm32 = Bits32 (opcode, 11, 0); 6647 add = BitIsSet (opcode, 23); 6648 6649 // if t == 13 then UNPREDICTABLE; 6650 if (t == 13) 6651 return false; 6652 6653 break; 6654 6655 case eEncodingA1: 6656 { 6657 uint32_t imm4H = Bits32 (opcode, 11, 8); 6658 uint32_t imm4L = Bits32 (opcode, 3, 0); 6659 6660 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6661 t = Bits32 (opcode, 15, 12); 6662 imm32 = (imm4H << 4) | imm4L; 6663 add = BitIsSet (opcode, 23); 6664 6665 // if t == 15 then UNPREDICTABLE; 6666 if (t == 15) 6667 return false; 6668 break; 6669 } 6670 6671 default: 6672 return false; 6673 } 6674 6675 // base = Align(PC,4); 6676 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6677 if (!success) 6678 return false; 6679 6680 addr_t base = AlignPC (pc_value); 6681 addr_t address; 6682 6683 // address = if add then (base + imm32) else (base - imm32); 6684 if (add) 6685 address = base + imm32; 6686 else 6687 address = base - imm32; 6688 6689 // data = MemU[address,2]; 6690 RegisterInfo base_reg; 6691 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6692 6693 EmulateInstruction::Context context; 6694 context.type = eContextRegisterLoad; 6695 context.SetRegisterPlusOffset (base_reg, address - base); 6696 6697 uint64_t data = MemURead (context, address, 2, 0, &success); 6698 if (!success) 6699 return false; 6700 6701 6702 // if UnalignedSupport() || address<0> = '0' then 6703 if (UnalignedSupport () || BitIsClear (address, 0)) 6704 { 6705 // R[t] = ZeroExtend(data, 32); 6706 context.type = eContextRegisterLoad; 6707 context.SetRegisterPlusOffset (base_reg, address - base); 6708 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6709 return false; 6710 6711 } 6712 else // Can only apply before ARMv7 6713 { 6714 // R[t] = bits(32) UNKNOWN; 6715 WriteBits32Unknown (t); 6716 } 6717 } 6718 return true; 6719 } 6720 6721 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6722 // from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6723 // be shifted left by 0, 1, 2, or 3 bits. 6724 bool 6725 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6726 { 6727 #if 0 6728 if ConditionPassed() then 6729 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6730 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6731 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6732 address = if index then offset_addr else R[n]; 6733 data = MemU[address,2]; 6734 if wback then R[n] = offset_addr; 6735 if UnalignedSupport() || address<0> = '0' then 6736 R[t] = ZeroExtend(data, 32); 6737 else // Can only apply before ARMv7 6738 R[t] = bits(32) UNKNOWN; 6739 #endif 6740 6741 bool success = false; 6742 6743 if (ConditionPassed(opcode)) 6744 { 6745 uint32_t t; 6746 uint32_t n; 6747 uint32_t m; 6748 bool index; 6749 bool add; 6750 bool wback; 6751 ARM_ShifterType shift_t; 6752 uint32_t shift_n; 6753 6754 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6755 switch (encoding) 6756 { 6757 case eEncodingT1: 6758 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6759 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6760 t = Bits32 (opcode, 2, 0); 6761 n = Bits32 (opcode, 5, 3); 6762 m = Bits32 (opcode, 8, 6); 6763 6764 // index = TRUE; add = TRUE; wback = FALSE; 6765 index = true; 6766 add = true; 6767 wback = false; 6768 6769 // (shift_t, shift_n) = (SRType_LSL, 0); 6770 shift_t = SRType_LSL; 6771 shift_n = 0; 6772 6773 break; 6774 6775 case eEncodingT2: 6776 // if Rn == '1111' then SEE LDRH (literal); 6777 // if Rt == '1111' then SEE "Unallocated memory hints"; 6778 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6779 t = Bits32 (opcode, 15, 12); 6780 n = Bits32 (opcode, 19, 16); 6781 m = Bits32 (opcode, 3, 0); 6782 6783 // index = TRUE; add = TRUE; wback = FALSE; 6784 index = true; 6785 add = true; 6786 wback = false; 6787 6788 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6789 shift_t = SRType_LSL; 6790 shift_n = Bits32 (opcode, 5, 4); 6791 6792 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6793 if ((t == 13) || BadReg (m)) 6794 return false; 6795 break; 6796 6797 case eEncodingA1: 6798 // if P == '0' && W == '1' then SEE LDRHT; 6799 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6800 t = Bits32 (opcode, 15, 12); 6801 n = Bits32 (opcode, 19, 16); 6802 m = Bits32 (opcode, 3, 0); 6803 6804 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6805 index = BitIsSet (opcode, 24); 6806 add = BitIsSet (opcode, 23); 6807 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6808 6809 // (shift_t, shift_n) = (SRType_LSL, 0); 6810 shift_t = SRType_LSL; 6811 shift_n = 0; 6812 6813 // if t == 15 || m == 15 then UNPREDICTABLE; 6814 if ((t == 15) || (m == 15)) 6815 return false; 6816 6817 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6818 if (wback && ((n == 15) || (n == t))) 6819 return false; 6820 6821 break; 6822 6823 default: 6824 return false; 6825 } 6826 6827 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6828 6829 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6830 if (!success) 6831 return false; 6832 6833 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6834 if (!success) 6835 return false; 6836 6837 addr_t offset_addr; 6838 addr_t address; 6839 6840 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6841 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6842 if (!success) 6843 return false; 6844 6845 if (add) 6846 offset_addr = Rn + offset; 6847 else 6848 offset_addr = Rn - offset; 6849 6850 // address = if index then offset_addr else R[n]; 6851 if (index) 6852 address = offset_addr; 6853 else 6854 address = Rn; 6855 6856 // data = MemU[address,2]; 6857 RegisterInfo base_reg; 6858 RegisterInfo offset_reg; 6859 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6860 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 6861 6862 EmulateInstruction::Context context; 6863 context.type = eContextRegisterLoad; 6864 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6865 uint64_t data = MemURead (context, address, 2, 0, &success); 6866 if (!success) 6867 return false; 6868 6869 // if wback then R[n] = offset_addr; 6870 if (wback) 6871 { 6872 context.type = eContextAdjustBaseRegister; 6873 context.SetAddress (offset_addr); 6874 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6875 return false; 6876 } 6877 6878 // if UnalignedSupport() || address<0> = '0' then 6879 if (UnalignedSupport() || BitIsClear (address, 0)) 6880 { 6881 // R[t] = ZeroExtend(data, 32); 6882 context.type = eContextRegisterLoad; 6883 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 6884 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6885 return false; 6886 } 6887 else // Can only apply before ARMv7 6888 { 6889 // R[t] = bits(32) UNKNOWN; 6890 WriteBits32Unknown (t); 6891 } 6892 } 6893 return true; 6894 } 6895 6896 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 6897 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 6898 // or pre-indexed addressing. 6899 bool 6900 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6901 { 6902 #if 0 6903 if ConditionPassed() then 6904 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6905 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6906 address = if index then offset_addr else R[n]; 6907 R[t] = SignExtend(MemU[address,1], 32); 6908 if wback then R[n] = offset_addr; 6909 #endif 6910 6911 bool success = false; 6912 6913 if (ConditionPassed(opcode)) 6914 { 6915 uint32_t t; 6916 uint32_t n; 6917 uint32_t imm32; 6918 bool index; 6919 bool add; 6920 bool wback; 6921 6922 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6923 switch (encoding) 6924 { 6925 case eEncodingT1: 6926 // if Rt == '1111' then SEE PLI; 6927 // if Rn == '1111' then SEE LDRSB (literal); 6928 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6929 t = Bits32 (opcode, 15, 12); 6930 n = Bits32 (opcode, 19, 16); 6931 imm32 = Bits32 (opcode, 11, 0); 6932 6933 // index = TRUE; add = TRUE; wback = FALSE; 6934 index = true; 6935 add = true; 6936 wback = false; 6937 6938 // if t == 13 then UNPREDICTABLE; 6939 if (t == 13) 6940 return false; 6941 6942 break; 6943 6944 case eEncodingT2: 6945 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 6946 // if Rn == '1111' then SEE LDRSB (literal); 6947 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 6948 // if P == '0' && W == '0' then UNDEFINED; 6949 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6950 return false; 6951 6952 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6953 t = Bits32 (opcode, 15, 12); 6954 n = Bits32 (opcode, 19, 16); 6955 imm32 = Bits32 (opcode, 7, 0); 6956 6957 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6958 index = BitIsSet (opcode, 10); 6959 add = BitIsSet (opcode, 9); 6960 wback = BitIsSet (opcode, 8); 6961 6962 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6963 if (((t == 13) || ((t == 15) 6964 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 6965 || (wback && (n == t))) 6966 return false; 6967 6968 break; 6969 6970 case eEncodingA1: 6971 { 6972 // if Rn == '1111' then SEE LDRSB (literal); 6973 // if P == '0' && W == '1' then SEE LDRSBT; 6974 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 6975 t = Bits32 (opcode, 15, 12); 6976 n = Bits32 (opcode, 19, 16); 6977 6978 uint32_t imm4H = Bits32 (opcode, 11, 8); 6979 uint32_t imm4L = Bits32 (opcode, 3, 0); 6980 imm32 = (imm4H << 4) | imm4L; 6981 6982 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6983 index = BitIsSet (opcode, 24); 6984 add = BitIsSet (opcode, 23); 6985 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6986 6987 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 6988 if ((t == 15) || (wback && (n == t))) 6989 return false; 6990 6991 break; 6992 } 6993 6994 default: 6995 return false; 6996 } 6997 6998 uint64_t Rn = ReadCoreReg (n, &success); 6999 if (!success) 7000 return false; 7001 7002 addr_t offset_addr; 7003 addr_t address; 7004 7005 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7006 if (add) 7007 offset_addr = Rn + imm32; 7008 else 7009 offset_addr = Rn - imm32; 7010 7011 // address = if index then offset_addr else R[n]; 7012 if (index) 7013 address = offset_addr; 7014 else 7015 address = Rn; 7016 7017 // R[t] = SignExtend(MemU[address,1], 32); 7018 RegisterInfo base_reg; 7019 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7020 7021 EmulateInstruction::Context context; 7022 context.type = eContextRegisterLoad; 7023 context.SetRegisterPlusOffset (base_reg, address - Rn); 7024 7025 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7026 if (!success) 7027 return false; 7028 7029 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7030 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7031 return false; 7032 7033 // if wback then R[n] = offset_addr; 7034 if (wback) 7035 { 7036 context.type = eContextAdjustBaseRegister; 7037 context.SetAddress (offset_addr); 7038 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7039 return false; 7040 } 7041 } 7042 7043 return true; 7044 } 7045 7046 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7047 // sign-extends it to form a 32-bit word, and writes tit to a register. 7048 bool 7049 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7050 { 7051 #if 0 7052 if ConditionPassed() then 7053 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7054 base = Align(PC,4); 7055 address = if add then (base + imm32) else (base - imm32); 7056 R[t] = SignExtend(MemU[address,1], 32); 7057 #endif 7058 7059 bool success = false; 7060 7061 if (ConditionPassed(opcode)) 7062 { 7063 uint32_t t; 7064 uint32_t imm32; 7065 bool add; 7066 7067 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7068 switch (encoding) 7069 { 7070 case eEncodingT1: 7071 // if Rt == '1111' then SEE PLI; 7072 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7073 t = Bits32 (opcode, 15, 12); 7074 imm32 = Bits32 (opcode, 11, 0); 7075 add = BitIsSet (opcode, 23); 7076 7077 // if t == 13 then UNPREDICTABLE; 7078 if (t == 13) 7079 return false; 7080 7081 break; 7082 7083 case eEncodingA1: 7084 { 7085 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7086 t = Bits32 (opcode, 15, 12); 7087 uint32_t imm4H = Bits32 (opcode, 11, 8); 7088 uint32_t imm4L = Bits32 (opcode, 3, 0); 7089 imm32 = (imm4H << 4) | imm4L; 7090 add = BitIsSet (opcode, 23); 7091 7092 // if t == 15 then UNPREDICTABLE; 7093 if (t == 15) 7094 return false; 7095 7096 break; 7097 } 7098 7099 default: 7100 return false; 7101 } 7102 7103 // base = Align(PC,4); 7104 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7105 if (!success) 7106 return false; 7107 uint64_t base = AlignPC (pc_value); 7108 7109 // address = if add then (base + imm32) else (base - imm32); 7110 addr_t address; 7111 if (add) 7112 address = base + imm32; 7113 else 7114 address = base - imm32; 7115 7116 // R[t] = SignExtend(MemU[address,1], 32); 7117 RegisterInfo base_reg; 7118 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7119 7120 EmulateInstruction::Context context; 7121 context.type = eContextRegisterLoad; 7122 context.SetRegisterPlusOffset (base_reg, address - base); 7123 7124 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7125 if (!success) 7126 return false; 7127 7128 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7129 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7130 return false; 7131 } 7132 return true; 7133 } 7134 7135 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7136 // memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7137 // shifted left by 0, 1, 2, or 3 bits. 7138 bool 7139 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7140 { 7141 #if 0 7142 if ConditionPassed() then 7143 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7144 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7145 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7146 address = if index then offset_addr else R[n]; 7147 R[t] = SignExtend(MemU[address,1], 32); 7148 if wback then R[n] = offset_addr; 7149 #endif 7150 7151 bool success = false; 7152 7153 if (ConditionPassed(opcode)) 7154 { 7155 uint32_t t; 7156 uint32_t n; 7157 uint32_t m; 7158 bool index; 7159 bool add; 7160 bool wback; 7161 ARM_ShifterType shift_t; 7162 uint32_t shift_n; 7163 7164 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7165 switch (encoding) 7166 { 7167 case eEncodingT1: 7168 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7169 t = Bits32 (opcode, 2, 0); 7170 n = Bits32 (opcode, 5, 3); 7171 m = Bits32 (opcode, 8, 6); 7172 7173 // index = TRUE; add = TRUE; wback = FALSE; 7174 index = true; 7175 add = true; 7176 wback = false; 7177 7178 // (shift_t, shift_n) = (SRType_LSL, 0); 7179 shift_t = SRType_LSL; 7180 shift_n = 0; 7181 7182 break; 7183 7184 case eEncodingT2: 7185 // if Rt == '1111' then SEE PLI; 7186 // if Rn == '1111' then SEE LDRSB (literal); 7187 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7188 t = Bits32 (opcode, 15, 12); 7189 n = Bits32 (opcode, 19, 16); 7190 m = Bits32 (opcode, 3, 0); 7191 7192 // index = TRUE; add = TRUE; wback = FALSE; 7193 index = true; 7194 add = true; 7195 wback = false; 7196 7197 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7198 shift_t = SRType_LSL; 7199 shift_n = Bits32 (opcode, 5, 4); 7200 7201 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7202 if ((t == 13) || BadReg (m)) 7203 return false; 7204 break; 7205 7206 case eEncodingA1: 7207 // if P == '0' && W == '1' then SEE LDRSBT; 7208 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7209 t = Bits32 (opcode, 15, 12); 7210 n = Bits32 (opcode, 19, 16); 7211 m = Bits32 (opcode, 3, 0); 7212 7213 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7214 index = BitIsSet (opcode, 24); 7215 add = BitIsSet (opcode, 23); 7216 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7217 7218 // (shift_t, shift_n) = (SRType_LSL, 0); 7219 shift_t = SRType_LSL; 7220 shift_n = 0; 7221 7222 // if t == 15 || m == 15 then UNPREDICTABLE; 7223 if ((t == 15) || (m == 15)) 7224 return false; 7225 7226 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7227 if (wback && ((n == 15) || (n == t))) 7228 return false; 7229 break; 7230 7231 default: 7232 return false; 7233 } 7234 7235 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7236 if (!success) 7237 return false; 7238 7239 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7240 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7241 if (!success) 7242 return false; 7243 7244 addr_t offset_addr; 7245 addr_t address; 7246 7247 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7248 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7249 if (!success) 7250 return false; 7251 7252 if (add) 7253 offset_addr = Rn + offset; 7254 else 7255 offset_addr = Rn - offset; 7256 7257 // address = if index then offset_addr else R[n]; 7258 if (index) 7259 address = offset_addr; 7260 else 7261 address = Rn; 7262 7263 // R[t] = SignExtend(MemU[address,1], 32); 7264 RegisterInfo base_reg; 7265 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7266 RegisterInfo offset_reg; 7267 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7268 7269 EmulateInstruction::Context context; 7270 context.type = eContextRegisterLoad; 7271 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7272 7273 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7274 if (!success) 7275 return false; 7276 7277 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7278 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7279 return false; 7280 7281 // if wback then R[n] = offset_addr; 7282 if (wback) 7283 { 7284 context.type = eContextAdjustBaseRegister; 7285 context.SetAddress (offset_addr); 7286 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7287 return false; 7288 } 7289 } 7290 return true; 7291 } 7292 7293 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7294 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7295 // pre-indexed addressing. 7296 bool 7297 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7298 { 7299 #if 0 7300 if ConditionPassed() then 7301 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7302 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7303 address = if index then offset_addr else R[n]; 7304 data = MemU[address,2]; 7305 if wback then R[n] = offset_addr; 7306 if UnalignedSupport() || address<0> = '0' then 7307 R[t] = SignExtend(data, 32); 7308 else // Can only apply before ARMv7 7309 R[t] = bits(32) UNKNOWN; 7310 #endif 7311 7312 bool success = false; 7313 7314 if (ConditionPassed(opcode)) 7315 { 7316 uint32_t t; 7317 uint32_t n; 7318 uint32_t imm32; 7319 bool index; 7320 bool add; 7321 bool wback; 7322 7323 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7324 switch (encoding) 7325 { 7326 case eEncodingT1: 7327 // if Rn == '1111' then SEE LDRSH (literal); 7328 // if Rt == '1111' then SEE "Unallocated memory hints"; 7329 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7330 t = Bits32 (opcode, 15, 12); 7331 n = Bits32 (opcode, 19, 16); 7332 imm32 = Bits32 (opcode, 11, 0); 7333 7334 // index = TRUE; add = TRUE; wback = FALSE; 7335 index = true; 7336 add = true; 7337 wback = false; 7338 7339 // if t == 13 then UNPREDICTABLE; 7340 if (t == 13) 7341 return false; 7342 7343 break; 7344 7345 case eEncodingT2: 7346 // if Rn == '1111' then SEE LDRSH (literal); 7347 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7348 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7349 // if P == '0' && W == '0' then UNDEFINED; 7350 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7351 return false; 7352 7353 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7354 t = Bits32 (opcode, 15, 12); 7355 n = Bits32 (opcode, 19, 16); 7356 imm32 = Bits32 (opcode, 7, 0); 7357 7358 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7359 index = BitIsSet (opcode, 10); 7360 add = BitIsSet (opcode, 9); 7361 wback = BitIsSet (opcode, 8); 7362 7363 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7364 if (BadReg (t) || (wback && (n == t))) 7365 return false; 7366 7367 break; 7368 7369 case eEncodingA1: 7370 { 7371 // if Rn == '1111' then SEE LDRSH (literal); 7372 // if P == '0' && W == '1' then SEE LDRSHT; 7373 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7374 t = Bits32 (opcode, 15, 12); 7375 n = Bits32 (opcode, 19, 16); 7376 uint32_t imm4H = Bits32 (opcode, 11,8); 7377 uint32_t imm4L = Bits32 (opcode, 3, 0); 7378 imm32 = (imm4H << 4) | imm4L; 7379 7380 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7381 index = BitIsSet (opcode, 24); 7382 add = BitIsSet (opcode, 23); 7383 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7384 7385 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7386 if ((t == 15) || (wback && (n == t))) 7387 return false; 7388 7389 break; 7390 } 7391 7392 default: 7393 return false; 7394 } 7395 7396 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7397 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7398 if (!success) 7399 return false; 7400 7401 addr_t offset_addr; 7402 if (add) 7403 offset_addr = Rn + imm32; 7404 else 7405 offset_addr = Rn - imm32; 7406 7407 // address = if index then offset_addr else R[n]; 7408 addr_t address; 7409 if (index) 7410 address = offset_addr; 7411 else 7412 address = Rn; 7413 7414 // data = MemU[address,2]; 7415 RegisterInfo base_reg; 7416 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7417 7418 EmulateInstruction::Context context; 7419 context.type = eContextRegisterLoad; 7420 context.SetRegisterPlusOffset (base_reg, address - Rn); 7421 7422 uint64_t data = MemURead (context, address, 2, 0, &success); 7423 if (!success) 7424 return false; 7425 7426 // if wback then R[n] = offset_addr; 7427 if (wback) 7428 { 7429 context.type = eContextAdjustBaseRegister; 7430 context.SetAddress (offset_addr); 7431 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7432 return false; 7433 } 7434 7435 // if UnalignedSupport() || address<0> = '0' then 7436 if (UnalignedSupport() || BitIsClear (address, 0)) 7437 { 7438 // R[t] = SignExtend(data, 32); 7439 int64_t signed_data = llvm::SignExtend64<16>(data); 7440 context.type = eContextRegisterLoad; 7441 context.SetRegisterPlusOffset (base_reg, address - Rn); 7442 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7443 return false; 7444 } 7445 else // Can only apply before ARMv7 7446 { 7447 // R[t] = bits(32) UNKNOWN; 7448 WriteBits32Unknown (t); 7449 } 7450 } 7451 return true; 7452 } 7453 7454 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7455 // sign-extends it to from a 32-bit word, and writes it to a register. 7456 bool 7457 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7458 { 7459 #if 0 7460 if ConditionPassed() then 7461 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7462 base = Align(PC,4); 7463 address = if add then (base + imm32) else (base - imm32); 7464 data = MemU[address,2]; 7465 if UnalignedSupport() || address<0> = '0' then 7466 R[t] = SignExtend(data, 32); 7467 else // Can only apply before ARMv7 7468 R[t] = bits(32) UNKNOWN; 7469 #endif 7470 7471 bool success = false; 7472 7473 if (ConditionPassed(opcode)) 7474 { 7475 uint32_t t; 7476 uint32_t imm32; 7477 bool add; 7478 7479 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7480 switch (encoding) 7481 { 7482 case eEncodingT1: 7483 // if Rt == '1111' then SEE "Unallocated memory hints"; 7484 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7485 t = Bits32 (opcode, 15, 12); 7486 imm32 = Bits32 (opcode, 11, 0); 7487 add = BitIsSet (opcode, 23); 7488 7489 // if t == 13 then UNPREDICTABLE; 7490 if (t == 13) 7491 return false; 7492 7493 break; 7494 7495 case eEncodingA1: 7496 { 7497 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7498 t = Bits32 (opcode, 15, 12); 7499 uint32_t imm4H = Bits32 (opcode, 11, 8); 7500 uint32_t imm4L = Bits32 (opcode, 3, 0); 7501 imm32 = (imm4H << 4) | imm4L; 7502 add = BitIsSet (opcode, 23); 7503 7504 // if t == 15 then UNPREDICTABLE; 7505 if (t == 15) 7506 return false; 7507 7508 break; 7509 } 7510 default: 7511 return false; 7512 } 7513 7514 // base = Align(PC,4); 7515 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7516 if (!success) 7517 return false; 7518 7519 uint64_t base = AlignPC (pc_value); 7520 7521 addr_t address; 7522 // address = if add then (base + imm32) else (base - imm32); 7523 if (add) 7524 address = base + imm32; 7525 else 7526 address = base - imm32; 7527 7528 // data = MemU[address,2]; 7529 RegisterInfo base_reg; 7530 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7531 7532 EmulateInstruction::Context context; 7533 context.type = eContextRegisterLoad; 7534 context.SetRegisterPlusOffset (base_reg, imm32); 7535 7536 uint64_t data = MemURead (context, address, 2, 0, &success); 7537 if (!success) 7538 return false; 7539 7540 // if UnalignedSupport() || address<0> = '0' then 7541 if (UnalignedSupport() || BitIsClear (address, 0)) 7542 { 7543 // R[t] = SignExtend(data, 32); 7544 int64_t signed_data = llvm::SignExtend64<16>(data); 7545 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7546 return false; 7547 } 7548 else // Can only apply before ARMv7 7549 { 7550 // R[t] = bits(32) UNKNOWN; 7551 WriteBits32Unknown (t); 7552 } 7553 } 7554 return true; 7555 } 7556 7557 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7558 // from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7559 // shifted left by 0, 1, 2, or 3 bits. 7560 bool 7561 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7562 { 7563 #if 0 7564 if ConditionPassed() then 7565 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7566 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7567 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7568 address = if index then offset_addr else R[n]; 7569 data = MemU[address,2]; 7570 if wback then R[n] = offset_addr; 7571 if UnalignedSupport() || address<0> = '0' then 7572 R[t] = SignExtend(data, 32); 7573 else // Can only apply before ARMv7 7574 R[t] = bits(32) UNKNOWN; 7575 #endif 7576 7577 bool success = false; 7578 7579 if (ConditionPassed(opcode)) 7580 { 7581 uint32_t t; 7582 uint32_t n; 7583 uint32_t m; 7584 bool index; 7585 bool add; 7586 bool wback; 7587 ARM_ShifterType shift_t; 7588 uint32_t shift_n; 7589 7590 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7591 switch (encoding) 7592 { 7593 case eEncodingT1: 7594 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7595 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7596 t = Bits32 (opcode, 2, 0); 7597 n = Bits32 (opcode, 5, 3); 7598 m = Bits32 (opcode, 8, 6); 7599 7600 // index = TRUE; add = TRUE; wback = FALSE; 7601 index = true; 7602 add = true; 7603 wback = false; 7604 7605 // (shift_t, shift_n) = (SRType_LSL, 0); 7606 shift_t = SRType_LSL; 7607 shift_n = 0; 7608 7609 break; 7610 7611 case eEncodingT2: 7612 // if Rn == '1111' then SEE LDRSH (literal); 7613 // if Rt == '1111' then SEE "Unallocated memory hints"; 7614 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7615 t = Bits32 (opcode, 15, 12); 7616 n = Bits32 (opcode, 19, 16); 7617 m = Bits32 (opcode, 3, 0); 7618 7619 // index = TRUE; add = TRUE; wback = FALSE; 7620 index = true; 7621 add = true; 7622 wback = false; 7623 7624 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7625 shift_t = SRType_LSL; 7626 shift_n = Bits32 (opcode, 5, 4); 7627 7628 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7629 if ((t == 13) || BadReg (m)) 7630 return false; 7631 7632 break; 7633 7634 case eEncodingA1: 7635 // if P == '0' && W == '1' then SEE LDRSHT; 7636 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7637 t = Bits32 (opcode, 15, 12); 7638 n = Bits32 (opcode, 19, 16); 7639 m = Bits32 (opcode, 3, 0); 7640 7641 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7642 index = BitIsSet (opcode, 24); 7643 add = BitIsSet (opcode, 23); 7644 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7645 7646 // (shift_t, shift_n) = (SRType_LSL, 0); 7647 shift_t = SRType_LSL; 7648 shift_n = 0; 7649 7650 // if t == 15 || m == 15 then UNPREDICTABLE; 7651 if ((t == 15) || (m == 15)) 7652 return false; 7653 7654 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7655 if (wback && ((n == 15) || (n == t))) 7656 return false; 7657 7658 break; 7659 7660 default: 7661 return false; 7662 } 7663 7664 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7665 if (!success) 7666 return false; 7667 7668 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7669 if (!success) 7670 return false; 7671 7672 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7673 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7674 if (!success) 7675 return false; 7676 7677 addr_t offset_addr; 7678 addr_t address; 7679 7680 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7681 if (add) 7682 offset_addr = Rn + offset; 7683 else 7684 offset_addr = Rn - offset; 7685 7686 // address = if index then offset_addr else R[n]; 7687 if (index) 7688 address = offset_addr; 7689 else 7690 address = Rn; 7691 7692 // data = MemU[address,2]; 7693 RegisterInfo base_reg; 7694 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7695 7696 RegisterInfo offset_reg; 7697 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7698 7699 EmulateInstruction::Context context; 7700 context.type = eContextRegisterLoad; 7701 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7702 7703 uint64_t data = MemURead (context, address, 2, 0, &success); 7704 if (!success) 7705 return false; 7706 7707 // if wback then R[n] = offset_addr; 7708 if (wback) 7709 { 7710 context.type = eContextAdjustBaseRegister; 7711 context.SetAddress (offset_addr); 7712 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7713 return false; 7714 } 7715 7716 // if UnalignedSupport() || address<0> = '0' then 7717 if (UnalignedSupport() || BitIsClear (address, 0)) 7718 { 7719 // R[t] = SignExtend(data, 32); 7720 context.type = eContextRegisterLoad; 7721 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7722 7723 int64_t signed_data = llvm::SignExtend64<16>(data); 7724 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7725 return false; 7726 } 7727 else // Can only apply before ARMv7 7728 { 7729 // R[t] = bits(32) UNKNOWN; 7730 WriteBits32Unknown (t); 7731 } 7732 } 7733 return true; 7734 } 7735 7736 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7737 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7738 bool 7739 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7740 { 7741 #if 0 7742 if ConditionPassed() then 7743 EncodingSpecificOperations(); 7744 rotated = ROR(R[m], rotation); 7745 R[d] = SignExtend(rotated<7:0>, 32); 7746 #endif 7747 7748 bool success = false; 7749 7750 if (ConditionPassed(opcode)) 7751 { 7752 uint32_t d; 7753 uint32_t m; 7754 uint32_t rotation; 7755 7756 // EncodingSpecificOperations(); 7757 switch (encoding) 7758 { 7759 case eEncodingT1: 7760 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7761 d = Bits32 (opcode, 2, 0); 7762 m = Bits32 (opcode, 5, 3); 7763 rotation = 0; 7764 7765 break; 7766 7767 case eEncodingT2: 7768 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7769 d = Bits32 (opcode, 11, 8); 7770 m = Bits32 (opcode, 3, 0); 7771 rotation = Bits32 (opcode, 5, 4) << 3; 7772 7773 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7774 if (BadReg (d) || BadReg (m)) 7775 return false; 7776 7777 break; 7778 7779 case eEncodingA1: 7780 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7781 d = Bits32 (opcode, 15, 12); 7782 m = Bits32 (opcode, 3, 0); 7783 rotation = Bits32 (opcode, 11, 10) << 3; 7784 7785 // if d == 15 || m == 15 then UNPREDICTABLE; 7786 if ((d == 15) || (m == 15)) 7787 return false; 7788 7789 break; 7790 7791 default: 7792 return false; 7793 } 7794 7795 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7796 if (!success) 7797 return false; 7798 7799 // rotated = ROR(R[m], rotation); 7800 uint64_t rotated = ROR (Rm, rotation, &success); 7801 if (!success) 7802 return false; 7803 7804 // R[d] = SignExtend(rotated<7:0>, 32); 7805 int64_t data = llvm::SignExtend64<8>(rotated); 7806 7807 RegisterInfo source_reg; 7808 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7809 7810 EmulateInstruction::Context context; 7811 context.type = eContextRegisterLoad; 7812 context.SetRegister (source_reg); 7813 7814 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7815 return false; 7816 } 7817 return true; 7818 } 7819 7820 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7821 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7822 bool 7823 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7824 { 7825 #if 0 7826 if ConditionPassed() then 7827 EncodingSpecificOperations(); 7828 rotated = ROR(R[m], rotation); 7829 R[d] = SignExtend(rotated<15:0>, 32); 7830 #endif 7831 7832 bool success = false; 7833 7834 if (ConditionPassed(opcode)) 7835 { 7836 uint32_t d; 7837 uint32_t m; 7838 uint32_t rotation; 7839 7840 // EncodingSpecificOperations(); 7841 switch (encoding) 7842 { 7843 case eEncodingT1: 7844 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7845 d = Bits32 (opcode, 2, 0); 7846 m = Bits32 (opcode, 5, 3); 7847 rotation = 0; 7848 7849 break; 7850 7851 case eEncodingT2: 7852 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7853 d = Bits32 (opcode, 11, 8); 7854 m = Bits32 (opcode, 3, 0); 7855 rotation = Bits32 (opcode, 5, 4) << 3; 7856 7857 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7858 if (BadReg (d) || BadReg (m)) 7859 return false; 7860 7861 break; 7862 7863 case eEncodingA1: 7864 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7865 d = Bits32 (opcode, 15, 12); 7866 m = Bits32 (opcode, 3, 0); 7867 rotation = Bits32 (opcode, 11, 10) << 3; 7868 7869 // if d == 15 || m == 15 then UNPREDICTABLE; 7870 if ((d == 15) || (m == 15)) 7871 return false; 7872 7873 break; 7874 7875 default: 7876 return false; 7877 } 7878 7879 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7880 if (!success) 7881 return false; 7882 7883 // rotated = ROR(R[m], rotation); 7884 uint64_t rotated = ROR (Rm, rotation, &success); 7885 if (!success) 7886 return false; 7887 7888 // R[d] = SignExtend(rotated<15:0>, 32); 7889 RegisterInfo source_reg; 7890 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7891 7892 EmulateInstruction::Context context; 7893 context.type = eContextRegisterLoad; 7894 context.SetRegister (source_reg); 7895 7896 int64_t data = llvm::SignExtend64<16> (rotated); 7897 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7898 return false; 7899 } 7900 7901 return true; 7902 } 7903 7904 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 7905 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7906 bool 7907 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 7908 { 7909 #if 0 7910 if ConditionPassed() then 7911 EncodingSpecificOperations(); 7912 rotated = ROR(R[m], rotation); 7913 R[d] = ZeroExtend(rotated<7:0>, 32); 7914 #endif 7915 7916 bool success = false; 7917 7918 if (ConditionPassed(opcode)) 7919 { 7920 uint32_t d; 7921 uint32_t m; 7922 uint32_t rotation; 7923 7924 // EncodingSpecificOperations(); 7925 switch (encoding) 7926 { 7927 case eEncodingT1: 7928 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7929 d = Bits32 (opcode, 2, 0); 7930 m = Bits32 (opcode, 5, 3); 7931 rotation = 0; 7932 7933 break; 7934 7935 case eEncodingT2: 7936 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7937 d = Bits32 (opcode, 11, 8); 7938 m = Bits32 (opcode, 3, 0); 7939 rotation = Bits32 (opcode, 5, 4) << 3; 7940 7941 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7942 if (BadReg (d) || BadReg (m)) 7943 return false; 7944 7945 break; 7946 7947 case eEncodingA1: 7948 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7949 d = Bits32 (opcode, 15, 12); 7950 m = Bits32 (opcode, 3, 0); 7951 rotation = Bits32 (opcode, 11, 10) << 3; 7952 7953 // if d == 15 || m == 15 then UNPREDICTABLE; 7954 if ((d == 15) || (m == 15)) 7955 return false; 7956 7957 break; 7958 7959 default: 7960 return false; 7961 } 7962 7963 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7964 if (!success) 7965 return false; 7966 7967 // rotated = ROR(R[m], rotation); 7968 uint64_t rotated = ROR (Rm, rotation, &success); 7969 if (!success) 7970 return false; 7971 7972 // R[d] = ZeroExtend(rotated<7:0>, 32); 7973 RegisterInfo source_reg; 7974 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7975 7976 EmulateInstruction::Context context; 7977 context.type = eContextRegisterLoad; 7978 context.SetRegister (source_reg); 7979 7980 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 7981 return false; 7982 } 7983 return true; 7984 } 7985 7986 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 7987 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7988 bool 7989 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 7990 { 7991 #if 0 7992 if ConditionPassed() then 7993 EncodingSpecificOperations(); 7994 rotated = ROR(R[m], rotation); 7995 R[d] = ZeroExtend(rotated<15:0>, 32); 7996 #endif 7997 7998 bool success = false; 7999 8000 if (ConditionPassed(opcode)) 8001 { 8002 uint32_t d; 8003 uint32_t m; 8004 uint32_t rotation; 8005 8006 switch (encoding) 8007 { 8008 case eEncodingT1: 8009 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8010 d = Bits32 (opcode, 2, 0); 8011 m = Bits32 (opcode, 5, 3); 8012 rotation = 0; 8013 8014 break; 8015 8016 case eEncodingT2: 8017 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8018 d = Bits32 (opcode, 11, 8); 8019 m = Bits32 (opcode, 3, 0); 8020 rotation = Bits32 (opcode, 5, 4) << 3; 8021 8022 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8023 if (BadReg (d) || BadReg (m)) 8024 return false; 8025 8026 break; 8027 8028 case eEncodingA1: 8029 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8030 d = Bits32 (opcode, 15, 12); 8031 m = Bits32 (opcode, 3, 0); 8032 rotation = Bits32 (opcode, 11, 10) << 3; 8033 8034 // if d == 15 || m == 15 then UNPREDICTABLE; 8035 if ((d == 15) || (m == 15)) 8036 return false; 8037 8038 break; 8039 8040 default: 8041 return false; 8042 } 8043 8044 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8045 if (!success) 8046 return false; 8047 8048 // rotated = ROR(R[m], rotation); 8049 uint64_t rotated = ROR (Rm, rotation, &success); 8050 if (!success) 8051 return false; 8052 8053 // R[d] = ZeroExtend(rotated<15:0>, 32); 8054 RegisterInfo source_reg; 8055 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8056 8057 EmulateInstruction::Context context; 8058 context.type = eContextRegisterLoad; 8059 context.SetRegister (source_reg); 8060 8061 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8062 return false; 8063 } 8064 return true; 8065 } 8066 8067 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8068 // word respectively. 8069 bool 8070 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8071 { 8072 #if 0 8073 if ConditionPassed() then 8074 EncodingSpecificOperations(); 8075 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8076 UNPREDICTABLE; 8077 else 8078 address = if increment then R[n] else R[n]-8; 8079 if wordhigher then address = address+4; 8080 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8081 BranchWritePC(MemA[address,4]); 8082 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8083 #endif 8084 8085 bool success = false; 8086 8087 if (ConditionPassed(opcode)) 8088 { 8089 uint32_t n; 8090 bool wback; 8091 bool increment; 8092 bool wordhigher; 8093 8094 // EncodingSpecificOperations(); 8095 switch (encoding) 8096 { 8097 case eEncodingT1: 8098 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8099 n = Bits32 (opcode, 19, 16); 8100 wback = BitIsSet (opcode, 21); 8101 increment = false; 8102 wordhigher = false; 8103 8104 // if n == 15 then UNPREDICTABLE; 8105 if (n == 15) 8106 return false; 8107 8108 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8109 if (InITBlock() && !LastInITBlock()) 8110 return false; 8111 8112 break; 8113 8114 case eEncodingT2: 8115 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8116 n = Bits32 (opcode, 19, 16); 8117 wback = BitIsSet (opcode, 21); 8118 increment = true; 8119 wordhigher = false; 8120 8121 // if n == 15 then UNPREDICTABLE; 8122 if (n == 15) 8123 return false; 8124 8125 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8126 if (InITBlock() && !LastInITBlock()) 8127 return false; 8128 8129 break; 8130 8131 case eEncodingA1: 8132 // n = UInt(Rn); 8133 n = Bits32 (opcode, 19, 16); 8134 8135 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8136 wback = BitIsSet (opcode, 21); 8137 increment = BitIsSet (opcode, 23); 8138 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8139 8140 // if n == 15 then UNPREDICTABLE; 8141 if (n == 15) 8142 return false; 8143 8144 break; 8145 8146 default: 8147 return false; 8148 } 8149 8150 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8151 if (!CurrentModeIsPrivileged ()) 8152 // UNPREDICTABLE; 8153 return false; 8154 else 8155 { 8156 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8157 if (!success) 8158 return false; 8159 8160 addr_t address; 8161 // address = if increment then R[n] else R[n]-8; 8162 if (increment) 8163 address = Rn; 8164 else 8165 address = Rn - 8; 8166 8167 // if wordhigher then address = address+4; 8168 if (wordhigher) 8169 address = address + 4; 8170 8171 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8172 RegisterInfo base_reg; 8173 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8174 8175 EmulateInstruction::Context context; 8176 context.type = eContextReturnFromException; 8177 context.SetRegisterPlusOffset (base_reg, address - Rn); 8178 8179 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8180 if (!success) 8181 return false; 8182 8183 CPSRWriteByInstr (data, 15, true); 8184 8185 // BranchWritePC(MemA[address,4]); 8186 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8187 if (!success) 8188 return false; 8189 8190 BranchWritePC (context, data2); 8191 8192 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8193 if (wback) 8194 { 8195 context.type = eContextAdjustBaseRegister; 8196 if (increment) 8197 { 8198 context.SetOffset (8); 8199 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8200 return false; 8201 } 8202 else 8203 { 8204 context.SetOffset (-8); 8205 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8206 return false; 8207 } 8208 } // if wback 8209 } 8210 } // if ConditionPassed() 8211 return true; 8212 } 8213 8214 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8215 // and writes the result to the destination register. It can optionally update the condition flags based on 8216 // the result. 8217 bool 8218 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8219 { 8220 #if 0 8221 // ARM pseudo code... 8222 if ConditionPassed() then 8223 EncodingSpecificOperations(); 8224 result = R[n] EOR imm32; 8225 if d == 15 then // Can only occur for ARM encoding 8226 ALUWritePC(result); // setflags is always FALSE here 8227 else 8228 R[d] = result; 8229 if setflags then 8230 APSR.N = result<31>; 8231 APSR.Z = IsZeroBit(result); 8232 APSR.C = carry; 8233 // APSR.V unchanged 8234 #endif 8235 8236 bool success = false; 8237 8238 if (ConditionPassed(opcode)) 8239 { 8240 uint32_t Rd, Rn; 8241 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8242 bool setflags; 8243 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8244 switch (encoding) 8245 { 8246 case eEncodingT1: 8247 Rd = Bits32(opcode, 11, 8); 8248 Rn = Bits32(opcode, 19, 16); 8249 setflags = BitIsSet(opcode, 20); 8250 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8251 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8252 if (Rd == 15 && setflags) 8253 return EmulateTEQImm (opcode, eEncodingT1); 8254 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8255 return false; 8256 break; 8257 case eEncodingA1: 8258 Rd = Bits32(opcode, 15, 12); 8259 Rn = Bits32(opcode, 19, 16); 8260 setflags = BitIsSet(opcode, 20); 8261 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8262 8263 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8264 if (Rd == 15 && setflags) 8265 return EmulateSUBSPcLrEtc (opcode, encoding); 8266 break; 8267 default: 8268 return false; 8269 } 8270 8271 // Read the first operand. 8272 uint32_t val1 = ReadCoreReg(Rn, &success); 8273 if (!success) 8274 return false; 8275 8276 uint32_t result = val1 ^ imm32; 8277 8278 EmulateInstruction::Context context; 8279 context.type = EmulateInstruction::eContextImmediate; 8280 context.SetNoArgs (); 8281 8282 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8283 return false; 8284 } 8285 return true; 8286 } 8287 8288 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8289 // optionally-shifted register value, and writes the result to the destination register. 8290 // It can optionally update the condition flags based on the result. 8291 bool 8292 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8293 { 8294 #if 0 8295 // ARM pseudo code... 8296 if ConditionPassed() then 8297 EncodingSpecificOperations(); 8298 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8299 result = R[n] EOR shifted; 8300 if d == 15 then // Can only occur for ARM encoding 8301 ALUWritePC(result); // setflags is always FALSE here 8302 else 8303 R[d] = result; 8304 if setflags then 8305 APSR.N = result<31>; 8306 APSR.Z = IsZeroBit(result); 8307 APSR.C = carry; 8308 // APSR.V unchanged 8309 #endif 8310 8311 bool success = false; 8312 8313 if (ConditionPassed(opcode)) 8314 { 8315 uint32_t Rd, Rn, Rm; 8316 ARM_ShifterType shift_t; 8317 uint32_t shift_n; // the shift applied to the value read from Rm 8318 bool setflags; 8319 uint32_t carry; 8320 switch (encoding) 8321 { 8322 case eEncodingT1: 8323 Rd = Rn = Bits32(opcode, 2, 0); 8324 Rm = Bits32(opcode, 5, 3); 8325 setflags = !InITBlock(); 8326 shift_t = SRType_LSL; 8327 shift_n = 0; 8328 break; 8329 case eEncodingT2: 8330 Rd = Bits32(opcode, 11, 8); 8331 Rn = Bits32(opcode, 19, 16); 8332 Rm = Bits32(opcode, 3, 0); 8333 setflags = BitIsSet(opcode, 20); 8334 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8335 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8336 if (Rd == 15 && setflags) 8337 return EmulateTEQReg (opcode, eEncodingT1); 8338 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8339 return false; 8340 break; 8341 case eEncodingA1: 8342 Rd = Bits32(opcode, 15, 12); 8343 Rn = Bits32(opcode, 19, 16); 8344 Rm = Bits32(opcode, 3, 0); 8345 setflags = BitIsSet(opcode, 20); 8346 shift_n = DecodeImmShiftARM(opcode, shift_t); 8347 8348 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8349 if (Rd == 15 && setflags) 8350 return EmulateSUBSPcLrEtc (opcode, encoding); 8351 break; 8352 default: 8353 return false; 8354 } 8355 8356 // Read the first operand. 8357 uint32_t val1 = ReadCoreReg(Rn, &success); 8358 if (!success) 8359 return false; 8360 8361 // Read the second operand. 8362 uint32_t val2 = ReadCoreReg(Rm, &success); 8363 if (!success) 8364 return false; 8365 8366 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8367 if (!success) 8368 return false; 8369 uint32_t result = val1 ^ shifted; 8370 8371 EmulateInstruction::Context context; 8372 context.type = EmulateInstruction::eContextImmediate; 8373 context.SetNoArgs (); 8374 8375 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8376 return false; 8377 } 8378 return true; 8379 } 8380 8381 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8382 // writes the result to the destination register. It can optionally update the condition flags based 8383 // on the result. 8384 bool 8385 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8386 { 8387 #if 0 8388 // ARM pseudo code... 8389 if ConditionPassed() then 8390 EncodingSpecificOperations(); 8391 result = R[n] OR imm32; 8392 if d == 15 then // Can only occur for ARM encoding 8393 ALUWritePC(result); // setflags is always FALSE here 8394 else 8395 R[d] = result; 8396 if setflags then 8397 APSR.N = result<31>; 8398 APSR.Z = IsZeroBit(result); 8399 APSR.C = carry; 8400 // APSR.V unchanged 8401 #endif 8402 8403 bool success = false; 8404 8405 if (ConditionPassed(opcode)) 8406 { 8407 uint32_t Rd, Rn; 8408 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8409 bool setflags; 8410 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8411 switch (encoding) 8412 { 8413 case eEncodingT1: 8414 Rd = Bits32(opcode, 11, 8); 8415 Rn = Bits32(opcode, 19, 16); 8416 setflags = BitIsSet(opcode, 20); 8417 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8418 // if Rn == '1111' then SEE MOV (immediate); 8419 if (Rn == 15) 8420 return EmulateMOVRdImm (opcode, eEncodingT2); 8421 if (BadReg(Rd) || Rn == 13) 8422 return false; 8423 break; 8424 case eEncodingA1: 8425 Rd = Bits32(opcode, 15, 12); 8426 Rn = Bits32(opcode, 19, 16); 8427 setflags = BitIsSet(opcode, 20); 8428 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8429 8430 if (Rd == 15 && setflags) 8431 return EmulateSUBSPcLrEtc (opcode, encoding); 8432 break; 8433 default: 8434 return false; 8435 } 8436 8437 // Read the first operand. 8438 uint32_t val1 = ReadCoreReg(Rn, &success); 8439 if (!success) 8440 return false; 8441 8442 uint32_t result = val1 | imm32; 8443 8444 EmulateInstruction::Context context; 8445 context.type = EmulateInstruction::eContextImmediate; 8446 context.SetNoArgs (); 8447 8448 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8449 return false; 8450 } 8451 return true; 8452 } 8453 8454 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8455 // value, and writes the result to the destination register. It can optionally update the condition flags based 8456 // on the result. 8457 bool 8458 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8459 { 8460 #if 0 8461 // ARM pseudo code... 8462 if ConditionPassed() then 8463 EncodingSpecificOperations(); 8464 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8465 result = R[n] OR shifted; 8466 if d == 15 then // Can only occur for ARM encoding 8467 ALUWritePC(result); // setflags is always FALSE here 8468 else 8469 R[d] = result; 8470 if setflags then 8471 APSR.N = result<31>; 8472 APSR.Z = IsZeroBit(result); 8473 APSR.C = carry; 8474 // APSR.V unchanged 8475 #endif 8476 8477 bool success = false; 8478 8479 if (ConditionPassed(opcode)) 8480 { 8481 uint32_t Rd, Rn, Rm; 8482 ARM_ShifterType shift_t; 8483 uint32_t shift_n; // the shift applied to the value read from Rm 8484 bool setflags; 8485 uint32_t carry; 8486 switch (encoding) 8487 { 8488 case eEncodingT1: 8489 Rd = Rn = Bits32(opcode, 2, 0); 8490 Rm = Bits32(opcode, 5, 3); 8491 setflags = !InITBlock(); 8492 shift_t = SRType_LSL; 8493 shift_n = 0; 8494 break; 8495 case eEncodingT2: 8496 Rd = Bits32(opcode, 11, 8); 8497 Rn = Bits32(opcode, 19, 16); 8498 Rm = Bits32(opcode, 3, 0); 8499 setflags = BitIsSet(opcode, 20); 8500 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8501 // if Rn == '1111' then SEE MOV (register); 8502 if (Rn == 15) 8503 return EmulateMOVRdRm (opcode, eEncodingT3); 8504 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8505 return false; 8506 break; 8507 case eEncodingA1: 8508 Rd = Bits32(opcode, 15, 12); 8509 Rn = Bits32(opcode, 19, 16); 8510 Rm = Bits32(opcode, 3, 0); 8511 setflags = BitIsSet(opcode, 20); 8512 shift_n = DecodeImmShiftARM(opcode, shift_t); 8513 8514 if (Rd == 15 && setflags) 8515 return EmulateSUBSPcLrEtc (opcode, encoding); 8516 break; 8517 default: 8518 return false; 8519 } 8520 8521 // Read the first operand. 8522 uint32_t val1 = ReadCoreReg(Rn, &success); 8523 if (!success) 8524 return false; 8525 8526 // Read the second operand. 8527 uint32_t val2 = ReadCoreReg(Rm, &success); 8528 if (!success) 8529 return false; 8530 8531 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8532 if (!success) 8533 return false; 8534 uint32_t result = val1 | shifted; 8535 8536 EmulateInstruction::Context context; 8537 context.type = EmulateInstruction::eContextImmediate; 8538 context.SetNoArgs (); 8539 8540 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8541 return false; 8542 } 8543 return true; 8544 } 8545 8546 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8547 // the destination register. It can optionally update the condition flags based on the result. 8548 bool 8549 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8550 { 8551 #if 0 8552 // ARM pseudo code... 8553 if ConditionPassed() then 8554 EncodingSpecificOperations(); 8555 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8556 if d == 15 then // Can only occur for ARM encoding 8557 ALUWritePC(result); // setflags is always FALSE here 8558 else 8559 R[d] = result; 8560 if setflags then 8561 APSR.N = result<31>; 8562 APSR.Z = IsZeroBit(result); 8563 APSR.C = carry; 8564 APSR.V = overflow; 8565 #endif 8566 8567 bool success = false; 8568 8569 uint32_t Rd; // the destination register 8570 uint32_t Rn; // the first operand 8571 bool setflags; 8572 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8573 switch (encoding) { 8574 case eEncodingT1: 8575 Rd = Bits32(opcode, 2, 0); 8576 Rn = Bits32(opcode, 5, 3); 8577 setflags = !InITBlock(); 8578 imm32 = 0; 8579 break; 8580 case eEncodingT2: 8581 Rd = Bits32(opcode, 11, 8); 8582 Rn = Bits32(opcode, 19, 16); 8583 setflags = BitIsSet(opcode, 20); 8584 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8585 if (BadReg(Rd) || BadReg(Rn)) 8586 return false; 8587 break; 8588 case eEncodingA1: 8589 Rd = Bits32(opcode, 15, 12); 8590 Rn = Bits32(opcode, 19, 16); 8591 setflags = BitIsSet(opcode, 20); 8592 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8593 8594 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8595 if (Rd == 15 && setflags) 8596 return EmulateSUBSPcLrEtc (opcode, encoding); 8597 break; 8598 default: 8599 return false; 8600 } 8601 // Read the register value from the operand register Rn. 8602 uint32_t reg_val = ReadCoreReg(Rn, &success); 8603 if (!success) 8604 return false; 8605 8606 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8607 8608 EmulateInstruction::Context context; 8609 context.type = EmulateInstruction::eContextImmediate; 8610 context.SetNoArgs (); 8611 8612 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8613 return false; 8614 8615 return true; 8616 } 8617 8618 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8619 // result to the destination register. It can optionally update the condition flags based on the result. 8620 bool 8621 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8622 { 8623 #if 0 8624 // ARM pseudo code... 8625 if ConditionPassed() then 8626 EncodingSpecificOperations(); 8627 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8628 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8629 if d == 15 then // Can only occur for ARM encoding 8630 ALUWritePC(result); // setflags is always FALSE here 8631 else 8632 R[d] = result; 8633 if setflags then 8634 APSR.N = result<31>; 8635 APSR.Z = IsZeroBit(result); 8636 APSR.C = carry; 8637 APSR.V = overflow; 8638 #endif 8639 8640 bool success = false; 8641 8642 uint32_t Rd; // the destination register 8643 uint32_t Rn; // the first operand 8644 uint32_t Rm; // the second operand 8645 bool setflags; 8646 ARM_ShifterType shift_t; 8647 uint32_t shift_n; // the shift applied to the value read from Rm 8648 switch (encoding) { 8649 case eEncodingT1: 8650 Rd = Bits32(opcode, 11, 8); 8651 Rn = Bits32(opcode, 19, 16); 8652 Rm = Bits32(opcode, 3, 0); 8653 setflags = BitIsSet(opcode, 20); 8654 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8655 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8656 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8657 return false; 8658 break; 8659 case eEncodingA1: 8660 Rd = Bits32(opcode, 15, 12); 8661 Rn = Bits32(opcode, 19, 16); 8662 Rm = Bits32(opcode, 3, 0); 8663 setflags = BitIsSet(opcode, 20); 8664 shift_n = DecodeImmShiftARM(opcode, shift_t); 8665 8666 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8667 if (Rd == 15 && setflags) 8668 return EmulateSUBSPcLrEtc (opcode, encoding); 8669 break; 8670 default: 8671 return false; 8672 } 8673 // Read the register value from register Rn. 8674 uint32_t val1 = ReadCoreReg(Rn, &success); 8675 if (!success) 8676 return false; 8677 8678 // Read the register value from register Rm. 8679 uint32_t val2 = ReadCoreReg(Rm, &success); 8680 if (!success) 8681 return false; 8682 8683 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8684 if (!success) 8685 return false; 8686 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8687 8688 EmulateInstruction::Context context; 8689 context.type = EmulateInstruction::eContextImmediate; 8690 context.SetNoArgs(); 8691 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8692 return false; 8693 8694 return true; 8695 } 8696 8697 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8698 // an immediate value, and writes the result to the destination register. It can optionally update the condition 8699 // flags based on the result. 8700 bool 8701 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8702 { 8703 #if 0 8704 // ARM pseudo code... 8705 if ConditionPassed() then 8706 EncodingSpecificOperations(); 8707 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8708 if d == 15 then 8709 ALUWritePC(result); // setflags is always FALSE here 8710 else 8711 R[d] = result; 8712 if setflags then 8713 APSR.N = result<31>; 8714 APSR.Z = IsZeroBit(result); 8715 APSR.C = carry; 8716 APSR.V = overflow; 8717 #endif 8718 8719 bool success = false; 8720 8721 uint32_t Rd; // the destination register 8722 uint32_t Rn; // the first operand 8723 bool setflags; 8724 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8725 switch (encoding) { 8726 case eEncodingA1: 8727 Rd = Bits32(opcode, 15, 12); 8728 Rn = Bits32(opcode, 19, 16); 8729 setflags = BitIsSet(opcode, 20); 8730 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8731 8732 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8733 if (Rd == 15 && setflags) 8734 return EmulateSUBSPcLrEtc (opcode, encoding); 8735 break; 8736 default: 8737 return false; 8738 } 8739 // Read the register value from the operand register Rn. 8740 uint32_t reg_val = ReadCoreReg(Rn, &success); 8741 if (!success) 8742 return false; 8743 8744 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8745 8746 EmulateInstruction::Context context; 8747 context.type = EmulateInstruction::eContextImmediate; 8748 context.SetNoArgs (); 8749 8750 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8751 return false; 8752 8753 return true; 8754 } 8755 8756 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8757 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8758 // condition flags based on the result. 8759 bool 8760 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8761 { 8762 #if 0 8763 // ARM pseudo code... 8764 if ConditionPassed() then 8765 EncodingSpecificOperations(); 8766 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8767 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8768 if d == 15 then 8769 ALUWritePC(result); // setflags is always FALSE here 8770 else 8771 R[d] = result; 8772 if setflags then 8773 APSR.N = result<31>; 8774 APSR.Z = IsZeroBit(result); 8775 APSR.C = carry; 8776 APSR.V = overflow; 8777 #endif 8778 8779 bool success = false; 8780 8781 uint32_t Rd; // the destination register 8782 uint32_t Rn; // the first operand 8783 uint32_t Rm; // the second operand 8784 bool setflags; 8785 ARM_ShifterType shift_t; 8786 uint32_t shift_n; // the shift applied to the value read from Rm 8787 switch (encoding) { 8788 case eEncodingA1: 8789 Rd = Bits32(opcode, 15, 12); 8790 Rn = Bits32(opcode, 19, 16); 8791 Rm = Bits32(opcode, 3, 0); 8792 setflags = BitIsSet(opcode, 20); 8793 shift_n = DecodeImmShiftARM(opcode, shift_t); 8794 8795 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8796 if (Rd == 15 && setflags) 8797 return EmulateSUBSPcLrEtc (opcode, encoding); 8798 break; 8799 default: 8800 return false; 8801 } 8802 // Read the register value from register Rn. 8803 uint32_t val1 = ReadCoreReg(Rn, &success); 8804 if (!success) 8805 return false; 8806 8807 // Read the register value from register Rm. 8808 uint32_t val2 = ReadCoreReg(Rm, &success); 8809 if (!success) 8810 return false; 8811 8812 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8813 if (!success) 8814 return false; 8815 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8816 8817 EmulateInstruction::Context context; 8818 context.type = EmulateInstruction::eContextImmediate; 8819 context.SetNoArgs(); 8820 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8821 return false; 8822 8823 return true; 8824 } 8825 8826 // Subtract with Carry (immediate) subtracts an immediate value and the value of 8827 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8828 // It can optionally update the condition flags based on the result. 8829 bool 8830 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8831 { 8832 #if 0 8833 // ARM pseudo code... 8834 if ConditionPassed() then 8835 EncodingSpecificOperations(); 8836 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8837 if d == 15 then // Can only occur for ARM encoding 8838 ALUWritePC(result); // setflags is always FALSE here 8839 else 8840 R[d] = result; 8841 if setflags then 8842 APSR.N = result<31>; 8843 APSR.Z = IsZeroBit(result); 8844 APSR.C = carry; 8845 APSR.V = overflow; 8846 #endif 8847 8848 bool success = false; 8849 8850 uint32_t Rd; // the destination register 8851 uint32_t Rn; // the first operand 8852 bool setflags; 8853 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8854 switch (encoding) { 8855 case eEncodingT1: 8856 Rd = Bits32(opcode, 11, 8); 8857 Rn = Bits32(opcode, 19, 16); 8858 setflags = BitIsSet(opcode, 20); 8859 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8860 if (BadReg(Rd) || BadReg(Rn)) 8861 return false; 8862 break; 8863 case eEncodingA1: 8864 Rd = Bits32(opcode, 15, 12); 8865 Rn = Bits32(opcode, 19, 16); 8866 setflags = BitIsSet(opcode, 20); 8867 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8868 8869 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8870 if (Rd == 15 && setflags) 8871 return EmulateSUBSPcLrEtc (opcode, encoding); 8872 break; 8873 default: 8874 return false; 8875 } 8876 // Read the register value from the operand register Rn. 8877 uint32_t reg_val = ReadCoreReg(Rn, &success); 8878 if (!success) 8879 return false; 8880 8881 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 8882 8883 EmulateInstruction::Context context; 8884 context.type = EmulateInstruction::eContextImmediate; 8885 context.SetNoArgs (); 8886 8887 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8888 return false; 8889 8890 return true; 8891 } 8892 8893 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 8894 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8895 // It can optionally update the condition flags based on the result. 8896 bool 8897 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 8898 { 8899 #if 0 8900 // ARM pseudo code... 8901 if ConditionPassed() then 8902 EncodingSpecificOperations(); 8903 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8904 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 8905 if d == 15 then // Can only occur for ARM encoding 8906 ALUWritePC(result); // setflags is always FALSE here 8907 else 8908 R[d] = result; 8909 if setflags then 8910 APSR.N = result<31>; 8911 APSR.Z = IsZeroBit(result); 8912 APSR.C = carry; 8913 APSR.V = overflow; 8914 #endif 8915 8916 bool success = false; 8917 8918 uint32_t Rd; // the destination register 8919 uint32_t Rn; // the first operand 8920 uint32_t Rm; // the second operand 8921 bool setflags; 8922 ARM_ShifterType shift_t; 8923 uint32_t shift_n; // the shift applied to the value read from Rm 8924 switch (encoding) { 8925 case eEncodingT1: 8926 Rd = Rn = Bits32(opcode, 2, 0); 8927 Rm = Bits32(opcode, 5, 3); 8928 setflags = !InITBlock(); 8929 shift_t = SRType_LSL; 8930 shift_n = 0; 8931 break; 8932 case eEncodingT2: 8933 Rd = Bits32(opcode, 11, 8); 8934 Rn = Bits32(opcode, 19, 16); 8935 Rm = Bits32(opcode, 3, 0); 8936 setflags = BitIsSet(opcode, 20); 8937 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8938 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8939 return false; 8940 break; 8941 case eEncodingA1: 8942 Rd = Bits32(opcode, 15, 12); 8943 Rn = Bits32(opcode, 19, 16); 8944 Rm = Bits32(opcode, 3, 0); 8945 setflags = BitIsSet(opcode, 20); 8946 shift_n = DecodeImmShiftARM(opcode, shift_t); 8947 8948 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8949 if (Rd == 15 && setflags) 8950 return EmulateSUBSPcLrEtc (opcode, encoding); 8951 break; 8952 default: 8953 return false; 8954 } 8955 // Read the register value from register Rn. 8956 uint32_t val1 = ReadCoreReg(Rn, &success); 8957 if (!success) 8958 return false; 8959 8960 // Read the register value from register Rm. 8961 uint32_t val2 = ReadCoreReg(Rm, &success); 8962 if (!success) 8963 return false; 8964 8965 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8966 if (!success) 8967 return false; 8968 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 8969 8970 EmulateInstruction::Context context; 8971 context.type = EmulateInstruction::eContextImmediate; 8972 context.SetNoArgs(); 8973 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8974 return false; 8975 8976 return true; 8977 } 8978 8979 // This instruction subtracts an immediate value from a register value, and writes the result 8980 // to the destination register. It can optionally update the condition flags based on the result. 8981 bool 8982 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 8983 { 8984 #if 0 8985 // ARM pseudo code... 8986 if ConditionPassed() then 8987 EncodingSpecificOperations(); 8988 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 8989 R[d] = result; 8990 if setflags then 8991 APSR.N = result<31>; 8992 APSR.Z = IsZeroBit(result); 8993 APSR.C = carry; 8994 APSR.V = overflow; 8995 #endif 8996 8997 bool success = false; 8998 8999 uint32_t Rd; // the destination register 9000 uint32_t Rn; // the first operand 9001 bool setflags; 9002 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9003 switch (encoding) { 9004 case eEncodingT1: 9005 Rd = Bits32(opcode, 2, 0); 9006 Rn = Bits32(opcode, 5, 3); 9007 setflags = !InITBlock(); 9008 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9009 break; 9010 case eEncodingT2: 9011 Rd = Rn = Bits32(opcode, 10, 8); 9012 setflags = !InITBlock(); 9013 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9014 break; 9015 case eEncodingT3: 9016 Rd = Bits32(opcode, 11, 8); 9017 Rn = Bits32(opcode, 19, 16); 9018 setflags = BitIsSet(opcode, 20); 9019 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9020 9021 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9022 if (Rd == 15 && setflags) 9023 return EmulateCMPImm (opcode, eEncodingT2); 9024 9025 // if Rn == '1101' then SEE SUB (SP minus immediate); 9026 if (Rn == 13) 9027 return EmulateSUBSPImm (opcode, eEncodingT2); 9028 9029 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9030 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9031 return false; 9032 break; 9033 case eEncodingT4: 9034 Rd = Bits32(opcode, 11, 8); 9035 Rn = Bits32(opcode, 19, 16); 9036 setflags = BitIsSet(opcode, 20); 9037 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9038 9039 // if Rn == '1111' then SEE ADR; 9040 if (Rn == 15) 9041 return EmulateADR (opcode, eEncodingT2); 9042 9043 // if Rn == '1101' then SEE SUB (SP minus immediate); 9044 if (Rn == 13) 9045 return EmulateSUBSPImm (opcode, eEncodingT3); 9046 9047 if (BadReg(Rd)) 9048 return false; 9049 break; 9050 default: 9051 return false; 9052 } 9053 // Read the register value from the operand register Rn. 9054 uint32_t reg_val = ReadCoreReg(Rn, &success); 9055 if (!success) 9056 return false; 9057 9058 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9059 9060 EmulateInstruction::Context context; 9061 context.type = EmulateInstruction::eContextImmediate; 9062 context.SetNoArgs (); 9063 9064 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9065 return false; 9066 9067 return true; 9068 } 9069 9070 // This instruction subtracts an immediate value from a register value, and writes the result 9071 // to the destination register. It can optionally update the condition flags based on the result. 9072 bool 9073 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9074 { 9075 #if 0 9076 // ARM pseudo code... 9077 if ConditionPassed() then 9078 EncodingSpecificOperations(); 9079 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9080 if d == 15 then 9081 ALUWritePC(result); // setflags is always FALSE here 9082 else 9083 R[d] = result; 9084 if setflags then 9085 APSR.N = result<31>; 9086 APSR.Z = IsZeroBit(result); 9087 APSR.C = carry; 9088 APSR.V = overflow; 9089 #endif 9090 9091 bool success = false; 9092 9093 uint32_t Rd; // the destination register 9094 uint32_t Rn; // the first operand 9095 bool setflags; 9096 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9097 switch (encoding) { 9098 case eEncodingA1: 9099 Rd = Bits32(opcode, 15, 12); 9100 Rn = Bits32(opcode, 19, 16); 9101 setflags = BitIsSet(opcode, 20); 9102 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9103 9104 // if Rn == '1111' && S == '0' then SEE ADR; 9105 if (Rn == 15 && !setflags) 9106 return EmulateADR (opcode, eEncodingA2); 9107 9108 // if Rn == '1101' then SEE SUB (SP minus immediate); 9109 if (Rn == 13) 9110 return EmulateSUBSPImm (opcode, eEncodingA1); 9111 9112 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9113 if (Rd == 15 && setflags) 9114 return EmulateSUBSPcLrEtc (opcode, encoding); 9115 break; 9116 default: 9117 return false; 9118 } 9119 // Read the register value from the operand register Rn. 9120 uint32_t reg_val = ReadCoreReg(Rn, &success); 9121 if (!success) 9122 return false; 9123 9124 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9125 9126 EmulateInstruction::Context context; 9127 context.type = EmulateInstruction::eContextImmediate; 9128 context.SetNoArgs (); 9129 9130 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9131 return false; 9132 9133 return true; 9134 } 9135 9136 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9137 // immediate value. It updates the condition flags based on the result, and discards the result. 9138 bool 9139 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9140 { 9141 #if 0 9142 // ARM pseudo code... 9143 if ConditionPassed() then 9144 EncodingSpecificOperations(); 9145 result = R[n] EOR imm32; 9146 APSR.N = result<31>; 9147 APSR.Z = IsZeroBit(result); 9148 APSR.C = carry; 9149 // APSR.V unchanged 9150 #endif 9151 9152 bool success = false; 9153 9154 if (ConditionPassed(opcode)) 9155 { 9156 uint32_t Rn; 9157 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9158 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9159 switch (encoding) 9160 { 9161 case eEncodingT1: 9162 Rn = Bits32(opcode, 19, 16); 9163 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9164 if (BadReg(Rn)) 9165 return false; 9166 break; 9167 case eEncodingA1: 9168 Rn = Bits32(opcode, 19, 16); 9169 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9170 break; 9171 default: 9172 return false; 9173 } 9174 9175 // Read the first operand. 9176 uint32_t val1 = ReadCoreReg(Rn, &success); 9177 if (!success) 9178 return false; 9179 9180 uint32_t result = val1 ^ imm32; 9181 9182 EmulateInstruction::Context context; 9183 context.type = EmulateInstruction::eContextImmediate; 9184 context.SetNoArgs (); 9185 9186 if (!WriteFlags(context, result, carry)) 9187 return false; 9188 } 9189 return true; 9190 } 9191 9192 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9193 // optionally-shifted register value. It updates the condition flags based on the result, and discards 9194 // the result. 9195 bool 9196 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9197 { 9198 #if 0 9199 // ARM pseudo code... 9200 if ConditionPassed() then 9201 EncodingSpecificOperations(); 9202 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9203 result = R[n] EOR shifted; 9204 APSR.N = result<31>; 9205 APSR.Z = IsZeroBit(result); 9206 APSR.C = carry; 9207 // APSR.V unchanged 9208 #endif 9209 9210 bool success = false; 9211 9212 if (ConditionPassed(opcode)) 9213 { 9214 uint32_t Rn, Rm; 9215 ARM_ShifterType shift_t; 9216 uint32_t shift_n; // the shift applied to the value read from Rm 9217 uint32_t carry; 9218 switch (encoding) 9219 { 9220 case eEncodingT1: 9221 Rn = Bits32(opcode, 19, 16); 9222 Rm = Bits32(opcode, 3, 0); 9223 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9224 if (BadReg(Rn) || BadReg(Rm)) 9225 return false; 9226 break; 9227 case eEncodingA1: 9228 Rn = Bits32(opcode, 19, 16); 9229 Rm = Bits32(opcode, 3, 0); 9230 shift_n = DecodeImmShiftARM(opcode, shift_t); 9231 break; 9232 default: 9233 return false; 9234 } 9235 9236 // Read the first operand. 9237 uint32_t val1 = ReadCoreReg(Rn, &success); 9238 if (!success) 9239 return false; 9240 9241 // Read the second operand. 9242 uint32_t val2 = ReadCoreReg(Rm, &success); 9243 if (!success) 9244 return false; 9245 9246 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9247 if (!success) 9248 return false; 9249 uint32_t result = val1 ^ shifted; 9250 9251 EmulateInstruction::Context context; 9252 context.type = EmulateInstruction::eContextImmediate; 9253 context.SetNoArgs (); 9254 9255 if (!WriteFlags(context, result, carry)) 9256 return false; 9257 } 9258 return true; 9259 } 9260 9261 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9262 // It updates the condition flags based on the result, and discards the result. 9263 bool 9264 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9265 { 9266 #if 0 9267 // ARM pseudo code... 9268 if ConditionPassed() then 9269 EncodingSpecificOperations(); 9270 result = R[n] AND imm32; 9271 APSR.N = result<31>; 9272 APSR.Z = IsZeroBit(result); 9273 APSR.C = carry; 9274 // APSR.V unchanged 9275 #endif 9276 9277 bool success = false; 9278 9279 if (ConditionPassed(opcode)) 9280 { 9281 uint32_t Rn; 9282 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9283 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9284 switch (encoding) 9285 { 9286 case eEncodingT1: 9287 Rn = Bits32(opcode, 19, 16); 9288 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9289 if (BadReg(Rn)) 9290 return false; 9291 break; 9292 case eEncodingA1: 9293 Rn = Bits32(opcode, 19, 16); 9294 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9295 break; 9296 default: 9297 return false; 9298 } 9299 9300 // Read the first operand. 9301 uint32_t val1 = ReadCoreReg(Rn, &success); 9302 if (!success) 9303 return false; 9304 9305 uint32_t result = val1 & imm32; 9306 9307 EmulateInstruction::Context context; 9308 context.type = EmulateInstruction::eContextImmediate; 9309 context.SetNoArgs (); 9310 9311 if (!WriteFlags(context, result, carry)) 9312 return false; 9313 } 9314 return true; 9315 } 9316 9317 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9318 // It updates the condition flags based on the result, and discards the result. 9319 bool 9320 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9321 { 9322 #if 0 9323 // ARM pseudo code... 9324 if ConditionPassed() then 9325 EncodingSpecificOperations(); 9326 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9327 result = R[n] AND shifted; 9328 APSR.N = result<31>; 9329 APSR.Z = IsZeroBit(result); 9330 APSR.C = carry; 9331 // APSR.V unchanged 9332 #endif 9333 9334 bool success = false; 9335 9336 if (ConditionPassed(opcode)) 9337 { 9338 uint32_t Rn, Rm; 9339 ARM_ShifterType shift_t; 9340 uint32_t shift_n; // the shift applied to the value read from Rm 9341 uint32_t carry; 9342 switch (encoding) 9343 { 9344 case eEncodingT1: 9345 Rn = Bits32(opcode, 2, 0); 9346 Rm = Bits32(opcode, 5, 3); 9347 shift_t = SRType_LSL; 9348 shift_n = 0; 9349 break; 9350 case eEncodingT2: 9351 Rn = Bits32(opcode, 19, 16); 9352 Rm = Bits32(opcode, 3, 0); 9353 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9354 if (BadReg(Rn) || BadReg(Rm)) 9355 return false; 9356 break; 9357 case eEncodingA1: 9358 Rn = Bits32(opcode, 19, 16); 9359 Rm = Bits32(opcode, 3, 0); 9360 shift_n = DecodeImmShiftARM(opcode, shift_t); 9361 break; 9362 default: 9363 return false; 9364 } 9365 9366 // Read the first operand. 9367 uint32_t val1 = ReadCoreReg(Rn, &success); 9368 if (!success) 9369 return false; 9370 9371 // Read the second operand. 9372 uint32_t val2 = ReadCoreReg(Rm, &success); 9373 if (!success) 9374 return false; 9375 9376 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9377 if (!success) 9378 return false; 9379 uint32_t result = val1 & shifted; 9380 9381 EmulateInstruction::Context context; 9382 context.type = EmulateInstruction::eContextImmediate; 9383 context.SetNoArgs (); 9384 9385 if (!WriteFlags(context, result, carry)) 9386 return false; 9387 } 9388 return true; 9389 } 9390 9391 // A8.6.216 SUB (SP minus register) 9392 bool 9393 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9394 { 9395 #if 0 9396 if ConditionPassed() then 9397 EncodingSpecificOperations(); 9398 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9399 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9400 if d == 15 then // Can only occur for ARM encoding 9401 ALUWritePC(result); // setflags is always FALSE here 9402 else 9403 R[d] = result; 9404 if setflags then 9405 APSR.N = result<31>; 9406 APSR.Z = IsZeroBit(result); 9407 APSR.C = carry; 9408 APSR.V = overflow; 9409 #endif 9410 9411 bool success = false; 9412 9413 if (ConditionPassed(opcode)) 9414 { 9415 uint32_t d; 9416 uint32_t m; 9417 bool setflags; 9418 ARM_ShifterType shift_t; 9419 uint32_t shift_n; 9420 9421 switch (encoding) 9422 { 9423 case eEncodingT1: 9424 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9425 d = Bits32 (opcode, 11, 8); 9426 m = Bits32 (opcode, 3, 0); 9427 setflags = BitIsSet (opcode, 20); 9428 9429 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9430 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9431 9432 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9433 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9434 return false; 9435 9436 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9437 if ((d == 15) || BadReg (m)) 9438 return false; 9439 break; 9440 9441 case eEncodingA1: 9442 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�); 9443 d = Bits32 (opcode, 15, 12); 9444 m = Bits32 (opcode, 3, 0); 9445 setflags = BitIsSet (opcode, 20); 9446 9447 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9448 if (d == 15 && setflags) 9449 EmulateSUBSPcLrEtc (opcode, encoding); 9450 9451 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9452 shift_n = DecodeImmShiftARM (opcode, shift_t); 9453 break; 9454 9455 default: 9456 return false; 9457 } 9458 9459 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9460 uint32_t Rm = ReadCoreReg (m, &success); 9461 if (!success) 9462 return false; 9463 9464 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9465 if (!success) 9466 return false; 9467 9468 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�); 9469 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9470 if (!success) 9471 return false; 9472 9473 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9474 9475 EmulateInstruction::Context context; 9476 context.type = eContextArithmetic; 9477 RegisterInfo sp_reg; 9478 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9479 RegisterInfo dwarf_reg; 9480 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9481 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9482 9483 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9484 return false; 9485 } 9486 return true; 9487 } 9488 9489 9490 // A8.6.7 ADD (register-shifted register) 9491 bool 9492 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9493 { 9494 #if 0 9495 if ConditionPassed() then 9496 EncodingSpecificOperations(); 9497 shift_n = UInt(R[s]<7:0>); 9498 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9499 (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9500 R[d] = result; 9501 if setflags then 9502 APSR.N = result<31>; 9503 APSR.Z = IsZeroBit(result); 9504 APSR.C = carry; 9505 APSR.V = overflow; 9506 #endif 9507 9508 bool success = false; 9509 9510 if (ConditionPassed(opcode)) 9511 { 9512 uint32_t d; 9513 uint32_t n; 9514 uint32_t m; 9515 uint32_t s; 9516 bool setflags; 9517 ARM_ShifterType shift_t; 9518 9519 switch (encoding) 9520 { 9521 case eEncodingA1: 9522 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9523 d = Bits32 (opcode, 15, 12); 9524 n = Bits32 (opcode, 19, 16); 9525 m = Bits32 (opcode, 3, 0); 9526 s = Bits32 (opcode, 11, 8); 9527 9528 // setflags = (S == �1�); shift_t = DecodeRegShift(type); 9529 setflags = BitIsSet (opcode, 20); 9530 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9531 9532 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9533 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9534 return false; 9535 break; 9536 9537 default: 9538 return false; 9539 } 9540 9541 // shift_n = UInt(R[s]<7:0>); 9542 uint32_t Rs = ReadCoreReg (s, &success); 9543 if (!success) 9544 return false; 9545 9546 uint32_t shift_n = Bits32 (Rs, 7, 0); 9547 9548 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9549 uint32_t Rm = ReadCoreReg (m, &success); 9550 if (!success) 9551 return false; 9552 9553 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9554 if (!success) 9555 return false; 9556 9557 // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�); 9558 uint32_t Rn = ReadCoreReg (n, &success); 9559 if (!success) 9560 return false; 9561 9562 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9563 9564 // R[d] = result; 9565 EmulateInstruction::Context context; 9566 context.type = eContextArithmetic; 9567 RegisterInfo reg_n; 9568 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9569 RegisterInfo reg_m; 9570 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9571 9572 context.SetRegisterRegisterOperands (reg_n, reg_m); 9573 9574 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9575 return false; 9576 9577 // if setflags then 9578 // APSR.N = result<31>; 9579 // APSR.Z = IsZeroBit(result); 9580 // APSR.C = carry; 9581 // APSR.V = overflow; 9582 if (setflags) 9583 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9584 } 9585 return true; 9586 } 9587 9588 // A8.6.213 SUB (register) 9589 bool 9590 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9591 { 9592 #if 0 9593 if ConditionPassed() then 9594 EncodingSpecificOperations(); 9595 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9596 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9597 if d == 15 then // Can only occur for ARM encoding 9598 ALUWritePC(result); // setflags is always FALSE here 9599 else 9600 R[d] = result; 9601 if setflags then 9602 APSR.N = result<31>; 9603 APSR.Z = IsZeroBit(result); 9604 APSR.C = carry; 9605 APSR.V = overflow; 9606 #endif 9607 9608 bool success = false; 9609 9610 if (ConditionPassed(opcode)) 9611 { 9612 uint32_t d; 9613 uint32_t n; 9614 uint32_t m; 9615 bool setflags; 9616 ARM_ShifterType shift_t; 9617 uint32_t shift_n; 9618 9619 switch (encoding) 9620 { 9621 case eEncodingT1: 9622 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9623 d = Bits32 (opcode, 2, 0); 9624 n = Bits32 (opcode, 5, 3); 9625 m = Bits32 (opcode, 8, 6); 9626 setflags = !InITBlock(); 9627 9628 // (shift_t, shift_n) = (SRType_LSL, 0); 9629 shift_t = SRType_LSL; 9630 shift_n = 0; 9631 9632 break; 9633 9634 case eEncodingT2: 9635 // if Rd == �1111� && S == �1� then SEE CMP (register); 9636 // if Rn == �1101� then SEE SUB (SP minus register); 9637 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9638 d = Bits32 (opcode, 11, 8); 9639 n = Bits32 (opcode, 19, 16); 9640 m = Bits32 (opcode, 3, 0); 9641 setflags = BitIsSet (opcode, 20); 9642 9643 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9644 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9645 9646 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9647 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9648 return false; 9649 9650 break; 9651 9652 case eEncodingA1: 9653 // if Rn == �1101� then SEE SUB (SP minus register); 9654 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�); 9655 d = Bits32 (opcode, 15, 12); 9656 n = Bits32 (opcode, 19, 16); 9657 m = Bits32 (opcode, 3, 0); 9658 setflags = BitIsSet (opcode, 20); 9659 9660 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions; 9661 if ((d == 15) && setflags) 9662 EmulateSUBSPcLrEtc (opcode, encoding); 9663 9664 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9665 shift_n = DecodeImmShiftARM (opcode, shift_t); 9666 9667 break; 9668 9669 default: 9670 return false; 9671 } 9672 9673 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9674 uint32_t Rm = ReadCoreReg (m, &success); 9675 if (!success) 9676 return false; 9677 9678 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9679 if (!success) 9680 return false; 9681 9682 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�); 9683 uint32_t Rn = ReadCoreReg (n, &success); 9684 if (!success) 9685 return false; 9686 9687 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9688 9689 // if d == 15 then // Can only occur for ARM encoding 9690 // ALUWritePC(result); // setflags is always FALSE here 9691 // else 9692 // R[d] = result; 9693 // if setflags then 9694 // APSR.N = result<31>; 9695 // APSR.Z = IsZeroBit(result); 9696 // APSR.C = carry; 9697 // APSR.V = overflow; 9698 9699 EmulateInstruction::Context context; 9700 context.type = eContextArithmetic; 9701 RegisterInfo reg_n; 9702 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9703 RegisterInfo reg_m; 9704 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9705 context.SetRegisterRegisterOperands (reg_n, reg_m); 9706 9707 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9708 return false; 9709 } 9710 return true; 9711 } 9712 9713 // A8.6.202 STREX 9714 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9715 // word from a register to memory if the executing processor has exclusive access to the memory addressed. 9716 bool 9717 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9718 { 9719 #if 0 9720 if ConditionPassed() then 9721 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9722 address = R[n] + imm32; 9723 if ExclusiveMonitorsPass(address,4) then 9724 MemA[address,4] = R[t]; 9725 R[d] = 0; 9726 else 9727 R[d] = 1; 9728 #endif 9729 9730 bool success = false; 9731 9732 if (ConditionPassed(opcode)) 9733 { 9734 uint32_t d; 9735 uint32_t t; 9736 uint32_t n; 9737 uint32_t imm32; 9738 const uint32_t addr_byte_size = GetAddressByteSize(); 9739 9740 switch (encoding) 9741 { 9742 case eEncodingT1: 9743 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 9744 d = Bits32 (opcode, 11, 8); 9745 t = Bits32 (opcode, 15, 12); 9746 n = Bits32 (opcode, 19, 16); 9747 imm32 = Bits32 (opcode, 7, 0) << 2; 9748 9749 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9750 if (BadReg (d) || BadReg (t) || (n == 15)) 9751 return false; 9752 9753 // if d == n || d == t then UNPREDICTABLE; 9754 if ((d == n) || (d == t)) 9755 return false; 9756 9757 break; 9758 9759 case eEncodingA1: 9760 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9761 d = Bits32 (opcode, 15, 12); 9762 t = Bits32 (opcode, 3, 0); 9763 n = Bits32 (opcode, 19, 16); 9764 imm32 = 0; 9765 9766 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9767 if ((d == 15) || (t == 15) || (n == 15)) 9768 return false; 9769 9770 // if d == n || d == t then UNPREDICTABLE; 9771 if ((d == n) || (d == t)) 9772 return false; 9773 9774 break; 9775 9776 default: 9777 return false; 9778 } 9779 9780 // address = R[n] + imm32; 9781 uint32_t Rn = ReadCoreReg (n, &success); 9782 if (!success) 9783 return false; 9784 9785 addr_t address = Rn + imm32; 9786 9787 RegisterInfo base_reg; 9788 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9789 RegisterInfo data_reg; 9790 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9791 EmulateInstruction::Context context; 9792 context.type = eContextRegisterStore; 9793 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9794 9795 // if ExclusiveMonitorsPass(address,4) then 9796 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9797 // always return true. 9798 if (true) 9799 { 9800 // MemA[address,4] = R[t]; 9801 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9802 if (!success) 9803 return false; 9804 9805 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9806 return false; 9807 9808 // R[d] = 0; 9809 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9810 return false; 9811 } 9812 else 9813 { 9814 // R[d] = 1; 9815 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9816 return false; 9817 } 9818 } 9819 return true; 9820 } 9821 9822 // A8.6.197 STRB (immediate, ARM) 9823 bool 9824 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9825 { 9826 #if 0 9827 if ConditionPassed() then 9828 EncodingSpecificOperations(); 9829 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9830 address = if index then offset_addr else R[n]; 9831 MemU[address,1] = R[t]<7:0>; 9832 if wback then R[n] = offset_addr; 9833 #endif 9834 9835 bool success = false; 9836 9837 if (ConditionPassed(opcode)) 9838 { 9839 uint32_t t; 9840 uint32_t n; 9841 uint32_t imm32; 9842 bool index; 9843 bool add; 9844 bool wback; 9845 9846 switch (encoding) 9847 { 9848 case eEncodingA1: 9849 // if P == �0� && W == �1� then SEE STRBT; 9850 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9851 t = Bits32 (opcode, 15, 12); 9852 n = Bits32 (opcode, 19, 16); 9853 imm32 = Bits32 (opcode, 11, 0); 9854 9855 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9856 index = BitIsSet (opcode, 24); 9857 add = BitIsSet (opcode, 23); 9858 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9859 9860 // if t == 15 then UNPREDICTABLE; 9861 if (t == 15) 9862 return false; 9863 9864 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9865 if (wback && ((n == 15) || (n == t))) 9866 return false; 9867 9868 break; 9869 9870 default: 9871 return false; 9872 } 9873 9874 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9875 uint32_t Rn = ReadCoreReg (n, &success); 9876 if (!success) 9877 return false; 9878 9879 addr_t offset_addr; 9880 if (add) 9881 offset_addr = Rn + imm32; 9882 else 9883 offset_addr = Rn - imm32; 9884 9885 // address = if index then offset_addr else R[n]; 9886 addr_t address; 9887 if (index) 9888 address = offset_addr; 9889 else 9890 address = Rn; 9891 9892 // MemU[address,1] = R[t]<7:0>; 9893 uint32_t Rt = ReadCoreReg (t, &success); 9894 if (!success) 9895 return false; 9896 9897 RegisterInfo base_reg; 9898 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9899 RegisterInfo data_reg; 9900 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9901 EmulateInstruction::Context context; 9902 context.type = eContextRegisterStore; 9903 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9904 9905 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 9906 return false; 9907 9908 // if wback then R[n] = offset_addr; 9909 if (wback) 9910 { 9911 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 9912 return false; 9913 } 9914 } 9915 return true; 9916 } 9917 9918 // A8.6.194 STR (immediate, ARM) 9919 bool 9920 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 9921 { 9922 #if 0 9923 if ConditionPassed() then 9924 EncodingSpecificOperations(); 9925 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9926 address = if index then offset_addr else R[n]; 9927 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9928 if wback then R[n] = offset_addr; 9929 #endif 9930 9931 bool success = false; 9932 9933 if (ConditionPassed(opcode)) 9934 { 9935 uint32_t t; 9936 uint32_t n; 9937 uint32_t imm32; 9938 bool index; 9939 bool add; 9940 bool wback; 9941 9942 const uint32_t addr_byte_size = GetAddressByteSize(); 9943 9944 switch (encoding) 9945 { 9946 case eEncodingA1: 9947 // if P == �0� && W == �1� then SEE STRT; 9948 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH; 9949 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 9950 t = Bits32 (opcode, 15, 12); 9951 n = Bits32 (opcode, 19, 16); 9952 imm32 = Bits32 (opcode, 11, 0); 9953 9954 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 9955 index = BitIsSet (opcode, 24); 9956 add = BitIsSet (opcode, 23); 9957 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 9958 9959 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 9960 if (wback && ((n == 15) || (n == t))) 9961 return false; 9962 9963 break; 9964 9965 default: 9966 return false; 9967 } 9968 9969 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9970 uint32_t Rn = ReadCoreReg (n, &success); 9971 if (!success) 9972 return false; 9973 9974 addr_t offset_addr; 9975 if (add) 9976 offset_addr = Rn + imm32; 9977 else 9978 offset_addr = Rn - imm32; 9979 9980 // address = if index then offset_addr else R[n]; 9981 addr_t address; 9982 if (index) 9983 address = offset_addr; 9984 else 9985 address = Rn; 9986 9987 RegisterInfo base_reg; 9988 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9989 RegisterInfo data_reg; 9990 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9991 EmulateInstruction::Context context; 9992 context.type = eContextRegisterStore; 9993 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 9994 9995 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 9996 uint32_t Rt = ReadCoreReg (t, &success); 9997 if (!success) 9998 return false; 9999 10000 if (t == 15) 10001 { 10002 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10003 if (!success) 10004 return false; 10005 10006 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10007 return false; 10008 } 10009 else 10010 { 10011 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10012 return false; 10013 } 10014 10015 // if wback then R[n] = offset_addr; 10016 if (wback) 10017 { 10018 context.type = eContextAdjustBaseRegister; 10019 context.SetImmediate (offset_addr); 10020 10021 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10022 return false; 10023 } 10024 } 10025 return true; 10026 } 10027 10028 // A8.6.66 LDRD (immediate) 10029 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10030 // words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10031 bool 10032 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10033 { 10034 #if 0 10035 if ConditionPassed() then 10036 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10037 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10038 address = if index then offset_addr else R[n]; 10039 R[t] = MemA[address,4]; 10040 R[t2] = MemA[address+4,4]; 10041 if wback then R[n] = offset_addr; 10042 #endif 10043 10044 bool success = false; 10045 10046 if (ConditionPassed(opcode)) 10047 { 10048 uint32_t t; 10049 uint32_t t2; 10050 uint32_t n; 10051 uint32_t imm32; 10052 bool index; 10053 bool add; 10054 bool wback; 10055 10056 switch (encoding) 10057 { 10058 case eEncodingT1: 10059 //if P == �0� && W == �0� then SEE �Related encodings�; 10060 //if Rn == �1111� then SEE LDRD (literal); 10061 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10062 t = Bits32 (opcode, 15, 12); 10063 t2 = Bits32 (opcode, 11, 8); 10064 n = Bits32 (opcode, 19, 16); 10065 imm32 = Bits32 (opcode, 7, 0) << 2; 10066 10067 //index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10068 index = BitIsSet (opcode, 24); 10069 add = BitIsSet (opcode, 23); 10070 wback = BitIsSet (opcode, 21); 10071 10072 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10073 if (wback && ((n == t) || (n == t2))) 10074 return false; 10075 10076 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10077 if (BadReg (t) || BadReg (t2) || (t == t2)) 10078 return false; 10079 10080 break; 10081 10082 case eEncodingA1: 10083 //if Rn == �1111� then SEE LDRD (literal); 10084 //if Rt<0> == �1� then UNPREDICTABLE; 10085 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10086 t = Bits32 (opcode, 15, 12); 10087 if (BitIsSet (t, 0)) 10088 return false; 10089 t2 = t + 1; 10090 n = Bits32 (opcode, 19, 16); 10091 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10092 10093 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10094 index = BitIsSet (opcode, 24); 10095 add = BitIsSet (opcode, 23); 10096 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10097 10098 //if P == �0� && W == �1� then UNPREDICTABLE; 10099 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10100 return false; 10101 10102 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10103 if (wback && ((n == t) || (n == t2))) 10104 return false; 10105 10106 //if t2 == 15 then UNPREDICTABLE; 10107 if (t2 == 15) 10108 return false; 10109 10110 break; 10111 10112 default: 10113 return false; 10114 } 10115 10116 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10117 uint32_t Rn = ReadCoreReg (n, &success); 10118 if (!success) 10119 return false; 10120 10121 addr_t offset_addr; 10122 if (add) 10123 offset_addr = Rn + imm32; 10124 else 10125 offset_addr = Rn - imm32; 10126 10127 //address = if index then offset_addr else R[n]; 10128 addr_t address; 10129 if (index) 10130 address = offset_addr; 10131 else 10132 address = Rn; 10133 10134 //R[t] = MemA[address,4]; 10135 RegisterInfo base_reg; 10136 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10137 10138 EmulateInstruction::Context context; 10139 context.type = eContextRegisterLoad; 10140 context.SetRegisterPlusOffset (base_reg, address - Rn); 10141 10142 const uint32_t addr_byte_size = GetAddressByteSize(); 10143 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10144 if (!success) 10145 return false; 10146 10147 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10148 return false; 10149 10150 //R[t2] = MemA[address+4,4]; 10151 10152 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10153 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10154 if (!success) 10155 return false; 10156 10157 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10158 return false; 10159 10160 //if wback then R[n] = offset_addr; 10161 if (wback) 10162 { 10163 context.type = eContextAdjustBaseRegister; 10164 context.SetAddress (offset_addr); 10165 10166 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10167 return false; 10168 } 10169 } 10170 return true; 10171 } 10172 10173 // A8.6.68 LDRD (register) 10174 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10175 // words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10176 bool 10177 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10178 { 10179 #if 0 10180 if ConditionPassed() then 10181 EncodingSpecificOperations(); 10182 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10183 address = if index then offset_addr else R[n]; 10184 R[t] = MemA[address,4]; 10185 R[t2] = MemA[address+4,4]; 10186 if wback then R[n] = offset_addr; 10187 #endif 10188 10189 bool success = false; 10190 10191 if (ConditionPassed(opcode)) 10192 { 10193 uint32_t t; 10194 uint32_t t2; 10195 uint32_t n; 10196 uint32_t m; 10197 bool index; 10198 bool add; 10199 bool wback; 10200 10201 switch (encoding) 10202 { 10203 case eEncodingA1: 10204 // if Rt<0> == �1� then UNPREDICTABLE; 10205 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10206 t = Bits32 (opcode, 15, 12); 10207 if (BitIsSet (t, 0)) 10208 return false; 10209 t2 = t + 1; 10210 n = Bits32 (opcode, 19, 16); 10211 m = Bits32 (opcode, 3, 0); 10212 10213 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10214 index = BitIsSet (opcode, 24); 10215 add = BitIsSet (opcode, 23); 10216 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10217 10218 // if P == �0� && W == �1� then UNPREDICTABLE; 10219 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10220 return false; 10221 10222 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10223 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10224 return false; 10225 10226 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10227 if (wback && ((n == 15) || (n == t) || (n == t2))) 10228 return false; 10229 10230 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10231 if ((ArchVersion() < 6) && wback && (m == n)) 10232 return false; 10233 break; 10234 10235 default: 10236 return false; 10237 } 10238 10239 uint32_t Rn = ReadCoreReg (n, &success); 10240 if (!success) 10241 return false; 10242 RegisterInfo base_reg; 10243 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10244 10245 uint32_t Rm = ReadCoreReg (m, &success); 10246 if (!success) 10247 return false; 10248 RegisterInfo offset_reg; 10249 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10250 10251 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10252 addr_t offset_addr; 10253 if (add) 10254 offset_addr = Rn + Rm; 10255 else 10256 offset_addr = Rn - Rm; 10257 10258 // address = if index then offset_addr else R[n]; 10259 addr_t address; 10260 if (index) 10261 address = offset_addr; 10262 else 10263 address = Rn; 10264 10265 EmulateInstruction::Context context; 10266 context.type = eContextRegisterLoad; 10267 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10268 10269 // R[t] = MemA[address,4]; 10270 const uint32_t addr_byte_size = GetAddressByteSize(); 10271 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10272 if (!success) 10273 return false; 10274 10275 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10276 return false; 10277 10278 // R[t2] = MemA[address+4,4]; 10279 10280 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10281 if (!success) 10282 return false; 10283 10284 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10285 return false; 10286 10287 // if wback then R[n] = offset_addr; 10288 if (wback) 10289 { 10290 context.type = eContextAdjustBaseRegister; 10291 context.SetAddress (offset_addr); 10292 10293 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10294 return false; 10295 } 10296 } 10297 return true; 10298 } 10299 10300 // A8.6.200 STRD (immediate) 10301 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10302 // stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10303 bool 10304 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10305 { 10306 #if 0 10307 if ConditionPassed() then 10308 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10309 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10310 address = if index then offset_addr else R[n]; 10311 MemA[address,4] = R[t]; 10312 MemA[address+4,4] = R[t2]; 10313 if wback then R[n] = offset_addr; 10314 #endif 10315 10316 bool success = false; 10317 10318 if (ConditionPassed(opcode)) 10319 { 10320 uint32_t t; 10321 uint32_t t2; 10322 uint32_t n; 10323 uint32_t imm32; 10324 bool index; 10325 bool add; 10326 bool wback; 10327 10328 switch (encoding) 10329 { 10330 case eEncodingT1: 10331 // if P == �0� && W == �0� then SEE �Related encodings�; 10332 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10333 t = Bits32 (opcode, 15, 12); 10334 t2 = Bits32 (opcode, 11, 8); 10335 n = Bits32 (opcode, 19, 16); 10336 imm32 = Bits32 (opcode, 7, 0) << 2; 10337 10338 // index = (P == �1�); add = (U == �1�); wback = (W == �1�); 10339 index = BitIsSet (opcode, 24); 10340 add = BitIsSet (opcode, 23); 10341 wback = BitIsSet (opcode, 21); 10342 10343 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10344 if (wback && ((n == t) || (n == t2))) 10345 return false; 10346 10347 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10348 if ((n == 15) || BadReg (t) || BadReg (t2)) 10349 return false; 10350 10351 break; 10352 10353 case eEncodingA1: 10354 // if Rt<0> == �1� then UNPREDICTABLE; 10355 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10356 t = Bits32 (opcode, 15, 12); 10357 if (BitIsSet (t, 0)) 10358 return false; 10359 10360 t2 = t + 1; 10361 n = Bits32 (opcode, 19, 16); 10362 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10363 10364 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10365 index = BitIsSet (opcode, 24); 10366 add = BitIsSet (opcode, 23); 10367 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10368 10369 // if P == �0� && W == �1� then UNPREDICTABLE; 10370 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10371 return false; 10372 10373 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10374 if (wback && ((n == 15) || (n == t) || (n == t2))) 10375 return false; 10376 10377 // if t2 == 15 then UNPREDICTABLE; 10378 if (t2 == 15) 10379 return false; 10380 10381 break; 10382 10383 default: 10384 return false; 10385 } 10386 10387 RegisterInfo base_reg; 10388 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10389 10390 uint32_t Rn = ReadCoreReg (n, &success); 10391 if (!success) 10392 return false; 10393 10394 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10395 addr_t offset_addr; 10396 if (add) 10397 offset_addr = Rn + imm32; 10398 else 10399 offset_addr = Rn - imm32; 10400 10401 //address = if index then offset_addr else R[n]; 10402 addr_t address; 10403 if (index) 10404 address = offset_addr; 10405 else 10406 address = Rn; 10407 10408 //MemA[address,4] = R[t]; 10409 RegisterInfo data_reg; 10410 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10411 10412 uint32_t data = ReadCoreReg (t, &success); 10413 if (!success) 10414 return false; 10415 10416 EmulateInstruction::Context context; 10417 context.type = eContextRegisterStore; 10418 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10419 10420 const uint32_t addr_byte_size = GetAddressByteSize(); 10421 10422 if (!MemAWrite (context, address, data, addr_byte_size)) 10423 return false; 10424 10425 //MemA[address+4,4] = R[t2]; 10426 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10427 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10428 10429 data = ReadCoreReg (t2, &success); 10430 if (!success) 10431 return false; 10432 10433 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10434 return false; 10435 10436 //if wback then R[n] = offset_addr; 10437 if (wback) 10438 { 10439 context.type = eContextAdjustBaseRegister; 10440 context.SetAddress (offset_addr); 10441 10442 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10443 return false; 10444 } 10445 } 10446 return true; 10447 } 10448 10449 10450 // A8.6.201 STRD (register) 10451 bool 10452 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10453 { 10454 #if 0 10455 if ConditionPassed() then 10456 EncodingSpecificOperations(); 10457 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10458 address = if index then offset_addr else R[n]; 10459 MemA[address,4] = R[t]; 10460 MemA[address+4,4] = R[t2]; 10461 if wback then R[n] = offset_addr; 10462 #endif 10463 10464 bool success = false; 10465 10466 if (ConditionPassed(opcode)) 10467 { 10468 uint32_t t; 10469 uint32_t t2; 10470 uint32_t n; 10471 uint32_t m; 10472 bool index; 10473 bool add; 10474 bool wback; 10475 10476 switch (encoding) 10477 { 10478 case eEncodingA1: 10479 // if Rt<0> == �1� then UNPREDICTABLE; 10480 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10481 t = Bits32 (opcode, 15, 12); 10482 if (BitIsSet (t, 0)) 10483 return false; 10484 10485 t2 = t+1; 10486 n = Bits32 (opcode, 19, 16); 10487 m = Bits32 (opcode, 3, 0); 10488 10489 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�); 10490 index = BitIsSet (opcode, 24); 10491 add = BitIsSet (opcode, 23); 10492 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10493 10494 // if P == �0� && W == �1� then UNPREDICTABLE; 10495 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10496 return false; 10497 10498 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10499 if ((t2 == 15) || (m == 15)) 10500 return false; 10501 10502 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10503 if (wback && ((n == 15) || (n == t) || (n == t2))) 10504 return false; 10505 10506 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10507 if ((ArchVersion() < 6) && wback && (m == n)) 10508 return false; 10509 10510 break; 10511 10512 default: 10513 return false; 10514 } 10515 10516 RegisterInfo base_reg; 10517 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10518 RegisterInfo offset_reg; 10519 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10520 RegisterInfo data_reg; 10521 10522 uint32_t Rn = ReadCoreReg (n, &success); 10523 if (!success) 10524 return false; 10525 10526 uint32_t Rm = ReadCoreReg (m, &success); 10527 if (!success) 10528 return false; 10529 10530 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10531 addr_t offset_addr; 10532 if (add) 10533 offset_addr = Rn + Rm; 10534 else 10535 offset_addr = Rn - Rm; 10536 10537 // address = if index then offset_addr else R[n]; 10538 addr_t address; 10539 if (index) 10540 address = offset_addr; 10541 else 10542 address = Rn; 10543 // MemA[address,4] = R[t]; 10544 uint32_t Rt = ReadCoreReg (t, &success); 10545 if (!success) 10546 return false; 10547 10548 EmulateInstruction::Context context; 10549 context.type = eContextRegisterStore; 10550 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10551 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10552 10553 const uint32_t addr_byte_size = GetAddressByteSize(); 10554 10555 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10556 return false; 10557 10558 // MemA[address+4,4] = R[t2]; 10559 uint32_t Rt2 = ReadCoreReg (t2, &success); 10560 if (!success) 10561 return false; 10562 10563 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10564 10565 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10566 10567 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10568 return false; 10569 10570 // if wback then R[n] = offset_addr; 10571 if (wback) 10572 { 10573 context.type = eContextAdjustBaseRegister; 10574 context.SetAddress (offset_addr); 10575 10576 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10577 return false; 10578 10579 } 10580 } 10581 return true; 10582 } 10583 10584 // A8.6.319 VLDM 10585 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10586 // an ARM core register. 10587 bool 10588 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10589 { 10590 #if 0 10591 if ConditionPassed() then 10592 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10593 address = if add then R[n] else R[n]-imm32; 10594 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10595 for r = 0 to regs-1 10596 if single_regs then 10597 S[d+r] = MemA[address,4]; address = address+4; 10598 else 10599 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10600 // Combine the word-aligned words in the correct order for current endianness. 10601 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10602 #endif 10603 10604 bool success = false; 10605 10606 if (ConditionPassed(opcode)) 10607 { 10608 bool single_regs; 10609 bool add; 10610 bool wback; 10611 uint32_t d; 10612 uint32_t n; 10613 uint32_t imm32; 10614 uint32_t regs; 10615 10616 switch (encoding) 10617 { 10618 case eEncodingT1: 10619 case eEncodingA1: 10620 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10621 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10622 // if P == �1� && W == �0� then SEE VLDR; 10623 // if P == U && W == �1� then UNDEFINED; 10624 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10625 return false; 10626 10627 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10628 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10629 single_regs = false; 10630 add = BitIsSet (opcode, 23); 10631 wback = BitIsSet (opcode, 21); 10632 10633 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10634 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10635 n = Bits32 (opcode, 19, 16); 10636 imm32 = Bits32 (opcode, 7, 0) << 2; 10637 10638 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�. 10639 regs = Bits32 (opcode, 7, 0) / 2; 10640 10641 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10642 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10643 return false; 10644 10645 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10646 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10647 return false; 10648 10649 break; 10650 10651 case eEncodingT2: 10652 case eEncodingA2: 10653 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10654 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP; 10655 // if P == �1� && W == �0� then SEE VLDR; 10656 // if P == U && W == �1� then UNDEFINED; 10657 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10658 return false; 10659 10660 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10661 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10662 single_regs = true; 10663 add = BitIsSet (opcode, 23); 10664 wback = BitIsSet (opcode, 21); 10665 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10666 n = Bits32 (opcode, 19, 16); 10667 10668 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10669 imm32 = Bits32 (opcode, 7, 0) << 2; 10670 regs = Bits32 (opcode, 7, 0); 10671 10672 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10673 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10674 return false; 10675 10676 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10677 if ((regs == 0) || ((d + regs) > 32)) 10678 return false; 10679 break; 10680 10681 default: 10682 return false; 10683 } 10684 10685 RegisterInfo base_reg; 10686 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10687 10688 uint32_t Rn = ReadCoreReg (n, &success); 10689 if (!success) 10690 return false; 10691 10692 // address = if add then R[n] else R[n]-imm32; 10693 addr_t address; 10694 if (add) 10695 address = Rn; 10696 else 10697 address = Rn - imm32; 10698 10699 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10700 EmulateInstruction::Context context; 10701 10702 if (wback) 10703 { 10704 uint32_t value; 10705 if (add) 10706 value = Rn + imm32; 10707 else 10708 value = Rn - imm32; 10709 10710 context.type = eContextAdjustBaseRegister; 10711 context.SetImmediateSigned (value - Rn); 10712 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10713 return false; 10714 10715 } 10716 10717 const uint32_t addr_byte_size = GetAddressByteSize(); 10718 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10719 10720 context.type = eContextRegisterLoad; 10721 10722 // for r = 0 to regs-1 10723 for (uint32_t r = 0; r < regs; ++r) 10724 { 10725 if (single_regs) 10726 { 10727 // S[d+r] = MemA[address,4]; address = address+4; 10728 context.SetRegisterPlusOffset (base_reg, address - Rn); 10729 10730 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10731 if (!success) 10732 return false; 10733 10734 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10735 return false; 10736 10737 address = address + 4; 10738 } 10739 else 10740 { 10741 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10742 context.SetRegisterPlusOffset (base_reg, address - Rn); 10743 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10744 if (!success) 10745 return false; 10746 10747 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10748 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10749 if (!success) 10750 return false; 10751 10752 address = address + 8; 10753 // // Combine the word-aligned words in the correct order for current endianness. 10754 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10755 uint64_t data; 10756 if (GetByteOrder() == eByteOrderBig) 10757 { 10758 data = word1; 10759 data = (data << 32) | word2; 10760 } 10761 else 10762 { 10763 data = word2; 10764 data = (data << 32) | word1; 10765 } 10766 10767 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10768 return false; 10769 } 10770 } 10771 } 10772 return true; 10773 } 10774 10775 // A8.6.399 VSTM 10776 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10777 // ARM core register. 10778 bool 10779 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10780 { 10781 #if 0 10782 if ConditionPassed() then 10783 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10784 address = if add then R[n] else R[n]-imm32; 10785 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10786 for r = 0 to regs-1 10787 if single_regs then 10788 MemA[address,4] = S[d+r]; address = address+4; 10789 else 10790 // Store as two word-aligned words in the correct order for current endianness. 10791 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10792 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10793 address = address+8; 10794 #endif 10795 10796 bool success = false; 10797 10798 if (ConditionPassed (opcode)) 10799 { 10800 bool single_regs; 10801 bool add; 10802 bool wback; 10803 uint32_t d; 10804 uint32_t n; 10805 uint32_t imm32; 10806 uint32_t regs; 10807 10808 switch (encoding) 10809 { 10810 case eEncodingT1: 10811 case eEncodingA1: 10812 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10813 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10814 // if P == �1� && W == �0� then SEE VSTR; 10815 // if P == U && W == �1� then UNDEFINED; 10816 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10817 return false; 10818 10819 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10820 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�); 10821 single_regs = false; 10822 add = BitIsSet (opcode, 23); 10823 wback = BitIsSet (opcode, 21); 10824 10825 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32); 10826 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10827 n = Bits32 (opcode, 19, 16); 10828 imm32 = Bits32 (opcode, 7, 0) << 2; 10829 10830 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�. 10831 regs = Bits32 (opcode, 7, 0) / 2; 10832 10833 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10834 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10835 return false; 10836 10837 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10838 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10839 return false; 10840 10841 break; 10842 10843 case eEncodingT2: 10844 case eEncodingA2: 10845 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�; 10846 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH; 10847 // if P == �1� && W == �0� then SEE VSTR; 10848 // if P == U && W == �1� then UNDEFINED; 10849 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10850 return false; 10851 10852 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10853 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn); 10854 single_regs = true; 10855 add = BitIsSet (opcode, 23); 10856 wback = BitIsSet (opcode, 21); 10857 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10858 n = Bits32 (opcode, 19, 16); 10859 10860 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8); 10861 imm32 = Bits32 (opcode, 7, 0) << 2; 10862 regs = Bits32 (opcode, 7, 0); 10863 10864 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10865 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 10866 return false; 10867 10868 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10869 if ((regs == 0) || ((d + regs) > 32)) 10870 return false; 10871 10872 break; 10873 10874 default: 10875 return false; 10876 } 10877 10878 RegisterInfo base_reg; 10879 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10880 10881 uint32_t Rn = ReadCoreReg (n, &success); 10882 if (!success) 10883 return false; 10884 10885 // address = if add then R[n] else R[n]-imm32; 10886 addr_t address; 10887 if (add) 10888 address = Rn; 10889 else 10890 address = Rn - imm32; 10891 10892 EmulateInstruction::Context context; 10893 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10894 if (wback) 10895 { 10896 uint32_t value; 10897 if (add) 10898 value = Rn + imm32; 10899 else 10900 value = Rn - imm32; 10901 10902 context.type = eContextAdjustBaseRegister; 10903 context.SetRegisterPlusOffset (base_reg, value - Rn); 10904 10905 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10906 return false; 10907 } 10908 10909 const uint32_t addr_byte_size = GetAddressByteSize(); 10910 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10911 10912 context.type = eContextRegisterStore; 10913 // for r = 0 to regs-1 10914 for (int r = 0; r < regs; ++r) 10915 { 10916 10917 if (single_regs) 10918 { 10919 // MemA[address,4] = S[d+r]; address = address+4; 10920 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10921 if (!success) 10922 return false; 10923 10924 RegisterInfo data_reg; 10925 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10926 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10927 if (!MemAWrite (context, address, data, addr_byte_size)) 10928 return false; 10929 10930 address = address + 4; 10931 } 10932 else 10933 { 10934 // // Store as two word-aligned words in the correct order for current endianness. 10935 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10936 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10937 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 10938 if (!success) 10939 return false; 10940 10941 RegisterInfo data_reg; 10942 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 10943 10944 if (GetByteOrder() == eByteOrderBig) 10945 { 10946 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10947 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 10948 return false; 10949 10950 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10951 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 10952 return false; 10953 } 10954 else 10955 { 10956 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10957 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 10958 return false; 10959 10960 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10961 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 10962 return false; 10963 } 10964 // address = address+8; 10965 address = address + 8; 10966 } 10967 } 10968 } 10969 return true; 10970 } 10971 10972 // A8.6.320 10973 // This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with 10974 // an optional offset. 10975 bool 10976 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 10977 { 10978 #if 0 10979 if ConditionPassed() then 10980 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10981 base = if n == 15 then Align(PC,4) else R[n]; 10982 address = if add then (base + imm32) else (base - imm32); 10983 if single_reg then 10984 S[d] = MemA[address,4]; 10985 else 10986 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 10987 // Combine the word-aligned words in the correct order for current endianness. 10988 D[d] = if BigEndian() then word1:word2 else word2:word1; 10989 #endif 10990 10991 bool success = false; 10992 10993 if (ConditionPassed (opcode)) 10994 { 10995 bool single_reg; 10996 bool add; 10997 uint32_t imm32; 10998 uint32_t d; 10999 uint32_t n; 11000 11001 switch (encoding) 11002 { 11003 case eEncodingT1: 11004 case eEncodingA1: 11005 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11006 single_reg = false; 11007 add = BitIsSet (opcode, 23); 11008 imm32 = Bits32 (opcode, 7, 0) << 2; 11009 11010 // d = UInt(D:Vd); n = UInt(Rn); 11011 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11012 n = Bits32 (opcode, 19, 16); 11013 11014 break; 11015 11016 case eEncodingT2: 11017 case eEncodingA2: 11018 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11019 single_reg = true; 11020 add = BitIsSet (opcode, 23); 11021 imm32 = Bits32 (opcode, 7, 0) << 2; 11022 11023 // d = UInt(Vd:D); n = UInt(Rn); 11024 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11025 n = Bits32 (opcode, 19, 16); 11026 11027 break; 11028 11029 default: 11030 return false; 11031 } 11032 RegisterInfo base_reg; 11033 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11034 11035 uint32_t Rn = ReadCoreReg (n, &success); 11036 if (!success) 11037 return false; 11038 11039 // base = if n == 15 then Align(PC,4) else R[n]; 11040 uint32_t base; 11041 if (n == 15) 11042 base = AlignPC (Rn); 11043 else 11044 base = Rn; 11045 11046 // address = if add then (base + imm32) else (base - imm32); 11047 addr_t address; 11048 if (add) 11049 address = base + imm32; 11050 else 11051 address = base - imm32; 11052 11053 const uint32_t addr_byte_size = GetAddressByteSize(); 11054 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11055 11056 EmulateInstruction::Context context; 11057 context.type = eContextRegisterLoad; 11058 context.SetRegisterPlusOffset (base_reg, address - base); 11059 11060 if (single_reg) 11061 { 11062 // S[d] = MemA[address,4]; 11063 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11064 if (!success) 11065 return false; 11066 11067 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11068 return false; 11069 } 11070 else 11071 { 11072 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11073 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11074 if (!success) 11075 return false; 11076 11077 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11078 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11079 if (!success) 11080 return false; 11081 // // Combine the word-aligned words in the correct order for current endianness. 11082 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11083 uint64_t data64; 11084 if (GetByteOrder() == eByteOrderBig) 11085 { 11086 data64 = word1; 11087 data64 = (data64 << 32) | word2; 11088 } 11089 else 11090 { 11091 data64 = word2; 11092 data64 = (data64 << 32) | word1; 11093 } 11094 11095 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11096 return false; 11097 } 11098 } 11099 return true; 11100 } 11101 11102 // A8.6.400 VSTR 11103 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11104 // optional offset. 11105 bool 11106 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11107 { 11108 #if 0 11109 if ConditionPassed() then 11110 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11111 address = if add then (R[n] + imm32) else (R[n] - imm32); 11112 if single_reg then 11113 MemA[address,4] = S[d]; 11114 else 11115 // Store as two word-aligned words in the correct order for current endianness. 11116 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11117 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11118 #endif 11119 11120 bool success = false; 11121 11122 if (ConditionPassed (opcode)) 11123 { 11124 bool single_reg; 11125 bool add; 11126 uint32_t imm32; 11127 uint32_t d; 11128 uint32_t n; 11129 11130 switch (encoding) 11131 { 11132 case eEncodingT1: 11133 case eEncodingA1: 11134 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11135 single_reg = false; 11136 add = BitIsSet (opcode, 23); 11137 imm32 = Bits32 (opcode, 7, 0) << 2; 11138 11139 // d = UInt(D:Vd); n = UInt(Rn); 11140 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11141 n = Bits32 (opcode, 19, 16); 11142 11143 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11144 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11145 return false; 11146 11147 break; 11148 11149 case eEncodingT2: 11150 case eEncodingA2: 11151 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32); 11152 single_reg = true; 11153 add = BitIsSet (opcode, 23); 11154 imm32 = Bits32 (opcode, 7, 0) << 2; 11155 11156 // d = UInt(Vd:D); n = UInt(Rn); 11157 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11158 n = Bits32 (opcode, 19, 16); 11159 11160 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11161 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11162 return false; 11163 11164 break; 11165 11166 default: 11167 return false; 11168 } 11169 11170 RegisterInfo base_reg; 11171 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11172 11173 uint32_t Rn = ReadCoreReg (n, &success); 11174 if (!success) 11175 return false; 11176 11177 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11178 addr_t address; 11179 if (add) 11180 address = Rn + imm32; 11181 else 11182 address = Rn - imm32; 11183 11184 const uint32_t addr_byte_size = GetAddressByteSize(); 11185 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11186 11187 RegisterInfo data_reg; 11188 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11189 EmulateInstruction::Context context; 11190 context.type = eContextRegisterStore; 11191 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11192 11193 if (single_reg) 11194 { 11195 // MemA[address,4] = S[d]; 11196 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11197 if (!success) 11198 return false; 11199 11200 if (!MemAWrite (context, address, data, addr_byte_size)) 11201 return false; 11202 } 11203 else 11204 { 11205 // // Store as two word-aligned words in the correct order for current endianness. 11206 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11207 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11208 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11209 if (!success) 11210 return false; 11211 11212 if (GetByteOrder() == eByteOrderBig) 11213 { 11214 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11215 return false; 11216 11217 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11218 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11219 return false; 11220 } 11221 else 11222 { 11223 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11224 return false; 11225 11226 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11227 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11228 return false; 11229 } 11230 } 11231 } 11232 return true; 11233 } 11234 11235 // A8.6.307 VLDI1 (multiple single elements) 11236 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11237 // element of each register is loaded. 11238 bool 11239 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11240 { 11241 #if 0 11242 if ConditionPassed() then 11243 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11244 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11245 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11246 for r = 0 to regs-1 11247 for e = 0 to elements-1 11248 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11249 address = address + ebytes; 11250 #endif 11251 11252 bool success = false; 11253 11254 if (ConditionPassed (opcode)) 11255 { 11256 uint32_t regs; 11257 uint32_t alignment; 11258 uint32_t ebytes; 11259 uint32_t esize; 11260 uint32_t elements; 11261 uint32_t d; 11262 uint32_t n; 11263 uint32_t m; 11264 bool wback; 11265 bool register_index; 11266 11267 switch (encoding) 11268 { 11269 case eEncodingT1: 11270 case eEncodingA1: 11271 { 11272 // case type of 11273 // when �0111� 11274 // regs = 1; if align<1> == �1� then UNDEFINED; 11275 // when �1010� 11276 // regs = 2; if align == �11� then UNDEFINED; 11277 // when �0110� 11278 // regs = 3; if align<1> == �1� then UNDEFINED; 11279 // when �0010� 11280 // regs = 4; 11281 // otherwise 11282 // SEE �Related encodings�; 11283 uint32_t type = Bits32 (opcode, 11, 8); 11284 uint32_t align = Bits32 (opcode, 5, 4); 11285 if (type == 7) // '0111' 11286 { 11287 regs = 1; 11288 if (BitIsSet (align, 1)) 11289 return false; 11290 } 11291 else if (type == 10) // '1010' 11292 { 11293 regs = 2; 11294 if (align == 3) 11295 return false; 11296 11297 } 11298 else if (type == 6) // '0110' 11299 { 11300 regs = 3; 11301 if (BitIsSet (align, 1)) 11302 return false; 11303 } 11304 else if (type == 2) // '0010' 11305 { 11306 regs = 4; 11307 } 11308 else 11309 return false; 11310 11311 // alignment = if align == �00� then 1 else 4 << UInt(align); 11312 if (align == 0) 11313 alignment = 1; 11314 else 11315 alignment = 4 << align; 11316 11317 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11318 ebytes = 1 << Bits32 (opcode, 7, 6); 11319 esize = 8 * ebytes; 11320 elements = 8 / ebytes; 11321 11322 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11323 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11324 n = Bits32 (opcode, 19, 15); 11325 m = Bits32 (opcode, 3, 0); 11326 11327 // wback = (m != 15); register_index = (m != 15 && m != 13); 11328 wback = (m != 15); 11329 register_index = ((m != 15) && (m != 13)); 11330 11331 // if d+regs > 32 then UNPREDICTABLE; 11332 if ((d + regs) > 32) 11333 return false; 11334 } 11335 break; 11336 11337 default: 11338 return false; 11339 } 11340 11341 RegisterInfo base_reg; 11342 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11343 11344 uint32_t Rn = ReadCoreReg (n, &success); 11345 if (!success) 11346 return false; 11347 11348 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11349 addr_t address = Rn; 11350 if ((address % alignment) != 0) 11351 return false; 11352 11353 EmulateInstruction::Context context; 11354 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11355 if (wback) 11356 { 11357 uint32_t Rm = ReadCoreReg (m, &success); 11358 if (!success) 11359 return false; 11360 11361 uint32_t offset; 11362 if (register_index) 11363 offset = Rm; 11364 else 11365 offset = 8 * regs; 11366 11367 uint32_t value = Rn + offset; 11368 context.type = eContextAdjustBaseRegister; 11369 context.SetRegisterPlusOffset (base_reg, offset); 11370 11371 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11372 return false; 11373 11374 } 11375 11376 // for r = 0 to regs-1 11377 for (int r = 0; r < regs; ++r) 11378 { 11379 // for e = 0 to elements-1 11380 uint64_t assembled_data = 0; 11381 for (int e = 0; e < elements; ++e) 11382 { 11383 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11384 context.type = eContextRegisterLoad; 11385 context.SetRegisterPlusOffset (base_reg, address - Rn); 11386 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11387 if (!success) 11388 return false; 11389 11390 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11391 11392 // address = address + ebytes; 11393 address = address + ebytes; 11394 } 11395 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11396 return false; 11397 } 11398 } 11399 return true; 11400 } 11401 11402 // A8.6.308 VLD1 (single element to one lane) 11403 // 11404 bool 11405 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11406 { 11407 #if 0 11408 if ConditionPassed() then 11409 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11410 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11411 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11412 Elem[D[d],index,esize] = MemU[address,ebytes]; 11413 #endif 11414 11415 bool success = false; 11416 11417 if (ConditionPassed (opcode)) 11418 { 11419 uint32_t ebytes; 11420 uint32_t esize; 11421 uint32_t index; 11422 uint32_t alignment; 11423 uint32_t d; 11424 uint32_t n; 11425 uint32_t m; 11426 bool wback; 11427 bool register_index; 11428 11429 switch (encoding) 11430 { 11431 case eEncodingT1: 11432 case eEncodingA1: 11433 { 11434 uint32_t size = Bits32 (opcode, 11, 10); 11435 uint32_t index_align = Bits32 (opcode, 7, 4); 11436 // if size == �11� then SEE VLD1 (single element to all lanes); 11437 if (size == 3) 11438 return EmulateVLD1SingleAll (opcode, encoding); 11439 // case size of 11440 if (size == 0) // when '00' 11441 { 11442 // if index_align<0> != �0� then UNDEFINED; 11443 if (BitIsClear (index_align, 0)) 11444 return false; 11445 11446 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11447 ebytes = 1; 11448 esize = 8; 11449 index = Bits32 (index_align, 3, 1); 11450 alignment = 1; 11451 } 11452 else if (size == 1) // when �01� 11453 { 11454 // if index_align<1> != �0� then UNDEFINED; 11455 if (BitIsClear (index_align, 1)) 11456 return false; 11457 11458 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11459 ebytes = 2; 11460 esize = 16; 11461 index = Bits32 (index_align, 3, 2); 11462 11463 // alignment = if index_align<0> == �0� then 1 else 2; 11464 if (BitIsClear (index_align, 0)) 11465 alignment = 1; 11466 else 11467 alignment = 2; 11468 } 11469 else if (size == 2) // when �10� 11470 { 11471 // if index_align<2> != �0� then UNDEFINED; 11472 if (BitIsClear (index_align, 2)) 11473 return false; 11474 11475 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11476 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11477 return false; 11478 11479 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11480 ebytes = 4; 11481 esize = 32; 11482 index = Bit32 (index_align, 3); 11483 11484 // alignment = if index_align<1:0> == �00� then 1 else 4; 11485 if (Bits32 (index_align, 1, 0) == 0) 11486 alignment = 1; 11487 else 11488 alignment = 4; 11489 } 11490 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11491 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11492 n = Bits32 (opcode, 19, 16); 11493 m = Bits32 (opcode, 3, 0); 11494 11495 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11496 wback = (m != 15); 11497 register_index = ((m != 15) && (m != 13)); 11498 11499 if (n == 15) 11500 return false; 11501 11502 } 11503 break; 11504 11505 default: 11506 return false; 11507 } 11508 11509 RegisterInfo base_reg; 11510 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11511 11512 uint32_t Rn = ReadCoreReg (n, &success); 11513 if (!success) 11514 return false; 11515 11516 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11517 addr_t address = Rn; 11518 if ((address % alignment) != 0) 11519 return false; 11520 11521 EmulateInstruction::Context context; 11522 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11523 if (wback) 11524 { 11525 uint32_t Rm = ReadCoreReg (m, &success); 11526 if (!success) 11527 return false; 11528 11529 uint32_t offset; 11530 if (register_index) 11531 offset = Rm; 11532 else 11533 offset = ebytes; 11534 11535 uint32_t value = Rn + offset; 11536 11537 context.type = eContextAdjustBaseRegister; 11538 context.SetRegisterPlusOffset (base_reg, offset); 11539 11540 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11541 return false; 11542 } 11543 11544 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11545 uint32_t element = MemURead (context, address, esize, 0, &success); 11546 if (!success) 11547 return false; 11548 11549 element = element << (index * esize); 11550 11551 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11552 if (!success) 11553 return false; 11554 11555 uint64_t all_ones = -1; 11556 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11557 // at element & to the right of element. 11558 if (index > 0) 11559 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11560 // now mask should be 0's where element goes & 1's 11561 // everywhere else. 11562 11563 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11564 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11565 11566 context.type = eContextRegisterLoad; 11567 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11568 return false; 11569 } 11570 return true; 11571 } 11572 11573 // A8.6.391 VST1 (multiple single elements) 11574 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without 11575 // interleaving. Every element of each register is stored. 11576 bool 11577 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11578 { 11579 #if 0 11580 if ConditionPassed() then 11581 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11582 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11583 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11584 for r = 0 to regs-1 11585 for e = 0 to elements-1 11586 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11587 address = address + ebytes; 11588 #endif 11589 11590 bool success = false; 11591 11592 if (ConditionPassed (opcode)) 11593 { 11594 uint32_t regs; 11595 uint32_t alignment; 11596 uint32_t ebytes; 11597 uint32_t esize; 11598 uint32_t elements; 11599 uint32_t d; 11600 uint32_t n; 11601 uint32_t m; 11602 bool wback; 11603 bool register_index; 11604 11605 switch (encoding) 11606 { 11607 case eEncodingT1: 11608 case eEncodingA1: 11609 { 11610 uint32_t type = Bits32 (opcode, 11, 8); 11611 uint32_t align = Bits32 (opcode, 5, 4); 11612 11613 // case type of 11614 if (type == 7) // when �0111� 11615 { 11616 // regs = 1; if align<1> == �1� then UNDEFINED; 11617 regs = 1; 11618 if (BitIsSet (align, 1)) 11619 return false; 11620 } 11621 else if (type == 10) // when �1010� 11622 { 11623 // regs = 2; if align == �11� then UNDEFINED; 11624 regs = 2; 11625 if (align == 3) 11626 return false; 11627 } 11628 else if (type == 6) // when �0110� 11629 { 11630 // regs = 3; if align<1> == �1� then UNDEFINED; 11631 regs = 3; 11632 if (BitIsSet (align, 1)) 11633 return false; 11634 } 11635 else if (type == 2) // when �0010� 11636 // regs = 4; 11637 regs = 4; 11638 else // otherwise 11639 // SEE �Related encodings�; 11640 return false; 11641 11642 // alignment = if align == �00� then 1 else 4 << UInt(align); 11643 if (align == 0) 11644 alignment = 1; 11645 else 11646 alignment = 4 << align; 11647 11648 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11649 ebytes = 1 << Bits32 (opcode,7, 6); 11650 esize = 8 * ebytes; 11651 elements = 8 / ebytes; 11652 11653 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11654 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11655 n = Bits32 (opcode, 19, 16); 11656 m = Bits32 (opcode, 3, 0); 11657 11658 // wback = (m != 15); register_index = (m != 15 && m != 13); 11659 wback = (m != 15); 11660 register_index = ((m != 15) && (m != 13)); 11661 11662 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11663 if ((d + regs) > 32) 11664 return false; 11665 11666 if (n == 15) 11667 return false; 11668 11669 } 11670 break; 11671 11672 default: 11673 return false; 11674 } 11675 11676 RegisterInfo base_reg; 11677 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11678 11679 uint32_t Rn = ReadCoreReg (n, &success); 11680 if (!success) 11681 return false; 11682 11683 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11684 addr_t address = Rn; 11685 if ((address % alignment) != 0) 11686 return false; 11687 11688 EmulateInstruction::Context context; 11689 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11690 if (wback) 11691 { 11692 uint32_t Rm = ReadCoreReg (m, &success); 11693 if (!success) 11694 return false; 11695 11696 uint32_t offset; 11697 if (register_index) 11698 offset = Rm; 11699 else 11700 offset = 8 * regs; 11701 11702 context.type = eContextAdjustBaseRegister; 11703 context.SetRegisterPlusOffset (base_reg, offset); 11704 11705 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11706 return false; 11707 } 11708 11709 RegisterInfo data_reg; 11710 context.type = eContextRegisterStore; 11711 // for r = 0 to regs-1 11712 for (int r = 0; r < regs; ++r) 11713 { 11714 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11715 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11716 if (!success) 11717 return false; 11718 11719 // for e = 0 to elements-1 11720 for (int e = 0; e < elements; ++e) 11721 { 11722 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11723 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11724 11725 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11726 if (!MemUWrite (context, address, word, ebytes)) 11727 return false; 11728 11729 // address = address + ebytes; 11730 address = address + ebytes; 11731 } 11732 } 11733 } 11734 return true; 11735 } 11736 11737 // A8.6.392 VST1 (single element from one lane) 11738 // This instruction stores one element to memory from one element of a register. 11739 bool 11740 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11741 { 11742 #if 0 11743 if ConditionPassed() then 11744 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11745 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11746 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11747 MemU[address,ebytes] = Elem[D[d],index,esize]; 11748 #endif 11749 11750 bool success = false; 11751 11752 if (ConditionPassed (opcode)) 11753 { 11754 uint32_t ebytes; 11755 uint32_t esize; 11756 uint32_t index; 11757 uint32_t alignment; 11758 uint32_t d; 11759 uint32_t n; 11760 uint32_t m; 11761 bool wback; 11762 bool register_index; 11763 11764 switch (encoding) 11765 { 11766 case eEncodingT1: 11767 case eEncodingA1: 11768 { 11769 uint32_t size = Bits32 (opcode, 11, 10); 11770 uint32_t index_align = Bits32 (opcode, 7, 4); 11771 11772 // if size == �11� then UNDEFINED; 11773 if (size == 3) 11774 return false; 11775 11776 // case size of 11777 if (size == 0) // when �00� 11778 { 11779 // if index_align<0> != �0� then UNDEFINED; 11780 if (BitIsClear (index_align, 0)) 11781 return false; 11782 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11783 ebytes = 1; 11784 esize = 8; 11785 index = Bits32 (index_align, 3, 1); 11786 alignment = 1; 11787 } 11788 else if (size == 1) // when �01� 11789 { 11790 // if index_align<1> != �0� then UNDEFINED; 11791 if (BitIsClear (index_align, 1)) 11792 return false; 11793 11794 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11795 ebytes = 2; 11796 esize = 16; 11797 index = Bits32 (index_align, 3, 2); 11798 11799 // alignment = if index_align<0> == �0� then 1 else 2; 11800 if (BitIsClear (index_align, 0)) 11801 alignment = 1; 11802 else 11803 alignment = 2; 11804 } 11805 else if (size == 2) // when �10� 11806 { 11807 // if index_align<2> != �0� then UNDEFINED; 11808 if (BitIsClear (index_align, 2)) 11809 return false; 11810 11811 // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED; 11812 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11813 return false; 11814 11815 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11816 ebytes = 4; 11817 esize = 32; 11818 index = Bit32 (index_align, 3); 11819 11820 // alignment = if index_align<1:0> == �00� then 1 else 4; 11821 if (Bits32 (index_align, 1, 0) == 0) 11822 alignment = 1; 11823 else 11824 alignment = 4; 11825 } 11826 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11827 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11828 n = Bits32 (opcode, 19, 16); 11829 m = Bits32 (opcode, 3, 0); 11830 11831 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11832 wback = (m != 15); 11833 register_index = ((m != 15) && (m != 13)); 11834 11835 if (n == 15) 11836 return false; 11837 } 11838 break; 11839 11840 default: 11841 return false; 11842 } 11843 11844 RegisterInfo base_reg; 11845 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11846 11847 uint32_t Rn = ReadCoreReg (n, &success); 11848 if (!success) 11849 return false; 11850 11851 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11852 addr_t address = Rn; 11853 if ((address % alignment) != 0) 11854 return false; 11855 11856 EmulateInstruction::Context context; 11857 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11858 if (wback) 11859 { 11860 uint32_t Rm = ReadCoreReg (m, &success); 11861 if (!success) 11862 return false; 11863 11864 uint32_t offset; 11865 if (register_index) 11866 offset = Rm; 11867 else 11868 offset = ebytes; 11869 11870 context.type = eContextAdjustBaseRegister; 11871 context.SetRegisterPlusOffset (base_reg, offset); 11872 11873 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11874 return false; 11875 } 11876 11877 // MemU[address,ebytes] = Elem[D[d],index,esize]; 11878 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11879 if (!success) 11880 return false; 11881 11882 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 11883 11884 RegisterInfo data_reg; 11885 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 11886 context.type = eContextRegisterStore; 11887 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11888 11889 if (!MemUWrite (context, address, word, ebytes)) 11890 return false; 11891 } 11892 return true; 11893 } 11894 11895 // A8.6.309 VLD1 (single element to all lanes) 11896 // This instruction loads one element from memory into every element of one or two vectors. 11897 bool 11898 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 11899 { 11900 #if 0 11901 if ConditionPassed() then 11902 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11903 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11904 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11905 replicated_element = Replicate(MemU[address,ebytes], elements); 11906 for r = 0 to regs-1 11907 D[d+r] = replicated_element; 11908 #endif 11909 11910 bool success = false; 11911 11912 if (ConditionPassed (opcode)) 11913 { 11914 uint32_t ebytes; 11915 uint32_t elements; 11916 uint32_t regs; 11917 uint32_t alignment; 11918 uint32_t d; 11919 uint32_t n; 11920 uint32_t m; 11921 bool wback; 11922 bool register_index; 11923 11924 switch (encoding) 11925 { 11926 case eEncodingT1: 11927 case eEncodingA1: 11928 { 11929 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED; 11930 uint32_t size = Bits32 (opcode, 7, 6); 11931 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 11932 return false; 11933 11934 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2; 11935 ebytes = 1 << size; 11936 elements = 8 / ebytes; 11937 if (BitIsClear (opcode, 5)) 11938 regs = 1; 11939 else 11940 regs = 2; 11941 11942 //alignment = if a == �0� then 1 else ebytes; 11943 if (BitIsClear (opcode, 4)) 11944 alignment = 1; 11945 else 11946 alignment = ebytes; 11947 11948 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11949 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11950 n = Bits32 (opcode, 19, 16); 11951 m = Bits32 (opcode, 3, 0); 11952 11953 //wback = (m != 15); register_index = (m != 15 && m != 13); 11954 wback = (m != 15); 11955 register_index = ((m != 15) && (m != 13)); 11956 11957 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11958 if ((d + regs) > 32) 11959 return false; 11960 11961 if (n == 15) 11962 return false; 11963 } 11964 break; 11965 11966 default: 11967 return false; 11968 } 11969 11970 RegisterInfo base_reg; 11971 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11972 11973 uint32_t Rn = ReadCoreReg (n, &success); 11974 if (!success) 11975 return false; 11976 11977 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11978 addr_t address = Rn; 11979 if ((address % alignment) != 0) 11980 return false; 11981 11982 EmulateInstruction::Context context; 11983 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11984 if (wback) 11985 { 11986 uint32_t Rm = ReadCoreReg (m, &success); 11987 if (!success) 11988 return false; 11989 11990 uint32_t offset; 11991 if (register_index) 11992 offset = Rm; 11993 else 11994 offset = ebytes; 11995 11996 context.type = eContextAdjustBaseRegister; 11997 context.SetRegisterPlusOffset (base_reg, offset); 11998 11999 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12000 return false; 12001 } 12002 12003 // replicated_element = Replicate(MemU[address,ebytes], elements); 12004 12005 context.type = eContextRegisterLoad; 12006 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12007 if (!success) 12008 return false; 12009 12010 uint64_t replicated_element = 0; 12011 uint32_t esize = ebytes * 8; 12012 for (int e = 0; e < elements; ++e) 12013 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12014 12015 // for r = 0 to regs-1 12016 for (int r = 0; r < regs; ++r) 12017 { 12018 // D[d+r] = replicated_element; 12019 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12020 return false; 12021 } 12022 } 12023 return true; 12024 } 12025 12026 // B6.2.13 SUBS PC, LR and related instructions 12027 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12028 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12029 bool 12030 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12031 { 12032 #if 0 12033 if ConditionPassed() then 12034 EncodingSpecificOperations(); 12035 if CurrentInstrSet() == InstrSet_ThumbEE then 12036 UNPREDICTABLE; 12037 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12038 case opcode of 12039 when �0000� result = R[n] AND operand2; // AND 12040 when �0001� result = R[n] EOR operand2; // EOR 12041 when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12042 when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12043 when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12044 when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12045 when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12046 when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12047 when �1100� result = R[n] OR operand2; // ORR 12048 when �1101� result = operand2; // MOV 12049 when �1110� result = R[n] AND NOT(operand2); // BIC 12050 when �1111� result = NOT(operand2); // MVN 12051 CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12052 BranchWritePC(result); 12053 #endif 12054 12055 bool success = false; 12056 12057 if (ConditionPassed (opcode)) 12058 { 12059 uint32_t n; 12060 uint32_t m; 12061 uint32_t imm32; 12062 bool register_form; 12063 ARM_ShifterType shift_t; 12064 uint32_t shift_n; 12065 uint32_t code; 12066 12067 switch (encoding) 12068 { 12069 case eEncodingT1: 12070 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12071 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB 12072 n = 14; 12073 imm32 = Bits32 (opcode, 7, 0); 12074 register_form = false; 12075 code = 2; 12076 12077 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12078 if (InITBlock() && !LastInITBlock()) 12079 return false; 12080 12081 break; 12082 12083 case eEncodingA1: 12084 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12085 n = Bits32 (opcode, 19, 16); 12086 imm32 = ARMExpandImm (opcode); 12087 register_form = false; 12088 code = Bits32 (opcode, 24, 21); 12089 12090 break; 12091 12092 case eEncodingA2: 12093 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12094 n = Bits32 (opcode, 19, 16); 12095 m = Bits32 (opcode, 3, 0); 12096 register_form = true; 12097 12098 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12099 shift_n = DecodeImmShiftARM (opcode, shift_t); 12100 12101 break; 12102 12103 default: 12104 return false; 12105 } 12106 12107 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12108 uint32_t operand2; 12109 if (register_form) 12110 { 12111 uint32_t Rm = ReadCoreReg (m, &success); 12112 if (!success) 12113 return false; 12114 12115 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12116 if (!success) 12117 return false; 12118 } 12119 else 12120 { 12121 operand2 = imm32; 12122 } 12123 12124 uint32_t Rn = ReadCoreReg (n, &success); 12125 if (!success) 12126 return false; 12127 12128 AddWithCarryResult result; 12129 12130 // case opcode of 12131 switch (code) 12132 { 12133 case 0: // when �0000� 12134 // result = R[n] AND operand2; // AND 12135 result.result = Rn & operand2; 12136 break; 12137 12138 case 1: // when �0001� 12139 // result = R[n] EOR operand2; // EOR 12140 result.result = Rn ^ operand2; 12141 break; 12142 12143 case 2: // when �0010� 12144 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB 12145 result = AddWithCarry (Rn, ~(operand2), 1); 12146 break; 12147 12148 case 3: // when �0011� 12149 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB 12150 result = AddWithCarry (~(Rn), operand2, 1); 12151 break; 12152 12153 case 4: // when �0100� 12154 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD 12155 result = AddWithCarry (Rn, operand2, 0); 12156 break; 12157 12158 case 5: // when �0101� 12159 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12160 result = AddWithCarry (Rn, operand2, APSR_C); 12161 break; 12162 12163 case 6: // when �0110� 12164 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12165 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12166 break; 12167 12168 case 7: // when �0111� 12169 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12170 result = AddWithCarry (~(Rn), operand2, APSR_C); 12171 break; 12172 12173 case 10: // when �1100� 12174 // result = R[n] OR operand2; // ORR 12175 result.result = Rn | operand2; 12176 break; 12177 12178 case 11: // when �1101� 12179 // result = operand2; // MOV 12180 result.result = operand2; 12181 break; 12182 12183 case 12: // when �1110� 12184 // result = R[n] AND NOT(operand2); // BIC 12185 result.result = Rn & ~(operand2); 12186 break; 12187 12188 case 15: // when �1111� 12189 // result = NOT(operand2); // MVN 12190 result.result = ~(operand2); 12191 break; 12192 12193 default: 12194 return false; 12195 } 12196 // CPSRWriteByInstr(SPSR[], �1111�, TRUE); 12197 12198 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12199 // the best. 12200 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12201 if (!success) 12202 return false; 12203 12204 CPSRWriteByInstr (spsr, 15, true); 12205 12206 // BranchWritePC(result); 12207 EmulateInstruction::Context context; 12208 context.type = eContextAdjustPC; 12209 context.SetImmediate (result.result); 12210 12211 BranchWritePC (context, result.result); 12212 } 12213 return true; 12214 } 12215 12216 EmulateInstructionARM::ARMOpcode* 12217 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12218 { 12219 static ARMOpcode 12220 g_arm_opcodes[] = 12221 { 12222 //---------------------------------------------------------------------- 12223 // Prologue instructions 12224 //---------------------------------------------------------------------- 12225 12226 // push register(s) 12227 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12228 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12229 12230 // set r7 to point to a stack offset 12231 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12232 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12233 // copy the stack pointer to ip 12234 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12235 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12236 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12237 12238 // adjust the stack pointer 12239 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12240 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12241 12242 // push one register 12243 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12244 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12245 12246 // vector push consecutive extension register(s) 12247 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12248 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12249 12250 //---------------------------------------------------------------------- 12251 // Epilogue instructions 12252 //---------------------------------------------------------------------- 12253 12254 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12255 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12256 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12257 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12258 12259 //---------------------------------------------------------------------- 12260 // Supervisor Call (previously Software Interrupt) 12261 //---------------------------------------------------------------------- 12262 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12263 12264 //---------------------------------------------------------------------- 12265 // Branch instructions 12266 //---------------------------------------------------------------------- 12267 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12268 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 12269 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12270 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12271 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12272 // for example, "bx lr" 12273 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12274 // bxj 12275 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12276 12277 //---------------------------------------------------------------------- 12278 // Data-processing instructions 12279 //---------------------------------------------------------------------- 12280 // adc (immediate) 12281 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12282 // adc (register) 12283 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12284 // add (immediate) 12285 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12286 // add (register) 12287 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12288 // add (register-shifted register) 12289 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12290 // adr 12291 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12292 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12293 // and (immediate) 12294 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12295 // and (register) 12296 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12297 // bic (immediate) 12298 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12299 // bic (register) 12300 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12301 // eor (immediate) 12302 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12303 // eor (register) 12304 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12305 // orr (immediate) 12306 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12307 // orr (register) 12308 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12309 // rsb (immediate) 12310 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12311 // rsb (register) 12312 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12313 // rsc (immediate) 12314 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12315 // rsc (register) 12316 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12317 // sbc (immediate) 12318 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12319 // sbc (register) 12320 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12321 // sub (immediate, ARM) 12322 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12323 // sub (sp minus immediate) 12324 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12325 // sub (register) 12326 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12327 // teq (immediate) 12328 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12329 // teq (register) 12330 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12331 // tst (immediate) 12332 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12333 // tst (register) 12334 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12335 12336 // mov (immediate) 12337 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12338 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12339 // mov (register) 12340 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12341 // mvn (immediate) 12342 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12343 // mvn (register) 12344 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12345 // cmn (immediate) 12346 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12347 // cmn (register) 12348 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12349 // cmp (immediate) 12350 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12351 // cmp (register) 12352 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12353 // asr (immediate) 12354 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12355 // asr (register) 12356 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12357 // lsl (immediate) 12358 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12359 // lsl (register) 12360 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12361 // lsr (immediate) 12362 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12363 // lsr (register) 12364 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12365 // rrx is a special case encoding of ror (immediate) 12366 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12367 // ror (immediate) 12368 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12369 // ror (register) 12370 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12371 // mul 12372 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12373 12374 // subs pc, lr and related instructions 12375 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12376 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12377 12378 //---------------------------------------------------------------------- 12379 // Load instructions 12380 //---------------------------------------------------------------------- 12381 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12382 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12383 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12384 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12385 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12386 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12387 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12388 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12389 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12390 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12391 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12392 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12393 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12394 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12395 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12396 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12397 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12398 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12399 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12400 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12401 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12402 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12403 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12404 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12405 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12406 12407 //---------------------------------------------------------------------- 12408 // Store instructions 12409 //---------------------------------------------------------------------- 12410 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12411 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12412 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12413 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12414 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12415 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12416 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12417 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12418 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12419 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12420 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12421 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12422 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12423 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12424 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12425 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12426 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12427 12428 //---------------------------------------------------------------------- 12429 // Other instructions 12430 //---------------------------------------------------------------------- 12431 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12432 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12433 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12434 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12435 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12436 12437 }; 12438 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 12439 12440 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12441 { 12442 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12443 (g_arm_opcodes[i].variants & arm_isa) != 0) 12444 return &g_arm_opcodes[i]; 12445 } 12446 return NULL; 12447 } 12448 12449 12450 EmulateInstructionARM::ARMOpcode* 12451 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12452 { 12453 12454 static ARMOpcode 12455 g_thumb_opcodes[] = 12456 { 12457 //---------------------------------------------------------------------- 12458 // Prologue instructions 12459 //---------------------------------------------------------------------- 12460 12461 // push register(s) 12462 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12463 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12464 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12465 12466 // set r7 to point to a stack offset 12467 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12468 // copy the stack pointer to r7 12469 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12470 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12471 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12472 12473 // PC-relative load into register (see also EmulateADDSPRm) 12474 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12475 12476 // adjust the stack pointer 12477 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12478 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12479 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12480 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12481 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12482 12483 // vector push consecutive extension register(s) 12484 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12485 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12486 12487 //---------------------------------------------------------------------- 12488 // Epilogue instructions 12489 //---------------------------------------------------------------------- 12490 12491 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12492 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12493 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12494 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12495 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12496 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12497 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12498 12499 //---------------------------------------------------------------------- 12500 // Supervisor Call (previously Software Interrupt) 12501 //---------------------------------------------------------------------- 12502 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12503 12504 //---------------------------------------------------------------------- 12505 // If Then makes up to four following instructions conditional. 12506 //---------------------------------------------------------------------- 12507 // The next 5 opcode _must_ come before the if then instruction 12508 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12509 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12510 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12511 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12512 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12513 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12514 12515 //---------------------------------------------------------------------- 12516 // Branch instructions 12517 //---------------------------------------------------------------------- 12518 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12519 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12520 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12521 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12522 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12523 // J1 == J2 == 1 12524 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12525 // J1 == J2 == 1 12526 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12527 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12528 // for example, "bx lr" 12529 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12530 // bxj 12531 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12532 // compare and branch 12533 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12534 // table branch byte 12535 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12536 // table branch halfword 12537 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12538 12539 //---------------------------------------------------------------------- 12540 // Data-processing instructions 12541 //---------------------------------------------------------------------- 12542 // adc (immediate) 12543 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12544 // adc (register) 12545 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12546 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12547 // add (register) 12548 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12549 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12550 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12551 // adr 12552 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12553 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12554 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12555 // and (immediate) 12556 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12557 // and (register) 12558 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12559 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12560 // bic (immediate) 12561 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12562 // bic (register) 12563 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12564 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12565 // eor (immediate) 12566 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12567 // eor (register) 12568 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12569 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12570 // orr (immediate) 12571 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12572 // orr (register) 12573 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12574 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12575 // rsb (immediate) 12576 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12577 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12578 // rsb (register) 12579 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12580 // sbc (immediate) 12581 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12582 // sbc (register) 12583 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12584 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12585 // add (immediate, Thumb) 12586 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12587 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12588 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12589 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12590 // sub (immediate, Thumb) 12591 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12592 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12593 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12594 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12595 // sub (sp minus immediate) 12596 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12597 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12598 // sub (register) 12599 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12600 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12601 // teq (immediate) 12602 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12603 // teq (register) 12604 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12605 // tst (immediate) 12606 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12607 // tst (register) 12608 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12609 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12610 12611 12612 // move from high register to high register 12613 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12614 // move from low register to low register 12615 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12616 // mov{s}<c>.w <Rd>, <Rm> 12617 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12618 // move immediate 12619 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12620 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12621 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12622 // mvn (immediate) 12623 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12624 // mvn (register) 12625 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12626 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12627 // cmn (immediate) 12628 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12629 // cmn (register) 12630 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12631 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12632 // cmp (immediate) 12633 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12634 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12635 // cmp (register) (Rn and Rm both from r0-r7) 12636 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12637 // cmp (register) (Rn and Rm not both from r0-r7) 12638 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12639 // asr (immediate) 12640 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12641 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12642 // asr (register) 12643 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12644 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12645 // lsl (immediate) 12646 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12647 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12648 // lsl (register) 12649 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12650 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12651 // lsr (immediate) 12652 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12653 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12654 // lsr (register) 12655 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12656 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12657 // rrx is a special case encoding of ror (immediate) 12658 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12659 // ror (immediate) 12660 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12661 // ror (register) 12662 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12663 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12664 // mul 12665 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12666 // mul 12667 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12668 12669 // subs pc, lr and related instructions 12670 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12671 12672 //---------------------------------------------------------------------- 12673 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12674 // otherwise the wrong instructions will be selected. 12675 //---------------------------------------------------------------------- 12676 12677 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12678 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12679 12680 //---------------------------------------------------------------------- 12681 // Load instructions 12682 //---------------------------------------------------------------------- 12683 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12684 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12685 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12686 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12687 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12688 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12689 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12690 // Thumb2 PC-relative load into register 12691 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12692 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12693 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12694 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12695 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12696 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12697 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12698 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12699 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12700 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12701 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12702 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12703 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12704 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12705 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12706 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12707 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12708 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12709 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12710 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12711 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12712 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12713 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12714 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12715 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12716 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12717 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12718 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12719 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12720 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12721 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12722 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12723 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12724 12725 //---------------------------------------------------------------------- 12726 // Store instructions 12727 //---------------------------------------------------------------------- 12728 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12729 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12730 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12731 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12732 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12733 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12734 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12735 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12736 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12737 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12738 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12739 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12740 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12741 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12742 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12743 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12744 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12745 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12746 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12747 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12748 { 0xffb00000, 0xfa000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12749 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12750 12751 //---------------------------------------------------------------------- 12752 // Other instructions 12753 //---------------------------------------------------------------------- 12754 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12755 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12756 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12757 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12758 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12759 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12760 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12761 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12762 }; 12763 12764 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 12765 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12766 { 12767 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12768 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12769 return &g_thumb_opcodes[i]; 12770 } 12771 return NULL; 12772 } 12773 12774 bool 12775 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12776 { 12777 m_arch = arch; 12778 m_arm_isa = 0; 12779 const char *arch_cstr = arch.GetArchitectureName (); 12780 if (arch_cstr) 12781 { 12782 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12783 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12784 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12785 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12786 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12787 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12788 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12789 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12790 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12791 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12792 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12793 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12794 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12795 } 12796 return m_arm_isa != 0; 12797 } 12798 12799 bool 12800 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12801 { 12802 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12803 { 12804 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12805 m_opcode_mode = eModeThumb; 12806 else 12807 { 12808 AddressClass addr_class = inst_addr.GetAddressClass(); 12809 12810 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 12811 m_opcode_mode = eModeARM; 12812 else if (addr_class == eAddressClassCodeAlternateISA) 12813 m_opcode_mode = eModeThumb; 12814 else 12815 return false; 12816 } 12817 if (m_opcode_mode == eModeThumb) 12818 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 12819 else 12820 m_opcode_cpsr = CPSR_MODE_USR; 12821 return true; 12822 } 12823 return false; 12824 } 12825 12826 bool 12827 EmulateInstructionARM::ReadInstruction () 12828 { 12829 bool success = false; 12830 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 12831 if (success) 12832 { 12833 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 12834 if (success) 12835 { 12836 Context read_inst_context; 12837 read_inst_context.type = eContextReadOpcode; 12838 read_inst_context.SetNoArgs (); 12839 12840 if (m_opcode_cpsr & MASK_CPSR_T) 12841 { 12842 m_opcode_mode = eModeThumb; 12843 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 12844 12845 if (success) 12846 { 12847 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 12848 { 12849 m_opcode.SetOpcode16 (thumb_opcode); 12850 } 12851 else 12852 { 12853 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success)); 12854 } 12855 } 12856 } 12857 else 12858 { 12859 m_opcode_mode = eModeARM; 12860 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success)); 12861 } 12862 } 12863 } 12864 if (!success) 12865 { 12866 m_opcode_mode = eModeInvalid; 12867 m_addr = LLDB_INVALID_ADDRESS; 12868 } 12869 return success; 12870 } 12871 12872 uint32_t 12873 EmulateInstructionARM::ArchVersion () 12874 { 12875 return m_arm_isa; 12876 } 12877 12878 bool 12879 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) 12880 { 12881 // If we are ignoring conditions, then always return true. 12882 // this allows us to iterate over disassembly code and still 12883 // emulate an instruction even if we don't have all the right 12884 // bits set in the CPSR register... 12885 if (m_ignore_conditions) 12886 return true; 12887 12888 if (is_conditional) 12889 *is_conditional = true; 12890 12891 const uint32_t cond = CurrentCond (opcode); 12892 12893 if (cond == UINT32_MAX) 12894 return false; 12895 12896 bool result = false; 12897 switch (UnsignedBits(cond, 3, 1)) 12898 { 12899 case 0: 12900 if (m_opcode_cpsr == 0) 12901 result = true; 12902 else 12903 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 12904 break; 12905 case 1: 12906 if (m_opcode_cpsr == 0) 12907 result = true; 12908 else 12909 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 12910 break; 12911 case 2: 12912 if (m_opcode_cpsr == 0) 12913 result = true; 12914 else 12915 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 12916 break; 12917 case 3: 12918 if (m_opcode_cpsr == 0) 12919 result = true; 12920 else 12921 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 12922 break; 12923 case 4: 12924 if (m_opcode_cpsr == 0) 12925 result = true; 12926 else 12927 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12928 break; 12929 case 5: 12930 if (m_opcode_cpsr == 0) 12931 result = true; 12932 else 12933 { 12934 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12935 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12936 result = n == v; 12937 } 12938 break; 12939 case 6: 12940 if (m_opcode_cpsr == 0) 12941 result = true; 12942 else 12943 { 12944 bool n = (m_opcode_cpsr & MASK_CPSR_N); 12945 bool v = (m_opcode_cpsr & MASK_CPSR_V); 12946 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 12947 } 12948 break; 12949 case 7: 12950 // Always execute (cond == 0b1110, or the special 0b1111 which gives 12951 // opcodes different meanings, but always means execution happpens. 12952 if (is_conditional) 12953 *is_conditional = false; 12954 result = true; 12955 break; 12956 } 12957 12958 if (cond & 1) 12959 result = !result; 12960 return result; 12961 } 12962 12963 uint32_t 12964 EmulateInstructionARM::CurrentCond (const uint32_t opcode) 12965 { 12966 switch (m_opcode_mode) 12967 { 12968 default: 12969 case eModeInvalid: 12970 break; 12971 12972 case eModeARM: 12973 return UnsignedBits(opcode, 31, 28); 12974 12975 case eModeThumb: 12976 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 12977 // 'cond' field of the encoding. 12978 { 12979 const uint32_t byte_size = m_opcode.GetByteSize(); 12980 if (byte_size == 2) 12981 { 12982 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f) 12983 return Bits32(opcode, 11, 7); 12984 } 12985 else if (byte_size == 4) 12986 { 12987 if (Bits32(opcode, 31, 27) == 0x1e && 12988 Bits32(opcode, 15, 14) == 0x02 && 12989 Bits32(opcode, 12, 12) == 0x00 && 12990 Bits32(opcode, 25, 22) <= 0x0d) 12991 { 12992 return Bits32(opcode, 25, 22); 12993 } 12994 } 12995 else 12996 // We have an invalid thumb instruction, let's bail out. 12997 break; 12998 12999 return m_it_session.GetCond(); 13000 } 13001 } 13002 return UINT32_MAX; // Return invalid value 13003 } 13004 13005 bool 13006 EmulateInstructionARM::InITBlock() 13007 { 13008 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13009 } 13010 13011 bool 13012 EmulateInstructionARM::LastInITBlock() 13013 { 13014 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13015 } 13016 13017 bool 13018 EmulateInstructionARM::BadMode (uint32_t mode) 13019 { 13020 13021 switch (mode) 13022 { 13023 case 16: return false; // '10000' 13024 case 17: return false; // '10001' 13025 case 18: return false; // '10010' 13026 case 19: return false; // '10011' 13027 case 22: return false; // '10110' 13028 case 23: return false; // '10111' 13029 case 27: return false; // '11011' 13030 case 31: return false; // '11111' 13031 default: return true; 13032 } 13033 return true; 13034 } 13035 13036 bool 13037 EmulateInstructionARM::CurrentModeIsPrivileged () 13038 { 13039 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13040 13041 if (BadMode (mode)) 13042 return false; 13043 13044 if (mode == 16) 13045 return false; 13046 13047 return true; 13048 } 13049 13050 void 13051 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13052 { 13053 bool privileged = CurrentModeIsPrivileged(); 13054 13055 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13056 13057 if (BitIsSet (bytemask, 3)) 13058 { 13059 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13060 if (affect_execstate) 13061 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13062 } 13063 13064 if (BitIsSet (bytemask, 2)) 13065 { 13066 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13067 } 13068 13069 if (BitIsSet (bytemask, 1)) 13070 { 13071 if (affect_execstate) 13072 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13073 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13074 if (privileged) 13075 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13076 } 13077 13078 if (BitIsSet (bytemask, 0)) 13079 { 13080 if (privileged) 13081 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13082 if (affect_execstate) 13083 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13084 if (privileged) 13085 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13086 } 13087 13088 m_opcode_cpsr = tmp_cpsr; 13089 } 13090 13091 13092 bool 13093 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13094 { 13095 addr_t target; 13096 13097 // Check the current instruction set. 13098 if (CurrentInstrSet() == eModeARM) 13099 target = addr & 0xfffffffc; 13100 else 13101 target = addr & 0xfffffffe; 13102 13103 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13104 return false; 13105 13106 return true; 13107 } 13108 13109 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13110 bool 13111 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13112 { 13113 addr_t target; 13114 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13115 // we want to record it and issue a WriteRegister callback so the clients 13116 // can track the mode changes accordingly. 13117 bool cpsr_changed = false; 13118 13119 if (BitIsSet(addr, 0)) 13120 { 13121 if (CurrentInstrSet() != eModeThumb) 13122 { 13123 SelectInstrSet(eModeThumb); 13124 cpsr_changed = true; 13125 } 13126 target = addr & 0xfffffffe; 13127 context.SetISA (eModeThumb); 13128 } 13129 else if (BitIsClear(addr, 1)) 13130 { 13131 if (CurrentInstrSet() != eModeARM) 13132 { 13133 SelectInstrSet(eModeARM); 13134 cpsr_changed = true; 13135 } 13136 target = addr & 0xfffffffc; 13137 context.SetISA (eModeARM); 13138 } 13139 else 13140 return false; // address<1:0> == '10' => UNPREDICTABLE 13141 13142 if (cpsr_changed) 13143 { 13144 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13145 return false; 13146 } 13147 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13148 return false; 13149 13150 return true; 13151 } 13152 13153 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13154 bool 13155 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13156 { 13157 if (ArchVersion() >= ARMv5T) 13158 return BXWritePC(context, addr); 13159 else 13160 return BranchWritePC((const Context)context, addr); 13161 } 13162 13163 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13164 bool 13165 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13166 { 13167 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13168 return BXWritePC(context, addr); 13169 else 13170 return BranchWritePC((const Context)context, addr); 13171 } 13172 13173 EmulateInstructionARM::Mode 13174 EmulateInstructionARM::CurrentInstrSet () 13175 { 13176 return m_opcode_mode; 13177 } 13178 13179 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13180 // ReadInstruction() is performed. This function has a side effect of updating 13181 // the m_new_inst_cpsr member variable if necessary. 13182 bool 13183 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13184 { 13185 m_new_inst_cpsr = m_opcode_cpsr; 13186 switch (arm_or_thumb) 13187 { 13188 default: 13189 return false; 13190 case eModeARM: 13191 // Clear the T bit. 13192 m_new_inst_cpsr &= ~MASK_CPSR_T; 13193 break; 13194 case eModeThumb: 13195 // Set the T bit. 13196 m_new_inst_cpsr |= MASK_CPSR_T; 13197 break; 13198 } 13199 return true; 13200 } 13201 13202 // This function returns TRUE if the processor currently provides support for 13203 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13204 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13205 bool 13206 EmulateInstructionARM::UnalignedSupport() 13207 { 13208 return (ArchVersion() >= ARMv7); 13209 } 13210 13211 // The main addition and subtraction instructions can produce status information 13212 // about both unsigned carry and signed overflow conditions. This status 13213 // information can be used to synthesize multi-word additions and subtractions. 13214 EmulateInstructionARM::AddWithCarryResult 13215 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13216 { 13217 uint32_t result; 13218 uint8_t carry_out; 13219 uint8_t overflow; 13220 13221 uint64_t unsigned_sum = x + y + carry_in; 13222 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13223 13224 result = UnsignedBits(unsigned_sum, 31, 0); 13225 // carry_out = (result == unsigned_sum ? 0 : 1); 13226 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13227 13228 if (carry_in) 13229 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13230 else 13231 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13232 13233 AddWithCarryResult res = { result, carry_out, overflow }; 13234 return res; 13235 } 13236 13237 uint32_t 13238 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13239 { 13240 uint32_t reg_kind, reg_num; 13241 switch (num) 13242 { 13243 case SP_REG: 13244 reg_kind = eRegisterKindGeneric; 13245 reg_num = LLDB_REGNUM_GENERIC_SP; 13246 break; 13247 case LR_REG: 13248 reg_kind = eRegisterKindGeneric; 13249 reg_num = LLDB_REGNUM_GENERIC_RA; 13250 break; 13251 case PC_REG: 13252 reg_kind = eRegisterKindGeneric; 13253 reg_num = LLDB_REGNUM_GENERIC_PC; 13254 break; 13255 default: 13256 if (num < SP_REG) 13257 { 13258 reg_kind = eRegisterKindDWARF; 13259 reg_num = dwarf_r0 + num; 13260 } 13261 else 13262 { 13263 //assert(0 && "Invalid register number"); 13264 *success = false; 13265 return UINT32_MAX; 13266 } 13267 break; 13268 } 13269 13270 // Read our register. 13271 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13272 13273 // When executing an ARM instruction , PC reads as the address of the current 13274 // instruction plus 8. 13275 // When executing a Thumb instruction , PC reads as the address of the current 13276 // instruction plus 4. 13277 if (num == 15) 13278 { 13279 if (CurrentInstrSet() == eModeARM) 13280 val += 8; 13281 else 13282 val += 4; 13283 } 13284 13285 return val; 13286 } 13287 13288 // Write the result to the ARM core register Rd, and optionally update the 13289 // condition flags based on the result. 13290 // 13291 // This helper method tries to encapsulate the following pseudocode from the 13292 // ARM Architecture Reference Manual: 13293 // 13294 // if d == 15 then // Can only occur for encoding A1 13295 // ALUWritePC(result); // setflags is always FALSE here 13296 // else 13297 // R[d] = result; 13298 // if setflags then 13299 // APSR.N = result<31>; 13300 // APSR.Z = IsZeroBit(result); 13301 // APSR.C = carry; 13302 // // APSR.V unchanged 13303 // 13304 // In the above case, the API client does not pass in the overflow arg, which 13305 // defaults to ~0u. 13306 bool 13307 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13308 const uint32_t result, 13309 const uint32_t Rd, 13310 bool setflags, 13311 const uint32_t carry, 13312 const uint32_t overflow) 13313 { 13314 if (Rd == 15) 13315 { 13316 if (!ALUWritePC (context, result)) 13317 return false; 13318 } 13319 else 13320 { 13321 uint32_t reg_kind, reg_num; 13322 switch (Rd) 13323 { 13324 case SP_REG: 13325 reg_kind = eRegisterKindGeneric; 13326 reg_num = LLDB_REGNUM_GENERIC_SP; 13327 break; 13328 case LR_REG: 13329 reg_kind = eRegisterKindGeneric; 13330 reg_num = LLDB_REGNUM_GENERIC_RA; 13331 break; 13332 default: 13333 reg_kind = eRegisterKindDWARF; 13334 reg_num = dwarf_r0 + Rd; 13335 } 13336 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13337 return false; 13338 if (setflags) 13339 return WriteFlags (context, result, carry, overflow); 13340 } 13341 return true; 13342 } 13343 13344 // This helper method tries to encapsulate the following pseudocode from the 13345 // ARM Architecture Reference Manual: 13346 // 13347 // APSR.N = result<31>; 13348 // APSR.Z = IsZeroBit(result); 13349 // APSR.C = carry; 13350 // APSR.V = overflow 13351 // 13352 // Default arguments can be specified for carry and overflow parameters, which means 13353 // not to update the respective flags. 13354 bool 13355 EmulateInstructionARM::WriteFlags (Context &context, 13356 const uint32_t result, 13357 const uint32_t carry, 13358 const uint32_t overflow) 13359 { 13360 m_new_inst_cpsr = m_opcode_cpsr; 13361 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13362 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13363 if (carry != ~0u) 13364 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13365 if (overflow != ~0u) 13366 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13367 if (m_new_inst_cpsr != m_opcode_cpsr) 13368 { 13369 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13370 return false; 13371 } 13372 return true; 13373 } 13374 13375 bool 13376 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13377 { 13378 // Advance the ITSTATE bits to their values for the next instruction. 13379 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13380 m_it_session.ITAdvance(); 13381 13382 ARMOpcode *opcode_data = NULL; 13383 13384 if (m_opcode_mode == eModeThumb) 13385 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13386 else if (m_opcode_mode == eModeARM) 13387 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13388 13389 if (opcode_data == NULL) 13390 return false; 13391 13392 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13393 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13394 13395 bool success = false; 13396 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13397 { 13398 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13399 dwarf_cpsr, 13400 0, 13401 &success); 13402 } 13403 13404 // Only return false if we are unable to read the CPSR if we care about conditions 13405 if (success == false && m_ignore_conditions == false) 13406 return false; 13407 13408 uint32_t orig_pc_value = 0; 13409 if (auto_advance_pc) 13410 { 13411 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13412 if (!success) 13413 return false; 13414 } 13415 13416 // Call the Emulate... function. 13417 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13418 if (!success) 13419 return false; 13420 13421 if (auto_advance_pc) 13422 { 13423 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13424 if (!success) 13425 return false; 13426 13427 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13428 { 13429 if (opcode_data->size == eSize32) 13430 after_pc_value += 4; 13431 else if (opcode_data->size == eSize16) 13432 after_pc_value += 2; 13433 13434 EmulateInstruction::Context context; 13435 context.type = eContextAdvancePC; 13436 context.SetNoArgs(); 13437 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13438 return false; 13439 13440 } 13441 } 13442 return true; 13443 } 13444 13445 bool 13446 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13447 { 13448 if (!test_data) 13449 { 13450 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13451 return false; 13452 } 13453 13454 static ConstString opcode_key ("opcode"); 13455 static ConstString before_key ("before_state"); 13456 static ConstString after_key ("after_state"); 13457 13458 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13459 13460 uint32_t test_opcode; 13461 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13462 { 13463 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13464 return false; 13465 } 13466 test_opcode = value_sp->GetUInt64Value (); 13467 13468 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13469 { 13470 m_opcode_mode = eModeARM; 13471 m_opcode.SetOpcode32 (test_opcode); 13472 } 13473 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13474 { 13475 m_opcode_mode = eModeThumb; 13476 if (test_opcode < 0x10000) 13477 m_opcode.SetOpcode16 (test_opcode); 13478 else 13479 m_opcode.SetOpcode32 (test_opcode); 13480 13481 } 13482 else 13483 { 13484 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13485 return false; 13486 } 13487 13488 EmulationStateARM before_state; 13489 EmulationStateARM after_state; 13490 13491 value_sp = test_data->GetValueForKey (before_key); 13492 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13493 { 13494 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13495 return false; 13496 } 13497 13498 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13499 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13500 { 13501 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13502 return false; 13503 } 13504 13505 value_sp = test_data->GetValueForKey (after_key); 13506 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13507 { 13508 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13509 return false; 13510 } 13511 13512 state_dictionary = value_sp->GetAsDictionary (); 13513 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13514 { 13515 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13516 return false; 13517 } 13518 13519 SetBaton ((void *) &before_state); 13520 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13521 &EmulationStateARM::WritePseudoMemory, 13522 &EmulationStateARM::ReadPseudoRegister, 13523 &EmulationStateARM::WritePseudoRegister); 13524 13525 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13526 if (!success) 13527 { 13528 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13529 return false; 13530 } 13531 13532 success = before_state.CompareState (after_state); 13533 if (!success) 13534 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13535 13536 return success; 13537 } 13538 // 13539 // 13540 //const char * 13541 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13542 //{ 13543 // if (reg_kind == eRegisterKindGeneric) 13544 // { 13545 // switch (reg_num) 13546 // { 13547 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 13548 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 13549 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 13550 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 13551 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13552 // default: return NULL; 13553 // } 13554 // } 13555 // else if (reg_kind == eRegisterKindDWARF) 13556 // { 13557 // return GetARMDWARFRegisterName (reg_num); 13558 // } 13559 // return NULL; 13560 //} 13561 // 13562 bool 13563 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13564 { 13565 unwind_plan.Clear(); 13566 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13567 13568 UnwindPlan::Row row; 13569 13570 // Our previous Call Frame Address is the stack pointer 13571 row.SetCFARegister (dwarf_sp); 13572 13573 // Our previous PC is in the LR 13574 row.SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true); 13575 unwind_plan.AppendRow (row); 13576 13577 // All other registers are the same. 13578 13579 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13580 return true; 13581 } 13582 13583 13584 13585 13586