EmulateInstructionARM.cpp revision e7f8953988d593882971e4134f8423f4af1cffaa
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 "lldb/Core/ArchSpec.h" 14#include "lldb/Core/ConstString.h" 15 16#include "Plugins/Process/Utility/ARMDefines.h" 17#include "Plugins/Process/Utility/ARMUtils.h" 18#include "Utility/ARM_DWARF_Registers.h" 19 20#include "llvm/Support/MathExtras.h" // for SignExtend32 template function 21 // and CountTrailingZeros_32 function 22 23using namespace lldb; 24using namespace lldb_private; 25 26static inline uint32_t Align(uint32_t val, uint32_t alignment) 27{ 28 return alignment * (val / alignment); 29} 30 31//---------------------------------------------------------------------- 32// 33// ITSession implementation 34// 35//---------------------------------------------------------------------- 36 37// A8.6.50 38// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 39static unsigned short CountITSize(unsigned ITMask) { 40 // First count the trailing zeros of the IT mask. 41 unsigned TZ = llvm::CountTrailingZeros_32(ITMask); 42 if (TZ > 3) 43 { 44 printf("Encoding error: IT Mask '0000'\n"); 45 return 0; 46 } 47 return (4 - TZ); 48} 49 50// Init ITState. Note that at least one bit is always 1 in mask. 51bool ITSession::InitIT(unsigned short bits7_0) 52{ 53 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 54 if (ITCounter == 0) 55 return false; 56 57 // A8.6.50 IT 58 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 59 if (FirstCond == 0xF) 60 { 61 printf("Encoding error: IT FirstCond '1111'\n"); 62 return false; 63 } 64 if (FirstCond == 0xE && ITCounter != 1) 65 { 66 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 67 return false; 68 } 69 70 ITState = bits7_0; 71 return true; 72} 73 74// Update ITState if necessary. 75void ITSession::ITAdvance() 76{ 77 assert(ITCounter); 78 --ITCounter; 79 if (ITCounter == 0) 80 ITState = 0; 81 else 82 { 83 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 84 SetBits32(ITState, 4, 0, NewITState4_0); 85 } 86} 87 88// Return true if we're inside an IT Block. 89bool ITSession::InITBlock() 90{ 91 return ITCounter != 0; 92} 93 94// Return true if we're the last instruction inside an IT Block. 95bool ITSession::LastInITBlock() 96{ 97 return ITCounter == 1; 98} 99 100// Get condition bits for the current thumb instruction. 101uint32_t ITSession::GetCond() 102{ 103 if (InITBlock()) 104 return Bits32(ITState, 7, 4); 105 else 106 return COND_AL; 107} 108 109// ARM constants used during decoding 110#define REG_RD 0 111#define LDM_REGLIST 1 112#define PC_REG 15 113#define PC_REGLIST_BIT 0x8000 114 115#define ARMv4 (1u << 0) 116#define ARMv4T (1u << 1) 117#define ARMv5T (1u << 2) 118#define ARMv5TE (1u << 3) 119#define ARMv5TEJ (1u << 4) 120#define ARMv6 (1u << 5) 121#define ARMv6K (1u << 6) 122#define ARMv6T2 (1u << 7) 123#define ARMv7 (1u << 8) 124#define ARMv8 (1u << 9) 125#define ARMvAll (0xffffffffu) 126 127#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 128#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 129#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8) 130 131//---------------------------------------------------------------------- 132// 133// EmulateInstructionARM implementation 134// 135//---------------------------------------------------------------------- 136 137void 138EmulateInstructionARM::Initialize () 139{ 140} 141 142void 143EmulateInstructionARM::Terminate () 144{ 145} 146 147// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 148bool 149EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 150{ 151 EmulateInstruction::Context context; 152 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 153 context.SetNoArgs (); 154 155 uint32_t random_data = rand (); 156 const uint32_t addr_byte_size = GetAddressByteSize(); 157 158 if (!WriteMemoryUnsigned (context, address, random_data, addr_byte_size)) 159 return false; 160 161 return true; 162} 163 164// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 165bool 166EmulateInstructionARM::WriteBits32Unknown (int n) 167{ 168 EmulateInstruction::Context context; 169 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 170 context.SetNoArgs (); 171 172 bool success; 173 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 174 175 if (!success) 176 return false; 177 178 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 179 return false; 180 181 return true; 182} 183 184// Push Multiple Registers stores multiple registers to the stack, storing to 185// consecutive memory locations ending just below the address in SP, and updates 186// SP to point to the start of the stored data. 187bool 188EmulateInstructionARM::EmulatePush (ARMEncoding encoding) 189{ 190#if 0 191 // ARM pseudo code... 192 if (ConditionPassed()) 193 { 194 EncodingSpecificOperations(); 195 NullCheckIfThumbEE(13); 196 address = SP - 4*BitCount(registers); 197 198 for (i = 0 to 14) 199 { 200 if (registers<i> == ’1’) 201 { 202 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 203 MemA[address,4] = bits(32) UNKNOWN; 204 else 205 MemA[address,4] = R[i]; 206 address = address + 4; 207 } 208 } 209 210 if (registers<15> == ’1’) // Only possible for encoding A1 or A2 211 MemA[address,4] = PCStoreValue(); 212 213 SP = SP - 4*BitCount(registers); 214 } 215#endif 216 217 bool success = false; 218 const uint32_t opcode = OpcodeAsUnsigned (&success); 219 if (!success) 220 return false; 221 222 if (ConditionPassed()) 223 { 224 const uint32_t addr_byte_size = GetAddressByteSize(); 225 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 226 if (!success) 227 return false; 228 uint32_t registers = 0; 229 uint32_t Rt; // the source register 230 switch (encoding) { 231 case eEncodingT1: 232 registers = Bits32(opcode, 7, 0); 233 // The M bit represents LR. 234 if (Bit32(opcode, 8)) 235 registers |= (1u << 14); 236 // if BitCount(registers) < 1 then UNPREDICTABLE; 237 if (BitCount(registers) < 1) 238 return false; 239 break; 240 case eEncodingT2: 241 // Ignore bits 15 & 13. 242 registers = Bits32(opcode, 15, 0) & ~0xa000; 243 // if BitCount(registers) < 2 then UNPREDICTABLE; 244 if (BitCount(registers) < 2) 245 return false; 246 break; 247 case eEncodingT3: 248 Rt = Bits32(opcode, 15, 12); 249 // if BadReg(t) then UNPREDICTABLE; 250 if (BadReg(Rt)) 251 return false; 252 registers = (1u << Rt); 253 break; 254 case eEncodingA1: 255 registers = Bits32(opcode, 15, 0); 256 // Instead of return false, let's handle the following case as well, 257 // which amounts to pushing one reg onto the full descending stacks. 258 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 259 break; 260 case eEncodingA2: 261 Rt = Bits32(opcode, 15, 12); 262 // if t == 13 then UNPREDICTABLE; 263 if (Rt == dwarf_sp) 264 return false; 265 registers = (1u << Rt); 266 break; 267 default: 268 return false; 269 } 270 addr_t sp_offset = addr_byte_size * BitCount (registers); 271 addr_t addr = sp - sp_offset; 272 uint32_t i; 273 274 EmulateInstruction::Context context; 275 context.type = EmulateInstruction::eContextPushRegisterOnStack; 276 Register dwarf_reg; 277 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 278 for (i=0; i<15; ++i) 279 { 280 if (BitIsSet (registers, i)) 281 { 282 dwarf_reg.num = dwarf_r0 + i; 283 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 284 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 285 if (!success) 286 return false; 287 if (!WriteMemoryUnsigned (context, addr, reg_value, addr_byte_size)) 288 return false; 289 addr += addr_byte_size; 290 } 291 } 292 293 if (BitIsSet (registers, 15)) 294 { 295 dwarf_reg.num = dwarf_pc; 296 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 297 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 298 if (!success) 299 return false; 300 if (!WriteMemoryUnsigned (context, addr, pc + 8, addr_byte_size)) 301 return false; 302 } 303 304 context.type = EmulateInstruction::eContextAdjustStackPointer; 305 context.SetImmediateSigned (-sp_offset); 306 307 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 308 return false; 309 } 310 return true; 311} 312 313// Pop Multiple Registers loads multiple registers from the stack, loading from 314// consecutive memory locations staring at the address in SP, and updates 315// SP to point just above the loaded data. 316bool 317EmulateInstructionARM::EmulatePop (ARMEncoding encoding) 318{ 319#if 0 320 // ARM pseudo code... 321 if (ConditionPassed()) 322 { 323 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 324 address = SP; 325 for i = 0 to 14 326 if registers<i> == ‘1’ then 327 R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 328 if registers<15> == ‘1’ then 329 if UnalignedAllowed then 330 LoadWritePC(MemU[address,4]); 331 else 332 LoadWritePC(MemA[address,4]); 333 if registers<13> == ‘0’ then SP = SP + 4*BitCount(registers); 334 if registers<13> == ‘1’ then SP = bits(32) UNKNOWN; 335 } 336#endif 337 338 bool success = false; 339 const uint32_t opcode = OpcodeAsUnsigned (&success); 340 if (!success) 341 return false; 342 343 if (ConditionPassed()) 344 { 345 const uint32_t addr_byte_size = GetAddressByteSize(); 346 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 347 if (!success) 348 return false; 349 uint32_t registers = 0; 350 uint32_t Rt; // the destination register 351 switch (encoding) { 352 case eEncodingT1: 353 registers = Bits32(opcode, 7, 0); 354 // The P bit represents PC. 355 if (Bit32(opcode, 8)) 356 registers |= (1u << 15); 357 // if BitCount(registers) < 1 then UNPREDICTABLE; 358 if (BitCount(registers) < 1) 359 return false; 360 break; 361 case eEncodingT2: 362 // Ignore bit 13. 363 registers = Bits32(opcode, 15, 0) & ~0x2000; 364 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 365 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 366 return false; 367 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 368 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 369 return false; 370 break; 371 case eEncodingT3: 372 Rt = Bits32(opcode, 15, 12); 373 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 374 if (Rt == 13) 375 return false; 376 if (Rt == 15 && InITBlock() && !LastInITBlock()) 377 return false; 378 registers = (1u << Rt); 379 break; 380 case eEncodingA1: 381 registers = Bits32(opcode, 15, 0); 382 // Instead of return false, let's handle the following case as well, 383 // which amounts to popping one reg from the full descending stacks. 384 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 385 386 // if registers<13> == ‘1’ && ArchVersion() >= 7 then UNPREDICTABLE; 387 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 388 return false; 389 break; 390 case eEncodingA2: 391 Rt = Bits32(opcode, 15, 12); 392 // if t == 13 then UNPREDICTABLE; 393 if (Rt == dwarf_sp) 394 return false; 395 registers = (1u << Rt); 396 break; 397 default: 398 return false; 399 } 400 addr_t sp_offset = addr_byte_size * BitCount (registers); 401 addr_t addr = sp; 402 uint32_t i, data; 403 404 EmulateInstruction::Context context; 405 context.type = EmulateInstruction::eContextPopRegisterOffStack; 406 Register dwarf_reg; 407 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 408 for (i=0; i<15; ++i) 409 { 410 if (BitIsSet (registers, i)) 411 { 412 dwarf_reg.num = dwarf_r0 + i; 413 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 414 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 415 if (!success) 416 return false; 417 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 418 return false; 419 addr += addr_byte_size; 420 } 421 } 422 423 if (BitIsSet (registers, 15)) 424 { 425 dwarf_reg.num = dwarf_pc; 426 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 427 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 428 if (!success) 429 return false; 430 // In ARMv5T and above, this is an interworking branch. 431 if (!LoadWritePC(context, data)) 432 return false; 433 addr += addr_byte_size; 434 } 435 436 context.type = EmulateInstruction::eContextAdjustStackPointer; 437 context.SetImmediateSigned (sp_offset); 438 439 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 440 return false; 441 } 442 return true; 443} 444 445// Set r7 or ip to point to saved value residing within the stack. 446// ADD (SP plus immediate) 447bool 448EmulateInstructionARM::EmulateAddRdSPImmediate (ARMEncoding encoding) 449{ 450#if 0 451 // ARM pseudo code... 452 if (ConditionPassed()) 453 { 454 EncodingSpecificOperations(); 455 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 456 if d == 15 then 457 ALUWritePC(result); // setflags is always FALSE here 458 else 459 R[d] = result; 460 if setflags then 461 APSR.N = result<31>; 462 APSR.Z = IsZeroBit(result); 463 APSR.C = carry; 464 APSR.V = overflow; 465 } 466#endif 467 468 bool success = false; 469 const uint32_t opcode = OpcodeAsUnsigned (&success); 470 if (!success) 471 return false; 472 473 if (ConditionPassed()) 474 { 475 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 476 if (!success) 477 return false; 478 uint32_t Rd; // the destination register 479 uint32_t imm32; 480 switch (encoding) { 481 case eEncodingT1: 482 Rd = 7; 483 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 484 break; 485 case eEncodingA1: 486 Rd = Bits32(opcode, 15, 12); 487 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 488 break; 489 default: 490 return false; 491 } 492 addr_t sp_offset = imm32; 493 addr_t addr = sp + sp_offset; // a pointer to the stack area 494 495 EmulateInstruction::Context context; 496 context.type = EmulateInstruction::eContextRegisterPlusOffset; 497 Register sp_reg; 498 sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 499 context.SetRegisterPlusOffset (sp_reg, sp_offset); 500 501 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 502 return false; 503 } 504 return true; 505} 506 507// Set r7 or ip to the current stack pointer. 508// MOV (register) 509bool 510EmulateInstructionARM::EmulateMovRdSP (ARMEncoding encoding) 511{ 512#if 0 513 // ARM pseudo code... 514 if (ConditionPassed()) 515 { 516 EncodingSpecificOperations(); 517 result = R[m]; 518 if d == 15 then 519 ALUWritePC(result); // setflags is always FALSE here 520 else 521 R[d] = result; 522 if setflags then 523 APSR.N = result<31>; 524 APSR.Z = IsZeroBit(result); 525 // APSR.C unchanged 526 // APSR.V unchanged 527 } 528#endif 529 530 bool success = false; 531 //const uint32_t opcode = OpcodeAsUnsigned (&success); 532 //if (!success) 533 // return false; 534 535 if (ConditionPassed()) 536 { 537 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 538 if (!success) 539 return false; 540 uint32_t Rd; // the destination register 541 switch (encoding) { 542 case eEncodingT1: 543 Rd = 7; 544 break; 545 case eEncodingA1: 546 Rd = 12; 547 break; 548 default: 549 return false; 550 } 551 552 EmulateInstruction::Context context; 553 context.type = EmulateInstruction::eContextRegisterPlusOffset; 554 Register sp_reg; 555 sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 556 context.SetRegisterPlusOffset (sp_reg, 0); 557 558 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 559 return false; 560 } 561 return true; 562} 563 564// Move from high register (r8-r15) to low register (r0-r7). 565// MOV (register) 566bool 567EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding) 568{ 569 return EmulateMovRdRm (encoding); 570} 571 572// Move from register to register. 573// MOV (register) 574bool 575EmulateInstructionARM::EmulateMovRdRm (ARMEncoding encoding) 576{ 577#if 0 578 // ARM pseudo code... 579 if (ConditionPassed()) 580 { 581 EncodingSpecificOperations(); 582 result = R[m]; 583 if d == 15 then 584 ALUWritePC(result); // setflags is always FALSE here 585 else 586 R[d] = result; 587 if setflags then 588 APSR.N = result<31>; 589 APSR.Z = IsZeroBit(result); 590 // APSR.C unchanged 591 // APSR.V unchanged 592 } 593#endif 594 595 bool success = false; 596 const uint32_t opcode = OpcodeAsUnsigned (&success); 597 if (!success) 598 return false; 599 600 if (ConditionPassed()) 601 { 602 uint32_t Rm; // the source register 603 uint32_t Rd; // the destination register 604 bool setflags; 605 switch (encoding) { 606 case eEncodingT1: 607 Rm = Bits32(opcode, 6, 3); 608 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 1); 609 setflags = false; 610 break; 611 case eEncodingT2: 612 Rm = Bits32(opcode, 5, 3); 613 Rd = Bits32(opcode, 2, 1); 614 setflags = true; 615 break; 616 default: 617 return false; 618 } 619 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 620 if (!success) 621 return false; 622 623 // The context specifies that Rm is to be moved into Rd. 624 EmulateInstruction::Context context; 625 context.type = EmulateInstruction::eContextRegisterPlusOffset; 626 Register dwarf_reg; 627 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 628 context.SetRegisterPlusOffset (dwarf_reg, 0); 629 630 if (Rd == 15) 631 { 632 if (!ALUWritePC (context, reg_value)) 633 return false; 634 } 635 else 636 { 637 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, reg_value)) 638 return false; 639 if (setflags) 640 { 641 m_new_inst_cpsr = m_inst_cpsr; 642 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(reg_value, CPSR_N)); 643 SetBit32(m_new_inst_cpsr, CPSR_Z, reg_value == 0 ? 1 : 0); 644 if (m_new_inst_cpsr != m_inst_cpsr) 645 { 646 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 647 return false; 648 } 649 } 650 } 651 } 652 return true; 653} 654 655// Move (immediate) writes an immediate value to the destination register. It 656// can optionally update the condition flags based on the value. 657// MOV (immediate) 658bool 659EmulateInstructionARM::EmulateMovRdImm (ARMEncoding encoding) 660{ 661#if 0 662 // ARM pseudo code... 663 if (ConditionPassed()) 664 { 665 EncodingSpecificOperations(); 666 result = imm32; 667 if d == 15 then // Can only occur for ARM encoding 668 ALUWritePC(result); // setflags is always FALSE here 669 else 670 R[d] = result; 671 if setflags then 672 APSR.N = result<31>; 673 APSR.Z = IsZeroBit(result); 674 APSR.C = carry; 675 // APSR.V unchanged 676 } 677#endif 678 bool success = false; 679 const uint32_t opcode = OpcodeAsUnsigned (&success); 680 if (!success) 681 return false; 682 683 if (ConditionPassed()) 684 { 685 uint32_t Rd; // the destination register 686 uint32_t imm12; // some intermediate result 687 uint32_t imm32; // the immediate value to be written to Rd 688 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 689 bool setflags; 690 switch (encoding) { 691 case eEncodingT1: 692 Rd = Bits32(opcode, 11, 8); 693 setflags = !InITBlock(); 694 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 695 carry = Bit32(m_inst_cpsr, CPSR_C); 696 break; 697 case eEncodingT2: 698 Rd = Bits32(opcode, 15, 12); 699 setflags = BitIsSet(opcode, 20); 700 imm12 = Bit32(opcode, 26) << 11 | Bits32(opcode, 14, 12) << 8 | Bits32(opcode, 7, 0); 701 imm32 = ThumbExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry); 702 if (BadReg(Rd)) 703 return false; 704 break; 705 default: 706 return false; 707 } 708 uint32_t result = imm32; 709 710 // The context specifies that an immediate is to be moved into Rd. 711 EmulateInstruction::Context context; 712 context.type = EmulateInstruction::eContextImmediate; 713 context.SetNoArgs (); 714 715 if (Rd == 15) 716 { 717 if (!ALUWritePC (context, result)) 718 return false; 719 } 720 else 721 { 722 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result)) 723 return false; 724 if (setflags) 725 { 726 m_new_inst_cpsr = m_inst_cpsr; 727 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N)); 728 SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0); 729 SetBit32(m_new_inst_cpsr, CPSR_C, carry); 730 if (m_new_inst_cpsr != m_inst_cpsr) 731 { 732 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 733 return false; 734 } 735 } 736 } 737 } 738 return true; 739} 740 741// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 742// the destination register. It can optionally update the condition flags based 743// on the value. 744// MVN (immediate) 745bool 746EmulateInstructionARM::EmulateMvnRdImm (ARMEncoding encoding) 747{ 748#if 0 749 // ARM pseudo code... 750 if (ConditionPassed()) 751 { 752 EncodingSpecificOperations(); 753 result = NOT(imm32); 754 if d == 15 then // Can only occur for ARM encoding 755 ALUWritePC(result); // setflags is always FALSE here 756 else 757 R[d] = result; 758 if setflags then 759 APSR.N = result<31>; 760 APSR.Z = IsZeroBit(result); 761 APSR.C = carry; 762 // APSR.V unchanged 763 } 764#endif 765 bool success = false; 766 const uint32_t opcode = OpcodeAsUnsigned (&success); 767 if (!success) 768 return false; 769 770 if (ConditionPassed()) 771 { 772 uint32_t Rd; // the destination register 773 uint32_t imm12; // the first operand to ThumbExpandImm_C or ARMExpandImm_C 774 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 775 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 776 bool setflags; 777 switch (encoding) { 778 case eEncodingT1: 779 Rd = Bits32(opcode, 11, 8); 780 setflags = BitIsSet(opcode, 20); 781 imm12 = Bit32(opcode, 26) << 11 | Bits32(opcode, 14, 12) << 8 | Bits32(opcode, 7, 0); 782 imm32 = ThumbExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry); 783 break; 784 case eEncodingA1: 785 Rd = Bits32(opcode, 15, 12); 786 setflags = BitIsSet(opcode, 20); 787 imm12 = Bits32(opcode, 11, 0); 788 imm32 = ARMExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry); 789 break; 790 default: 791 return false; 792 } 793 uint32_t result = ~imm32; 794 795 // The context specifies that an immediate is to be moved into Rd. 796 EmulateInstruction::Context context; 797 context.type = EmulateInstruction::eContextImmediate; 798 context.SetNoArgs (); 799 800 if (Rd == 15) 801 { 802 if (!ALUWritePC (context, result)) 803 return false; 804 } 805 else 806 { 807 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result)) 808 return false; 809 if (setflags) 810 { 811 m_new_inst_cpsr = m_inst_cpsr; 812 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N)); 813 SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0); 814 SetBit32(m_new_inst_cpsr, CPSR_C, carry); 815 if (m_new_inst_cpsr != m_inst_cpsr) 816 { 817 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 818 return false; 819 } 820 } 821 } 822 } 823 return true; 824} 825 826// PC relative immediate load into register, possibly followed by ADD (SP plus register). 827// LDR (literal) 828bool 829EmulateInstructionARM::EmulateLDRRtPCRelative (ARMEncoding encoding) 830{ 831#if 0 832 // ARM pseudo code... 833 if (ConditionPassed()) 834 { 835 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 836 base = Align(PC,4); 837 address = if add then (base + imm32) else (base - imm32); 838 data = MemU[address,4]; 839 if t == 15 then 840 if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE; 841 elsif UnalignedSupport() || address<1:0> = ‘00’ then 842 R[t] = data; 843 else // Can only apply before ARMv7 844 if CurrentInstrSet() == InstrSet_ARM then 845 R[t] = ROR(data, 8*UInt(address<1:0>)); 846 else 847 R[t] = bits(32) UNKNOWN; 848 } 849#endif 850 851 bool success = false; 852 const uint32_t opcode = OpcodeAsUnsigned (&success); 853 if (!success) 854 return false; 855 856 if (ConditionPassed()) 857 { 858 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 859 if (!success) 860 return false; 861 862 // PC relative immediate load context 863 EmulateInstruction::Context context; 864 context.type = EmulateInstruction::eContextRegisterPlusOffset; 865 Register pc_reg; 866 pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 867 context.SetRegisterPlusOffset (pc_reg, 0); 868 869 uint32_t Rt; // the destination register 870 uint32_t imm32; // immediate offset from the PC 871 bool add; // +imm32 or -imm32? 872 addr_t base; // the base address 873 addr_t address; // the PC relative address 874 uint32_t data; // the literal data value from the PC relative load 875 switch (encoding) { 876 case eEncodingT1: 877 Rt = Bits32(opcode, 10, 8); 878 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 879 add = true; 880 base = Align(pc + 4, 4); 881 context.SetRegisterPlusOffset (pc_reg, 4 + imm32); 882 break; 883 case eEncodingT2: 884 Rt = Bits32(opcode, 15, 12); 885 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 886 add = BitIsSet(opcode, 23); 887 if (Rt == 15 && InITBlock() && !LastInITBlock()) 888 return false; 889 base = Align(pc + 4, 4); 890 context.SetRegisterPlusOffset (pc_reg, 4 + imm32); 891 break; 892 default: 893 return false; 894 } 895 896 if (add) 897 address = base + imm32; 898 else 899 address = base - imm32; 900 data = ReadMemoryUnsigned(context, address, 4, 0, &success); 901 if (!success) 902 return false; 903 904 if (Rt == 15) 905 { 906 if (Bits32(address, 1, 0) == 0) 907 { 908 // In ARMv5T and above, this is an interworking branch. 909 if (!LoadWritePC(context, data)) 910 return false; 911 } 912 else 913 return false; 914 } 915 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 916 { 917 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 918 return false; 919 } 920 else // We don't handle ARM for now. 921 return false; 922 923 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 924 return false; 925 } 926 return true; 927} 928 929// An add operation to adjust the SP. 930// ADD (SP plus immediate) 931bool 932EmulateInstructionARM::EmulateAddSPImmediate (ARMEncoding encoding) 933{ 934#if 0 935 // ARM pseudo code... 936 if (ConditionPassed()) 937 { 938 EncodingSpecificOperations(); 939 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 940 if d == 15 then // Can only occur for ARM encoding 941 ALUWritePC(result); // setflags is always FALSE here 942 else 943 R[d] = result; 944 if setflags then 945 APSR.N = result<31>; 946 APSR.Z = IsZeroBit(result); 947 APSR.C = carry; 948 APSR.V = overflow; 949 } 950#endif 951 952 bool success = false; 953 const uint32_t opcode = OpcodeAsUnsigned (&success); 954 if (!success) 955 return false; 956 957 if (ConditionPassed()) 958 { 959 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 960 if (!success) 961 return false; 962 uint32_t imm32; // the immediate operand 963 switch (encoding) { 964 case eEncodingT2: 965 imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 966 break; 967 default: 968 return false; 969 } 970 addr_t sp_offset = imm32; 971 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 972 973 EmulateInstruction::Context context; 974 context.type = EmulateInstruction::eContextAdjustStackPointer; 975 context.SetImmediateSigned (sp_offset); 976 977 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 978 return false; 979 } 980 return true; 981} 982 983// An add operation to adjust the SP. 984// ADD (SP plus register) 985bool 986EmulateInstructionARM::EmulateAddSPRm (ARMEncoding encoding) 987{ 988#if 0 989 // ARM pseudo code... 990 if (ConditionPassed()) 991 { 992 EncodingSpecificOperations(); 993 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 994 (result, carry, overflow) = AddWithCarry(SP, shifted, ‘0’); 995 if d == 15 then 996 ALUWritePC(result); // setflags is always FALSE here 997 else 998 R[d] = result; 999 if setflags then 1000 APSR.N = result<31>; 1001 APSR.Z = IsZeroBit(result); 1002 APSR.C = carry; 1003 APSR.V = overflow; 1004 } 1005#endif 1006 1007 bool success = false; 1008 const uint32_t opcode = OpcodeAsUnsigned (&success); 1009 if (!success) 1010 return false; 1011 1012 if (ConditionPassed()) 1013 { 1014 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1015 if (!success) 1016 return false; 1017 uint32_t Rm; // the second operand 1018 switch (encoding) { 1019 case eEncodingT2: 1020 Rm = Bits32(opcode, 6, 3); 1021 break; 1022 default: 1023 return false; 1024 } 1025 int32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1026 if (!success) 1027 return false; 1028 1029 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1030 1031 EmulateInstruction::Context context; 1032 context.type = EmulateInstruction::eContextAdjustStackPointer; 1033 context.SetImmediateSigned (reg_value); 1034 1035 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1036 return false; 1037 } 1038 return true; 1039} 1040 1041// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1042// at a PC-relative address, and changes instruction set from ARM to Thumb, or 1043// from Thumb to ARM. 1044// BLX (immediate) 1045bool 1046EmulateInstructionARM::EmulateBLXImmediate (ARMEncoding encoding) 1047{ 1048#if 0 1049 // ARM pseudo code... 1050 if (ConditionPassed()) 1051 { 1052 EncodingSpecificOperations(); 1053 if CurrentInstrSet() == InstrSet_ARM then 1054 LR = PC - 4; 1055 else 1056 LR = PC<31:1> : '1'; 1057 if targetInstrSet == InstrSet_ARM then 1058 targetAddress = Align(PC,4) + imm32; 1059 else 1060 targetAddress = PC + imm32; 1061 SelectInstrSet(targetInstrSet); 1062 BranchWritePC(targetAddress); 1063 } 1064#endif 1065 1066 bool success = false; 1067 const uint32_t opcode = OpcodeAsUnsigned (&success); 1068 if (!success) 1069 return false; 1070 1071 if (ConditionPassed()) 1072 { 1073 EmulateInstruction::Context context; 1074 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1075 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1076 if (!success) 1077 return false; 1078 addr_t lr; // next instruction address 1079 addr_t target; // target address 1080 int32_t imm32; // PC-relative offset 1081 switch (encoding) { 1082 case eEncodingT1: 1083 { 1084 lr = (pc + 4) | 1u; // return address 1085 uint32_t S = Bit32(opcode, 26); 1086 uint32_t imm10 = Bits32(opcode, 25, 16); 1087 uint32_t J1 = Bit32(opcode, 13); 1088 uint32_t J2 = Bit32(opcode, 11); 1089 uint32_t imm11 = Bits32(opcode, 10, 0); 1090 uint32_t I1 = !(J1 ^ S); 1091 uint32_t I2 = !(J2 ^ S); 1092 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1093 imm32 = llvm::SignExtend32<25>(imm25); 1094 target = pc + 4 + imm32; 1095 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1096 if (InITBlock() && !LastInITBlock()) 1097 return false; 1098 break; 1099 } 1100 case eEncodingT2: 1101 { 1102 lr = (pc + 4) | 1u; // return address 1103 uint32_t S = Bit32(opcode, 26); 1104 uint32_t imm10H = Bits32(opcode, 25, 16); 1105 uint32_t J1 = Bit32(opcode, 13); 1106 uint32_t J2 = Bit32(opcode, 11); 1107 uint32_t imm10L = Bits32(opcode, 10, 1); 1108 uint32_t I1 = !(J1 ^ S); 1109 uint32_t I2 = !(J2 ^ S); 1110 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1111 imm32 = llvm::SignExtend32<25>(imm25); 1112 target = Align(pc + 4, 4) + imm32; 1113 context.SetModeAndImmediateSigned (eModeARM, 4 + imm32); 1114 if (InITBlock() && !LastInITBlock()) 1115 return false; 1116 break; 1117 } 1118 case eEncodingA1: 1119 lr = pc + 4; // return address 1120 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1121 target = Align(pc + 8, 4) + imm32; 1122 context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 1123 break; 1124 case eEncodingA2: 1125 lr = pc + 4; // return address 1126 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1127 target = pc + 8 + imm32; 1128 context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32); 1129 break; 1130 default: 1131 return false; 1132 } 1133 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1134 return false; 1135 if (!BranchWritePC(context, target)) 1136 return false; 1137 } 1138 return true; 1139} 1140 1141// Branch with Link and Exchange (register) calls a subroutine at an address and 1142// instruction set specified by a register. 1143// BLX (register) 1144bool 1145EmulateInstructionARM::EmulateBLXRm (ARMEncoding encoding) 1146{ 1147#if 0 1148 // ARM pseudo code... 1149 if (ConditionPassed()) 1150 { 1151 EncodingSpecificOperations(); 1152 target = R[m]; 1153 if CurrentInstrSet() == InstrSet_ARM then 1154 next_instr_addr = PC - 4; 1155 LR = next_instr_addr; 1156 else 1157 next_instr_addr = PC - 2; 1158 LR = next_instr_addr<31:1> : ‘1’; 1159 BXWritePC(target); 1160 } 1161#endif 1162 1163 bool success = false; 1164 const uint32_t opcode = OpcodeAsUnsigned (&success); 1165 if (!success) 1166 return false; 1167 1168 if (ConditionPassed()) 1169 { 1170 EmulateInstruction::Context context; 1171 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1172 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1173 addr_t lr; // next instruction address 1174 if (!success) 1175 return false; 1176 uint32_t Rm; // the register with the target address 1177 switch (encoding) { 1178 case eEncodingT1: 1179 lr = (pc + 2) | 1u; // return address 1180 Rm = Bits32(opcode, 6, 3); 1181 // if m == 15 then UNPREDICTABLE; 1182 if (Rm == 15) 1183 return false; 1184 if (InITBlock() && !LastInITBlock()) 1185 return false; 1186 break; 1187 case eEncodingA1: 1188 lr = pc + 4; // return address 1189 Rm = Bits32(opcode, 3, 0); 1190 // if m == 15 then UNPREDICTABLE; 1191 if (Rm == 15) 1192 return false; 1193 break; 1194 default: 1195 return false; 1196 } 1197 addr_t target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1198 if (!success) 1199 return false; 1200 Register dwarf_reg; 1201 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 1202 context.SetRegister (dwarf_reg); 1203 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1204 return false; 1205 if (!BXWritePC(context, target)) 1206 return false; 1207 } 1208 return true; 1209} 1210 1211// Branch and Exchange causes a branch to an address and instruction set specified by a register. 1212// BX 1213bool 1214EmulateInstructionARM::EmulateBXRm (ARMEncoding encoding) 1215{ 1216#if 0 1217 // ARM pseudo code... 1218 if (ConditionPassed()) 1219 { 1220 EncodingSpecificOperations(); 1221 BXWritePC(R[m]); 1222 } 1223#endif 1224 1225 bool success = false; 1226 const uint32_t opcode = OpcodeAsUnsigned (&success); 1227 if (!success) 1228 return false; 1229 1230 if (ConditionPassed()) 1231 { 1232 EmulateInstruction::Context context; 1233 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1234 uint32_t Rm; // the register with the target address 1235 switch (encoding) { 1236 case eEncodingT1: 1237 Rm = Bits32(opcode, 6, 3); 1238 if (InITBlock() && !LastInITBlock()) 1239 return false; 1240 break; 1241 case eEncodingA1: 1242 Rm = Bits32(opcode, 3, 0); 1243 break; 1244 default: 1245 return false; 1246 } 1247 addr_t target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1248 if (!success) 1249 return false; 1250 1251 Register dwarf_reg; 1252 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 1253 context.SetRegister (dwarf_reg); 1254 if (!BXWritePC(context, target)) 1255 return false; 1256 } 1257 return true; 1258} 1259 1260// Set r7 to point to some ip offset. 1261// SUB (immediate) 1262bool 1263EmulateInstructionARM::EmulateSubR7IPImmediate (ARMEncoding encoding) 1264{ 1265#if 0 1266 // ARM pseudo code... 1267 if (ConditionPassed()) 1268 { 1269 EncodingSpecificOperations(); 1270 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1271 if d == 15 then // Can only occur for ARM encoding 1272 ALUWritePC(result); // setflags is always FALSE here 1273 else 1274 R[d] = result; 1275 if setflags then 1276 APSR.N = result<31>; 1277 APSR.Z = IsZeroBit(result); 1278 APSR.C = carry; 1279 APSR.V = overflow; 1280 } 1281#endif 1282 1283 bool success = false; 1284 const uint32_t opcode = OpcodeAsUnsigned (&success); 1285 if (!success) 1286 return false; 1287 1288 if (ConditionPassed()) 1289 { 1290 const addr_t ip = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r12, 0, &success); 1291 if (!success) 1292 return false; 1293 uint32_t imm32; 1294 switch (encoding) { 1295 case eEncodingA1: 1296 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1297 break; 1298 default: 1299 return false; 1300 } 1301 addr_t ip_offset = imm32; 1302 addr_t addr = ip - ip_offset; // the adjusted ip value 1303 1304 EmulateInstruction::Context context; 1305 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1306 Register dwarf_reg; 1307 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12); 1308 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1309 1310 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1311 return false; 1312 } 1313 return true; 1314} 1315 1316// Set ip to point to some stack offset. 1317// SUB (SP minus immediate) 1318bool 1319EmulateInstructionARM::EmulateSubIPSPImmediate (ARMEncoding encoding) 1320{ 1321#if 0 1322 // ARM pseudo code... 1323 if (ConditionPassed()) 1324 { 1325 EncodingSpecificOperations(); 1326 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1327 if d == 15 then // Can only occur for ARM encoding 1328 ALUWritePC(result); // setflags is always FALSE here 1329 else 1330 R[d] = result; 1331 if setflags then 1332 APSR.N = result<31>; 1333 APSR.Z = IsZeroBit(result); 1334 APSR.C = carry; 1335 APSR.V = overflow; 1336 } 1337#endif 1338 1339 bool success = false; 1340 const uint32_t opcode = OpcodeAsUnsigned (&success); 1341 if (!success) 1342 return false; 1343 1344 if (ConditionPassed()) 1345 { 1346 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1347 if (!success) 1348 return false; 1349 uint32_t imm32; 1350 switch (encoding) { 1351 case eEncodingA1: 1352 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1353 break; 1354 default: 1355 return false; 1356 } 1357 addr_t sp_offset = imm32; 1358 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1359 1360 EmulateInstruction::Context context; 1361 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1362 Register dwarf_reg; 1363 dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 1364 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1365 1366 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1367 return false; 1368 } 1369 return true; 1370} 1371 1372// A sub operation to adjust the SP -- allocate space for local storage. 1373bool 1374EmulateInstructionARM::EmulateSubSPImmdiate (ARMEncoding encoding) 1375{ 1376#if 0 1377 // ARM pseudo code... 1378 if (ConditionPassed()) 1379 { 1380 EncodingSpecificOperations(); 1381 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1382 if d == 15 then // Can only occur for ARM encoding 1383 ALUWritePC(result); // setflags is always FALSE here 1384 else 1385 R[d] = result; 1386 if setflags then 1387 APSR.N = result<31>; 1388 APSR.Z = IsZeroBit(result); 1389 APSR.C = carry; 1390 APSR.V = overflow; 1391 } 1392#endif 1393 1394 bool success = false; 1395 const uint32_t opcode = OpcodeAsUnsigned (&success); 1396 if (!success) 1397 return false; 1398 1399 if (ConditionPassed()) 1400 { 1401 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1402 if (!success) 1403 return false; 1404 uint32_t imm32; 1405 switch (encoding) { 1406 case eEncodingT1: 1407 imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1408 case eEncodingT2: 1409 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1410 break; 1411 case eEncodingT3: 1412 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1413 break; 1414 case eEncodingA1: 1415 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1416 break; 1417 default: 1418 return false; 1419 } 1420 addr_t sp_offset = imm32; 1421 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1422 1423 EmulateInstruction::Context context; 1424 context.type = EmulateInstruction::eContextAdjustStackPointer; 1425 context.SetImmediateSigned (-sp_offset); 1426 1427 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1428 return false; 1429 } 1430 return true; 1431} 1432 1433// A store operation to the stack that also updates the SP. 1434bool 1435EmulateInstructionARM::EmulateSTRRtSP (ARMEncoding encoding) 1436{ 1437#if 0 1438 // ARM pseudo code... 1439 if (ConditionPassed()) 1440 { 1441 EncodingSpecificOperations(); 1442 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1443 address = if index then offset_addr else R[n]; 1444 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1445 if wback then R[n] = offset_addr; 1446 } 1447#endif 1448 1449 bool success = false; 1450 const uint32_t opcode = OpcodeAsUnsigned (&success); 1451 if (!success) 1452 return false; 1453 1454 if (ConditionPassed()) 1455 { 1456 const uint32_t addr_byte_size = GetAddressByteSize(); 1457 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1458 if (!success) 1459 return false; 1460 uint32_t Rt; // the source register 1461 uint32_t imm12; 1462 switch (encoding) { 1463 case eEncodingA1: 1464 Rt = Bits32(opcode, 15, 12); 1465 imm12 = Bits32(opcode, 11, 0); 1466 break; 1467 default: 1468 return false; 1469 } 1470 addr_t sp_offset = imm12; 1471 addr_t addr = sp - sp_offset; 1472 1473 EmulateInstruction::Context context; 1474 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1475 Register dwarf_reg; 1476 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1477 if (Rt != 15) 1478 { 1479 dwarf_reg.num = dwarf_r0 + Rt; 1480 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1481 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 1482 if (!success) 1483 return false; 1484 if (!WriteMemoryUnsigned (context, addr, reg_value, addr_byte_size)) 1485 return false; 1486 } 1487 else 1488 { 1489 dwarf_reg.num = dwarf_pc; 1490 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1491 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1492 if (!success) 1493 return false; 1494 if (!WriteMemoryUnsigned (context, addr, pc + 8, addr_byte_size)) 1495 return false; 1496 } 1497 1498 context.type = EmulateInstruction::eContextAdjustStackPointer; 1499 context.SetImmediateSigned (-sp_offset); 1500 1501 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1502 return false; 1503 } 1504 return true; 1505} 1506 1507// Vector Push stores multiple extension registers to the stack. 1508// It also updates SP to point to the start of the stored data. 1509bool 1510EmulateInstructionARM::EmulateVPUSH (ARMEncoding encoding) 1511{ 1512#if 0 1513 // ARM pseudo code... 1514 if (ConditionPassed()) 1515 { 1516 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1517 address = SP - imm32; 1518 SP = SP - imm32; 1519 if single_regs then 1520 for r = 0 to regs-1 1521 MemA[address,4] = S[d+r]; address = address+4; 1522 else 1523 for r = 0 to regs-1 1524 // Store as two word-aligned words in the correct order for current endianness. 1525 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1526 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1527 address = address+8; 1528 } 1529#endif 1530 1531 bool success = false; 1532 const uint32_t opcode = OpcodeAsUnsigned (&success); 1533 if (!success) 1534 return false; 1535 1536 if (ConditionPassed()) 1537 { 1538 const uint32_t addr_byte_size = GetAddressByteSize(); 1539 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1540 if (!success) 1541 return false; 1542 bool single_regs; 1543 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1544 uint32_t imm32; // stack offset 1545 uint32_t regs; // number of registers 1546 switch (encoding) { 1547 case eEncodingT1: 1548 case eEncodingA1: 1549 single_regs = false; 1550 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1551 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1552 // If UInt(imm8) is odd, see "FSTMX". 1553 regs = Bits32(opcode, 7, 0) / 2; 1554 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1555 if (regs == 0 || regs > 16 || (d + regs) > 32) 1556 return false; 1557 break; 1558 case eEncodingT2: 1559 case eEncodingA2: 1560 single_regs = true; 1561 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1562 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1563 regs = Bits32(opcode, 7, 0); 1564 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1565 if (regs == 0 || regs > 16 || (d + regs) > 32) 1566 return false; 1567 break; 1568 default: 1569 return false; 1570 } 1571 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1572 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1573 addr_t sp_offset = imm32; 1574 addr_t addr = sp - sp_offset; 1575 uint32_t i; 1576 1577 EmulateInstruction::Context context; 1578 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1579 Register dwarf_reg; 1580 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1581 for (i=d; i<regs; ++i) 1582 { 1583 dwarf_reg.num = start_reg + i; 1584 context.SetRegisterPlusOffset ( dwarf_reg, addr - sp); 1585 // uint64_t to accommodate 64-bit registers. 1586 uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 1587 if (!success) 1588 return false; 1589 if (!WriteMemoryUnsigned (context, addr, reg_value, reg_byte_size)) 1590 return false; 1591 addr += reg_byte_size; 1592 } 1593 1594 context.type = EmulateInstruction::eContextAdjustStackPointer; 1595 context.SetImmediateSigned (-sp_offset); 1596 1597 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1598 return false; 1599 } 1600 return true; 1601} 1602 1603// Vector Pop loads multiple extension registers from the stack. 1604// It also updates SP to point just above the loaded data. 1605bool 1606EmulateInstructionARM::EmulateVPOP (ARMEncoding encoding) 1607{ 1608#if 0 1609 // ARM pseudo code... 1610 if (ConditionPassed()) 1611 { 1612 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1613 address = SP; 1614 SP = SP + imm32; 1615 if single_regs then 1616 for r = 0 to regs-1 1617 S[d+r] = MemA[address,4]; address = address+4; 1618 else 1619 for r = 0 to regs-1 1620 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 1621 // Combine the word-aligned words in the correct order for current endianness. 1622 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 1623 } 1624#endif 1625 1626 bool success = false; 1627 const uint32_t opcode = OpcodeAsUnsigned (&success); 1628 if (!success) 1629 return false; 1630 1631 if (ConditionPassed()) 1632 { 1633 const uint32_t addr_byte_size = GetAddressByteSize(); 1634 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1635 if (!success) 1636 return false; 1637 bool single_regs; 1638 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1639 uint32_t imm32; // stack offset 1640 uint32_t regs; // number of registers 1641 switch (encoding) { 1642 case eEncodingT1: 1643 case eEncodingA1: 1644 single_regs = false; 1645 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1646 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1647 // If UInt(imm8) is odd, see "FLDMX". 1648 regs = Bits32(opcode, 7, 0) / 2; 1649 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1650 if (regs == 0 || regs > 16 || (d + regs) > 32) 1651 return false; 1652 break; 1653 case eEncodingT2: 1654 case eEncodingA2: 1655 single_regs = true; 1656 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1657 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1658 regs = Bits32(opcode, 7, 0); 1659 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1660 if (regs == 0 || regs > 16 || (d + regs) > 32) 1661 return false; 1662 break; 1663 default: 1664 return false; 1665 } 1666 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1667 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1668 addr_t sp_offset = imm32; 1669 addr_t addr = sp; 1670 uint32_t i; 1671 uint64_t data; // uint64_t to accomodate 64-bit registers. 1672 1673 EmulateInstruction::Context context; 1674 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1675 Register dwarf_reg; 1676 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1677 for (i=d; i<regs; ++i) 1678 { 1679 dwarf_reg.num = start_reg + i; 1680 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1681 data = ReadMemoryUnsigned(context, addr, reg_byte_size, 0, &success); 1682 if (!success) 1683 return false; 1684 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 1685 return false; 1686 addr += reg_byte_size; 1687 } 1688 1689 context.type = EmulateInstruction::eContextAdjustStackPointer; 1690 context.SetImmediateSigned (sp_offset); 1691 1692 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1693 return false; 1694 } 1695 return true; 1696} 1697 1698// SVC (previously SWI) 1699bool 1700EmulateInstructionARM::EmulateSVC (ARMEncoding encoding) 1701{ 1702#if 0 1703 // ARM pseudo code... 1704 if (ConditionPassed()) 1705 { 1706 EncodingSpecificOperations(); 1707 CallSupervisor(); 1708 } 1709#endif 1710 1711 bool success = false; 1712 const uint32_t opcode = OpcodeAsUnsigned (&success); 1713 if (!success) 1714 return false; 1715 1716 if (ConditionPassed()) 1717 { 1718 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1719 addr_t lr; // next instruction address 1720 if (!success) 1721 return false; 1722 uint32_t imm32; // the immediate constant 1723 uint32_t mode; // ARM or Thumb mode 1724 switch (encoding) { 1725 case eEncodingT1: 1726 lr = (pc + 2) | 1u; // return address 1727 imm32 = Bits32(opcode, 7, 0); 1728 mode = eModeThumb; 1729 break; 1730 case eEncodingA1: 1731 lr = pc + 4; // return address 1732 imm32 = Bits32(opcode, 23, 0); 1733 mode = eModeARM; 1734 break; 1735 default: 1736 return false; 1737 } 1738 1739 EmulateInstruction::Context context; 1740 context.type = EmulateInstruction::eContextSupervisorCall; 1741 context.SetModeAndImmediate (mode, imm32); 1742 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1743 return false; 1744 } 1745 return true; 1746} 1747 1748// If Then makes up to four following instructions (the IT block) conditional. 1749bool 1750EmulateInstructionARM::EmulateIT (ARMEncoding encoding) 1751{ 1752#if 0 1753 // ARM pseudo code... 1754 EncodingSpecificOperations(); 1755 ITSTATE.IT<7:0> = firstcond:mask; 1756#endif 1757 1758 bool success = false; 1759 const uint32_t opcode = OpcodeAsUnsigned (&success); 1760 if (!success) 1761 return false; 1762 1763 m_it_session.InitIT(Bits32(opcode, 7, 0)); 1764 return true; 1765} 1766 1767// Branch causes a branch to a target address. 1768bool 1769EmulateInstructionARM::EmulateB (ARMEncoding encoding) 1770{ 1771#if 0 1772 // ARM pseudo code... 1773 if (ConditionPassed()) 1774 { 1775 EncodingSpecificOperations(); 1776 BranchWritePC(PC + imm32); 1777 } 1778#endif 1779 1780 bool success = false; 1781 const uint32_t opcode = OpcodeAsUnsigned (&success); 1782 if (!success) 1783 return false; 1784 1785 if (ConditionPassed()) 1786 { 1787 EmulateInstruction::Context context; 1788 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1789 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1790 if (!success) 1791 return false; 1792 addr_t target; // target address 1793 int32_t imm32; // PC-relative offset 1794 switch (encoding) { 1795 case eEncodingT1: 1796 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1797 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 1798 target = pc + 4 + imm32; 1799 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1800 break; 1801 case eEncodingT2: 1802 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 1803 target = pc + 4 + imm32; 1804 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1805 break; 1806 case eEncodingT3: 1807 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1808 { 1809 uint32_t S = Bit32(opcode, 26); 1810 uint32_t imm6 = Bits32(opcode, 21, 16); 1811 uint32_t J1 = Bit32(opcode, 13); 1812 uint32_t J2 = Bit32(opcode, 11); 1813 uint32_t imm11 = Bits32(opcode, 10, 0); 1814 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 1815 imm32 = llvm::SignExtend32<21>(imm21); 1816 target = pc + 4 + imm32; 1817 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1818 break; 1819 } 1820 case eEncodingT4: 1821 { 1822 uint32_t S = Bit32(opcode, 26); 1823 uint32_t imm10 = Bits32(opcode, 25, 16); 1824 uint32_t J1 = Bit32(opcode, 13); 1825 uint32_t J2 = Bit32(opcode, 11); 1826 uint32_t imm11 = Bits32(opcode, 10, 0); 1827 uint32_t I1 = !(J1 ^ S); 1828 uint32_t I2 = !(J2 ^ S); 1829 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1830 imm32 = llvm::SignExtend32<25>(imm25); 1831 target = pc + 4 + imm32; 1832 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1833 break; 1834 } 1835 case eEncodingA1: 1836 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1837 target = pc + 8 + imm32; 1838 context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 1839 break; 1840 default: 1841 return false; 1842 } 1843 if (!BranchWritePC(context, target)) 1844 return false; 1845 } 1846 return true; 1847} 1848 1849// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 1850// zero and conditionally branch forward a constant value. They do not affect the condition flags. 1851// CBNZ, CBZ 1852bool 1853EmulateInstructionARM::EmulateCB (ARMEncoding encoding) 1854{ 1855#if 0 1856 // ARM pseudo code... 1857 EncodingSpecificOperations(); 1858 if nonzero ^ IsZero(R[n]) then 1859 BranchWritePC(PC + imm32); 1860#endif 1861 1862 bool success = false; 1863 const uint32_t opcode = OpcodeAsUnsigned (&success); 1864 if (!success) 1865 return false; 1866 1867 // Read the register value from the operand register Rn. 1868 uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Bits32(opcode, 2, 0), 0, &success); 1869 if (!success) 1870 return false; 1871 1872 EmulateInstruction::Context context; 1873 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1874 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1875 if (!success) 1876 return false; 1877 1878 addr_t target; // target address 1879 uint32_t imm32; // PC-relative offset to branch forward 1880 bool nonzero; 1881 switch (encoding) { 1882 case eEncodingT1: 1883 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 1884 nonzero = BitIsSet(opcode, 11); 1885 target = pc + 4 + imm32; 1886 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1887 break; 1888 default: 1889 return false; 1890 } 1891 if (nonzero ^ (reg_val == 0)) 1892 if (!BranchWritePC(context, target)) 1893 return false; 1894 1895 return true; 1896} 1897 1898// ADD <Rdn>, <Rm> 1899// where <Rdn> the destination register is also the first operand register 1900// and <Rm> is the second operand register. 1901bool 1902EmulateInstructionARM::EmulateAddRdnRm (ARMEncoding encoding) 1903{ 1904#if 0 1905 // ARM pseudo code... 1906 if ConditionPassed() then 1907 EncodingSpecificOperations(); 1908 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1909 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 1910 if d == 15 then 1911 ALUWritePC(result); // setflags is always FALSE here 1912 else 1913 R[d] = result; 1914 if setflags then 1915 APSR.N = result<31>; 1916 APSR.Z = IsZeroBit(result); 1917 APSR.C = carry; 1918 APSR.V = overflow; 1919#endif 1920 1921 bool success = false; 1922 const uint32_t opcode = OpcodeAsUnsigned (&success); 1923 if (!success) 1924 return false; 1925 1926 if (ConditionPassed()) 1927 { 1928 uint32_t Rd, Rn, Rm; 1929 //bool setflags = false; 1930 switch (encoding) 1931 { 1932 case eEncodingT2: 1933 // setflags = FALSE 1934 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1935 Rm = Bits32(opcode, 6, 3); 1936 if (Rn == 15 && Rm == 15) 1937 return false; 1938 break; 1939 default: 1940 return false; 1941 } 1942 1943 int32_t result, val1, val2; 1944 // Read the first operand. 1945 if (Rn == 15) 1946 val1 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1947 else 1948 val1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 1949 if (!success) 1950 return false; 1951 1952 // Read the second operand. 1953 if (Rm == 15) 1954 val2 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1955 else 1956 val2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1957 if (!success) 1958 return false; 1959 1960 result = val1 + val2; 1961 1962 EmulateInstruction::Context context; 1963 context.type = EmulateInstruction::eContextImmediate; 1964 context.SetNoArgs (); 1965 1966 if (Rd == 15) 1967 { 1968 if (!ALUWritePC (context, result)) 1969 return false; 1970 } 1971 else 1972 { 1973 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result)) 1974 return false; 1975 } 1976 } 1977 return true; 1978} 1979 1980// CMP (immediate) 1981bool 1982EmulateInstructionARM::EmulateCmpRnImm (ARMEncoding encoding) 1983{ 1984#if 0 1985 // ARM pseudo code... 1986 if ConditionPassed() then 1987 EncodingSpecificOperations(); 1988 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 1989 APSR.N = result<31>; 1990 APSR.Z = IsZeroBit(result); 1991 APSR.C = carry; 1992 APSR.V = overflow; 1993#endif 1994 1995 bool success = false; 1996 const uint32_t opcode = OpcodeAsUnsigned (&success); 1997 if (!success) 1998 return false; 1999 2000 uint32_t Rn; // the first operand 2001 uint32_t imm32; // the immediate value to be compared with 2002 switch (encoding) { 2003 case eEncodingT1: 2004 Rn = Bits32(opcode, 10, 8); 2005 imm32 = Bits32(opcode, 7, 0); 2006 break; 2007 default: 2008 return false; 2009 } 2010 // Read the register value from the operand register Rn. 2011 uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 2012 if (!success) 2013 return false; 2014 2015 EmulateInstruction::Context context; 2016 context.type = EmulateInstruction::eContextImmediate; 2017 context.SetNoArgs (); 2018 2019 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2020 m_new_inst_cpsr = m_inst_cpsr; 2021 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(res.result, CPSR_N)); 2022 SetBit32(m_new_inst_cpsr, CPSR_Z, res.result == 0 ? 1 : 0); 2023 SetBit32(m_new_inst_cpsr, CPSR_C, res.carry_out); 2024 SetBit32(m_new_inst_cpsr, CPSR_V, res.overflow); 2025 if (m_new_inst_cpsr != m_inst_cpsr) 2026 { 2027 EmulateInstruction::Context context; 2028 context.type = EmulateInstruction::eContextImmediate; 2029 context.SetNoArgs (); 2030 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2031 return false; 2032 } 2033 return true; 2034} 2035 2036// CMP (register) 2037bool 2038EmulateInstructionARM::EmulateCmpRnRm (ARMEncoding encoding) 2039{ 2040#if 0 2041 // ARM pseudo code... 2042 if ConditionPassed() then 2043 EncodingSpecificOperations(); 2044 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2045 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2046 APSR.N = result<31>; 2047 APSR.Z = IsZeroBit(result); 2048 APSR.C = carry; 2049 APSR.V = overflow; 2050#endif 2051 2052 bool success = false; 2053 const uint32_t opcode = OpcodeAsUnsigned (&success); 2054 if (!success) 2055 return false; 2056 2057 uint32_t Rn; // the first operand 2058 uint32_t Rm; // the second operand 2059 switch (encoding) { 2060 case eEncodingT1: 2061 Rn = Bits32(opcode, 2, 0); 2062 Rm = Bits32(opcode, 5, 3); 2063 break; 2064 case eEncodingT2: 2065 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2066 Rm = Bits32(opcode, 6, 3); 2067 if (Rn < 8 && Rm < 8) 2068 return false; 2069 if (Rn == 15 || Rm == 15) 2070 return false; 2071 break; 2072 default: 2073 return false; 2074 } 2075 // Read the register value from register Rn. 2076 uint32_t reg_val1 = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 2077 if (!success) 2078 return false; 2079 // Read the register value from register Rm. 2080 // The register value is not being shifted since we don't handle ARM for now. 2081 uint32_t reg_val2 = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 2082 if (!success) 2083 return false; 2084 2085 EmulateInstruction::Context context; 2086 context.type = EmulateInstruction::eContextImmediate; 2087 context.SetNoArgs(); 2088 2089 AddWithCarryResult res = AddWithCarry(reg_val1, reg_val2, 1); 2090 m_new_inst_cpsr = m_inst_cpsr; 2091 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(res.result, CPSR_N)); 2092 SetBit32(m_new_inst_cpsr, CPSR_Z, res.result == 0 ? 1 : 0); 2093 SetBit32(m_new_inst_cpsr, CPSR_C, res.carry_out); 2094 SetBit32(m_new_inst_cpsr, CPSR_V, res.overflow); 2095 if (m_new_inst_cpsr != m_inst_cpsr) 2096 { 2097 EmulateInstruction::Context context; 2098 context.type = EmulateInstruction::eContextImmediate; 2099 context.SetNoArgs (); 2100 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2101 return false; 2102 } 2103 return true; 2104} 2105 2106// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2107// shifting in copies of its sign bit, and writes the result to the destination register. It can 2108// optionally update the condition flags based on the result. 2109bool 2110EmulateInstructionARM::EmulateASRImm (ARMEncoding encoding) 2111{ 2112#if 0 2113 // ARM pseudo code... 2114 if ConditionPassed() then 2115 EncodingSpecificOperations(); 2116 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2117 if d == 15 then // Can only occur for ARM encoding 2118 ALUWritePC(result); // setflags is always FALSE here 2119 else 2120 R[d] = result; 2121 if setflags then 2122 APSR.N = result<31>; 2123 APSR.Z = IsZeroBit(result); 2124 APSR.C = carry; 2125 // APSR.V unchanged 2126#endif 2127 2128 bool success = false; 2129 const uint32_t opcode = OpcodeAsUnsigned (&success); 2130 if (!success) 2131 return false; 2132 2133 if (ConditionPassed()) 2134 { 2135 uint32_t Rd; // the destination register 2136 uint32_t Rm; // the first operand register 2137 uint32_t imm5; // encoding for the shift amount 2138 uint32_t carry; // the carry bit after the shift operation 2139 bool setflags; 2140 switch (encoding) { 2141 case eEncodingT1: 2142 Rd = Bits32(opcode, 2, 0); 2143 Rm = Bits32(opcode, 5, 3); 2144 setflags = !InITBlock(); 2145 imm5 = Bits32(opcode, 10, 6); 2146 break; 2147 case eEncodingT2: 2148 Rd = Bits32(opcode, 11, 8); 2149 Rm = Bits32(opcode, 3, 0); 2150 setflags = BitIsSet(opcode, 20); 2151 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 2152 if (BadReg(Rd) || BadReg(Rm)) 2153 return false; 2154 break; 2155 case eEncodingA1: 2156 Rd = Bits32(opcode, 15, 12); 2157 Rm = Bits32(opcode, 3, 0); 2158 setflags = BitIsSet(opcode, 20); 2159 imm5 = Bits32(opcode, 11, 7); 2160 break; 2161 default: 2162 return false; 2163 } 2164 2165 // Get the first operand. 2166 uint32_t value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 2167 if (!success) 2168 return false; 2169 2170 // Decode the shift amount. 2171 uint32_t amt = DecodeImmShift(SRType_ASR, imm5); 2172 2173 uint32_t result = Shift_C(value, SRType_ASR, amt, Bit32(m_inst_cpsr, CPSR_C), carry); 2174 2175 // The context specifies that an immediate is to be moved into Rd. 2176 EmulateInstruction::Context context; 2177 context.type = EmulateInstruction::eContextImmediate; 2178 context.SetNoArgs (); 2179 2180 if (Rd == 15) 2181 { 2182 if (!ALUWritePC (context, result)) 2183 return false; 2184 } 2185 else 2186 { 2187 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result)) 2188 return false; 2189 if (setflags) 2190 { 2191 m_new_inst_cpsr = m_inst_cpsr; 2192 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N)); 2193 SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0); 2194 SetBit32(m_new_inst_cpsr, CPSR_C, carry); 2195 if (m_new_inst_cpsr != m_inst_cpsr) 2196 { 2197 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2198 return false; 2199 } 2200 } 2201 } 2202 } 2203 return true; 2204} 2205 2206// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 2207// shifting in copies of its sign bit, and writes the result to the destination register. 2208// The variable number of bits is read from the bottom byte of a register. It can optionally update 2209// the condition flags based on the result. 2210bool 2211EmulateInstructionARM::EmulateASRReg (ARMEncoding encoding) 2212{ 2213#if 0 2214 // ARM pseudo code... 2215 if ConditionPassed() then 2216 EncodingSpecificOperations(); 2217 shift_n = UInt(R[m]<7:0>); 2218 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2219 R[d] = result; 2220 if setflags then 2221 APSR.N = result<31>; 2222 APSR.Z = IsZeroBit(result); 2223 APSR.C = carry; 2224 // APSR.V unchanged 2225#endif 2226 2227 bool success = false; 2228 const uint32_t opcode = OpcodeAsUnsigned (&success); 2229 if (!success) 2230 return false; 2231 2232 if (ConditionPassed()) 2233 { 2234 uint32_t Rd; // the destination register 2235 uint32_t Rn; // the first operand register 2236 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 2237 uint32_t carry; // the carry bit after the shift operation 2238 bool setflags; 2239 switch (encoding) { 2240 case eEncodingT1: 2241 Rd = Bits32(opcode, 2, 0); 2242 Rn = Rd; 2243 Rm = Bits32(opcode, 5, 3); 2244 setflags = !InITBlock(); 2245 break; 2246 case eEncodingT2: 2247 Rd = Bits32(opcode, 11, 8); 2248 Rn = Bits32(opcode, 19, 16); 2249 Rm = Bits32(opcode, 3, 0); 2250 setflags = BitIsSet(opcode, 20); 2251 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 2252 return false; 2253 break; 2254 case eEncodingA1: 2255 Rd = Bits32(opcode, 15, 12); 2256 Rn = Bits32(opcode, 3, 0); 2257 Rm = Bits32(opcode, 11, 8); 2258 setflags = BitIsSet(opcode, 20); 2259 if (Rd == 15 || Rn == 15 || Rm == 15) 2260 return false; 2261 break; 2262 default: 2263 return false; 2264 } 2265 2266 // Get the first operand. 2267 uint32_t value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 2268 if (!success) 2269 return false; 2270 // Get the Rm register content. 2271 uint32_t val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 2272 if (!success) 2273 return false; 2274 2275 // Get the shift amount. 2276 uint32_t amt = Bits32(val, 7, 0); 2277 2278 uint32_t result = Shift_C(value, SRType_ASR, amt, Bit32(m_inst_cpsr, CPSR_C), carry); 2279 2280 // The context specifies that an immediate is to be moved into Rd. 2281 EmulateInstruction::Context context; 2282 context.type = EmulateInstruction::eContextImmediate; 2283 context.SetNoArgs (); 2284 2285 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result)) 2286 return false; 2287 if (setflags) 2288 { 2289 m_new_inst_cpsr = m_inst_cpsr; 2290 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N)); 2291 SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0); 2292 SetBit32(m_new_inst_cpsr, CPSR_C, carry); 2293 if (m_new_inst_cpsr != m_inst_cpsr) 2294 { 2295 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2296 return false; 2297 } 2298 } 2299 } 2300 return true; 2301} 2302 2303// LDM loads multiple registers from consecutive memory locations, using an 2304// address from a base register. Optionally the address just above the highest of those locations 2305// can be written back to the base register. 2306bool 2307EmulateInstructionARM::EmulateLDM (ARMEncoding encoding) 2308{ 2309#if 0 2310 // ARM pseudo code... 2311 if ConditionPassed() 2312 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 2313 address = R[n]; 2314 2315 for i = 0 to 14 2316 if registers<i> == '1' then 2317 R[i] = MemA[address, 4]; address = address + 4; 2318 if registers<15> == '1' then 2319 LoadWritePC (MemA[address, 4]); 2320 2321 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 2322 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2323 2324#endif 2325 2326 bool success = false; 2327 const uint32_t opcode = OpcodeAsUnsigned (&success); 2328 if (!success) 2329 return false; 2330 2331 if (ConditionPassed()) 2332 { 2333 uint32_t n; 2334 uint32_t registers = 0; 2335 bool wback; 2336 const uint32_t addr_byte_size = GetAddressByteSize(); 2337 switch (encoding) 2338 { 2339 case eEncodingT1: 2340 // n = UInt(Rn); registers = ’00000000’:register_list; wback = (registers<n> == ’0’); 2341 n = Bits32 (opcode, 10, 8); 2342 registers = Bits32 (opcode, 7, 0); 2343 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 2344 wback = BitIsClear (registers, n); 2345 // if BitCount(registers) < 1 then UNPREDICTABLE; 2346 if (BitCount(registers) < 1) 2347 return false; 2348 break; 2349 case eEncodingT2: 2350 // if W == ’1’ && Rn == ’1101’ then SEE POP; 2351 // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 2352 n = Bits32 (opcode, 19, 16); 2353 registers = Bits32 (opcode, 15, 0); 2354 registers = registers & 0xdfff; // Make sure bit 13 is zero. 2355 wback = BitIsSet (opcode, 21); 2356 2357 // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 2358 if ((n == 15) 2359 || (BitCount (registers) < 2) 2360 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 2361 return false; 2362 2363 // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 2364 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 2365 return false; 2366 2367 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 2368 if (wback 2369 && BitIsSet (registers, n)) 2370 return false; 2371 break; 2372 2373 case eEncodingA1: 2374 n = Bits32 (opcode, 19, 16); 2375 registers = Bits32 (opcode, 15, 0); 2376 wback = BitIsSet (opcode, 21); 2377 if ((n == 15) 2378 || (BitCount (registers) < 1)) 2379 return false; 2380 break; 2381 default: 2382 return false; 2383 } 2384 2385 int32_t offset = 0; 2386 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2387 if (!success) 2388 return false; 2389 2390 EmulateInstruction::Context context; 2391 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2392 Register dwarf_reg; 2393 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2394 context.SetRegisterPlusOffset (dwarf_reg, offset); 2395 2396 for (int i = 0; i < 14; ++i) 2397 { 2398 if (BitIsSet (registers, i)) 2399 { 2400 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2401 context.SetRegisterPlusOffset (dwarf_reg, offset); 2402 if (wback && (n == 13)) // Pop Instruction 2403 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2404 2405 // R[i] = MemA [address, 4]; address = address + 4; 2406 uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success); 2407 if (!success) 2408 return false; 2409 2410 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2411 return false; 2412 2413 offset += addr_byte_size; 2414 } 2415 } 2416 2417 if (BitIsSet (registers, 15)) 2418 { 2419 //LoadWritePC (MemA [address, 4]); 2420 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2421 context.SetRegisterPlusOffset (dwarf_reg, offset); 2422 uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success); 2423 if (!success) 2424 return false; 2425 // In ARMv5T and above, this is an interworking branch. 2426 if (!LoadWritePC(context, data)) 2427 return false; 2428 } 2429 2430 if (wback && BitIsClear (registers, n)) 2431 { 2432 // R[n] = R[n] + 4 * BitCount (registers) 2433 int32_t offset = addr_byte_size * BitCount (registers); 2434 context.type = EmulateInstruction::eContextAdjustBaseRegister; 2435 context.SetRegisterPlusOffset (dwarf_reg, offset); 2436 2437 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 2438 return false; 2439 } 2440 if (wback && BitIsSet (registers, n)) 2441 // R[n] bits(32) UNKNOWN; 2442 return WriteBits32Unknown (n); 2443 } 2444 return true; 2445} 2446 2447// LDMDA loads multiple registers from consecutive memory locations using an address from a base registers. 2448// The consecutive memorty locations end at this address and the address just below the lowest of those locations 2449// can optionally be written back tot he base registers. 2450bool 2451EmulateInstructionARM::EmulateLDMDA (ARMEncoding encoding) 2452{ 2453#if 0 2454 // ARM pseudo code... 2455 if ConditionPassed() then 2456 EncodingSpecificOperations(); 2457 address = R[n] - 4*BitCount(registers) + 4; 2458 2459 for i = 0 to 14 2460 if registers<i> == ’1’ then 2461 R[i] = MemA[address,4]; address = address + 4; 2462 2463 if registers<15> == ’1’ then 2464 LoadWritePC(MemA[address,4]); 2465 2466 if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2467 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 2468#endif 2469 2470 bool success = false; 2471 const uint32_t opcode = OpcodeAsUnsigned (&success); 2472 if (!success) 2473 return false; 2474 2475 if (ConditionPassed()) 2476 { 2477 uint32_t n; 2478 uint32_t registers = 0; 2479 bool wback; 2480 const uint32_t addr_byte_size = GetAddressByteSize(); 2481 2482 // EncodingSpecificOperations(); 2483 switch (encoding) 2484 { 2485 case eEncodingA1: 2486 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 2487 n = Bits32 (opcode, 19, 16); 2488 registers = Bits32 (opcode, 15, 0); 2489 wback = BitIsSet (opcode, 21); 2490 2491 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 2492 if ((n == 15) || (BitCount (registers) < 1)) 2493 return false; 2494 2495 break; 2496 2497 default: 2498 return false; 2499 } 2500 // address = R[n] - 4*BitCount(registers) + 4; 2501 2502 int32_t offset = 0; 2503 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2504 2505 if (!success) 2506 return false; 2507 2508 address = address - (addr_byte_size * BitCount (registers)) + addr_byte_size; 2509 2510 EmulateInstruction::Context context; 2511 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2512 Register dwarf_reg; 2513 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2514 context.SetRegisterPlusOffset (dwarf_reg, offset); 2515 2516 // for i = 0 to 14 2517 for (int i = 0; i < 14; ++i) 2518 { 2519 // if registers<i> == ’1’ then 2520 if (BitIsSet (registers, i)) 2521 { 2522 // R[i] = MemA[address,4]; address = address + 4; 2523 context.SetRegisterPlusOffset (dwarf_reg, offset); 2524 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2525 if (!success) 2526 return false; 2527 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2528 return false; 2529 offset += addr_byte_size; 2530 } 2531 } 2532 2533 // if registers<15> == ’1’ then 2534 // LoadWritePC(MemA[address,4]); 2535 if (BitIsSet (registers, 15)) 2536 { 2537 context.SetRegisterPlusOffset (dwarf_reg, offset); 2538 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2539 if (!success) 2540 return false; 2541 // In ARMv5T and above, this is an interworking branch. 2542 if (!LoadWritePC(context, data)) 2543 return false; 2544 } 2545 2546 // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2547 if (wback && BitIsClear (registers, n)) 2548 { 2549 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2550 if (!success) 2551 return false; 2552 2553 offset = (addr_byte_size * BitCount (registers)) * -1; 2554 context.type = EmulateInstruction::eContextAdjustBaseRegister; 2555 context.SetImmediateSigned (offset); 2556 addr = addr + offset; 2557 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 2558 return false; 2559 } 2560 2561 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 2562 if (wback && BitIsSet (registers, n)) 2563 return WriteBits32Unknown (n); 2564 } 2565 return true; 2566} 2567 2568// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 2569// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 2570// be optionally written back to the base register. 2571bool 2572EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding) 2573{ 2574#if 0 2575 // ARM pseudo code... 2576 if ConditionPassed() then 2577 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2578 address = R[n] - 4*BitCount(registers); 2579 2580 for i = 0 to 14 2581 if registers<i> == ’1’ then 2582 R[i] = MemA[address,4]; address = address + 4; 2583 if registers<15> == ’1’ then 2584 LoadWritePC(MemA[address,4]); 2585 2586 if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2587 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2588#endif 2589 2590 bool success = false; 2591 const uint32_t opcode = OpcodeAsUnsigned (&success); 2592 if (!success) 2593 return false; 2594 2595 if (ConditionPassed()) 2596 { 2597 uint32_t n; 2598 uint32_t registers = 0; 2599 bool wback; 2600 const uint32_t addr_byte_size = GetAddressByteSize(); 2601 switch (encoding) 2602 { 2603 case eEncodingT1: 2604 // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 2605 n = Bits32 (opcode, 19, 16); 2606 registers = Bits32 (opcode, 15, 0); 2607 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 2608 wback = BitIsSet (opcode, 21); 2609 2610 // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 2611 if ((n == 15) 2612 || (BitCount (registers) < 2) 2613 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 2614 return false; 2615 2616 // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 2617 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 2618 return false; 2619 2620 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 2621 if (wback && BitIsSet (registers, n)) 2622 return false; 2623 2624 break; 2625 2626 case eEncodingA1: 2627 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 2628 n = Bits32 (opcode, 19, 16); 2629 registers = Bits32 (opcode, 15, 0); 2630 wback = BitIsSet (opcode, 21); 2631 2632 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 2633 if ((n == 15) || (BitCount (registers) < 1)) 2634 return false; 2635 2636 break; 2637 2638 default: 2639 return false; 2640 } 2641 2642 // address = R[n] - 4*BitCount(registers); 2643 2644 int32_t offset = 0; 2645 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2646 2647 if (!success) 2648 return false; 2649 2650 address = address - (addr_byte_size * BitCount (registers)); 2651 EmulateInstruction::Context context; 2652 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2653 Register dwarf_reg; 2654 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2655 context.SetRegisterPlusOffset (dwarf_reg, offset); 2656 2657 for (int i = 0; i < 14; ++i) 2658 { 2659 if (BitIsSet (registers, i)) 2660 { 2661 // R[i] = MemA[address,4]; address = address + 4; 2662 context.SetRegisterPlusOffset (dwarf_reg, offset); 2663 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2664 if (!success) 2665 return false; 2666 2667 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2668 return false; 2669 2670 offset += addr_byte_size; 2671 } 2672 } 2673 2674 // if registers<15> == ’1’ then 2675 // LoadWritePC(MemA[address,4]); 2676 if (BitIsSet (registers, 15)) 2677 { 2678 context.SetRegisterPlusOffset (dwarf_reg, offset); 2679 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2680 if (!success) 2681 return false; 2682 // In ARMv5T and above, this is an interworking branch. 2683 if (!LoadWritePC(context, data)) 2684 return false; 2685 } 2686 2687 // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2688 if (wback && BitIsClear (registers, n)) 2689 { 2690 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2691 if (!success) 2692 return false; 2693 2694 offset = (addr_byte_size * BitCount (registers)) * -1; 2695 context.type = EmulateInstruction::eContextAdjustBaseRegister; 2696 context.SetImmediateSigned (offset); 2697 addr = addr + offset; 2698 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 2699 return false; 2700 } 2701 2702 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2703 if (wback && BitIsSet (registers, n)) 2704 return WriteBits32Unknown (n); 2705 } 2706 return true; 2707} 2708 2709// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 2710// consecutive memory locations start just above this address, and thea ddress of the last of those locations can 2711// optinoally be written back to the base register. 2712bool 2713EmulateInstructionARM::EmulateLDMIB (ARMEncoding encoding) 2714{ 2715#if 0 2716 if ConditionPassed() then 2717 EncodingSpecificOperations(); 2718 address = R[n] + 4; 2719 2720 for i = 0 to 14 2721 if registers<i> == ’1’ then 2722 R[i] = MemA[address,4]; address = address + 4; 2723 if registers<15> == ’1’ then 2724 LoadWritePC(MemA[address,4]); 2725 2726 if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 2727 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 2728#endif 2729 2730 bool success = false; 2731 const uint32_t opcode = OpcodeAsUnsigned (&success); 2732 if (!success) 2733 return false; 2734 2735 if (ConditionPassed()) 2736 { 2737 uint32_t n; 2738 uint32_t registers = 0; 2739 bool wback; 2740 const uint32_t addr_byte_size = GetAddressByteSize(); 2741 switch (encoding) 2742 { 2743 case eEncodingA1: 2744 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 2745 n = Bits32 (opcode, 19, 16); 2746 registers = Bits32 (opcode, 15, 0); 2747 wback = BitIsSet (opcode, 21); 2748 2749 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 2750 if ((n == 15) || (BitCount (registers) < 1)) 2751 return false; 2752 2753 break; 2754 default: 2755 return false; 2756 } 2757 // address = R[n] + 4; 2758 2759 int32_t offset = 0; 2760 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2761 2762 if (!success) 2763 return false; 2764 2765 address = address + addr_byte_size; 2766 2767 EmulateInstruction::Context context; 2768 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2769 Register dwarf_reg; 2770 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2771 context.SetRegisterPlusOffset (dwarf_reg, offset); 2772 2773 for (int i = 0; i < 14; ++i) 2774 { 2775 if (BitIsSet (registers, i)) 2776 { 2777 // R[i] = MemA[address,4]; address = address + 4; 2778 2779 context.SetRegisterPlusOffset (dwarf_reg, offset); 2780 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2781 if (!success) 2782 return false; 2783 2784 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2785 return false; 2786 2787 offset += addr_byte_size; 2788 } 2789 } 2790 2791 // if registers<15> == ’1’ then 2792 // LoadWritePC(MemA[address,4]); 2793 if (BitIsSet (registers, 15)) 2794 { 2795 context.SetRegisterPlusOffset (dwarf_reg, offset); 2796 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2797 if (!success) 2798 return false; 2799 // In ARMv5T and above, this is an interworking branch. 2800 if (!LoadWritePC(context, data)) 2801 return false; 2802 } 2803 2804 // if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 2805 if (wback && BitIsClear (registers, n)) 2806 { 2807 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2808 if (!success) 2809 return false; 2810 2811 offset = addr_byte_size * BitCount (registers); 2812 context.type = EmulateInstruction::eContextAdjustBaseRegister; 2813 context.SetImmediateSigned (offset); 2814 addr = addr + offset; 2815 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 2816 return false; 2817 } 2818 2819 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2820 if (wback && BitIsSet (registers, n)) 2821 return WriteBits32Unknown (n); 2822 } 2823 return true; 2824} 2825 2826// Load Register (immediate) calculates an address from a base register value and 2827// an immediate offset, loads a word from memory, and writes to a register. 2828// LDR (immediate, Thumb) 2829bool 2830EmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding) 2831{ 2832#if 0 2833 // ARM pseudo code... 2834 if (ConditionPassed()) 2835 { 2836 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 2837 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2838 address = if index then offset_addr else R[n]; 2839 data = MemU[address,4]; 2840 if wback then R[n] = offset_addr; 2841 if t == 15 then 2842 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 2843 elsif UnalignedSupport() || address<1:0> = '00' then 2844 R[t] = data; 2845 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 2846 } 2847#endif 2848 2849 bool success = false; 2850 const uint32_t opcode = OpcodeAsUnsigned (&success); 2851 if (!success) 2852 return false; 2853 2854 if (ConditionPassed()) 2855 { 2856 uint32_t Rt; // the destination register 2857 uint32_t Rn; // the base register 2858 uint32_t imm32; // the immediate offset used to form the address 2859 addr_t offset_addr; // the offset address 2860 addr_t address; // the calculated address 2861 uint32_t data; // the literal data value from memory load 2862 bool add, index, wback; 2863 switch (encoding) { 2864 case eEncodingT1: 2865 Rt = Bits32(opcode, 5, 3); 2866 Rn = Bits32(opcode, 2, 0); 2867 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 2868 // index = TRUE; add = TRUE; wback = FALSE 2869 add = true; 2870 index = true; 2871 wback = false; 2872 break; 2873 default: 2874 return false; 2875 } 2876 uint32_t base = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 2877 if (!success) 2878 return false; 2879 if (add) 2880 offset_addr = base + imm32; 2881 else 2882 offset_addr = base - imm32; 2883 2884 address = (index ? offset_addr : base); 2885 2886 if (wback) 2887 { 2888 EmulateInstruction::Context ctx; 2889 ctx.type = EmulateInstruction::eContextRegisterPlusOffset; 2890 Register dwarf_reg; 2891 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn); 2892 ctx.SetRegisterPlusOffset (dwarf_reg, (int32_t) (offset_addr - base)); 2893 2894 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 2895 return false; 2896 } 2897 2898 // Prepare to write to the Rt register. 2899 EmulateInstruction::Context context; 2900 context.type = EmulateInstruction::eContextImmediate; 2901 context.SetNoArgs (); 2902 2903 // Read memory from the address. 2904 data = ReadMemoryUnsigned(context, address, 4, 0, &success); 2905 if (!success) 2906 return false; 2907 2908 if (Rt == 15) 2909 { 2910 if (Bits32(address, 1, 0) == 0) 2911 { 2912 if (!LoadWritePC(context, data)) 2913 return false; 2914 } 2915 else 2916 return false; 2917 } 2918 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 2919 { 2920 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 2921 return false; 2922 } 2923 else 2924 return false; 2925 } 2926 return true; 2927} 2928 2929// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 2930// from a base register. The consecutive memory locations start at this address, and teh address just above the last 2931// of those locations can optionally be written back to the base register. 2932bool 2933EmulateInstructionARM::EmulateSTM (ARMEncoding encoding) 2934{ 2935#if 0 2936 if ConditionPassed() then 2937 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2938 address = R[n]; 2939 2940 for i = 0 to 14 2941 if registers<i> == ’1’ then 2942 if i == n && wback && i != LowestSetBit(registers) then 2943 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 2944 else 2945 MemA[address,4] = R[i]; 2946 address = address + 4; 2947 2948 if registers<15> == ’1’ then // Only possible for encoding A1 2949 MemA[address,4] = PCStoreValue(); 2950 if wback then R[n] = R[n] + 4*BitCount(registers); 2951#endif 2952 2953 bool success = false; 2954 const uint32_t opcode = OpcodeAsUnsigned (&success); 2955 if (!success) 2956 return false; 2957 2958 if (ConditionPassed ()) 2959 { 2960 uint32_t n; 2961 uint32_t registers = 0; 2962 bool wback; 2963 const uint32_t addr_byte_size = GetAddressByteSize(); 2964 2965 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2966 switch (encoding) 2967 { 2968 case eEncodingT1: 2969 // n = UInt(Rn); registers = ’00000000’:register_list; wback = TRUE; 2970 n = Bits32 (opcode, 10, 8); 2971 registers = Bits32 (opcode, 7, 0); 2972 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 2973 wback = true; 2974 2975 // if BitCount(registers) < 1 then UNPREDICTABLE; 2976 if (BitCount (registers) < 1) 2977 return false; 2978 2979 break; 2980 2981 case eEncodingT2: 2982 // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’); 2983 n = Bits32 (opcode, 19, 16); 2984 registers = Bits32 (opcode, 15, 0); 2985 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 2986 wback = BitIsSet (opcode, 21); 2987 2988 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 2989 if ((n == 15) || (BitCount (registers) < 2)) 2990 return false; 2991 2992 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 2993 if (wback && BitIsSet (registers, n)) 2994 return false; 2995 2996 break; 2997 2998 case eEncodingA1: 2999 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3000 n = Bits32 (opcode, 19, 16); 3001 registers = Bits32 (opcode, 15, 0); 3002 wback = BitIsSet (opcode, 21); 3003 3004 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3005 if ((n == 15) || (BitCount (registers) < 1)) 3006 return false; 3007 3008 break; 3009 3010 default: 3011 return false; 3012 } 3013 3014 // address = R[n]; 3015 int32_t offset = 0; 3016 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3017 if (!success) 3018 return false; 3019 3020 EmulateInstruction::Context context; 3021 context.type = EmulateInstruction::eContextRegisterStore; 3022 Register base_reg; 3023 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3024 3025 // for i = 0 to 14 3026 for (int i = 0; i < 14; ++i) 3027 { 3028 int lowest_set_bit = 14; 3029 // if registers<i> == ’1’ then 3030 if (BitIsSet (registers, i)) 3031 { 3032 if (i < lowest_set_bit) 3033 lowest_set_bit = i; 3034 // if i == n && wback && i != LowestSetBit(registers) then 3035 if ((i == n) && wback && (i != lowest_set_bit)) 3036 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 3037 WriteBits32UnknownToMemory (address + offset); 3038 else 3039 { 3040 // MemA[address,4] = R[i]; 3041 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3042 if (!success) 3043 return false; 3044 3045 Register data_reg; 3046 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3047 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3048 if (!WriteMemoryUnsigned (context, address + offset, data, addr_byte_size)) 3049 return false; 3050 } 3051 3052 // address = address + 4; 3053 offset += addr_byte_size; 3054 } 3055 } 3056 3057 // if registers<15> == ’1’ then // Only possible for encoding A1 3058 // MemA[address,4] = PCStoreValue(); 3059 if (BitIsSet (registers, 15)) 3060 { 3061 Register pc_reg; 3062 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3063 context.SetRegisterPlusOffset (pc_reg, 8); 3064 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3065 if (!success) 3066 return false; 3067 3068 if (!WriteMemoryUnsigned (context, address + offset, pc + 8, addr_byte_size)) 3069 return false; 3070 } 3071 3072 // if wback then R[n] = R[n] + 4*BitCount(registers); 3073 if (wback) 3074 { 3075 offset = addr_byte_size * BitCount (registers); 3076 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3077 context.SetImmediateSigned (offset); 3078 addr_t data = address + offset; 3079 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3080 return false; 3081 } 3082 } 3083 return true; 3084} 3085 3086// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 3087// from a base register. The consecutive memory locations end at this address, and the address just below the lowest 3088// of those locations can optionally be written back to the base register. 3089bool 3090EmulateInstructionARM::EmulateSTMDA (ARMEncoding encoding) 3091{ 3092#if 0 3093 if ConditionPassed() then 3094 EncodingSpecificOperations(); 3095 address = R[n] - 4*BitCount(registers) + 4; 3096 3097 for i = 0 to 14 3098 if registers<i> == ’1’ then 3099 if i == n && wback && i != LowestSetBit(registers) then 3100 MemA[address,4] = bits(32) UNKNOWN; 3101 else 3102 MemA[address,4] = R[i]; 3103 address = address + 4; 3104 3105 if registers<15> == ’1’ then 3106 MemA[address,4] = PCStoreValue(); 3107 3108 if wback then R[n] = R[n] - 4*BitCount(registers); 3109#endif 3110 3111 bool success = false; 3112 const uint32_t opcode = OpcodeAsUnsigned (&success); 3113 if (!success) 3114 return false; 3115 3116 if (ConditionPassed ()) 3117 { 3118 uint32_t n; 3119 uint32_t registers = 0; 3120 bool wback; 3121 const uint32_t addr_byte_size = GetAddressByteSize(); 3122 3123 // EncodingSpecificOperations(); 3124 switch (encoding) 3125 { 3126 case eEncodingA1: 3127 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3128 n = Bits32 (opcode, 19, 16); 3129 registers = Bits32 (opcode, 15, 0); 3130 wback = BitIsSet (opcode, 21); 3131 3132 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3133 if ((n == 15) || (BitCount (registers) < 1)) 3134 return false; 3135 break; 3136 default: 3137 return false; 3138 } 3139 3140 // address = R[n] - 4*BitCount(registers) + 4; 3141 int32_t offset = 0; 3142 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3143 if (!success) 3144 return false; 3145 3146 address = address - (addr_byte_size * BitCount (registers)) + 4; 3147 3148 EmulateInstruction::Context context; 3149 context.type = EmulateInstruction::eContextRegisterStore; 3150 Register base_reg; 3151 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3152 3153 // for i = 0 to 14 3154 for (int i = 0; i < 14; ++i) 3155 { 3156 int lowest_bit_set = 14; 3157 // if registers<i> == ’1’ then 3158 if (BitIsSet (registers, i)) 3159 { 3160 if (i < lowest_bit_set) 3161 lowest_bit_set = i; 3162 //if i == n && wback && i != LowestSetBit(registers) then 3163 if ((i == n) && wback && (i != lowest_bit_set)) 3164 // MemA[address,4] = bits(32) UNKNOWN; 3165 WriteBits32UnknownToMemory (address + offset); 3166 else 3167 { 3168 // MemA[address,4] = R[i]; 3169 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3170 if (!success) 3171 return false; 3172 3173 Register data_reg; 3174 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3175 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3176 if (!WriteMemoryUnsigned (context, address + offset, data, addr_byte_size)) 3177 return false; 3178 } 3179 3180 // address = address + 4; 3181 offset += addr_byte_size; 3182 } 3183 } 3184 3185 // if registers<15> == ’1’ then 3186 // MemA[address,4] = PCStoreValue(); 3187 if (BitIsSet (registers, 15)) 3188 { 3189 Register pc_reg; 3190 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3191 context.SetRegisterPlusOffset (pc_reg, 8); 3192 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3193 if (!success) 3194 return false; 3195 3196 if (!WriteMemoryUnsigned (context, address + offset, pc + 8, addr_byte_size)) 3197 return false; 3198 } 3199 3200 // if wback then R[n] = R[n] - 4*BitCount(registers); 3201 if (wback) 3202 { 3203 offset = (addr_byte_size * BitCount (registers)) * -1; 3204 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3205 context.SetImmediateSigned (offset); 3206 addr_t data = address + offset; 3207 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3208 return false; 3209 } 3210 } 3211 return true; 3212} 3213 3214// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 3215// from a base register. The consecutive memory locations end just below this address, and the address of the first of 3216// those locations can optionally be written back to the base register. 3217bool 3218EmulateInstructionARM::EmulateSTMDB (ARMEncoding encoding) 3219{ 3220#if 0 3221 if ConditionPassed() then 3222 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3223 address = R[n] - 4*BitCount(registers); 3224 3225 for i = 0 to 14 3226 if registers<i> == ’1’ then 3227 if i == n && wback && i != LowestSetBit(registers) then 3228 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 3229 else 3230 MemA[address,4] = R[i]; 3231 address = address + 4; 3232 3233 if registers<15> == ’1’ then // Only possible for encoding A1 3234 MemA[address,4] = PCStoreValue(); 3235 3236 if wback then R[n] = R[n] - 4*BitCount(registers); 3237#endif 3238 3239 3240 bool success = false; 3241 const uint32_t opcode = OpcodeAsUnsigned (&success); 3242 if (!success) 3243 return false; 3244 3245 if (ConditionPassed ()) 3246 { 3247 uint32_t n; 3248 uint32_t registers = 0; 3249 bool wback; 3250 const uint32_t addr_byte_size = GetAddressByteSize(); 3251 3252 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3253 switch (encoding) 3254 { 3255 case eEncodingT1: 3256 // if W == ’1’ && Rn == ’1101’ then SEE PUSH; 3257 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 3258 { 3259 // See PUSH 3260 } 3261 // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’); 3262 n = Bits32 (opcode, 19, 16); 3263 registers = Bits32 (opcode, 15, 0); 3264 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 3265 wback = BitIsSet (opcode, 21); 3266 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 3267 if ((n == 15) || BitCount (registers) < 2) 3268 return false; 3269 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 3270 if (wback && BitIsSet (registers, n)) 3271 return false; 3272 break; 3273 3274 case eEncodingA1: 3275 // if W == ’1’ && Rn == ’1101’ && BitCount(register_list) >= 2 then SEE PUSH; 3276 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 3277 { 3278 // See Push 3279 } 3280 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3281 n = Bits32 (opcode, 19, 16); 3282 registers = Bits32 (opcode, 15, 0); 3283 wback = BitIsSet (opcode, 21); 3284 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3285 if ((n == 15) || BitCount (registers) < 1) 3286 return false; 3287 break; 3288 3289 default: 3290 return false; 3291 } 3292 3293 // address = R[n] - 4*BitCount(registers); 3294 3295 int32_t offset = 0; 3296 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3297 if (!success) 3298 return false; 3299 3300 address = address - (addr_byte_size * BitCount (registers)); 3301 3302 EmulateInstruction::Context context; 3303 context.type = EmulateInstruction::eContextRegisterStore; 3304 Register base_reg; 3305 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3306 3307 // for i = 0 to 14 3308 for (int i = 0; i < 14; ++i) 3309 { 3310 uint32_t lowest_set_bit = 14; 3311 // if registers<i> == ’1’ then 3312 if (BitIsSet (registers, i)) 3313 { 3314 if (i < lowest_set_bit) 3315 lowest_set_bit = i; 3316 // if i == n && wback && i != LowestSetBit(registers) then 3317 if ((i == n) && wback && (i != lowest_set_bit)) 3318 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 3319 WriteBits32UnknownToMemory (address + offset); 3320 else 3321 { 3322 // MemA[address,4] = R[i]; 3323 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3324 if (!success) 3325 return false; 3326 3327 Register data_reg; 3328 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3329 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3330 if (!WriteMemoryUnsigned (context, address + offset, data, addr_byte_size)) 3331 return false; 3332 } 3333 3334 // address = address + 4; 3335 offset += addr_byte_size; 3336 } 3337 } 3338 3339 // if registers<15> == ’1’ then // Only possible for encoding A1 3340 // MemA[address,4] = PCStoreValue(); 3341 if (BitIsSet (registers, 15)) 3342 { 3343 Register pc_reg; 3344 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3345 context.SetRegisterPlusOffset (pc_reg, 8); 3346 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3347 if (!success) 3348 return false; 3349 3350 if (!WriteMemoryUnsigned (context, address + offset, pc + 8, addr_byte_size)) 3351 return false; 3352 } 3353 3354 // if wback then R[n] = R[n] - 4*BitCount(registers); 3355 if (wback) 3356 { 3357 offset = (addr_byte_size * BitCount (registers)) * -1; 3358 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3359 context.SetImmediateSigned (offset); 3360 addr_t data = address + offset; 3361 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3362 return false; 3363 } 3364 } 3365 return true; 3366} 3367 3368// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 3369// from a base register. The consecutive memory locations start just above this address, and the address of the last 3370// of those locations can optionally be written back to the base register. 3371bool 3372EmulateInstructionARM::EmulateSTMIB (ARMEncoding encoding) 3373{ 3374#if 0 3375 if ConditionPassed() then 3376 EncodingSpecificOperations(); 3377 address = R[n] + 4; 3378 3379 for i = 0 to 14 3380 if registers<i> == ’1’ then 3381 if i == n && wback && i != LowestSetBit(registers) then 3382 MemA[address,4] = bits(32) UNKNOWN; 3383 else 3384 MemA[address,4] = R[i]; 3385 address = address + 4; 3386 3387 if registers<15> == ’1’ then 3388 MemA[address,4] = PCStoreValue(); 3389 3390 if wback then R[n] = R[n] + 4*BitCount(registers); 3391#endif 3392 3393 bool success = false; 3394 const uint32_t opcode = OpcodeAsUnsigned (&success); 3395 if (!success) 3396 return false; 3397 3398 if (ConditionPassed()) 3399 { 3400 uint32_t n; 3401 uint32_t registers = 0; 3402 bool wback; 3403 const uint32_t addr_byte_size = GetAddressByteSize(); 3404 3405 // EncodingSpecificOperations(); 3406 switch (encoding) 3407 { 3408 case eEncodingA1: 3409 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3410 n = Bits32 (opcode, 19, 16); 3411 registers = Bits32 (opcode, 15, 0); 3412 wback = BitIsSet (opcode, 21); 3413 3414 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3415 if ((n == 15) && (BitCount (registers) < 1)) 3416 return false; 3417 break; 3418 default: 3419 return false; 3420 } 3421 // address = R[n] + 4; 3422 3423 int32_t offset = 0; 3424 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3425 if (!success) 3426 return false; 3427 3428 address = address + addr_byte_size; 3429 3430 EmulateInstruction::Context context; 3431 context.type = EmulateInstruction::eContextRegisterStore; 3432 Register base_reg; 3433 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3434 3435 uint32_t lowest_set_bit = 14; 3436 // for i = 0 to 14 3437 for (int i = 0; i < 14; ++i) 3438 { 3439 // if registers<i> == ’1’ then 3440 if (BitIsSet (registers, i)) 3441 { 3442 if (i < lowest_set_bit) 3443 lowest_set_bit = i; 3444 // if i == n && wback && i != LowestSetBit(registers) then 3445 if ((i == n) && wback && (i != lowest_set_bit)) 3446 // MemA[address,4] = bits(32) UNKNOWN; 3447 WriteBits32UnknownToMemory (address + offset); 3448 // else 3449 else 3450 { 3451 // MemA[address,4] = R[i]; 3452 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3453 if (!success) 3454 return false; 3455 3456 Register data_reg; 3457 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3458 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3459 if (!WriteMemoryUnsigned (context, address + offset, data, addr_byte_size)) 3460 return false; 3461 } 3462 3463 // address = address + 4; 3464 offset += addr_byte_size; 3465 } 3466 } 3467 3468 // if registers<15> == ’1’ then 3469 // MemA[address,4] = PCStoreValue(); 3470 if (BitIsSet (registers, 15)) 3471 { 3472 Register pc_reg; 3473 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3474 context.SetRegisterPlusOffset (pc_reg, 8); 3475 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3476 if (!success) 3477 return false; 3478 3479 if (!WriteMemoryUnsigned (context, address + offset, pc + 8, addr_byte_size)) 3480 return false; 3481 } 3482 3483 // if wback then R[n] = R[n] + 4*BitCount(registers); 3484 if (wback) 3485 { 3486 offset = addr_byte_size * BitCount (registers); 3487 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3488 context.SetImmediateSigned (offset); 3489 addr_t data = address + offset; 3490 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3491 return false; 3492 } 3493 } 3494 return true; 3495} 3496 3497// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word 3498// from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 3499bool 3500EmulateInstructionARM::EmulateSTRThumb (ARMEncoding encoding) 3501{ 3502#if 0 3503 if ConditionPassed() then 3504 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3505 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3506 address = if index then offset_addr else R[n]; 3507 if UnalignedSupport() || address<1:0> == ’00’ then 3508 MemU[address,4] = R[t]; 3509 else // Can only occur before ARMv7 3510 MemU[address,4] = bits(32) UNKNOWN; 3511 if wback then R[n] = offset_addr; 3512#endif 3513 3514 bool success = false; 3515 const uint32_t opcode = OpcodeAsUnsigned (&success); 3516 if (!success) 3517 return false; 3518 3519 if (ConditionPassed()) 3520 { 3521 const uint32_t addr_byte_size = GetAddressByteSize(); 3522 3523 uint32_t t; 3524 uint32_t n; 3525 uint32_t imm32; 3526 bool index; 3527 bool add; 3528 bool wback; 3529 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 3530 switch (encoding) 3531 { 3532 case eEncodingT1: 3533 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:’00’, 32); 3534 t = Bits32 (opcode, 2, 0); 3535 n = Bits32 (opcode, 5, 3); 3536 imm32 = Bits32 (opcode, 10, 6) << 2; 3537 3538 // index = TRUE; add = TRUE; wback = FALSE; 3539 index = true; 3540 add = false; 3541 wback = false; 3542 break; 3543 3544 case eEncodingT2: 3545 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:’00’, 32); 3546 t = Bits32 (opcode, 10, 8); 3547 n = 13; 3548 imm32 = Bits32 (opcode, 7, 0) << 2; 3549 3550 // index = TRUE; add = TRUE; wback = FALSE; 3551 index = true; 3552 add = true; 3553 wback = false; 3554 break; 3555 3556 case eEncodingT3: 3557 // if Rn == ’1111’ then UNDEFINED; 3558 if (Bits32 (opcode, 19, 16) == 15) 3559 return false; 3560 3561 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3562 t = Bits32 (opcode, 15, 12); 3563 n = Bits32 (opcode, 19, 16); 3564 imm32 = Bits32 (opcode, 11, 0); 3565 3566 // index = TRUE; add = TRUE; wback = FALSE; 3567 index = true; 3568 add = true; 3569 wback = false; 3570 3571 // if t == 15 then UNPREDICTABLE; 3572 if (t == 15) 3573 return false; 3574 break; 3575 3576 case eEncodingT4: 3577 // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRT; 3578 // if Rn == ’1101’ && P == ’1’ && U == ’0’ && W == ’1’ && imm8 == ’00000100’ then SEE PUSH; 3579 // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED; 3580 if ((Bits32 (opcode, 19, 16) == 15) 3581 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 3582 return false; 3583 3584 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 3585 t = Bits32 (opcode, 15, 12); 3586 n = Bits32 (opcode, 19, 16); 3587 imm32 = Bits32 (opcode, 7, 0); 3588 3589 // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’); 3590 index = BitIsSet (opcode, 10); 3591 add = BitIsSet (opcode, 9); 3592 wback = BitIsSet (opcode, 8); 3593 3594 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 3595 if ((t == 15) || (wback && (n == t))) 3596 return false; 3597 break; 3598 3599 default: 3600 return false; 3601 } 3602 3603 addr_t offset_addr; 3604 addr_t address; 3605 3606 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3607 uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3608 if (!success) 3609 return false; 3610 3611 if (add) 3612 offset_addr = base_address + imm32; 3613 else 3614 offset_addr = base_address - imm32; 3615 3616 // address = if index then offset_addr else R[n]; 3617 if (index) 3618 address = offset_addr; 3619 else 3620 address = base_address; 3621 3622 EmulateInstruction::Context context; 3623 context.type = eContextRegisterStore; 3624 Register base_reg; 3625 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3626 3627 // if UnalignedSupport() || address<1:0> == ’00’ then 3628 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 3629 { 3630 // MemU[address,4] = R[t]; 3631 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 3632 if (!success) 3633 return false; 3634 3635 Register data_reg; 3636 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t); 3637 int32_t offset = address - base_address; 3638 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3639 if (!WriteMemoryUnsigned (context, address, data, addr_byte_size)) 3640 return false; 3641 } 3642 else 3643 { 3644 // MemU[address,4] = bits(32) UNKNOWN; 3645 WriteBits32UnknownToMemory (address); 3646 } 3647 3648 // if wback then R[n] = offset_addr; 3649 if (wback) 3650 { 3651 context.type = eContextRegisterLoad; 3652 context.SetAddress (offset_addr); 3653 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 3654 return false; 3655 } 3656 } 3657 return true; 3658} 3659 3660EmulateInstructionARM::ARMOpcode* 3661EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) 3662{ 3663 static ARMOpcode 3664 g_arm_opcodes[] = 3665 { 3666 //---------------------------------------------------------------------- 3667 // Prologue instructions 3668 //---------------------------------------------------------------------- 3669 3670 // push register(s) 3671 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePush, "push <registers>" }, 3672 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePush, "push <register>" }, 3673 3674 // set r7 to point to a stack offset 3675 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #<const>" }, 3676 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubR7IPImmediate, "sub r7, ip, #<const>"}, 3677 // copy the stack pointer to ip 3678 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMovRdSP, "mov ip, sp" }, 3679 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add ip, sp, #<const>" }, 3680 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubIPSPImmediate, "sub ip, sp, #<const>"}, 3681 3682 // adjust the stack pointer 3683 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub sp, sp, #<const>"}, 3684 3685 // push one register 3686 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 3687 { 0x0fff0000, 0x052d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 3688 3689 // vector push consecutive extension register(s) 3690 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 3691 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 3692 3693 //---------------------------------------------------------------------- 3694 // Epilogue instructions 3695 //---------------------------------------------------------------------- 3696 3697 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePop, "pop <registers>"}, 3698 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePop, "pop <register>"}, 3699 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 3700 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 3701 3702 //---------------------------------------------------------------------- 3703 // Supervisor Call (previously Software Interrupt) 3704 //---------------------------------------------------------------------- 3705 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 3706 3707 //---------------------------------------------------------------------- 3708 // Branch instructions 3709 //---------------------------------------------------------------------- 3710 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "b #imm24"}, 3711 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 3712 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 3713 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 3714 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 3715 // for example, "bx lr" 3716 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 3717 3718 //---------------------------------------------------------------------- 3719 // Data-processing instructions 3720 //---------------------------------------------------------------------- 3721 // move bitwise not 3722 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMvnRdImm, "mvn{s} <Rd>, #<const>"}, 3723 // asr (immediate) 3724 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 3725 // asr (immediate) 3726 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 3727 3728 //---------------------------------------------------------------------- 3729 // Load instructions 3730 //---------------------------------------------------------------------- 3731 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 3732 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 3733 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 3734 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 3735 3736 //---------------------------------------------------------------------- 3737 // Store instructions 3738 //---------------------------------------------------------------------- 3739 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 3740 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 3741 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 3742 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" } 3743 3744 3745 }; 3746 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 3747 3748 for (size_t i=0; i<k_num_arm_opcodes; ++i) 3749 { 3750 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value) 3751 return &g_arm_opcodes[i]; 3752 } 3753 return NULL; 3754} 3755 3756 3757EmulateInstructionARM::ARMOpcode* 3758EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) 3759{ 3760 3761 static ARMOpcode 3762 g_thumb_opcodes[] = 3763 { 3764 //---------------------------------------------------------------------- 3765 // Prologue instructions 3766 //---------------------------------------------------------------------- 3767 3768 // push register(s) 3769 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePush, "push <registers>" }, 3770 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <registers>" }, 3771 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <register>" }, 3772 3773 // set r7 to point to a stack offset 3774 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #imm" }, 3775 // copy the stack pointer to r7 3776 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdSP, "mov r7, sp" }, 3777 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 3778 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovLowHigh, "mov r0-r7, r8-r15" }, 3779 3780 // PC-relative load into register (see also EmulateAddSPRm) 3781 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 3782 3783 // adjust the stack pointer 3784 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPRm, "add sp, <Rm>"}, 3785 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSubSPImmdiate, "add sp, sp, #imm"}, 3786 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub.w sp, sp, #<const>"}, 3787 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "subw sp, sp, #imm12"}, 3788 3789 // vector push consecutive extension register(s) 3790 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 3791 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 3792 3793 //---------------------------------------------------------------------- 3794 // Epilogue instructions 3795 //---------------------------------------------------------------------- 3796 3797 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPImmediate, "add sp, #imm"}, 3798 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePop, "pop <registers>"}, 3799 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <registers>" }, 3800 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <register>" }, 3801 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 3802 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 3803 3804 //---------------------------------------------------------------------- 3805 // Supervisor Call (previously Software Interrupt) 3806 //---------------------------------------------------------------------- 3807 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 3808 3809 //---------------------------------------------------------------------- 3810 // If Then makes up to four following instructions conditional. 3811 //---------------------------------------------------------------------- 3812 { 0xffffff00, 0x0000bf00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 3813 3814 //---------------------------------------------------------------------- 3815 // Branch instructions 3816 //---------------------------------------------------------------------- 3817 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 3818 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 3819 { 0xffff8000, 0x0000e000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"}, 3820 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 3821 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"}, 3822 // J1 == J2 == 1 3823 { 0xf800f800, 0xf000f800, ARMV4T_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 3824 // J1 == J2 == 1 3825 { 0xf800e800, 0xf000e800, ARMV5_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 3826 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 3827 // for example, "bx lr" 3828 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 3829 // compare and branch 3830 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 3831 3832 //---------------------------------------------------------------------- 3833 // Data-processing instructions 3834 //---------------------------------------------------------------------- 3835 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 3836 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdnRm, "add <Rdn>, <Rm>"}, 3837 // move from high register to high register 3838 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdRm, "mov<c> <Rd>, <Rm>"}, 3839 // move from low register to low register 3840 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMovRdRm, "movs <Rd>, <Rm>"}, 3841 // move immediate 3842 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdImm, "movs|mov<c> <Rd>, #imm8"}, 3843 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMovRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 3844 // move bitwise not 3845 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateMvnRdImm, "mvn{s} <Rd>, #<const>"}, 3846 // compare a register with immediate 3847 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCmpRnImm, "cmp<c> <Rn>, #imm8"}, 3848 // compare Rn with Rm (Rn and Rm both from r0-r7) 3849 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCmpRnRm, "cmp<c> <Rn>, <Rm>"}, 3850 // compare Rn with Rm (Rn and Rm not both from r0-r7) 3851 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateCmpRnRm, "cmp<c> <Rn>, <Rm>"}, 3852 // asr (immediate) 3853 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 3854 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 3855 // asr (register) 3856 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 3857 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 3858 3859 //---------------------------------------------------------------------- 3860 // Load instructions 3861 //---------------------------------------------------------------------- 3862 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 3863 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 3864 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 3865 { 0xfffff800, 0x00006800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 3866 // Thumb2 PC-relative load into register 3867 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 3868 3869 //---------------------------------------------------------------------- 3870 // Store instructions 3871 //---------------------------------------------------------------------- 3872 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 3873 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 3874 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 3875 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt> [<Rn>{,#<imm>}]" }, 3876 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt> [SP,#<imm>]" }, 3877 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt [<Rn>,#<imm12>]" }, 3878 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt> [<Rn>,#+/-<imm8>]" } 3879 }; 3880 3881 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 3882 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 3883 { 3884 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value) 3885 return &g_thumb_opcodes[i]; 3886 } 3887 return NULL; 3888} 3889 3890bool 3891EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 3892{ 3893 m_arm_isa = 0; 3894 const char *arch_cstr = arch.AsCString (); 3895 if (arch_cstr) 3896 { 3897 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 3898 else if (0 == ::strcasecmp(arch_cstr, "armv4")) m_arm_isa = ARMv4; 3899 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 3900 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 3901 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 3902 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 3903 else if (0 == ::strcasecmp(arch_cstr, "armv6")) m_arm_isa = ARMv6; 3904 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 3905 else if (0 == ::strcasecmp(arch_cstr, "armv7")) m_arm_isa = ARMv7; 3906 else if (0 == ::strcasecmp(arch_cstr, "armv8")) m_arm_isa = ARMv8; 3907 } 3908 return m_arm_isa != 0; 3909} 3910 3911 3912bool 3913EmulateInstructionARM::ReadInstruction () 3914{ 3915 bool success = false; 3916 m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 3917 if (success) 3918 { 3919 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 3920 if (success) 3921 { 3922 Context read_inst_context; 3923 read_inst_context.type = eContextReadOpcode; 3924 read_inst_context.SetNoArgs (); 3925 3926 if (m_inst_cpsr & MASK_CPSR_T) 3927 { 3928 m_inst_mode = eModeThumb; 3929 uint32_t thumb_opcode = ReadMemoryUnsigned(read_inst_context, pc, 2, 0, &success); 3930 3931 if (success) 3932 { 3933 if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0)) 3934 { 3935 m_inst.opcode_type = eOpcode16; 3936 m_inst.opcode.inst16 = thumb_opcode; 3937 } 3938 else 3939 { 3940 m_inst.opcode_type = eOpcode32; 3941 m_inst.opcode.inst32 = (thumb_opcode << 16) | ReadMemoryUnsigned(read_inst_context, pc + 2, 2, 0, &success); 3942 } 3943 } 3944 } 3945 else 3946 { 3947 m_inst_mode = eModeARM; 3948 m_inst.opcode_type = eOpcode32; 3949 m_inst.opcode.inst32 = ReadMemoryUnsigned(read_inst_context, pc, 4, 0, &success); 3950 } 3951 } 3952 } 3953 if (!success) 3954 { 3955 m_inst_mode = eModeInvalid; 3956 m_inst_pc = LLDB_INVALID_ADDRESS; 3957 } 3958 return success; 3959} 3960 3961uint32_t 3962EmulateInstructionARM::ArchVersion () 3963{ 3964 return m_arm_isa; 3965} 3966 3967bool 3968EmulateInstructionARM::ConditionPassed () 3969{ 3970 if (m_inst_cpsr == 0) 3971 return false; 3972 3973 const uint32_t cond = CurrentCond (); 3974 3975 if (cond == UINT32_MAX) 3976 return false; 3977 3978 bool result = false; 3979 switch (UnsignedBits(cond, 3, 1)) 3980 { 3981 case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break; 3982 case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break; 3983 case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break; 3984 case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break; 3985 case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break; 3986 case 5: 3987 { 3988 bool n = (m_inst_cpsr & MASK_CPSR_N); 3989 bool v = (m_inst_cpsr & MASK_CPSR_V); 3990 result = n == v; 3991 } 3992 break; 3993 case 6: 3994 { 3995 bool n = (m_inst_cpsr & MASK_CPSR_N); 3996 bool v = (m_inst_cpsr & MASK_CPSR_V); 3997 result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0); 3998 } 3999 break; 4000 case 7: 4001 result = true; 4002 break; 4003 } 4004 4005 if (cond & 1) 4006 result = !result; 4007 return result; 4008} 4009 4010uint32_t 4011EmulateInstructionARM::CurrentCond () 4012{ 4013 switch (m_inst_mode) 4014 { 4015 default: 4016 case eModeInvalid: 4017 break; 4018 4019 case eModeARM: 4020 return UnsignedBits(m_inst.opcode.inst32, 31, 28); 4021 4022 case eModeThumb: 4023 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 4024 // 'cond' field of the encoding. 4025 if (m_inst.opcode_type == eOpcode16 && 4026 Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d && 4027 Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f) 4028 { 4029 return Bits32(m_inst.opcode.inst16, 11, 7); 4030 } 4031 else if (m_inst.opcode_type == eOpcode32 && 4032 Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e && 4033 Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 && 4034 Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 && 4035 Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d) 4036 { 4037 return Bits32(m_inst.opcode.inst32, 25, 22); 4038 } 4039 4040 return m_it_session.GetCond(); 4041 } 4042 return UINT32_MAX; // Return invalid value 4043} 4044 4045bool 4046EmulateInstructionARM::InITBlock() 4047{ 4048 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 4049} 4050 4051bool 4052EmulateInstructionARM::LastInITBlock() 4053{ 4054 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 4055} 4056 4057bool 4058EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 4059{ 4060 addr_t target; 4061 4062 // Check the current instruction set. 4063 if (CurrentInstrSet() == eModeARM) 4064 target = addr & 0xfffffffc; 4065 else 4066 target = addr & 0xfffffffe; 4067 4068 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 4069 return false; 4070 4071 return true; 4072} 4073 4074// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 4075bool 4076EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 4077{ 4078 addr_t target; 4079 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 4080 // we want to record it and issue a WriteRegister callback so the clients 4081 // can track the mode changes accordingly. 4082 bool cpsr_changed = false; 4083 4084 if (BitIsSet(addr, 0)) 4085 { 4086 if (CurrentInstrSet() != eModeThumb) 4087 { 4088 SelectInstrSet(eModeThumb); 4089 cpsr_changed = true; 4090 } 4091 target = addr & 0xfffffffe; 4092 context.SetMode (eModeThumb); 4093 } 4094 else if (BitIsClear(addr, 1)) 4095 { 4096 if (CurrentInstrSet() != eModeARM) 4097 { 4098 SelectInstrSet(eModeARM); 4099 cpsr_changed = true; 4100 } 4101 target = addr & 0xfffffffc; 4102 context.SetMode (eModeARM); 4103 } 4104 else 4105 return false; // address<1:0> == '10' => UNPREDICTABLE 4106 4107 if (cpsr_changed) 4108 { 4109 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 4110 return false; 4111 } 4112 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 4113 return false; 4114 4115 return true; 4116} 4117 4118// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 4119bool 4120EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 4121{ 4122 if (ArchVersion() >= ARMv5T) 4123 return BXWritePC(context, addr); 4124 else 4125 return BranchWritePC((const Context)context, addr); 4126} 4127 4128// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 4129bool 4130EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 4131{ 4132 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 4133 return BXWritePC(context, addr); 4134 else 4135 return BranchWritePC((const Context)context, addr); 4136} 4137 4138EmulateInstructionARM::Mode 4139EmulateInstructionARM::CurrentInstrSet () 4140{ 4141 return m_inst_mode; 4142} 4143 4144// Set the 'T' bit of our CPSR. The m_inst_mode gets updated when the next 4145// ReadInstruction() is performed. This function has a side effect of updating 4146// the m_new_inst_cpsr member variable if necessary. 4147bool 4148EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 4149{ 4150 m_new_inst_cpsr = m_inst_cpsr; 4151 switch (arm_or_thumb) 4152 { 4153 default: 4154 return false; 4155 eModeARM: 4156 // Clear the T bit. 4157 m_new_inst_cpsr &= ~MASK_CPSR_T; 4158 break; 4159 eModeThumb: 4160 // Set the T bit. 4161 m_new_inst_cpsr |= MASK_CPSR_T; 4162 break; 4163 } 4164 return true; 4165} 4166 4167// This function returns TRUE if the processor currently provides support for 4168// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 4169// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 4170bool 4171EmulateInstructionARM::UnalignedSupport() 4172{ 4173 return (ArchVersion() >= ARMv7); 4174} 4175 4176// The main addition and subtraction instructions can produce status information 4177// about both unsigned carry and signed overflow conditions. This status 4178// information can be used to synthesize multi-word additions and subtractions. 4179EmulateInstructionARM::AddWithCarryResult 4180EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 4181{ 4182 uint32_t result; 4183 uint8_t carry_out; 4184 uint8_t overflow; 4185 4186 uint64_t unsigned_sum = x + y + carry_in; 4187 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 4188 4189 result = UnsignedBits(unsigned_sum, 31, 0); 4190 carry_out = (result == unsigned_sum ? 0 : 1); 4191 overflow = ((int32_t)result == signed_sum ? 0 : 1); 4192 4193 AddWithCarryResult res = { result, carry_out, overflow }; 4194 return res; 4195} 4196 4197bool 4198EmulateInstructionARM::EvaluateInstruction () 4199{ 4200 // Advance the ITSTATE bits to their values for the next instruction. 4201 if (m_inst_mode == eModeThumb && m_it_session.InITBlock()) 4202 m_it_session.ITAdvance(); 4203 4204 return false; 4205} 4206