EmulateInstructionARM.cpp revision bf6ad173895183797cbd0ebd18710b2364a2c4c8
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 "EmulateInstructionARM.h" 11#include "lldb/Core/ConstString.h" 12 13#include "Plugins/Process/Utility/ARMDefines.h" 14#include "Plugins/Process/Utility/ARMUtils.h" 15#include "Utility/ARM_DWARF_Registers.h" 16 17#include "llvm/Support/MathExtras.h" // for SignExtend32 template function 18 // and CountTrailingZeros_32 function 19 20using namespace lldb; 21using namespace lldb_private; 22 23static inline uint32_t Align(uint32_t val, uint32_t alignment) 24{ 25 return alignment * (val / alignment); 26} 27 28//---------------------------------------------------------------------- 29// 30// ITSession implementation 31// 32//---------------------------------------------------------------------- 33 34// A8.6.50 35// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 36static unsigned short CountITSize(unsigned ITMask) { 37 // First count the trailing zeros of the IT mask. 38 unsigned TZ = llvm::CountTrailingZeros_32(ITMask); 39 if (TZ > 3) 40 { 41 printf("Encoding error: IT Mask '0000'\n"); 42 return 0; 43 } 44 return (4 - TZ); 45} 46 47// Init ITState. Note that at least one bit is always 1 in mask. 48bool ITSession::InitIT(unsigned short bits7_0) 49{ 50 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 51 if (ITCounter == 0) 52 return false; 53 54 // A8.6.50 IT 55 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 56 if (FirstCond == 0xF) 57 { 58 printf("Encoding error: IT FirstCond '1111'\n"); 59 return false; 60 } 61 if (FirstCond == 0xE && ITCounter != 1) 62 { 63 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 64 return false; 65 } 66 67 ITState = bits7_0; 68 return true; 69} 70 71// Update ITState if necessary. 72void ITSession::ITAdvance() 73{ 74 assert(ITCounter); 75 --ITCounter; 76 if (ITCounter == 0) 77 ITState = 0; 78 else 79 { 80 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 81 SetBits32(ITState, 4, 0, NewITState4_0); 82 } 83} 84 85// Return true if we're inside an IT Block. 86bool ITSession::InITBlock() 87{ 88 return ITCounter != 0; 89} 90 91// Return true if we're the last instruction inside an IT Block. 92bool ITSession::LastInITBlock() 93{ 94 return ITCounter == 1; 95} 96 97// Get condition bits for the current thumb instruction. 98uint32_t ITSession::GetCond() 99{ 100 if (InITBlock()) 101 return Bits32(ITState, 7, 4); 102 else 103 return COND_AL; 104} 105 106// ARM constants used during decoding 107#define REG_RD 0 108#define LDM_REGLIST 1 109#define PC_REG 15 110#define PC_REGLIST_BIT 0x8000 111 112#define ARMv4 (1u << 0) 113#define ARMv4T (1u << 1) 114#define ARMv5T (1u << 2) 115#define ARMv5TE (1u << 3) 116#define ARMv5TEJ (1u << 4) 117#define ARMv6 (1u << 5) 118#define ARMv6K (1u << 6) 119#define ARMv6T2 (1u << 7) 120#define ARMv7 (1u << 8) 121#define ARMv8 (1u << 9) 122#define ARMvAll (0xffffffffu) 123 124#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 125#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 126#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8) 127 128//---------------------------------------------------------------------- 129// 130// EmulateInstructionARM implementation 131// 132//---------------------------------------------------------------------- 133 134void 135EmulateInstructionARM::Initialize () 136{ 137} 138 139void 140EmulateInstructionARM::Terminate () 141{ 142} 143 144// Push Multiple Registers stores multiple registers to the stack, storing to 145// consecutive memory locations ending just below the address in SP, and updates 146// SP to point to the start of the stored data. 147bool 148EmulateInstructionARM::EmulatePush (ARMEncoding encoding) 149{ 150#if 0 151 // ARM pseudo code... 152 if (ConditionPassed()) 153 { 154 EncodingSpecificOperations(); 155 NullCheckIfThumbEE(13); 156 address = SP - 4*BitCount(registers); 157 158 for (i = 0 to 14) 159 { 160 if (registers<i> == ’1’) 161 { 162 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 163 MemA[address,4] = bits(32) UNKNOWN; 164 else 165 MemA[address,4] = R[i]; 166 address = address + 4; 167 } 168 } 169 170 if (registers<15> == ’1’) // Only possible for encoding A1 or A2 171 MemA[address,4] = PCStoreValue(); 172 173 SP = SP - 4*BitCount(registers); 174 } 175#endif 176 177 bool success = false; 178 const uint32_t opcode = OpcodeAsUnsigned (&success); 179 if (!success) 180 return false; 181 182 if (ConditionPassed()) 183 { 184 const uint32_t addr_byte_size = GetAddressByteSize(); 185 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 186 if (!success) 187 return false; 188 uint32_t registers = 0; 189 uint32_t Rt; // the source register 190 switch (encoding) { 191 case eEncodingT1: 192 registers = Bits32(opcode, 7, 0); 193 // The M bit represents LR. 194 if (Bit32(opcode, 8)) 195 registers |= (1u << 14); 196 // if BitCount(registers) < 1 then UNPREDICTABLE; 197 if (BitCount(registers) < 1) 198 return false; 199 break; 200 case eEncodingT2: 201 // Ignore bits 15 & 13. 202 registers = Bits32(opcode, 15, 0) & ~0xa000; 203 // if BitCount(registers) < 2 then UNPREDICTABLE; 204 if (BitCount(registers) < 2) 205 return false; 206 break; 207 case eEncodingT3: 208 Rt = Bits32(opcode, 15, 12); 209 // if BadReg(t) then UNPREDICTABLE; 210 if (BadReg(Rt)) 211 return false; 212 registers = (1u << Rt); 213 break; 214 case eEncodingA1: 215 registers = Bits32(opcode, 15, 0); 216 // Instead of return false, let's handle the following case as well, 217 // which amounts to pushing one reg onto the full descending stacks. 218 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 219 break; 220 case eEncodingA2: 221 Rt = Bits32(opcode, 15, 12); 222 // if t == 13 then UNPREDICTABLE; 223 if (Rt == dwarf_sp) 224 return false; 225 registers = (1u << Rt); 226 break; 227 default: 228 return false; 229 } 230 addr_t sp_offset = addr_byte_size * BitCount (registers); 231 addr_t addr = sp - sp_offset; 232 uint32_t i; 233 234 EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 }; 235 for (i=0; i<15; ++i) 236 { 237 if (BitIsSet (registers, i)) 238 { 239 context.arg1 = dwarf_r0 + i; // arg1 in the context is the DWARF register number 240 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 241 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, context.arg1, 0, &success); 242 if (!success) 243 return false; 244 if (!WriteMemoryUnsigned (context, addr, reg_value, addr_byte_size)) 245 return false; 246 addr += addr_byte_size; 247 } 248 } 249 250 if (BitIsSet (registers, 15)) 251 { 252 context.arg1 = dwarf_pc; // arg1 in the context is the DWARF register number 253 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 254 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 255 if (!success) 256 return false; 257 if (!WriteMemoryUnsigned (context, addr, pc + 8, addr_byte_size)) 258 return false; 259 } 260 261 context.type = EmulateInstruction::eContextAdjustStackPointer; 262 context.arg0 = eRegisterKindGeneric; 263 context.arg1 = LLDB_REGNUM_GENERIC_SP; 264 context.arg2 = -sp_offset; 265 266 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 267 return false; 268 } 269 return true; 270} 271 272// Pop Multiple Registers loads multiple registers from the stack, loading from 273// consecutive memory locations staring at the address in SP, and updates 274// SP to point just above the loaded data. 275bool 276EmulateInstructionARM::EmulatePop (ARMEncoding encoding) 277{ 278#if 0 279 // ARM pseudo code... 280 if (ConditionPassed()) 281 { 282 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 283 address = SP; 284 for i = 0 to 14 285 if registers<i> == ‘1’ then 286 R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 287 if registers<15> == ‘1’ then 288 if UnalignedAllowed then 289 LoadWritePC(MemU[address,4]); 290 else 291 LoadWritePC(MemA[address,4]); 292 if registers<13> == ‘0’ then SP = SP + 4*BitCount(registers); 293 if registers<13> == ‘1’ then SP = bits(32) UNKNOWN; 294 } 295#endif 296 297 bool success = false; 298 const uint32_t opcode = OpcodeAsUnsigned (&success); 299 if (!success) 300 return false; 301 302 if (ConditionPassed()) 303 { 304 const uint32_t addr_byte_size = GetAddressByteSize(); 305 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 306 if (!success) 307 return false; 308 uint32_t registers = 0; 309 uint32_t Rt; // the destination register 310 switch (encoding) { 311 case eEncodingT1: 312 registers = Bits32(opcode, 7, 0); 313 // The P bit represents PC. 314 if (Bit32(opcode, 8)) 315 registers |= (1u << 15); 316 // if BitCount(registers) < 1 then UNPREDICTABLE; 317 if (BitCount(registers) < 1) 318 return false; 319 break; 320 case eEncodingT2: 321 // Ignore bit 13. 322 registers = Bits32(opcode, 15, 0) & ~0x2000; 323 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 324 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 325 return false; 326 break; 327 case eEncodingT3: 328 Rt = Bits32(opcode, 15, 12); 329 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 330 if (Rt == dwarf_sp) 331 return false; 332 registers = (1u << Rt); 333 break; 334 case eEncodingA1: 335 registers = Bits32(opcode, 15, 0); 336 // Instead of return false, let's handle the following case as well, 337 // which amounts to popping one reg from the full descending stacks. 338 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 339 340 // if registers<13> == ‘1’ && ArchVersion() >= 7 then UNPREDICTABLE; 341 if (Bit32(opcode, 13) && ArchVersion() >= ARMv7) 342 return false; 343 break; 344 case eEncodingA2: 345 Rt = Bits32(opcode, 15, 12); 346 // if t == 13 then UNPREDICTABLE; 347 if (Rt == dwarf_sp) 348 return false; 349 registers = (1u << Rt); 350 break; 351 default: 352 return false; 353 } 354 addr_t sp_offset = addr_byte_size * BitCount (registers); 355 addr_t addr = sp; 356 uint32_t i, data; 357 358 EmulateInstruction::Context context = { EmulateInstruction::eContextPopRegisterOffStack, eRegisterKindDWARF, 0, 0 }; 359 for (i=0; i<15; ++i) 360 { 361 if (BitIsSet (registers, i)) 362 { 363 context.arg1 = dwarf_r0 + i; // arg1 in the context is the DWARF register number 364 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 365 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 366 if (!success) 367 return false; 368 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, context.arg1, data)) 369 return false; 370 addr += addr_byte_size; 371 } 372 } 373 374 if (BitIsSet (registers, 15)) 375 { 376 context.arg1 = dwarf_pc; // arg1 in the context is the DWARF register number 377 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 378 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 379 if (!success) 380 return false; 381 // In ARMv5T and above, this is an interworking branch. 382 if (!LoadWritePC(context, data)) 383 return false; 384 addr += addr_byte_size; 385 } 386 387 context.type = EmulateInstruction::eContextAdjustStackPointer; 388 context.arg0 = eRegisterKindGeneric; 389 context.arg1 = LLDB_REGNUM_GENERIC_SP; 390 context.arg2 = sp_offset; 391 392 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 393 return false; 394 } 395 return true; 396} 397 398// Set r7 or ip to point to saved value residing within the stack. 399// ADD (SP plus immediate) 400bool 401EmulateInstructionARM::EmulateAddRdSPImmediate (ARMEncoding encoding) 402{ 403#if 0 404 // ARM pseudo code... 405 if (ConditionPassed()) 406 { 407 EncodingSpecificOperations(); 408 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 409 if d == 15 then 410 ALUWritePC(result); // setflags is always FALSE here 411 else 412 R[d] = result; 413 if setflags then 414 APSR.N = result<31>; 415 APSR.Z = IsZeroBit(result); 416 APSR.C = carry; 417 APSR.V = overflow; 418 } 419#endif 420 421 bool success = false; 422 const uint32_t opcode = OpcodeAsUnsigned (&success); 423 if (!success) 424 return false; 425 426 if (ConditionPassed()) 427 { 428 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 429 if (!success) 430 return false; 431 uint32_t Rd; // the destination register 432 uint32_t imm32; 433 switch (encoding) { 434 case eEncodingT1: 435 Rd = 7; 436 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 437 break; 438 case eEncodingA1: 439 Rd = Bits32(opcode, 15, 12); 440 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 441 break; 442 default: 443 return false; 444 } 445 addr_t sp_offset = imm32; 446 addr_t addr = sp + sp_offset; // a pointer to the stack area 447 448 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 449 eRegisterKindGeneric, 450 LLDB_REGNUM_GENERIC_SP, 451 sp_offset }; 452 453 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 454 return false; 455 } 456 return true; 457} 458 459// Set r7 or ip to the current stack pointer. 460// MOV (register) 461bool 462EmulateInstructionARM::EmulateMovRdSP (ARMEncoding encoding) 463{ 464#if 0 465 // ARM pseudo code... 466 if (ConditionPassed()) 467 { 468 EncodingSpecificOperations(); 469 result = R[m]; 470 if d == 15 then 471 ALUWritePC(result); // setflags is always FALSE here 472 else 473 R[d] = result; 474 if setflags then 475 APSR.N = result<31>; 476 APSR.Z = IsZeroBit(result); 477 // APSR.C unchanged 478 // APSR.V unchanged 479 } 480#endif 481 482 bool success = false; 483 //const uint32_t opcode = OpcodeAsUnsigned (&success); 484 //if (!success) 485 // return false; 486 487 if (ConditionPassed()) 488 { 489 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 490 if (!success) 491 return false; 492 uint32_t Rd; // the destination register 493 switch (encoding) { 494 case eEncodingT1: 495 Rd = 7; 496 break; 497 case eEncodingA1: 498 Rd = 12; 499 break; 500 default: 501 return false; 502 } 503 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 504 eRegisterKindGeneric, 505 LLDB_REGNUM_GENERIC_SP, 506 0 }; 507 508 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 509 return false; 510 } 511 return true; 512} 513 514// Move from high register (r8-r15) to low register (r0-r7). 515// MOV (register) 516bool 517EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding) 518{ 519 return EmulateMovRdRm (encoding); 520} 521 522// Move from register to register. 523// MOV (register) 524bool 525EmulateInstructionARM::EmulateMovRdRm (ARMEncoding encoding) 526{ 527#if 0 528 // ARM pseudo code... 529 if (ConditionPassed()) 530 { 531 EncodingSpecificOperations(); 532 result = R[m]; 533 if d == 15 then 534 ALUWritePC(result); // setflags is always FALSE here 535 else 536 R[d] = result; 537 if setflags then 538 APSR.N = result<31>; 539 APSR.Z = IsZeroBit(result); 540 // APSR.C unchanged 541 // APSR.V unchanged 542 } 543#endif 544 545 bool success = false; 546 const uint32_t opcode = OpcodeAsUnsigned (&success); 547 if (!success) 548 return false; 549 550 if (ConditionPassed()) 551 { 552 uint32_t Rm; // the source register 553 uint32_t Rd; // the destination register 554 bool setflags; 555 switch (encoding) { 556 case eEncodingT1: 557 Rm = Bits32(opcode, 6, 3); 558 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 1); 559 setflags = false; 560 break; 561 case eEncodingT2: 562 Rm = Bits32(opcode, 5, 3); 563 Rd = Bits32(opcode, 2, 1); 564 setflags = true; 565 break; 566 default: 567 return false; 568 } 569 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 570 if (!success) 571 return false; 572 573 // The context specifies that Rm is to be moved into Rd. 574 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 575 eRegisterKindDWARF, 576 dwarf_r0 + Rm, 577 0 }; 578 579 if (Rd == 15) 580 { 581 if (!ALUWritePC (context, reg_value)) 582 return false; 583 } 584 else 585 { 586 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, reg_value)) 587 return false; 588 if (setflags) 589 { 590 m_new_inst_cpsr = m_inst_cpsr; 591 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(reg_value, CPSR_N)); 592 SetBit32(m_new_inst_cpsr, CPSR_Z, reg_value == 0 ? 1 : 0); 593 if (m_new_inst_cpsr != m_inst_cpsr) 594 { 595 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 596 return false; 597 } 598 } 599 } 600 } 601 return true; 602} 603 604// PC relative immediate load into register, possibly followed by ADD (SP plus register). 605// LDR (literal) 606bool 607EmulateInstructionARM::EmulateLDRRdPCRelative (ARMEncoding encoding) 608{ 609#if 0 610 // ARM pseudo code... 611 if (ConditionPassed()) 612 { 613 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 614 base = Align(PC,4); 615 address = if add then (base + imm32) else (base - imm32); 616 data = MemU[address,4]; 617 if t == 15 then 618 if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE; 619 elsif UnalignedSupport() || address<1:0> = ‘00’ then 620 R[t] = data; 621 else // Can only apply before ARMv7 622 if CurrentInstrSet() == InstrSet_ARM then 623 R[t] = ROR(data, 8*UInt(address<1:0>)); 624 else 625 R[t] = bits(32) UNKNOWN; 626 } 627#endif 628 629 bool success = false; 630 const uint32_t opcode = OpcodeAsUnsigned (&success); 631 if (!success) 632 return false; 633 634 if (ConditionPassed()) 635 { 636 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 637 if (!success) 638 return false; 639 640 // PC relative immediate load context 641 EmulateInstruction::Context context = {EmulateInstruction::eContextRegisterPlusOffset, 642 eRegisterKindGeneric, 643 LLDB_REGNUM_GENERIC_PC, 644 0}; 645 uint32_t Rd; // the destination register 646 uint32_t imm32; // immediate offset from the PC 647 addr_t addr; // the PC relative address 648 uint32_t data; // the literal data value from the PC relative load 649 switch (encoding) { 650 case eEncodingT1: 651 Rd = Bits32(opcode, 10, 8); 652 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 653 addr = pc + 4 + imm32; 654 context.arg2 = 4 + imm32; 655 break; 656 default: 657 return false; 658 } 659 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 660 if (!success) 661 return false; 662 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, data)) 663 return false; 664 } 665 return true; 666} 667 668// An add operation to adjust the SP. 669// ADD (SP plus immediate) 670bool 671EmulateInstructionARM::EmulateAddSPImmediate (ARMEncoding encoding) 672{ 673#if 0 674 // ARM pseudo code... 675 if (ConditionPassed()) 676 { 677 EncodingSpecificOperations(); 678 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 679 if d == 15 then // Can only occur for ARM encoding 680 ALUWritePC(result); // setflags is always FALSE here 681 else 682 R[d] = result; 683 if setflags then 684 APSR.N = result<31>; 685 APSR.Z = IsZeroBit(result); 686 APSR.C = carry; 687 APSR.V = overflow; 688 } 689#endif 690 691 bool success = false; 692 const uint32_t opcode = OpcodeAsUnsigned (&success); 693 if (!success) 694 return false; 695 696 if (ConditionPassed()) 697 { 698 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 699 if (!success) 700 return false; 701 uint32_t imm32; // the immediate operand 702 switch (encoding) { 703 case eEncodingT2: 704 imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 705 break; 706 default: 707 return false; 708 } 709 addr_t sp_offset = imm32; 710 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 711 712 EmulateInstruction::Context context = { EmulateInstruction::eContextAdjustStackPointer, 713 eRegisterKindGeneric, 714 LLDB_REGNUM_GENERIC_SP, 715 sp_offset }; 716 717 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 718 return false; 719 } 720 return true; 721} 722 723// An add operation to adjust the SP. 724// ADD (SP plus register) 725bool 726EmulateInstructionARM::EmulateAddSPRm (ARMEncoding encoding) 727{ 728#if 0 729 // ARM pseudo code... 730 if (ConditionPassed()) 731 { 732 EncodingSpecificOperations(); 733 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 734 (result, carry, overflow) = AddWithCarry(SP, shifted, ‘0’); 735 if d == 15 then 736 ALUWritePC(result); // setflags is always FALSE here 737 else 738 R[d] = result; 739 if setflags then 740 APSR.N = result<31>; 741 APSR.Z = IsZeroBit(result); 742 APSR.C = carry; 743 APSR.V = overflow; 744 } 745#endif 746 747 bool success = false; 748 const uint32_t opcode = OpcodeAsUnsigned (&success); 749 if (!success) 750 return false; 751 752 if (ConditionPassed()) 753 { 754 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 755 if (!success) 756 return false; 757 uint32_t Rm; // the second operand 758 switch (encoding) { 759 case eEncodingT2: 760 Rm = Bits32(opcode, 6, 3); 761 break; 762 default: 763 return false; 764 } 765 int32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 766 if (!success) 767 return false; 768 769 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 770 771 EmulateInstruction::Context context = { EmulateInstruction::eContextAdjustStackPointer, 772 eRegisterKindGeneric, 773 LLDB_REGNUM_GENERIC_SP, 774 reg_value }; 775 776 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 777 return false; 778 } 779 return true; 780} 781 782// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 783// at a PC-relative address, and changes instruction set from ARM to Thumb, or 784// from Thumb to ARM. 785// BLX (immediate) 786bool 787EmulateInstructionARM::EmulateBLXImmediate (ARMEncoding encoding) 788{ 789#if 0 790 // ARM pseudo code... 791 if (ConditionPassed()) 792 { 793 EncodingSpecificOperations(); 794 if CurrentInstrSet() == InstrSet_ARM then 795 LR = PC - 4; 796 else 797 LR = PC<31:1> : '1'; 798 if targetInstrSet == InstrSet_ARM then 799 targetAddress = Align(PC,4) + imm32; 800 else 801 targetAddress = PC + imm32; 802 SelectInstrSet(targetInstrSet); 803 BranchWritePC(targetAddress); 804 } 805#endif 806 807 bool success = false; 808 const uint32_t opcode = OpcodeAsUnsigned (&success); 809 if (!success) 810 return false; 811 812 if (ConditionPassed()) 813 { 814 EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0}; 815 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 816 if (!success) 817 return false; 818 addr_t lr; // next instruction address 819 addr_t target; // target address 820 int32_t imm32; // PC-relative offset 821 switch (encoding) { 822 case eEncodingT1: 823 { 824 lr = (pc + 4) | 1u; // return address 825 uint32_t S = Bit32(opcode, 26); 826 uint32_t imm10 = Bits32(opcode, 25, 16); 827 uint32_t J1 = Bit32(opcode, 13); 828 uint32_t J2 = Bit32(opcode, 11); 829 uint32_t imm11 = Bits32(opcode, 10, 0); 830 uint32_t I1 = !(J1 ^ S); 831 uint32_t I2 = !(J2 ^ S); 832 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 833 imm32 = llvm::SignExtend32<25>(imm25); 834 target = pc + 4 + imm32; 835 context.arg1 = 4 + imm32; // signed offset 836 context.arg2 = eModeThumb; // target instruction set 837 break; 838 } 839 case eEncodingT2: 840 { 841 lr = (pc + 4) | 1u; // return address 842 uint32_t S = Bit32(opcode, 26); 843 uint32_t imm10H = Bits32(opcode, 25, 16); 844 uint32_t J1 = Bit32(opcode, 13); 845 uint32_t J2 = Bit32(opcode, 11); 846 uint32_t imm10L = Bits32(opcode, 10, 1); 847 uint32_t I1 = !(J1 ^ S); 848 uint32_t I2 = !(J2 ^ S); 849 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 850 imm32 = llvm::SignExtend32<25>(imm25); 851 target = Align(pc + 4, 4) + imm32; 852 context.arg1 = 4 + imm32; // signed offset 853 context.arg2 = eModeARM; // target instruction set 854 break; 855 } 856 case eEncodingA1: 857 lr = pc + 4; // return address 858 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 859 target = Align(pc + 8, 4) + imm32; 860 context.arg1 = 8 + imm32; // signed offset 861 context.arg2 = eModeARM; // target instruction set 862 break; 863 case eEncodingA2: 864 lr = pc + 4; // return address 865 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 866 target = pc + 8 + imm32; 867 context.arg1 = 8 + imm32; // signed offset 868 context.arg2 = eModeThumb; // target instruction set 869 break; 870 default: 871 return false; 872 } 873 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 874 return false; 875 if (!BranchWritePC(context, target)) 876 return false; 877 } 878 return true; 879} 880 881// Branch with Link and Exchange (register) calls a subroutine at an address and 882// instruction set specified by a register. 883// BLX (register) 884bool 885EmulateInstructionARM::EmulateBLXRm (ARMEncoding encoding) 886{ 887#if 0 888 // ARM pseudo code... 889 if (ConditionPassed()) 890 { 891 EncodingSpecificOperations(); 892 target = R[m]; 893 if CurrentInstrSet() == InstrSet_ARM then 894 next_instr_addr = PC - 4; 895 LR = next_instr_addr; 896 else 897 next_instr_addr = PC - 2; 898 LR = next_instr_addr<31:1> : ‘1’; 899 BXWritePC(target); 900 } 901#endif 902 903 bool success = false; 904 const uint32_t opcode = OpcodeAsUnsigned (&success); 905 if (!success) 906 return false; 907 908 if (ConditionPassed()) 909 { 910 EmulateInstruction::Context context = { EmulateInstruction::eContextAbsoluteBranchRegister, 0, 0, 0}; 911 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 912 addr_t lr; // next instruction address 913 addr_t target; // target address 914 if (!success) 915 return false; 916 uint32_t Rm; // the register with the target address 917 switch (encoding) { 918 case eEncodingT1: 919 lr = (pc + 2) | 1u; // return address 920 Rm = Bits32(opcode, 6, 3); 921 // if m == 15 then UNPREDICTABLE; 922 if (Rm == 15) 923 return false; 924 target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 925 break; 926 case eEncodingA1: 927 lr = pc + 4; // return address 928 Rm = Bits32(opcode, 3, 0); 929 // if m == 15 then UNPREDICTABLE; 930 if (Rm == 15) 931 return false; 932 target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 933 break; 934 default: 935 return false; 936 } 937 context.arg0 = eRegisterKindDWARF; 938 context.arg1 = dwarf_r0 + Rm; 939 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 940 return false; 941 if (!BXWritePC(context, target)) 942 return false; 943 } 944 return true; 945} 946 947// Set r7 to point to some ip offset. 948// SUB (immediate) 949bool 950EmulateInstructionARM::EmulateSubR7IPImmediate (ARMEncoding encoding) 951{ 952#if 0 953 // ARM pseudo code... 954 if (ConditionPassed()) 955 { 956 EncodingSpecificOperations(); 957 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 958 if d == 15 then // Can only occur for ARM encoding 959 ALUWritePC(result); // setflags is always FALSE here 960 else 961 R[d] = result; 962 if setflags then 963 APSR.N = result<31>; 964 APSR.Z = IsZeroBit(result); 965 APSR.C = carry; 966 APSR.V = overflow; 967 } 968#endif 969 970 bool success = false; 971 const uint32_t opcode = OpcodeAsUnsigned (&success); 972 if (!success) 973 return false; 974 975 if (ConditionPassed()) 976 { 977 const addr_t ip = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r12, 0, &success); 978 if (!success) 979 return false; 980 uint32_t imm32; 981 switch (encoding) { 982 case eEncodingA1: 983 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 984 break; 985 default: 986 return false; 987 } 988 addr_t ip_offset = imm32; 989 addr_t addr = ip - ip_offset; // the adjusted ip value 990 991 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 992 eRegisterKindDWARF, 993 dwarf_r12, 994 -ip_offset }; 995 996 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 997 return false; 998 } 999 return true; 1000} 1001 1002// Set ip to point to some stack offset. 1003// SUB (SP minus immediate) 1004bool 1005EmulateInstructionARM::EmulateSubIPSPImmediate (ARMEncoding encoding) 1006{ 1007#if 0 1008 // ARM pseudo code... 1009 if (ConditionPassed()) 1010 { 1011 EncodingSpecificOperations(); 1012 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1013 if d == 15 then // Can only occur for ARM encoding 1014 ALUWritePC(result); // setflags is always FALSE here 1015 else 1016 R[d] = result; 1017 if setflags then 1018 APSR.N = result<31>; 1019 APSR.Z = IsZeroBit(result); 1020 APSR.C = carry; 1021 APSR.V = overflow; 1022 } 1023#endif 1024 1025 bool success = false; 1026 const uint32_t opcode = OpcodeAsUnsigned (&success); 1027 if (!success) 1028 return false; 1029 1030 if (ConditionPassed()) 1031 { 1032 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1033 if (!success) 1034 return false; 1035 uint32_t imm32; 1036 switch (encoding) { 1037 case eEncodingA1: 1038 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1039 break; 1040 default: 1041 return false; 1042 } 1043 addr_t sp_offset = imm32; 1044 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1045 1046 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1047 eRegisterKindGeneric, 1048 LLDB_REGNUM_GENERIC_SP, 1049 -sp_offset }; 1050 1051 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1052 return false; 1053 } 1054 return true; 1055} 1056 1057// A sub operation to adjust the SP -- allocate space for local storage. 1058bool 1059EmulateInstructionARM::EmulateSubSPImmdiate (ARMEncoding encoding) 1060{ 1061#if 0 1062 // ARM pseudo code... 1063 if (ConditionPassed()) 1064 { 1065 EncodingSpecificOperations(); 1066 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1067 if d == 15 then // Can only occur for ARM encoding 1068 ALUWritePC(result); // setflags is always FALSE here 1069 else 1070 R[d] = result; 1071 if setflags then 1072 APSR.N = result<31>; 1073 APSR.Z = IsZeroBit(result); 1074 APSR.C = carry; 1075 APSR.V = overflow; 1076 } 1077#endif 1078 1079 bool success = false; 1080 const uint32_t opcode = OpcodeAsUnsigned (&success); 1081 if (!success) 1082 return false; 1083 1084 if (ConditionPassed()) 1085 { 1086 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1087 if (!success) 1088 return false; 1089 uint32_t imm32; 1090 switch (encoding) { 1091 case eEncodingT1: 1092 imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1093 case eEncodingT2: 1094 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1095 break; 1096 case eEncodingT3: 1097 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1098 break; 1099 case eEncodingA1: 1100 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1101 break; 1102 default: 1103 return false; 1104 } 1105 addr_t sp_offset = imm32; 1106 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1107 1108 EmulateInstruction::Context context = { EmulateInstruction::eContextAdjustStackPointer, 1109 eRegisterKindGeneric, 1110 LLDB_REGNUM_GENERIC_SP, 1111 -sp_offset }; 1112 1113 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1114 return false; 1115 } 1116 return true; 1117} 1118 1119// A store operation to the stack that also updates the SP. 1120bool 1121EmulateInstructionARM::EmulateSTRRtSP (ARMEncoding encoding) 1122{ 1123#if 0 1124 // ARM pseudo code... 1125 if (ConditionPassed()) 1126 { 1127 EncodingSpecificOperations(); 1128 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1129 address = if index then offset_addr else R[n]; 1130 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1131 if wback then R[n] = offset_addr; 1132 } 1133#endif 1134 1135 bool success = false; 1136 const uint32_t opcode = OpcodeAsUnsigned (&success); 1137 if (!success) 1138 return false; 1139 1140 if (ConditionPassed()) 1141 { 1142 const uint32_t addr_byte_size = GetAddressByteSize(); 1143 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1144 if (!success) 1145 return false; 1146 uint32_t Rt; // the source register 1147 uint32_t imm12; 1148 switch (encoding) { 1149 case eEncodingA1: 1150 Rt = Bits32(opcode, 15, 12); 1151 imm12 = Bits32(opcode, 11, 0); 1152 break; 1153 default: 1154 return false; 1155 } 1156 addr_t sp_offset = imm12; 1157 addr_t addr = sp - sp_offset; 1158 1159 EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 }; 1160 if (Rt != 15) 1161 { 1162 context.arg1 = dwarf_r0 + Rt; // arg1 in the context is the DWARF register number 1163 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 1164 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, context.arg1, 0, &success); 1165 if (!success) 1166 return false; 1167 if (!WriteMemoryUnsigned (context, addr, reg_value, addr_byte_size)) 1168 return false; 1169 } 1170 else 1171 { 1172 context.arg1 = dwarf_pc; // arg1 in the context is the DWARF register number 1173 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 1174 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1175 if (!success) 1176 return false; 1177 if (!WriteMemoryUnsigned (context, addr, pc + 8, addr_byte_size)) 1178 return false; 1179 } 1180 1181 context.type = EmulateInstruction::eContextAdjustStackPointer; 1182 context.arg0 = eRegisterKindGeneric; 1183 context.arg1 = LLDB_REGNUM_GENERIC_SP; 1184 context.arg2 = -sp_offset; 1185 1186 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1187 return false; 1188 } 1189 return true; 1190} 1191 1192// Vector Push stores multiple extension registers to the stack. 1193// It also updates SP to point to the start of the stored data. 1194bool 1195EmulateInstructionARM::EmulateVPUSH (ARMEncoding encoding) 1196{ 1197#if 0 1198 // ARM pseudo code... 1199 if (ConditionPassed()) 1200 { 1201 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1202 address = SP - imm32; 1203 SP = SP - imm32; 1204 if single_regs then 1205 for r = 0 to regs-1 1206 MemA[address,4] = S[d+r]; address = address+4; 1207 else 1208 for r = 0 to regs-1 1209 // Store as two word-aligned words in the correct order for current endianness. 1210 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1211 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1212 address = address+8; 1213 } 1214#endif 1215 1216 bool success = false; 1217 const uint32_t opcode = OpcodeAsUnsigned (&success); 1218 if (!success) 1219 return false; 1220 1221 if (ConditionPassed()) 1222 { 1223 const uint32_t addr_byte_size = GetAddressByteSize(); 1224 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1225 if (!success) 1226 return false; 1227 bool single_regs; 1228 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1229 uint32_t imm32; // stack offset 1230 uint32_t regs; // number of registers 1231 switch (encoding) { 1232 case eEncodingT1: 1233 case eEncodingA1: 1234 single_regs = false; 1235 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1236 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1237 // If UInt(imm8) is odd, see "FSTMX". 1238 regs = Bits32(opcode, 7, 0) / 2; 1239 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1240 if (regs == 0 || regs > 16 || (d + regs) > 32) 1241 return false; 1242 break; 1243 case eEncodingT2: 1244 case eEncodingA2: 1245 single_regs = true; 1246 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1247 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1248 regs = Bits32(opcode, 7, 0); 1249 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1250 if (regs == 0 || regs > 16 || (d + regs) > 32) 1251 return false; 1252 break; 1253 default: 1254 return false; 1255 } 1256 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1257 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1258 addr_t sp_offset = imm32; 1259 addr_t addr = sp - sp_offset; 1260 uint32_t i; 1261 1262 EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 }; 1263 for (i=d; i<regs; ++i) 1264 { 1265 context.arg1 = start_reg + i; // arg1 in the context is the DWARF register number 1266 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 1267 // uint64_t to accommodate 64-bit registers. 1268 uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, context.arg1, 0, &success); 1269 if (!success) 1270 return false; 1271 if (!WriteMemoryUnsigned (context, addr, reg_value, reg_byte_size)) 1272 return false; 1273 addr += reg_byte_size; 1274 } 1275 1276 context.type = EmulateInstruction::eContextAdjustStackPointer; 1277 context.arg0 = eRegisterKindGeneric; 1278 context.arg1 = LLDB_REGNUM_GENERIC_SP; 1279 context.arg2 = -sp_offset; 1280 1281 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1282 return false; 1283 } 1284 return true; 1285} 1286 1287// Vector Pop loads multiple extension registers from the stack. 1288// It also updates SP to point just above the loaded data. 1289bool 1290EmulateInstructionARM::EmulateVPOP (ARMEncoding encoding) 1291{ 1292#if 0 1293 // ARM pseudo code... 1294 if (ConditionPassed()) 1295 { 1296 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1297 address = SP; 1298 SP = SP + imm32; 1299 if single_regs then 1300 for r = 0 to regs-1 1301 S[d+r] = MemA[address,4]; address = address+4; 1302 else 1303 for r = 0 to regs-1 1304 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 1305 // Combine the word-aligned words in the correct order for current endianness. 1306 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 1307 } 1308#endif 1309 1310 bool success = false; 1311 const uint32_t opcode = OpcodeAsUnsigned (&success); 1312 if (!success) 1313 return false; 1314 1315 if (ConditionPassed()) 1316 { 1317 const uint32_t addr_byte_size = GetAddressByteSize(); 1318 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1319 if (!success) 1320 return false; 1321 bool single_regs; 1322 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1323 uint32_t imm32; // stack offset 1324 uint32_t regs; // number of registers 1325 switch (encoding) { 1326 case eEncodingT1: 1327 case eEncodingA1: 1328 single_regs = false; 1329 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1330 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1331 // If UInt(imm8) is odd, see "FLDMX". 1332 regs = Bits32(opcode, 7, 0) / 2; 1333 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1334 if (regs == 0 || regs > 16 || (d + regs) > 32) 1335 return false; 1336 break; 1337 case eEncodingT2: 1338 case eEncodingA2: 1339 single_regs = true; 1340 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1341 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1342 regs = Bits32(opcode, 7, 0); 1343 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1344 if (regs == 0 || regs > 16 || (d + regs) > 32) 1345 return false; 1346 break; 1347 default: 1348 return false; 1349 } 1350 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1351 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1352 addr_t sp_offset = imm32; 1353 addr_t addr = sp; 1354 uint32_t i; 1355 uint64_t data; // uint64_t to accomodate 64-bit registers. 1356 1357 EmulateInstruction::Context context = { EmulateInstruction::eContextPopRegisterOffStack, eRegisterKindDWARF, 0, 0 }; 1358 for (i=d; i<regs; ++i) 1359 { 1360 context.arg1 = start_reg + i; // arg1 in the context is the DWARF register number 1361 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 1362 data = ReadMemoryUnsigned(context, addr, reg_byte_size, 0, &success); 1363 if (!success) 1364 return false; 1365 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, context.arg1, data)) 1366 return false; 1367 addr += reg_byte_size; 1368 } 1369 1370 context.type = EmulateInstruction::eContextAdjustStackPointer; 1371 context.arg0 = eRegisterKindGeneric; 1372 context.arg1 = LLDB_REGNUM_GENERIC_SP; 1373 context.arg2 = sp_offset; 1374 1375 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1376 return false; 1377 } 1378 return true; 1379} 1380 1381// SVC (previously SWI) 1382bool 1383EmulateInstructionARM::EmulateSVC (ARMEncoding encoding) 1384{ 1385#if 0 1386 // ARM pseudo code... 1387 if (ConditionPassed()) 1388 { 1389 EncodingSpecificOperations(); 1390 CallSupervisor(); 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 uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1402 addr_t lr; // next instruction address 1403 if (!success) 1404 return false; 1405 uint32_t imm32; // the immediate constant 1406 uint32_t mode; // ARM or Thumb mode 1407 switch (encoding) { 1408 case eEncodingT1: 1409 lr = (pc + 2) | 1u; // return address 1410 imm32 = Bits32(opcode, 7, 0); 1411 mode = eModeThumb; 1412 break; 1413 case eEncodingA1: 1414 lr = pc + 4; // return address 1415 imm32 = Bits32(opcode, 23, 0); 1416 mode = eModeARM; 1417 break; 1418 default: 1419 return false; 1420 } 1421 EmulateInstruction::Context context = { EmulateInstruction::eContextSupervisorCall, mode, imm32, 0}; 1422 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1423 return false; 1424 } 1425 return true; 1426} 1427 1428// If Then makes up to four following instructions (the IT block) conditional. 1429bool 1430EmulateInstructionARM::EmulateIT (ARMEncoding encoding) 1431{ 1432#if 0 1433 // ARM pseudo code... 1434 EncodingSpecificOperations(); 1435 ITSTATE.IT<7:0> = firstcond:mask; 1436#endif 1437 1438 bool success = false; 1439 const uint32_t opcode = OpcodeAsUnsigned (&success); 1440 if (!success) 1441 return false; 1442 1443 m_it_session.InitIT(Bits32(opcode, 7, 0)); 1444 return true; 1445} 1446 1447// Branch causes a branch to a target address. 1448bool 1449EmulateInstructionARM::EmulateB (ARMEncoding encoding) 1450{ 1451#if 0 1452 // ARM pseudo code... 1453 if (ConditionPassed()) 1454 { 1455 EncodingSpecificOperations(); 1456 BranchWritePC(PC + imm32); 1457 } 1458#endif 1459 1460 bool success = false; 1461 const uint32_t opcode = OpcodeAsUnsigned (&success); 1462 if (!success) 1463 return false; 1464 1465 if (ConditionPassed()) 1466 { 1467 EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0}; 1468 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1469 if (!success) 1470 return false; 1471 addr_t target; // target address 1472 int32_t imm32; // PC-relative offset 1473 switch (encoding) { 1474 case eEncodingT1: 1475 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1476 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 1477 target = pc + 4 + imm32; 1478 context.arg1 = 4 + imm32; // signed offset 1479 context.arg2 = eModeThumb; // target instruction set 1480 break; 1481 case eEncodingT2: 1482 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 1483 target = pc + 4 + imm32; 1484 context.arg1 = 4 + imm32; // signed offset 1485 context.arg2 = eModeThumb; // target instruction set 1486 break; 1487 case eEncodingT3: 1488 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1489 { 1490 uint32_t S = Bit32(opcode, 26); 1491 uint32_t imm6 = Bits32(opcode, 21, 16); 1492 uint32_t J1 = Bit32(opcode, 13); 1493 uint32_t J2 = Bit32(opcode, 11); 1494 uint32_t imm11 = Bits32(opcode, 10, 0); 1495 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 1496 imm32 = llvm::SignExtend32<21>(imm21); 1497 target = pc + 4 + imm32; 1498 context.arg1 = eModeThumb; // target instruction set 1499 context.arg2 = 4 + imm32; // signed offset 1500 break; 1501 } 1502 case eEncodingT4: 1503 { 1504 uint32_t S = Bit32(opcode, 26); 1505 uint32_t imm10 = Bits32(opcode, 25, 16); 1506 uint32_t J1 = Bit32(opcode, 13); 1507 uint32_t J2 = Bit32(opcode, 11); 1508 uint32_t imm11 = Bits32(opcode, 10, 0); 1509 uint32_t I1 = !(J1 ^ S); 1510 uint32_t I2 = !(J2 ^ S); 1511 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1512 imm32 = llvm::SignExtend32<25>(imm25); 1513 target = pc + 4 + imm32; 1514 context.arg1 = eModeThumb; // target instruction set 1515 context.arg2 = 4 + imm32; // signed offset 1516 break; 1517 } 1518 case eEncodingA1: 1519 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1520 target = pc + 8 + imm32; 1521 context.arg1 = eModeARM; // target instruction set 1522 context.arg2 = 8 + imm32; // signed offset 1523 break; 1524 default: 1525 return false; 1526 } 1527 if (!BranchWritePC(context, target)) 1528 return false; 1529 } 1530 return true; 1531} 1532 1533// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 1534// zero and conditionally branch forward a constant value. They do not affect the condition flags. 1535// CBNZ, CBZ 1536bool 1537EmulateInstructionARM::EmulateCB (ARMEncoding encoding) 1538{ 1539#if 0 1540 // ARM pseudo code... 1541 EncodingSpecificOperations(); 1542 if nonzero ^ IsZero(R[n]) then 1543 BranchWritePC(PC + imm32); 1544#endif 1545 1546 bool success = false; 1547 const uint32_t opcode = OpcodeAsUnsigned (&success); 1548 if (!success) 1549 return false; 1550 1551 // Read the register value from the operand register Rn. 1552 uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Bits32(opcode, 2, 0), 0, &success); 1553 if (!success) 1554 return false; 1555 1556 EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0}; 1557 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1558 if (!success) 1559 return false; 1560 1561 addr_t target; // target address 1562 uint32_t imm32; // PC-relative offset to branch forward 1563 bool nonzero; 1564 switch (encoding) { 1565 case eEncodingT1: 1566 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 1567 nonzero = BitIsSet(opcode, 11); 1568 target = pc + 4 + imm32; 1569 context.arg1 = 4 + imm32; // signed offset 1570 context.arg2 = eModeThumb; // target instruction set 1571 break; 1572 default: 1573 return false; 1574 } 1575 if (nonzero ^ (reg_val == 0)) 1576 if (!BranchWritePC(context, target)) 1577 return false; 1578 1579 return true; 1580} 1581 1582// ADD <Rdn>, <Rm> 1583// where <Rdn> the destination register is also the first operand register 1584// and <Rm> is the second operand register. 1585bool 1586EmulateInstructionARM::EmulateAddRdnRm (ARMEncoding encoding) 1587{ 1588#if 0 1589 // ARM pseudo code... 1590 if ConditionPassed() then 1591 EncodingSpecificOperations(); 1592 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1593 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 1594 if d == 15 then 1595 ALUWritePC(result); // setflags is always FALSE here 1596 else 1597 R[d] = result; 1598 if setflags then 1599 APSR.N = result<31>; 1600 APSR.Z = IsZeroBit(result); 1601 APSR.C = carry; 1602 APSR.V = overflow; 1603#endif 1604 1605 bool success = false; 1606 const uint32_t opcode = OpcodeAsUnsigned (&success); 1607 if (!success) 1608 return false; 1609 1610 if (ConditionPassed()) 1611 { 1612 uint32_t Rd, Rn, Rm; 1613 //bool setflags = false; 1614 switch (encoding) 1615 { 1616 case eEncodingT2: 1617 // setflags = FALSE 1618 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1619 Rm = Bits32(opcode, 6, 3); 1620 if (Rn == 15 && Rm == 15) 1621 return false; 1622 break; 1623 default: 1624 return false; 1625 } 1626 1627 int32_t result, val1, val2; 1628 // Read the first operand. 1629 if (Rn == 15) 1630 val1 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1631 else 1632 val1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 1633 if (!success) 1634 return false; 1635 1636 // Read the second operand. 1637 if (Rm == 15) 1638 val2 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1639 else 1640 val2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1641 if (!success) 1642 return false; 1643 1644 result = val1 + val2; 1645 EmulateInstruction::Context context = { EmulateInstruction::eContextImmediate, 1646 result, 1647 0, 1648 0 }; 1649 1650 if (Rd == 15) 1651 { 1652 if (!ALUWritePC (context, result)) 1653 return false; 1654 } 1655 else 1656 { 1657 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, result)) 1658 return false; 1659 } 1660 } 1661 return true; 1662} 1663 1664// LDM loads multiple registers from consecutive memory locations, using an 1665// address from a base register. Optionally the addres just above the highest of those locations 1666// can be written back to the base register. 1667bool 1668EmulateInstructionARM::EmulateLDM (ARMEncoding encoding) 1669{ 1670#if 0 1671 // ARM pseudo code... 1672 if ConditionPassed() 1673 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 1674 address = R[n]; 1675 1676 for i = 0 to 14 1677 if registers<i> == '1' then 1678 R[i] = MemA[address, 4]; address = address + 4; 1679 if registers<15> == '1' then 1680 LoadWritePC (MemA[address, 4]); 1681 1682 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 1683 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 1684 1685#endif 1686 1687 bool success = false; 1688 const uint32_t opcode = OpcodeAsUnsigned (&success); 1689 if (!success) 1690 return false; 1691 1692 if (ConditionPassed()) 1693 { 1694 uint32_t n; 1695 uint32_t registers = 0; 1696 bool wback; 1697 const uint32_t addr_byte_size = GetAddressByteSize(); 1698 switch (encoding) 1699 { 1700 case eEncodingT1: 1701 n = Bits32 (opcode, 10, 8); 1702 registers = Bits32 (opcode, 7, 0); 1703 wback = BitIsClear (registers, n); 1704 // if BitCount(registers) < 1 then UNPREDICTABLE; 1705 if (BitCount(registers) < 1) 1706 return false; 1707 break; 1708 case eEncodingT2: 1709 n = Bits32 (opcode, 19, 16); 1710 registers = Bits32 (opcode, 15, 0); 1711 wback = BitIsSet (opcode, 21); 1712 if ((n == 15) 1713 || (BitCount (registers) < 2) 1714 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 1715 return false; 1716 if (BitIsSet (registers, 15) 1717 && m_it_session.InITBlock() 1718 && !m_it_session.LastInITBlock()) 1719 return false; 1720 if (wback 1721 && BitIsSet (registers, n)) 1722 return false; 1723 break; 1724 case eEncodingA1: 1725 n = Bits32 (opcode, 19, 16); 1726 registers = Bits32 (opcode, 15, 0); 1727 wback = BitIsSet (opcode, 21); 1728 if ((n == 15) 1729 || (BitCount (registers) < 1)) 1730 return false; 1731 break; 1732 default: 1733 return false; 1734 } 1735 1736 int32_t offset = 0; 1737 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1738 if (!success) 1739 return false; 1740 1741 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1742 eRegisterKindDWARF, 1743 dwarf_r0 + n, 1744 offset }; 1745 1746 for (int i = 0; i < 14; ++i) 1747 { 1748 if (BitIsSet (registers, i)) 1749 { 1750 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1751 context.arg2 = offset; 1752 if (wback && (n == 13)) // Pop Instruction 1753 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1754 1755 // R[i] = MemA [address, 4]; address = address + 4; 1756 uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success); 1757 if (!success) 1758 return false; 1759 1760 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 1761 return false; 1762 1763 offset += addr_byte_size; 1764 } 1765 } 1766 1767 if (BitIsSet (registers, 15)) 1768 { 1769 //LoadWritePC (MemA [address, 4]); 1770 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1771 context.arg2 = offset; 1772 uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success); 1773 if (!success) 1774 return false; 1775 // In ARMv5T and above, this is an interworking branch. 1776 if (!LoadWritePC(context, data)) 1777 return false; 1778 } 1779 1780 if (wback && BitIsClear (registers, n)) 1781 { 1782 addr_t offset = addr_byte_size * BitCount (registers); 1783 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1784 context.arg2 = offset; 1785 1786 // R[n] = R[n] + 4 * BitCount (registers) 1787 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 1788 return false; 1789 } 1790 if (wback && BitIsSet (registers, n)) 1791 // R[n] bits(32) UNKNOWN; 1792 return false; //I'm not convinced this is the right thing to do here... 1793 } 1794 return true; 1795} 1796 1797bool 1798EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding) 1799{ 1800#if 0 1801 // ARM pseudo code... 1802 if ConditionPassed() then 1803 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 1804 address = R[n] - 4*BitCount(registers); 1805 1806 for i = 0 to 14 1807 if registers<i> == ’1’ then 1808 R[i] = MemA[address,4]; address = address + 4; 1809 if registers<15> == ’1’ then 1810 LoadWritePC(MemA[address,4]); 1811 1812 if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 1813 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 1814#endif 1815 1816 bool success = false; 1817 const uint32_t opcode = OpcodeAsUnsigned (&success); 1818 if (!success) 1819 return false; 1820 1821 if (ConditionPassed()) 1822 { 1823 uint32_t n; 1824 uint32_t registers = 0; 1825 bool wback; 1826 const uint32_t addr_byte_size = GetAddressByteSize(); 1827 switch (encoding) 1828 { 1829 case eEncodingT1: 1830 // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 1831 n = Bits32 (opcode, 19, 16); 1832 registers = Bits32 (opcode, 15, 0); 1833 wback = BitIsSet (opcode, 21); 1834 1835 // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 1836 if ((n == 15) 1837 || (BitCount (registers) < 2) 1838 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 1839 return false; 1840 1841 // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 1842 if (BitIsSet (registers, 15) 1843 && m_it_session.InITBlock() 1844 && !m_it_session.LastInITBlock()) 1845 return false; 1846 1847 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 1848 if (wback && BitIsSet (registers, n)) 1849 return false; 1850 1851 break; 1852 1853 case eEncodingA1: 1854 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 1855 n = Bits32 (opcode, 19, 16); 1856 registers = Bits32 (opcode, 15, 0); 1857 wback = BitIsSet (opcode, 21); 1858 1859 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 1860 if ((n == 15) || (BitCount (registers) < 1)) 1861 return false; 1862 1863 break; 1864 1865 default: 1866 return false; 1867 } 1868 1869 int32_t offset = 0; 1870 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success) 1871 - (addr_byte_size * BitCount (registers)); 1872 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1873 eRegisterKindDWARF, 1874 dwarf_r0 + n, 1875 offset }; 1876 1877 for (int i = 0; i < 14; ++i) 1878 { 1879 if (BitIsSet (registers, i)) 1880 { 1881 // R[i] = MemA[address,4]; address = address + 4; 1882 context.arg2 = offset; 1883 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 1884 if (!success) 1885 return false; 1886 1887 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 1888 return false; 1889 1890 offset += addr_byte_size; 1891 } 1892 } 1893 1894 // if registers<15> == ’1’ then 1895 // LoadWritePC(MemA[address,4]); 1896 if (BitIsSet (registers, 15)) 1897 { 1898 context.arg2 = offset; 1899 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 1900 if (!success) 1901 return false; 1902 // In ARMv5T and above, this is an interworking branch. 1903 if (!LoadWritePC(context, data)) 1904 return false; 1905 } 1906 1907 // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 1908 if (wback && BitIsClear (registers, n)) 1909 { 1910 context.arg2 = offset; 1911 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1912 if (!success) 1913 return false; 1914 addr = addr - (addr_byte_size * BitCount (registers)); 1915 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 1916 return false; 1917 } 1918 1919 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 1920 if (wback && BitIsSet (registers, n)) 1921 return false; // I'm not sure this is right; how do I set R[n] to bits(32) UNKNOWN. 1922 } 1923 return true; 1924} 1925 1926bool 1927EmulateInstructionARM::EmulateLDMIB (ARMEncoding encoding) 1928{ 1929#if 0 1930 if ConditionPassed() then 1931 EncodingSpecificOperations(); 1932 address = R[n] + 4; 1933 1934 for i = 0 to 14 1935 if registers<i> == ’1’ then 1936 R[i] = MemA[address,4]; address = address + 4; 1937 if registers<15> == ’1’ then 1938 LoadWritePC(MemA[address,4]); 1939 1940 if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 1941 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 1942#endif 1943 1944 bool success = false; 1945 const uint32_t opcode = OpcodeAsUnsigned (&success); 1946 if (!success) 1947 return false; 1948 1949 if (ConditionPassed()) 1950 { 1951 uint32_t n; 1952 uint32_t registers = 0; 1953 bool wback; 1954 const uint32_t addr_byte_size = GetAddressByteSize(); 1955 switch (encoding) 1956 { 1957 case eEncodingA1: 1958 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 1959 n = Bits32 (opcode, 19, 16); 1960 registers = Bits32 (opcode, 15, 0); 1961 wback = BitIsSet (opcode, 21); 1962 1963 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 1964 if ((n == 15) || (BitCount (registers) < 1)) 1965 return false; 1966 1967 break; 1968 default: 1969 return false; 1970 } 1971 // address = R[n] + 4; 1972 1973 int32_t offset = 0; 1974 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success) + addr_byte_size; 1975 1976 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1977 eRegisterKindDWARF, 1978 dwarf_r0 + n, 1979 offset }; 1980 1981 for (int i = 0; i < 14; ++i) 1982 { 1983 if (BitIsSet (registers, i)) 1984 { 1985 // R[i] = MemA[address,4]; address = address + 4; 1986 1987 context.arg2 = offset; 1988 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 1989 if (!success) 1990 return false; 1991 1992 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 1993 return false; 1994 1995 offset += addr_byte_size; 1996 } 1997 } 1998 1999 // if registers<15> == ’1’ then 2000 // LoadWritePC(MemA[address,4]); 2001 if (BitIsSet (registers, 15)) 2002 { 2003 context.arg2 = offset; 2004 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2005 if (!success) 2006 return false; 2007 // In ARMv5T and above, this is an interworking branch. 2008 if (!LoadWritePC(context, data)) 2009 return false; 2010 } 2011 2012 // if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 2013 if (wback && BitIsClear (registers, n)) 2014 { 2015 context.arg2 = offset; 2016 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2017 if (!success) 2018 return false; 2019 addr = addr + (addr_byte_size * BitCount (registers)); 2020 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 2021 return false; 2022 } 2023 2024 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2025 if (wback && BitIsSet (registers, n)) 2026 return false; // I'm not sure this is right; how do I set R[n] to bits(32) UNKNOWN. 2027 } 2028 return true; 2029} 2030 2031// Load Register (immediate) calculates an address from a base register value and 2032// an immediate offset, loads a word from memory, and writes to a register. 2033// LDR (immediate, Thumb) 2034bool 2035EmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding) 2036{ 2037#if 0 2038 // ARM pseudo code... 2039 if (ConditionPassed()) 2040 { 2041 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 2042 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2043 address = if index then offset_addr else R[n]; 2044 data = MemU[address,4]; 2045 if wback then R[n] = offset_addr; 2046 if t == 15 then 2047 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 2048 elsif UnalignedSupport() || address<1:0> = '00' then 2049 R[t] = data; 2050 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 2051 } 2052#endif 2053 2054 bool success = false; 2055 const uint32_t opcode = OpcodeAsUnsigned (&success); 2056 if (!success) 2057 return false; 2058 2059 if (ConditionPassed()) 2060 { 2061 uint32_t Rt; // the destination register 2062 uint32_t Rn; // the base register 2063 uint32_t imm32; // the immediate offset used to form the address 2064 addr_t offset_addr; // the offset address 2065 addr_t address; // the calculated address 2066 uint32_t data; // the literal data value from memory load 2067 bool add, index, wback; 2068 switch (encoding) { 2069 case eEncodingT1: 2070 Rt = Bits32(opcode, 5, 3); 2071 Rn = Bits32(opcode, 2, 0); 2072 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 2073 // index = TRUE; add = TRUE; wback = FALSE 2074 add = true; 2075 index = true; 2076 wback = false; 2077 break; 2078 default: 2079 return false; 2080 } 2081 uint32_t base = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 2082 if (!success) 2083 return false; 2084 if (add) 2085 offset_addr = base + imm32; 2086 else 2087 offset_addr = base - imm32; 2088 2089 address = (index ? offset_addr : base); 2090 2091 if (wback) 2092 { 2093 EmulateInstruction::Context ctx = { EmulateInstruction::eContextRegisterPlusOffset, 2094 eRegisterKindDWARF, 2095 dwarf_r0 + Rn, 2096 (int32_t) (offset_addr - base)}; 2097 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 2098 return false; 2099 } 2100 2101 // Prepare to write to the Rt register. 2102 EmulateInstruction::Context context = {EmulateInstruction::eContextImmediate, 2103 0, 2104 0, 2105 0}; 2106 2107 // Read memory from the address. 2108 data = ReadMemoryUnsigned(context, address, 4, 0, &success); 2109 if (!success) 2110 return false; 2111 context.arg0 = data; 2112 2113 if (Rt == 15) 2114 { 2115 if (Bits32(address, 1, 0) == 0) 2116 { 2117 if (!LoadWritePC(context, data)) 2118 return false; 2119 } 2120 else 2121 return false; 2122 } 2123 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 2124 { 2125 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 2126 return false; 2127 } 2128 else 2129 return false; 2130 } 2131 return true; 2132} 2133 2134EmulateInstructionARM::ARMOpcode* 2135EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) 2136{ 2137 static ARMOpcode 2138 g_arm_opcodes[] = 2139 { 2140 //---------------------------------------------------------------------- 2141 // Prologue instructions 2142 //---------------------------------------------------------------------- 2143 2144 // push register(s) 2145 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePush, "push <registers>" }, 2146 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePush, "push <register>" }, 2147 2148 // set r7 to point to a stack offset 2149 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #<const>" }, 2150 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubR7IPImmediate, "sub r7, ip, #<const>"}, 2151 // copy the stack pointer to ip 2152 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMovRdSP, "mov ip, sp" }, 2153 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add ip, sp, #<const>" }, 2154 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubIPSPImmediate, "sub ip, sp, #<const>"}, 2155 2156 // adjust the stack pointer 2157 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub sp, sp, #<const>"}, 2158 2159 // push one register 2160 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 2161 { 0x0fff0000, 0x052d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 2162 2163 // vector push consecutive extension register(s) 2164 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 2165 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 2166 2167 //---------------------------------------------------------------------- 2168 // Epilogue instructions 2169 //---------------------------------------------------------------------- 2170 2171 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 2172 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 2173 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 2174 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 2175 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePop, "pop <registers>"}, 2176 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePop, "pop <register>"}, 2177 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 2178 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 2179 2180 //---------------------------------------------------------------------- 2181 // Supervisor Call (previously Software Interrupt) 2182 //---------------------------------------------------------------------- 2183 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 2184 2185 //---------------------------------------------------------------------- 2186 // Branch instructions 2187 //---------------------------------------------------------------------- 2188 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "b #imm24"}, 2189 2190 //---------------------------------------------------------------------- 2191 // Load instructions 2192 //---------------------------------------------------------------------- 2193 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 2194 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 2195 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" } 2196 2197 }; 2198 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 2199 2200 for (size_t i=0; i<k_num_arm_opcodes; ++i) 2201 { 2202 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value) 2203 return &g_arm_opcodes[i]; 2204 } 2205 return NULL; 2206} 2207 2208 2209EmulateInstructionARM::ARMOpcode* 2210EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) 2211{ 2212 2213 static ARMOpcode 2214 g_thumb_opcodes[] = 2215 { 2216 //---------------------------------------------------------------------- 2217 // Prologue instructions 2218 //---------------------------------------------------------------------- 2219 2220 // push register(s) 2221 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePush, "push <registers>" }, 2222 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <registers>" }, 2223 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <register>" }, 2224 2225 // set r7 to point to a stack offset 2226 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #imm" }, 2227 // copy the stack pointer to r7 2228 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdSP, "mov r7, sp" }, 2229 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 2230 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovLowHigh, "mov r0-r7, r8-r15" }, 2231 2232 // PC relative load into register (see also EmulateAddSPRm) 2233 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRdPCRelative, "ldr <Rd>, [PC, #imm]"}, 2234 2235 // adjust the stack pointer 2236 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPRm, "add sp, <Rm>"}, 2237 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSubSPImmdiate, "add sp, sp, #imm"}, 2238 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub.w sp, sp, #<const>"}, 2239 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "subw sp, sp, #imm12"}, 2240 2241 // vector push consecutive extension register(s) 2242 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 2243 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 2244 2245 //---------------------------------------------------------------------- 2246 // Epilogue instructions 2247 //---------------------------------------------------------------------- 2248 2249 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPImmediate, "add sp, #imm"}, 2250 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 2251 // J1 == J2 == 1 2252 { 0xf800f800, 0xf000f800, ARMV4T_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 2253 // J1 == J2 == 1 2254 { 0xf800e800, 0xf000e800, ARMV5_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 2255 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePop, "pop <registers>"}, 2256 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <registers>" }, 2257 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <register>" }, 2258 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 2259 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 2260 2261 //---------------------------------------------------------------------- 2262 // Supervisor Call (previously Software Interrupt) 2263 //---------------------------------------------------------------------- 2264 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 2265 2266 //---------------------------------------------------------------------- 2267 // If Then makes up to four following instructions conditional. 2268 //---------------------------------------------------------------------- 2269 { 0xffffff00, 0x0000bf00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 2270 2271 //---------------------------------------------------------------------- 2272 // Branch instructions 2273 //---------------------------------------------------------------------- 2274 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 2275 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 2276 { 0xffff8000, 0x0000e000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"}, 2277 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 2278 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"}, 2279 // compare and branch 2280 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 2281 2282 //---------------------------------------------------------------------- 2283 // Data-processing instructions 2284 //---------------------------------------------------------------------- 2285 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 2286 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdnRm, "add <Rdn>, <Rm>"}, 2287 // move from high register to high register 2288 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdRm, "mov<c> <Rd>, <Rm>"}, 2289 // move from low register to low register 2290 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMovRdRm, "movs <Rd>, <Rm>"}, 2291 2292 //---------------------------------------------------------------------- 2293 // Load instructions 2294 //---------------------------------------------------------------------- 2295 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 2296 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 2297 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 2298 { 0xfffff800, 0x00006800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"} 2299 2300 }; 2301 2302 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 2303 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 2304 { 2305 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value) 2306 return &g_thumb_opcodes[i]; 2307 } 2308 return NULL; 2309} 2310 2311bool 2312EmulateInstructionARM::SetTargetTriple (const ConstString &triple) 2313{ 2314 m_arm_isa = 0; 2315 const char *triple_cstr = triple.GetCString(); 2316 if (triple_cstr) 2317 { 2318 const char *dash = ::strchr (triple_cstr, '-'); 2319 if (dash) 2320 { 2321 std::string arch (triple_cstr, dash); 2322 const char *arch_cstr = arch.c_str(); 2323 if (strcasecmp(arch_cstr, "armv4t") == 0) 2324 m_arm_isa = ARMv4T; 2325 else if (strcasecmp(arch_cstr, "armv4") == 0) 2326 m_arm_isa = ARMv4; 2327 else if (strcasecmp(arch_cstr, "armv5tej") == 0) 2328 m_arm_isa = ARMv5TEJ; 2329 else if (strcasecmp(arch_cstr, "armv5te") == 0) 2330 m_arm_isa = ARMv5TE; 2331 else if (strcasecmp(arch_cstr, "armv5t") == 0) 2332 m_arm_isa = ARMv5T; 2333 else if (strcasecmp(arch_cstr, "armv6k") == 0) 2334 m_arm_isa = ARMv6K; 2335 else if (strcasecmp(arch_cstr, "armv6") == 0) 2336 m_arm_isa = ARMv6; 2337 else if (strcasecmp(arch_cstr, "armv6t2") == 0) 2338 m_arm_isa = ARMv6T2; 2339 else if (strcasecmp(arch_cstr, "armv7") == 0) 2340 m_arm_isa = ARMv7; 2341 else if (strcasecmp(arch_cstr, "armv8") == 0) 2342 m_arm_isa = ARMv8; 2343 } 2344 } 2345 return m_arm_isa != 0; 2346} 2347 2348 2349bool 2350EmulateInstructionARM::ReadInstruction () 2351{ 2352 bool success = false; 2353 m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 2354 if (success) 2355 { 2356 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 2357 if (success) 2358 { 2359 Context read_inst_context = {eContextReadOpcode, 0, 0}; 2360 if (m_inst_cpsr & MASK_CPSR_T) 2361 { 2362 m_inst_mode = eModeThumb; 2363 uint32_t thumb_opcode = ReadMemoryUnsigned(read_inst_context, pc, 2, 0, &success); 2364 2365 if (success) 2366 { 2367 if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0)) 2368 { 2369 m_inst.opcode_type = eOpcode16; 2370 m_inst.opcode.inst16 = thumb_opcode; 2371 } 2372 else 2373 { 2374 m_inst.opcode_type = eOpcode32; 2375 m_inst.opcode.inst32 = (thumb_opcode << 16) | ReadMemoryUnsigned(read_inst_context, pc + 2, 2, 0, &success); 2376 } 2377 } 2378 } 2379 else 2380 { 2381 m_inst_mode = eModeARM; 2382 m_inst.opcode_type = eOpcode32; 2383 m_inst.opcode.inst32 = ReadMemoryUnsigned(read_inst_context, pc, 4, 0, &success); 2384 } 2385 } 2386 } 2387 if (!success) 2388 { 2389 m_inst_mode = eModeInvalid; 2390 m_inst_pc = LLDB_INVALID_ADDRESS; 2391 } 2392 return success; 2393} 2394 2395uint32_t 2396EmulateInstructionARM::ArchVersion () 2397{ 2398 return m_arm_isa; 2399} 2400 2401bool 2402EmulateInstructionARM::ConditionPassed () 2403{ 2404 if (m_inst_cpsr == 0) 2405 return false; 2406 2407 const uint32_t cond = CurrentCond (); 2408 2409 if (cond == UINT32_MAX) 2410 return false; 2411 2412 bool result = false; 2413 switch (UnsignedBits(cond, 3, 1)) 2414 { 2415 case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break; 2416 case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break; 2417 case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break; 2418 case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break; 2419 case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break; 2420 case 5: 2421 { 2422 bool n = (m_inst_cpsr & MASK_CPSR_N); 2423 bool v = (m_inst_cpsr & MASK_CPSR_V); 2424 result = n == v; 2425 } 2426 break; 2427 case 6: 2428 { 2429 bool n = (m_inst_cpsr & MASK_CPSR_N); 2430 bool v = (m_inst_cpsr & MASK_CPSR_V); 2431 result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0); 2432 } 2433 break; 2434 case 7: 2435 result = true; 2436 break; 2437 } 2438 2439 if (cond & 1) 2440 result = !result; 2441 return result; 2442} 2443 2444uint32_t 2445EmulateInstructionARM::CurrentCond () 2446{ 2447 switch (m_inst_mode) 2448 { 2449 default: 2450 case eModeInvalid: 2451 break; 2452 2453 case eModeARM: 2454 return UnsignedBits(m_inst.opcode.inst32, 31, 28); 2455 2456 case eModeThumb: 2457 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 2458 // 'cond' field of the encoding. 2459 if (m_inst.opcode_type == eOpcode16 && 2460 Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d && 2461 Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f) 2462 { 2463 return Bits32(m_inst.opcode.inst16, 11, 7); 2464 } 2465 else if (m_inst.opcode_type == eOpcode32 && 2466 Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e && 2467 Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 && 2468 Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 && 2469 Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d) 2470 { 2471 return Bits32(m_inst.opcode.inst32, 25, 22); 2472 } 2473 2474 return m_it_session.GetCond(); 2475 } 2476 return UINT32_MAX; // Return invalid value 2477} 2478 2479bool 2480EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 2481{ 2482 addr_t target; 2483 2484 // Check the current instruction set. 2485 if (CurrentInstrSet() == eModeARM) 2486 target = addr & 0xfffffffc; 2487 else 2488 target = addr & 0xfffffffe; 2489 2490 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 2491 return false; 2492 2493 return true; 2494} 2495 2496// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 2497bool 2498EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 2499{ 2500 addr_t target; 2501 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 2502 // we want to record it and issue a WriteRegister callback so the clients 2503 // can track the mode changes accordingly. 2504 bool cpsr_changed = false; 2505 2506 if (BitIsSet(addr, 0)) 2507 { 2508 if (CurrentInstrSet() != eModeThumb) 2509 { 2510 SelectInstrSet(eModeThumb); 2511 cpsr_changed = true; 2512 } 2513 target = addr & 0xfffffffe; 2514 context.arg2 = eModeThumb; 2515 } 2516 else if (BitIsClear(addr, 1)) 2517 { 2518 if (CurrentInstrSet() != eModeARM) 2519 { 2520 SelectInstrSet(eModeARM); 2521 cpsr_changed = true; 2522 } 2523 target = addr & 0xfffffffc; 2524 context.arg2 = eModeARM; 2525 } 2526 else 2527 return false; // address<1:0> == '10' => UNPREDICTABLE 2528 2529 if (cpsr_changed) 2530 { 2531 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2532 return false; 2533 } 2534 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 2535 return false; 2536 2537 return true; 2538} 2539 2540// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 2541bool 2542EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 2543{ 2544 if (ArchVersion() >= ARMv5T) 2545 return BXWritePC(context, addr); 2546 else 2547 return BranchWritePC((const Context)context, addr); 2548} 2549 2550// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 2551bool 2552EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 2553{ 2554 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 2555 return BXWritePC(context, addr); 2556 else 2557 return BranchWritePC((const Context)context, addr); 2558} 2559 2560EmulateInstructionARM::Mode 2561EmulateInstructionARM::CurrentInstrSet () 2562{ 2563 return m_inst_mode; 2564} 2565 2566// Set the 'T' bit of our CPSR. The m_inst_mode gets updated when the next 2567// ReadInstruction() is performed. This function has a side effect of updating 2568// the m_new_inst_cpsr member variable if necessary. 2569bool 2570EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 2571{ 2572 m_new_inst_cpsr = m_inst_cpsr; 2573 switch (arm_or_thumb) 2574 { 2575 default: 2576 return false; 2577 eModeARM: 2578 // Clear the T bit. 2579 m_new_inst_cpsr &= ~MASK_CPSR_T; 2580 break; 2581 eModeThumb: 2582 // Set the T bit. 2583 m_new_inst_cpsr |= MASK_CPSR_T; 2584 break; 2585 } 2586 return true; 2587} 2588 2589// This function returns TRUE if the processor currently provides support for 2590// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 2591// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 2592bool 2593EmulateInstructionARM::UnalignedSupport() 2594{ 2595 return (ArchVersion() >= ARMv7); 2596} 2597 2598// The main addition and subtraction instructions can produce status information 2599// about both unsigned carry and signed overflow conditions. This status 2600// information can be used to synthesize multi-word additions and subtractions. 2601EmulateInstructionARM::AddWithCarryResult 2602EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 2603{ 2604 uint32_t result; 2605 uint8_t carry_out; 2606 uint8_t overflow; 2607 2608 uint64_t unsigned_sum = x + y + carry_in; 2609 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 2610 2611 result = UnsignedBits(unsigned_sum, 31, 0); 2612 carry_out = (result == unsigned_sum ? 0 : 1); 2613 overflow = ((int32_t)result == signed_sum ? 0 : 1); 2614 2615 AddWithCarryResult res = { result, carry_out, overflow }; 2616 return res; 2617} 2618 2619bool 2620EmulateInstructionARM::EvaluateInstruction () 2621{ 2622 // Advance the ITSTATE bits to their values for the next instruction. 2623 if (m_inst_mode == eModeThumb && m_it_session.InITBlock()) 2624 m_it_session.ITAdvance(); 2625 2626 return false; 2627} 2628