1 //===-- EmulateInstructionMIPS.cpp ----------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "EmulateInstructionMIPS.h" 10 11 #include <cstdlib> 12 13 #include "lldb/Core/Address.h" 14 #include "lldb/Core/Opcode.h" 15 #include "lldb/Core/PluginManager.h" 16 #include "lldb/Symbol/UnwindPlan.h" 17 #include "lldb/Target/Target.h" 18 #include "lldb/Utility/ArchSpec.h" 19 #include "lldb/Utility/ConstString.h" 20 #include "lldb/Utility/DataExtractor.h" 21 #include "lldb/Utility/RegisterValue.h" 22 #include "lldb/Utility/Stream.h" 23 #include "llvm-c/Disassembler.h" 24 #include "llvm/MC/MCAsmInfo.h" 25 #include "llvm/MC/MCContext.h" 26 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 27 #include "llvm/MC/MCInst.h" 28 #include "llvm/MC/MCInstrInfo.h" 29 #include "llvm/MC/MCRegisterInfo.h" 30 #include "llvm/MC/MCSubtargetInfo.h" 31 #include "llvm/MC/MCTargetOptions.h" 32 #include "llvm/MC/TargetRegistry.h" 33 #include "llvm/Support/TargetSelect.h" 34 35 #include "llvm/ADT/STLExtras.h" 36 37 #include "Plugins/Process/Utility/InstructionUtils.h" 38 #include "Plugins/Process/Utility/RegisterContext_mips.h" 39 40 using namespace lldb; 41 using namespace lldb_private; 42 43 LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionMIPS, InstructionMIPS) 44 45 #define UInt(x) ((uint64_t)x) 46 #define integer int64_t 47 48 // 49 // EmulateInstructionMIPS implementation 50 // 51 52 #ifdef __mips__ 53 extern "C" { 54 void LLVMInitializeMipsTargetInfo(); 55 void LLVMInitializeMipsTarget(); 56 void LLVMInitializeMipsAsmPrinter(); 57 void LLVMInitializeMipsTargetMC(); 58 void LLVMInitializeMipsDisassembler(); 59 } 60 #endif 61 62 EmulateInstructionMIPS::EmulateInstructionMIPS( 63 const lldb_private::ArchSpec &arch) 64 : EmulateInstruction(arch) { 65 /* Create instance of llvm::MCDisassembler */ 66 std::string Status; 67 llvm::Triple triple = arch.GetTriple(); 68 const llvm::Target *target = 69 llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status); 70 71 /* 72 * If we fail to get the target then we haven't registered it. The 73 * SystemInitializerCommon 74 * does not initialize targets, MCs and disassemblers. However we need the 75 * MCDisassembler 76 * to decode the instructions so that the decoding complexity stays with LLVM. 77 * Initialize the MIPS targets and disassemblers. 78 */ 79 #ifdef __mips__ 80 if (!target) { 81 LLVMInitializeMipsTargetInfo(); 82 LLVMInitializeMipsTarget(); 83 LLVMInitializeMipsAsmPrinter(); 84 LLVMInitializeMipsTargetMC(); 85 LLVMInitializeMipsDisassembler(); 86 target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status); 87 } 88 #endif 89 90 assert(target); 91 92 llvm::StringRef cpu; 93 94 switch (arch.GetCore()) { 95 case ArchSpec::eCore_mips32: 96 case ArchSpec::eCore_mips32el: 97 cpu = "mips32"; 98 break; 99 case ArchSpec::eCore_mips32r2: 100 case ArchSpec::eCore_mips32r2el: 101 cpu = "mips32r2"; 102 break; 103 case ArchSpec::eCore_mips32r3: 104 case ArchSpec::eCore_mips32r3el: 105 cpu = "mips32r3"; 106 break; 107 case ArchSpec::eCore_mips32r5: 108 case ArchSpec::eCore_mips32r5el: 109 cpu = "mips32r5"; 110 break; 111 case ArchSpec::eCore_mips32r6: 112 case ArchSpec::eCore_mips32r6el: 113 cpu = "mips32r6"; 114 break; 115 case ArchSpec::eCore_mips64: 116 case ArchSpec::eCore_mips64el: 117 cpu = "mips64"; 118 break; 119 case ArchSpec::eCore_mips64r2: 120 case ArchSpec::eCore_mips64r2el: 121 cpu = "mips64r2"; 122 break; 123 case ArchSpec::eCore_mips64r3: 124 case ArchSpec::eCore_mips64r3el: 125 cpu = "mips64r3"; 126 break; 127 case ArchSpec::eCore_mips64r5: 128 case ArchSpec::eCore_mips64r5el: 129 cpu = "mips64r5"; 130 break; 131 case ArchSpec::eCore_mips64r6: 132 case ArchSpec::eCore_mips64r6el: 133 cpu = "mips64r6"; 134 break; 135 default: 136 cpu = "generic"; 137 break; 138 } 139 140 std::string features; 141 uint32_t arch_flags = arch.GetFlags(); 142 if (arch_flags & ArchSpec::eMIPSAse_msa) 143 features += "+msa,"; 144 if (arch_flags & ArchSpec::eMIPSAse_dsp) 145 features += "+dsp,"; 146 if (arch_flags & ArchSpec::eMIPSAse_dspr2) 147 features += "+dspr2,"; 148 149 m_reg_info.reset(target->createMCRegInfo(triple.getTriple())); 150 assert(m_reg_info.get()); 151 152 m_insn_info.reset(target->createMCInstrInfo()); 153 assert(m_insn_info.get()); 154 155 llvm::MCTargetOptions MCOptions; 156 m_asm_info.reset( 157 target->createMCAsmInfo(*m_reg_info, triple.getTriple(), MCOptions)); 158 m_subtype_info.reset( 159 target->createMCSubtargetInfo(triple.getTriple(), cpu, features)); 160 assert(m_asm_info.get() && m_subtype_info.get()); 161 162 m_context = std::make_unique<llvm::MCContext>( 163 triple, m_asm_info.get(), m_reg_info.get(), m_subtype_info.get()); 164 assert(m_context.get()); 165 166 m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context)); 167 assert(m_disasm.get()); 168 169 /* Create alternate disassembler for microMIPS */ 170 if (arch_flags & ArchSpec::eMIPSAse_mips16) 171 features += "+mips16,"; 172 else if (arch_flags & ArchSpec::eMIPSAse_micromips) 173 features += "+micromips,"; 174 175 m_alt_subtype_info.reset( 176 target->createMCSubtargetInfo(triple.getTriple(), cpu, features)); 177 assert(m_alt_subtype_info.get()); 178 179 m_alt_disasm.reset( 180 target->createMCDisassembler(*m_alt_subtype_info, *m_context)); 181 assert(m_alt_disasm.get()); 182 183 m_next_inst_size = 0; 184 m_use_alt_disaasm = false; 185 } 186 187 void EmulateInstructionMIPS::Initialize() { 188 PluginManager::RegisterPlugin(GetPluginNameStatic(), 189 GetPluginDescriptionStatic(), CreateInstance); 190 } 191 192 void EmulateInstructionMIPS::Terminate() { 193 PluginManager::UnregisterPlugin(CreateInstance); 194 } 195 196 llvm::StringRef EmulateInstructionMIPS::GetPluginDescriptionStatic() { 197 return "Emulate instructions for the MIPS32 architecture."; 198 } 199 200 EmulateInstruction * 201 EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch, 202 InstructionType inst_type) { 203 if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic( 204 inst_type)) { 205 if (arch.GetTriple().getArch() == llvm::Triple::mips || 206 arch.GetTriple().getArch() == llvm::Triple::mipsel) { 207 return new EmulateInstructionMIPS(arch); 208 } 209 } 210 211 return nullptr; 212 } 213 214 bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) { 215 return arch.GetTriple().getArch() == llvm::Triple::mips || 216 arch.GetTriple().getArch() == llvm::Triple::mipsel; 217 } 218 219 const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num, 220 bool alternate_name) { 221 if (alternate_name) { 222 switch (reg_num) { 223 case dwarf_sp_mips: 224 return "r29"; 225 case dwarf_r30_mips: 226 return "r30"; 227 case dwarf_ra_mips: 228 return "r31"; 229 case dwarf_f0_mips: 230 return "f0"; 231 case dwarf_f1_mips: 232 return "f1"; 233 case dwarf_f2_mips: 234 return "f2"; 235 case dwarf_f3_mips: 236 return "f3"; 237 case dwarf_f4_mips: 238 return "f4"; 239 case dwarf_f5_mips: 240 return "f5"; 241 case dwarf_f6_mips: 242 return "f6"; 243 case dwarf_f7_mips: 244 return "f7"; 245 case dwarf_f8_mips: 246 return "f8"; 247 case dwarf_f9_mips: 248 return "f9"; 249 case dwarf_f10_mips: 250 return "f10"; 251 case dwarf_f11_mips: 252 return "f11"; 253 case dwarf_f12_mips: 254 return "f12"; 255 case dwarf_f13_mips: 256 return "f13"; 257 case dwarf_f14_mips: 258 return "f14"; 259 case dwarf_f15_mips: 260 return "f15"; 261 case dwarf_f16_mips: 262 return "f16"; 263 case dwarf_f17_mips: 264 return "f17"; 265 case dwarf_f18_mips: 266 return "f18"; 267 case dwarf_f19_mips: 268 return "f19"; 269 case dwarf_f20_mips: 270 return "f20"; 271 case dwarf_f21_mips: 272 return "f21"; 273 case dwarf_f22_mips: 274 return "f22"; 275 case dwarf_f23_mips: 276 return "f23"; 277 case dwarf_f24_mips: 278 return "f24"; 279 case dwarf_f25_mips: 280 return "f25"; 281 case dwarf_f26_mips: 282 return "f26"; 283 case dwarf_f27_mips: 284 return "f27"; 285 case dwarf_f28_mips: 286 return "f28"; 287 case dwarf_f29_mips: 288 return "f29"; 289 case dwarf_f30_mips: 290 return "f30"; 291 case dwarf_f31_mips: 292 return "f31"; 293 case dwarf_w0_mips: 294 return "w0"; 295 case dwarf_w1_mips: 296 return "w1"; 297 case dwarf_w2_mips: 298 return "w2"; 299 case dwarf_w3_mips: 300 return "w3"; 301 case dwarf_w4_mips: 302 return "w4"; 303 case dwarf_w5_mips: 304 return "w5"; 305 case dwarf_w6_mips: 306 return "w6"; 307 case dwarf_w7_mips: 308 return "w7"; 309 case dwarf_w8_mips: 310 return "w8"; 311 case dwarf_w9_mips: 312 return "w9"; 313 case dwarf_w10_mips: 314 return "w10"; 315 case dwarf_w11_mips: 316 return "w11"; 317 case dwarf_w12_mips: 318 return "w12"; 319 case dwarf_w13_mips: 320 return "w13"; 321 case dwarf_w14_mips: 322 return "w14"; 323 case dwarf_w15_mips: 324 return "w15"; 325 case dwarf_w16_mips: 326 return "w16"; 327 case dwarf_w17_mips: 328 return "w17"; 329 case dwarf_w18_mips: 330 return "w18"; 331 case dwarf_w19_mips: 332 return "w19"; 333 case dwarf_w20_mips: 334 return "w20"; 335 case dwarf_w21_mips: 336 return "w21"; 337 case dwarf_w22_mips: 338 return "w22"; 339 case dwarf_w23_mips: 340 return "w23"; 341 case dwarf_w24_mips: 342 return "w24"; 343 case dwarf_w25_mips: 344 return "w25"; 345 case dwarf_w26_mips: 346 return "w26"; 347 case dwarf_w27_mips: 348 return "w27"; 349 case dwarf_w28_mips: 350 return "w28"; 351 case dwarf_w29_mips: 352 return "w29"; 353 case dwarf_w30_mips: 354 return "w30"; 355 case dwarf_w31_mips: 356 return "w31"; 357 case dwarf_mir_mips: 358 return "mir"; 359 case dwarf_mcsr_mips: 360 return "mcsr"; 361 case dwarf_config5_mips: 362 return "config5"; 363 default: 364 break; 365 } 366 return nullptr; 367 } 368 369 switch (reg_num) { 370 case dwarf_zero_mips: 371 return "r0"; 372 case dwarf_r1_mips: 373 return "r1"; 374 case dwarf_r2_mips: 375 return "r2"; 376 case dwarf_r3_mips: 377 return "r3"; 378 case dwarf_r4_mips: 379 return "r4"; 380 case dwarf_r5_mips: 381 return "r5"; 382 case dwarf_r6_mips: 383 return "r6"; 384 case dwarf_r7_mips: 385 return "r7"; 386 case dwarf_r8_mips: 387 return "r8"; 388 case dwarf_r9_mips: 389 return "r9"; 390 case dwarf_r10_mips: 391 return "r10"; 392 case dwarf_r11_mips: 393 return "r11"; 394 case dwarf_r12_mips: 395 return "r12"; 396 case dwarf_r13_mips: 397 return "r13"; 398 case dwarf_r14_mips: 399 return "r14"; 400 case dwarf_r15_mips: 401 return "r15"; 402 case dwarf_r16_mips: 403 return "r16"; 404 case dwarf_r17_mips: 405 return "r17"; 406 case dwarf_r18_mips: 407 return "r18"; 408 case dwarf_r19_mips: 409 return "r19"; 410 case dwarf_r20_mips: 411 return "r20"; 412 case dwarf_r21_mips: 413 return "r21"; 414 case dwarf_r22_mips: 415 return "r22"; 416 case dwarf_r23_mips: 417 return "r23"; 418 case dwarf_r24_mips: 419 return "r24"; 420 case dwarf_r25_mips: 421 return "r25"; 422 case dwarf_r26_mips: 423 return "r26"; 424 case dwarf_r27_mips: 425 return "r27"; 426 case dwarf_gp_mips: 427 return "gp"; 428 case dwarf_sp_mips: 429 return "sp"; 430 case dwarf_r30_mips: 431 return "fp"; 432 case dwarf_ra_mips: 433 return "ra"; 434 case dwarf_sr_mips: 435 return "sr"; 436 case dwarf_lo_mips: 437 return "lo"; 438 case dwarf_hi_mips: 439 return "hi"; 440 case dwarf_bad_mips: 441 return "bad"; 442 case dwarf_cause_mips: 443 return "cause"; 444 case dwarf_pc_mips: 445 return "pc"; 446 case dwarf_f0_mips: 447 return "f0"; 448 case dwarf_f1_mips: 449 return "f1"; 450 case dwarf_f2_mips: 451 return "f2"; 452 case dwarf_f3_mips: 453 return "f3"; 454 case dwarf_f4_mips: 455 return "f4"; 456 case dwarf_f5_mips: 457 return "f5"; 458 case dwarf_f6_mips: 459 return "f6"; 460 case dwarf_f7_mips: 461 return "f7"; 462 case dwarf_f8_mips: 463 return "f8"; 464 case dwarf_f9_mips: 465 return "f9"; 466 case dwarf_f10_mips: 467 return "f10"; 468 case dwarf_f11_mips: 469 return "f11"; 470 case dwarf_f12_mips: 471 return "f12"; 472 case dwarf_f13_mips: 473 return "f13"; 474 case dwarf_f14_mips: 475 return "f14"; 476 case dwarf_f15_mips: 477 return "f15"; 478 case dwarf_f16_mips: 479 return "f16"; 480 case dwarf_f17_mips: 481 return "f17"; 482 case dwarf_f18_mips: 483 return "f18"; 484 case dwarf_f19_mips: 485 return "f19"; 486 case dwarf_f20_mips: 487 return "f20"; 488 case dwarf_f21_mips: 489 return "f21"; 490 case dwarf_f22_mips: 491 return "f22"; 492 case dwarf_f23_mips: 493 return "f23"; 494 case dwarf_f24_mips: 495 return "f24"; 496 case dwarf_f25_mips: 497 return "f25"; 498 case dwarf_f26_mips: 499 return "f26"; 500 case dwarf_f27_mips: 501 return "f27"; 502 case dwarf_f28_mips: 503 return "f28"; 504 case dwarf_f29_mips: 505 return "f29"; 506 case dwarf_f30_mips: 507 return "f30"; 508 case dwarf_f31_mips: 509 return "f31"; 510 case dwarf_fcsr_mips: 511 return "fcsr"; 512 case dwarf_fir_mips: 513 return "fir"; 514 case dwarf_w0_mips: 515 return "w0"; 516 case dwarf_w1_mips: 517 return "w1"; 518 case dwarf_w2_mips: 519 return "w2"; 520 case dwarf_w3_mips: 521 return "w3"; 522 case dwarf_w4_mips: 523 return "w4"; 524 case dwarf_w5_mips: 525 return "w5"; 526 case dwarf_w6_mips: 527 return "w6"; 528 case dwarf_w7_mips: 529 return "w7"; 530 case dwarf_w8_mips: 531 return "w8"; 532 case dwarf_w9_mips: 533 return "w9"; 534 case dwarf_w10_mips: 535 return "w10"; 536 case dwarf_w11_mips: 537 return "w11"; 538 case dwarf_w12_mips: 539 return "w12"; 540 case dwarf_w13_mips: 541 return "w13"; 542 case dwarf_w14_mips: 543 return "w14"; 544 case dwarf_w15_mips: 545 return "w15"; 546 case dwarf_w16_mips: 547 return "w16"; 548 case dwarf_w17_mips: 549 return "w17"; 550 case dwarf_w18_mips: 551 return "w18"; 552 case dwarf_w19_mips: 553 return "w19"; 554 case dwarf_w20_mips: 555 return "w20"; 556 case dwarf_w21_mips: 557 return "w21"; 558 case dwarf_w22_mips: 559 return "w22"; 560 case dwarf_w23_mips: 561 return "w23"; 562 case dwarf_w24_mips: 563 return "w24"; 564 case dwarf_w25_mips: 565 return "w25"; 566 case dwarf_w26_mips: 567 return "w26"; 568 case dwarf_w27_mips: 569 return "w27"; 570 case dwarf_w28_mips: 571 return "w28"; 572 case dwarf_w29_mips: 573 return "w29"; 574 case dwarf_w30_mips: 575 return "w30"; 576 case dwarf_w31_mips: 577 return "w31"; 578 case dwarf_mcsr_mips: 579 return "mcsr"; 580 case dwarf_mir_mips: 581 return "mir"; 582 case dwarf_config5_mips: 583 return "config5"; 584 } 585 return nullptr; 586 } 587 588 bool EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind, 589 uint32_t reg_num, 590 RegisterInfo ®_info) { 591 if (reg_kind == eRegisterKindGeneric) { 592 switch (reg_num) { 593 case LLDB_REGNUM_GENERIC_PC: 594 reg_kind = eRegisterKindDWARF; 595 reg_num = dwarf_pc_mips; 596 break; 597 case LLDB_REGNUM_GENERIC_SP: 598 reg_kind = eRegisterKindDWARF; 599 reg_num = dwarf_sp_mips; 600 break; 601 case LLDB_REGNUM_GENERIC_FP: 602 reg_kind = eRegisterKindDWARF; 603 reg_num = dwarf_r30_mips; 604 break; 605 case LLDB_REGNUM_GENERIC_RA: 606 reg_kind = eRegisterKindDWARF; 607 reg_num = dwarf_ra_mips; 608 break; 609 case LLDB_REGNUM_GENERIC_FLAGS: 610 reg_kind = eRegisterKindDWARF; 611 reg_num = dwarf_sr_mips; 612 break; 613 default: 614 return false; 615 } 616 } 617 618 if (reg_kind == eRegisterKindDWARF) { 619 ::memset(®_info, 0, sizeof(RegisterInfo)); 620 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); 621 622 if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips || 623 reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips || 624 reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) { 625 reg_info.byte_size = 4; 626 reg_info.format = eFormatHex; 627 reg_info.encoding = eEncodingUint; 628 } else if ((int)reg_num >= dwarf_zero_mips && 629 (int)reg_num <= dwarf_f31_mips) { 630 reg_info.byte_size = 4; 631 reg_info.format = eFormatHex; 632 reg_info.encoding = eEncodingUint; 633 } else if ((int)reg_num >= dwarf_w0_mips && 634 (int)reg_num <= dwarf_w31_mips) { 635 reg_info.byte_size = 16; 636 reg_info.format = eFormatVectorOfUInt8; 637 reg_info.encoding = eEncodingVector; 638 } else { 639 return false; 640 } 641 642 reg_info.name = GetRegisterName(reg_num, false); 643 reg_info.alt_name = GetRegisterName(reg_num, true); 644 reg_info.kinds[eRegisterKindDWARF] = reg_num; 645 646 switch (reg_num) { 647 case dwarf_r30_mips: 648 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; 649 break; 650 case dwarf_ra_mips: 651 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; 652 break; 653 case dwarf_sp_mips: 654 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; 655 break; 656 case dwarf_pc_mips: 657 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; 658 break; 659 case dwarf_sr_mips: 660 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; 661 break; 662 default: 663 break; 664 } 665 return true; 666 } 667 return false; 668 } 669 670 EmulateInstructionMIPS::MipsOpcode * 671 EmulateInstructionMIPS::GetOpcodeForInstruction(llvm::StringRef name) { 672 static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = { 673 // Prologue/Epilogue instructions 674 {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu, 675 "ADDIU rt, rs, immediate"}, 676 {"SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)"}, 677 {"LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)"}, 678 {"SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt"}, 679 {"ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt"}, 680 {"LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate"}, 681 682 // MicroMIPS Prologue/Epilogue instructions 683 {"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP, 684 "ADDIU immediate"}, 685 {"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5, 686 "ADDIUS5 rd,immediate"}, 687 {"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)"}, 688 {"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, 689 "SWM16 reglist,offset(sp)"}, 690 {"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, 691 "SWM32 reglist,offset(base)"}, 692 {"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, 693 "SWP rs1,offset(base)"}, 694 {"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)"}, 695 {"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, 696 "LWM16 reglist,offset(sp)"}, 697 {"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, 698 "LWM32 reglist,offset(base)"}, 699 {"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, 700 "LWP rd,offset(base)"}, 701 {"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP, 702 "JRADDIUSP immediate"}, 703 704 // Load/Store instructions 705 /* Following list of emulated instructions are required by implementation 706 of hardware watchpoint 707 for MIPS in lldb. As we just need the address accessed by instructions, 708 we have generalised 709 all these instructions in 2 functions depending on their addressing 710 modes */ 711 712 {"LB", &EmulateInstructionMIPS::Emulate_LDST_Imm, 713 "LB rt, offset(base)"}, 714 {"LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 715 "LBE rt, offset(base)"}, 716 {"LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm, 717 "LBU rt, offset(base)"}, 718 {"LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 719 "LBUE rt, offset(base)"}, 720 {"LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, 721 "LDC1 ft, offset(base)"}, 722 {"LD", &EmulateInstructionMIPS::Emulate_LDST_Imm, 723 "LD rt, offset(base)"}, 724 {"LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm, 725 "LDL rt, offset(base)"}, 726 {"LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm, 727 "LDR rt, offset(base)"}, 728 {"LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm, 729 "LLD rt, offset(base)"}, 730 {"LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, 731 "LDC2 rt, offset(base)"}, 732 {"LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, 733 "LDXC1 fd, index (base)"}, 734 {"LH", &EmulateInstructionMIPS::Emulate_LDST_Imm, 735 "LH rt, offset(base)"}, 736 {"LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 737 "LHE rt, offset(base)"}, 738 {"LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm, 739 "LHU rt, offset(base)"}, 740 {"LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 741 "LHUE rt, offset(base)"}, 742 {"LL", &EmulateInstructionMIPS::Emulate_LDST_Imm, 743 "LL rt, offset(base)"}, 744 {"LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 745 "LLE rt, offset(base)"}, 746 {"LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, 747 "LUXC1 fd, index (base)"}, 748 {"LW", &EmulateInstructionMIPS::Emulate_LDST_Imm, 749 "LW rt, offset(base)"}, 750 {"LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, 751 "LWC1 ft, offset(base)"}, 752 {"LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, 753 "LWC2 rt, offset(base)"}, 754 {"LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 755 "LWE rt, offset(base)"}, 756 {"LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm, 757 "LWL rt, offset(base)"}, 758 {"LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 759 "LWLE rt, offset(base)"}, 760 {"LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm, 761 "LWR rt, offset(base)"}, 762 {"LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 763 "LWRE rt, offset(base)"}, 764 {"LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, 765 "LWXC1 fd, index (base)"}, 766 {"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm, 767 "LLX rt, offset(base)"}, 768 {"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 769 "LLXE rt, offset(base)"}, 770 {"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, 771 "LLDX rt, offset(base)"}, 772 773 {"SB", &EmulateInstructionMIPS::Emulate_LDST_Imm, 774 "SB rt, offset(base)"}, 775 {"SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 776 "SBE rt, offset(base)"}, 777 {"SC", &EmulateInstructionMIPS::Emulate_LDST_Imm, 778 "SC rt, offset(base)"}, 779 {"SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 780 "SCE rt, offset(base)"}, 781 {"SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm, 782 "SCD rt, offset(base)"}, 783 {"SD", &EmulateInstructionMIPS::Emulate_LDST_Imm, 784 "SD rt, offset(base)"}, 785 {"SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm, 786 "SDL rt, offset(base)"}, 787 {"SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm, 788 "SDR rt, offset(base)"}, 789 {"SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, 790 "SDC1 ft, offset(base)"}, 791 {"SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, 792 "SDC2 rt, offset(base)"}, 793 {"SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, 794 "SDXC1 fs, index(base)"}, 795 {"SH", &EmulateInstructionMIPS::Emulate_LDST_Imm, 796 "SH rt, offset(base)"}, 797 {"SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 798 "SHE rt, offset(base)"}, 799 {"SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, 800 "SUXC1 fs, index (base)"}, 801 {"SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, 802 "SWC1 ft, offset(base)"}, 803 {"SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, 804 "SWC2 rt, offset(base)"}, 805 {"SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 806 "SWE rt, offset(base)"}, 807 {"SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm, 808 "SWL rt, offset(base)"}, 809 {"SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 810 "SWLE rt, offset(base)"}, 811 {"SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm, 812 "SWR rt, offset(base)"}, 813 {"SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 814 "SWRE rt, offset(base)"}, 815 {"SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, 816 "SWXC1 fs, index (base)"}, 817 {"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm, 818 "SCX rt, offset(base)"}, 819 {"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, 820 "SCXE rt, offset(base)"}, 821 {"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, 822 "SCDX rt, offset(base)"}, 823 824 // MicroMIPS Load/Store instructions 825 {"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 826 "LBU16 rt, decoded_offset(base)"}, 827 {"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 828 "LHU16 rt, left_shifted_offset(base)"}, 829 {"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 830 "LW16 rt, left_shifted_offset(base)"}, 831 {"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 832 "LWGP rt, left_shifted_offset(gp)"}, 833 {"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 834 "SH16 rt, left_shifted_offset(base)"}, 835 {"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 836 "SW16 rt, left_shifted_offset(base)"}, 837 {"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 838 "SWSP rt, left_shifted_offset(base)"}, 839 {"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, 840 "SB16 rt, offset(base)"}, 841 842 // Branch instructions 843 {"BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset"}, 844 {"BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset"}, 845 {"BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset"}, 846 {"BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset"}, 847 {"BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link, 848 "BGEZALL rt,offset"}, 849 {"BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset"}, 850 {"BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link, 851 "BGEZAL rs,offset"}, 852 {"BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset"}, 853 {"BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset"}, 854 {"BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset"}, 855 {"BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C, 856 "BLEZALC rs,offset"}, 857 {"BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C, 858 "BGEZALC rs,offset"}, 859 {"BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C, 860 "BLTZALC rs,offset"}, 861 {"BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C, 862 "BGTZALC rs,offset"}, 863 {"BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C, 864 "BEQZALC rs,offset"}, 865 {"BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C, 866 "BNEZALC rs,offset"}, 867 {"BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 868 "BEQC rs,rt,offset"}, 869 {"BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 870 "BNEC rs,rt,offset"}, 871 {"BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 872 "BLTC rs,rt,offset"}, 873 {"BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 874 "BGEC rs,rt,offset"}, 875 {"BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 876 "BLTUC rs,rt,offset"}, 877 {"BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 878 "BGEUC rs,rt,offset"}, 879 {"BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset"}, 880 {"BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset"}, 881 {"BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset"}, 882 {"BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset"}, 883 {"BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset"}, 884 {"BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset"}, 885 {"BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset"}, 886 {"BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset"}, 887 {"BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset"}, 888 {"BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset"}, 889 {"BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset"}, 890 {"BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset"}, 891 {"BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link, 892 "BLTZAL rt,offset"}, 893 {"BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link, 894 "BLTZALL rt,offset"}, 895 {"BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset"}, 896 {"BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 897 "BOVC rs,rt,offset"}, 898 {"BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, 899 "BNVC rs,rt,offset"}, 900 {"J", &EmulateInstructionMIPS::Emulate_J, "J target"}, 901 {"JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target"}, 902 {"JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target"}, 903 {"JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target"}, 904 {"JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target"}, 905 {"JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset"}, 906 {"JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset"}, 907 {"JR", &EmulateInstructionMIPS::Emulate_JR, "JR target"}, 908 {"JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target"}, 909 {"BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset"}, 910 {"BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset"}, 911 {"BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset"}, 912 {"BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset"}, 913 {"BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset"}, 914 {"BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset"}, 915 {"BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch, 916 "BC1ANY2F cc, offset"}, 917 {"BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch, 918 "BC1ANY2T cc, offset"}, 919 {"BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch, 920 "BC1ANY4F cc, offset"}, 921 {"BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch, 922 "BC1ANY4T cc, offset"}, 923 {"BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16"}, 924 {"BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16"}, 925 {"BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16"}, 926 {"BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16"}, 927 {"BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16"}, 928 {"BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16"}, 929 {"BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16"}, 930 {"BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16"}, 931 {"BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16"}, 932 {"BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16"}, 933 934 // MicroMIPS Branch instructions 935 {"B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset"}, 936 {"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, 937 "BEQZ16 rs, offset"}, 938 {"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, 939 "BNEZ16 rs, offset"}, 940 {"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, 941 "BEQZC rs, offset"}, 942 {"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, 943 "BNEZC rs, offset"}, 944 {"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, 945 "BGEZALS rs, offset"}, 946 {"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, 947 "BLTZALS rs, offset"}, 948 {"JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs"}, 949 {"JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs"}, 950 {"JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs"}, 951 {"JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs"}, 952 {"JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target"}, 953 {"JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target"}, 954 {"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs"}, 955 }; 956 957 for (MipsOpcode &opcode : g_opcodes) { 958 if (name.equals_insensitive(opcode.op_name)) 959 return &opcode; 960 } 961 return nullptr; 962 } 963 964 uint32_t 965 EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor &data, 966 uint64_t inst_addr) { 967 uint64_t next_inst_size = 0; 968 llvm::MCInst mc_insn; 969 llvm::MCDisassembler::DecodeStatus decode_status; 970 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize()); 971 972 if (m_use_alt_disaasm) 973 decode_status = m_alt_disasm->getInstruction( 974 mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls()); 975 else 976 decode_status = m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn, 977 inst_addr, llvm::nulls()); 978 979 if (decode_status != llvm::MCDisassembler::Success) 980 return false; 981 982 return m_insn_info->get(mc_insn.getOpcode()).getSize(); 983 } 984 985 bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode, 986 const Address &inst_addr, 987 Target *target) { 988 m_use_alt_disaasm = false; 989 990 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 991 if (inst_addr.GetAddressClass() == AddressClass::eCodeAlternateISA) { 992 Status error; 993 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 994 995 /* 996 * The address belongs to microMIPS function. To find the size of 997 * next instruction use microMIPS disassembler. 998 */ 999 m_use_alt_disaasm = true; 1000 1001 uint32_t current_inst_size = insn_opcode.GetByteSize(); 1002 uint8_t buf[sizeof(uint32_t)]; 1003 uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size; 1004 Address next_addr(next_inst_addr); 1005 1006 const size_t bytes_read = 1007 target->ReadMemory(next_addr, /* Address of next instruction */ 1008 buf, sizeof(uint32_t), error, 1009 false, /* force_live_memory */ 1010 &load_addr); 1011 1012 if (bytes_read == 0) 1013 return true; 1014 1015 DataExtractor data(buf, sizeof(uint32_t), GetByteOrder(), 1016 GetAddressByteSize()); 1017 m_next_inst_size = GetSizeOfInstruction(data, next_inst_addr); 1018 return true; 1019 } else { 1020 /* 1021 * If the address class is not AddressClass::eCodeAlternateISA then 1022 * the function is not microMIPS. In this case instruction size is 1023 * always 4 bytes. 1024 */ 1025 m_next_inst_size = 4; 1026 return true; 1027 } 1028 } 1029 return false; 1030 } 1031 1032 bool EmulateInstructionMIPS::ReadInstruction() { 1033 bool success = false; 1034 m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 1035 LLDB_INVALID_ADDRESS, &success); 1036 if (success) { 1037 Context read_inst_context; 1038 read_inst_context.type = eContextReadOpcode; 1039 read_inst_context.SetNoArgs(); 1040 m_opcode.SetOpcode32( 1041 ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success), 1042 GetByteOrder()); 1043 } 1044 if (!success) 1045 m_addr = LLDB_INVALID_ADDRESS; 1046 return success; 1047 } 1048 1049 bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options) { 1050 bool success = false; 1051 llvm::MCInst mc_insn; 1052 uint64_t insn_size; 1053 DataExtractor data; 1054 1055 /* Keep the complexity of the decode logic with the llvm::MCDisassembler 1056 * class. */ 1057 if (m_opcode.GetData(data)) { 1058 llvm::MCDisassembler::DecodeStatus decode_status; 1059 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize()); 1060 if (m_use_alt_disaasm) 1061 decode_status = m_alt_disasm->getInstruction(mc_insn, insn_size, raw_insn, 1062 m_addr, llvm::nulls()); 1063 else 1064 decode_status = m_disasm->getInstruction(mc_insn, insn_size, raw_insn, 1065 m_addr, llvm::nulls()); 1066 1067 if (decode_status != llvm::MCDisassembler::Success) 1068 return false; 1069 } 1070 1071 /* 1072 * mc_insn.getOpcode() returns decoded opcode. However to make use 1073 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc". 1074 */ 1075 const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data(); 1076 1077 if (op_name == nullptr) 1078 return false; 1079 1080 /* 1081 * Decoding has been done already. Just get the call-back function 1082 * and emulate the instruction. 1083 */ 1084 MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name); 1085 1086 if (opcode_data == nullptr) 1087 return false; 1088 1089 uint64_t old_pc = 0, new_pc = 0; 1090 const bool auto_advance_pc = 1091 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 1092 1093 if (auto_advance_pc) { 1094 old_pc = 1095 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1096 if (!success) 1097 return false; 1098 } 1099 1100 /* emulate instruction */ 1101 success = (this->*opcode_data->callback)(mc_insn); 1102 if (!success) 1103 return false; 1104 1105 if (auto_advance_pc) { 1106 new_pc = 1107 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1108 if (!success) 1109 return false; 1110 1111 /* If we haven't changed the PC, change it here */ 1112 if (old_pc == new_pc) { 1113 new_pc += 4; 1114 Context context; 1115 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1116 new_pc)) 1117 return false; 1118 } 1119 } 1120 1121 return true; 1122 } 1123 1124 bool EmulateInstructionMIPS::CreateFunctionEntryUnwind( 1125 UnwindPlan &unwind_plan) { 1126 unwind_plan.Clear(); 1127 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 1128 1129 UnwindPlan::RowSP row(new UnwindPlan::Row); 1130 const bool can_replace = false; 1131 1132 // Our previous Call Frame Address is the stack pointer 1133 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0); 1134 1135 // Our previous PC is in the RA 1136 row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace); 1137 1138 unwind_plan.AppendRow(row); 1139 1140 // All other registers are the same. 1141 unwind_plan.SetSourceName("EmulateInstructionMIPS"); 1142 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 1143 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 1144 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 1145 unwind_plan.SetReturnAddressRegister(dwarf_ra_mips); 1146 1147 return true; 1148 } 1149 1150 bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) { 1151 switch (regnum) { 1152 case dwarf_r16_mips: 1153 case dwarf_r17_mips: 1154 case dwarf_r18_mips: 1155 case dwarf_r19_mips: 1156 case dwarf_r20_mips: 1157 case dwarf_r21_mips: 1158 case dwarf_r22_mips: 1159 case dwarf_r23_mips: 1160 case dwarf_gp_mips: 1161 case dwarf_sp_mips: 1162 case dwarf_r30_mips: 1163 case dwarf_ra_mips: 1164 return true; 1165 default: 1166 return false; 1167 } 1168 return false; 1169 } 1170 1171 bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) { 1172 // ADDIU rt, rs, immediate 1173 // GPR[rt] <- GPR[rs] + sign_extend(immediate) 1174 1175 uint8_t dst, src; 1176 bool success = false; 1177 const uint32_t imm16 = insn.getOperand(2).getImm(); 1178 int64_t imm = SignedBits(imm16, 15, 0); 1179 1180 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1181 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1182 1183 // If immediate value is greater then 2^16 - 1 then clang generate LUI, 1184 // ADDIU, SUBU instructions in prolog. Example lui $1, 0x2 addiu $1, $1, 1185 // -0x5920 subu $sp, $sp, $1 In this case, ADDIU dst and src will be same 1186 // and not equal to sp 1187 if (dst == src) { 1188 Context context; 1189 1190 /* read <src> register */ 1191 const int64_t src_opd_val = ReadRegisterUnsigned( 1192 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); 1193 if (!success) 1194 return false; 1195 1196 /* Check if this is daddiu sp, sp, imm16 */ 1197 if (dst == dwarf_sp_mips) { 1198 uint64_t result = src_opd_val + imm; 1199 RegisterInfo reg_info_sp; 1200 1201 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1202 context.SetRegisterPlusOffset(reg_info_sp, imm); 1203 1204 /* We are allocating bytes on stack */ 1205 context.type = eContextAdjustStackPointer; 1206 1207 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result); 1208 return true; 1209 } 1210 1211 imm += src_opd_val; 1212 context.SetImmediateSigned(imm); 1213 context.type = eContextImmediate; 1214 1215 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 1216 dwarf_zero_mips + dst, imm)) 1217 return false; 1218 } 1219 1220 return true; 1221 } 1222 1223 bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) { 1224 bool success = false; 1225 uint32_t imm16 = insn.getOperand(2).getImm(); 1226 uint32_t imm = SignedBits(imm16, 15, 0); 1227 uint32_t src, base; 1228 int32_t address; 1229 Context bad_vaddr_context; 1230 1231 RegisterInfo reg_info_base; 1232 1233 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1234 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1235 1236 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 1237 reg_info_base)) 1238 return false; 1239 1240 /* read base register */ 1241 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1242 dwarf_zero_mips + base, 0, &success); 1243 if (!success) 1244 return false; 1245 1246 /* destination address */ 1247 address = address + imm; 1248 1249 /* Set the bad_vaddr register with base address used in the instruction */ 1250 bad_vaddr_context.type = eContextInvalid; 1251 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 1252 address); 1253 1254 /* We look for sp based non-volatile register stores */ 1255 if (nonvolatile_reg_p(src)) { 1256 1257 RegisterInfo reg_info_src; 1258 1259 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src, 1260 reg_info_src)) 1261 return false; 1262 1263 Context context; 1264 RegisterValue data_src; 1265 context.type = eContextPushRegisterOnStack; 1266 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0); 1267 1268 uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; 1269 Status error; 1270 1271 if (!ReadRegister(®_info_base, data_src)) 1272 return false; 1273 1274 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size, 1275 eByteOrderLittle, error) == 0) 1276 return false; 1277 1278 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size)) 1279 return false; 1280 1281 return true; 1282 } 1283 1284 return false; 1285 } 1286 1287 bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) { 1288 bool success = false; 1289 uint32_t src, base; 1290 int32_t imm, address; 1291 Context bad_vaddr_context; 1292 1293 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1294 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1295 imm = insn.getOperand(2).getImm(); 1296 1297 RegisterInfo reg_info_base; 1298 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 1299 reg_info_base)) 1300 return false; 1301 1302 /* read base register */ 1303 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1304 dwarf_zero_mips + base, 0, &success); 1305 if (!success) 1306 return false; 1307 1308 /* destination address */ 1309 address = address + imm; 1310 1311 /* Set the bad_vaddr register with base address used in the instruction */ 1312 bad_vaddr_context.type = eContextInvalid; 1313 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 1314 address); 1315 1316 if (nonvolatile_reg_p(src)) { 1317 RegisterValue data_src; 1318 RegisterInfo reg_info_src; 1319 1320 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src, 1321 reg_info_src)) 1322 return false; 1323 1324 Context context; 1325 context.type = eContextPopRegisterOffStack; 1326 context.SetAddress(address); 1327 1328 return WriteRegister(context, ®_info_src, data_src); 1329 } 1330 1331 return false; 1332 } 1333 1334 bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) { 1335 // SUBU sp, <src>, <rt> 1336 // ADDU sp, <src>, <rt> 1337 // ADDU dst, sp, <rt> 1338 1339 bool success = false; 1340 uint64_t result; 1341 uint8_t src, dst, rt; 1342 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1343 1344 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1345 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1346 1347 /* Check if sp is destination register */ 1348 if (dst == dwarf_sp_mips) { 1349 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg()); 1350 1351 /* read <src> register */ 1352 uint64_t src_opd_val = ReadRegisterUnsigned( 1353 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); 1354 if (!success) 1355 return false; 1356 1357 /* read <rt > register */ 1358 uint64_t rt_opd_val = ReadRegisterUnsigned( 1359 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); 1360 if (!success) 1361 return false; 1362 1363 if (op_name.equals_insensitive("SUBU")) 1364 result = src_opd_val - rt_opd_val; 1365 else 1366 result = src_opd_val + rt_opd_val; 1367 1368 Context context; 1369 RegisterInfo reg_info_sp; 1370 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1371 context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val); 1372 1373 /* We are allocating bytes on stack */ 1374 context.type = eContextAdjustStackPointer; 1375 1376 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result); 1377 1378 return true; 1379 } else if (src == dwarf_sp_mips) { 1380 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg()); 1381 1382 /* read <src> register */ 1383 uint64_t src_opd_val = ReadRegisterUnsigned( 1384 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); 1385 if (!success) 1386 return false; 1387 1388 /* read <rt> register */ 1389 uint64_t rt_opd_val = ReadRegisterUnsigned( 1390 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); 1391 if (!success) 1392 return false; 1393 1394 Context context; 1395 1396 if (op_name.equals_insensitive("SUBU")) 1397 result = src_opd_val - rt_opd_val; 1398 else 1399 result = src_opd_val + rt_opd_val; 1400 1401 context.SetImmediateSigned(result); 1402 context.type = eContextImmediate; 1403 1404 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 1405 dwarf_zero_mips + dst, result)) 1406 return false; 1407 } 1408 1409 return true; 1410 } 1411 1412 bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) { 1413 // LUI rt, immediate 1414 // GPR[rt] <- sign_extend(immediate << 16) 1415 1416 const uint32_t imm32 = insn.getOperand(1).getImm() << 16; 1417 int64_t imm = SignedBits(imm32, 31, 0); 1418 uint8_t rt; 1419 Context context; 1420 1421 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1422 context.SetImmediateSigned(imm); 1423 context.type = eContextImmediate; 1424 1425 return WriteRegisterUnsigned(context, eRegisterKindDWARF, 1426 dwarf_zero_mips + rt, imm); 1427 } 1428 1429 bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) { 1430 bool success = false; 1431 const uint32_t imm9 = insn.getOperand(0).getImm(); 1432 uint64_t result; 1433 1434 // This instruction operates implicitly on stack pointer, so read <sp> 1435 // register. 1436 uint64_t src_opd_val = 1437 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success); 1438 if (!success) 1439 return false; 1440 1441 result = src_opd_val + imm9; 1442 1443 Context context; 1444 RegisterInfo reg_info_sp; 1445 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1446 context.SetRegisterPlusOffset(reg_info_sp, imm9); 1447 1448 // We are adjusting the stack. 1449 context.type = eContextAdjustStackPointer; 1450 1451 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result); 1452 return true; 1453 } 1454 1455 bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) { 1456 bool success = false; 1457 uint32_t base; 1458 const uint32_t imm4 = insn.getOperand(2).getImm(); 1459 uint64_t result; 1460 1461 // The source and destination register is same for this instruction. 1462 base = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1463 1464 // We are looking for stack adjustment only 1465 if (base == dwarf_sp_mips) { 1466 // Read stack pointer register 1467 uint64_t src_opd_val = ReadRegisterUnsigned( 1468 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1469 if (!success) 1470 return false; 1471 1472 result = src_opd_val + imm4; 1473 1474 Context context; 1475 RegisterInfo reg_info_sp; 1476 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1477 context.SetRegisterPlusOffset(reg_info_sp, imm4); 1478 1479 // We are adjusting the stack. 1480 context.type = eContextAdjustStackPointer; 1481 1482 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result); 1483 } 1484 1485 return true; 1486 } 1487 1488 bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) { 1489 bool success = false; 1490 uint32_t imm5 = insn.getOperand(2).getImm(); 1491 uint32_t src, base; 1492 Context bad_vaddr_context; 1493 uint32_t address; 1494 1495 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1496 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1497 1498 RegisterInfo reg_info_base; 1499 1500 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 1501 reg_info_base)) 1502 return false; 1503 1504 // read base register 1505 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0, 1506 &success); 1507 if (!success) 1508 return false; 1509 1510 // destination address 1511 address = address + imm5; 1512 1513 // We use bad_vaddr_context to store base address which is used by H/W 1514 // watchpoint Set the bad_vaddr register with base address used in the 1515 // instruction 1516 bad_vaddr_context.type = eContextInvalid; 1517 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 1518 address); 1519 1520 // We look for sp based non-volatile register stores. 1521 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) { 1522 RegisterInfo reg_info_src = {}; 1523 Context context; 1524 RegisterValue data_src; 1525 context.type = eContextPushRegisterOnStack; 1526 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0); 1527 1528 uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; 1529 Status error; 1530 1531 if (!ReadRegister(®_info_base, data_src)) 1532 return false; 1533 1534 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size, 1535 eByteOrderLittle, error) == 0) 1536 return false; 1537 1538 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size)) 1539 return false; 1540 1541 return true; 1542 } 1543 1544 return false; 1545 } 1546 1547 /* Emulate SWM16,SWM32 and SWP instruction. 1548 1549 SWM16 always has stack pointer as a base register (but it is still available 1550 in MCInst as an operand). 1551 SWM32 and SWP can have base register other than stack pointer. 1552 */ 1553 bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) { 1554 bool success = false; 1555 uint32_t src, base; 1556 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on 1557 // no of regs to store. 1558 1559 // Base register is second last operand of the instruction. 1560 base = 1561 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 1562 1563 // We are looking for sp based stores so if base is not a stack pointer then 1564 // don't proceed. 1565 if (base != dwarf_sp_mips) 1566 return false; 1567 1568 // offset is always the last operand. 1569 uint32_t offset = insn.getOperand(num_operands - 1).getImm(); 1570 1571 RegisterInfo reg_info_base; 1572 RegisterInfo reg_info_src; 1573 1574 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 1575 reg_info_base)) 1576 return false; 1577 1578 // read SP 1579 uint32_t base_address = ReadRegisterUnsigned( 1580 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1581 if (!success) 1582 return false; 1583 1584 // Resulting base addrss 1585 base_address = base_address + offset; 1586 1587 // Total no of registers to be stored are num_operands-2. 1588 for (uint32_t i = 0; i < num_operands - 2; i++) { 1589 // Get the register number to be stored. 1590 src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg()); 1591 1592 /* 1593 Record only non-volatile stores. 1594 This check is required for SWP instruction because source operand could 1595 be any register. 1596 SWM16 and SWM32 instruction always has saved registers as source 1597 operands. 1598 */ 1599 if (!nonvolatile_reg_p(src)) 1600 return false; 1601 1602 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src, 1603 reg_info_src)) 1604 return false; 1605 1606 Context context; 1607 RegisterValue data_src; 1608 context.type = eContextPushRegisterOnStack; 1609 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0); 1610 1611 uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; 1612 Status error; 1613 1614 if (!ReadRegister(®_info_base, data_src)) 1615 return false; 1616 1617 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size, 1618 eByteOrderLittle, error) == 0) 1619 return false; 1620 1621 if (!WriteMemory(context, base_address, buffer, reg_info_src.byte_size)) 1622 return false; 1623 1624 // Stack address for next register 1625 base_address = base_address + reg_info_src.byte_size; 1626 } 1627 return true; 1628 } 1629 1630 bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) { 1631 bool success = false; 1632 uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1633 uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1634 uint32_t imm5 = insn.getOperand(2).getImm(); 1635 Context bad_vaddr_context; 1636 1637 RegisterInfo reg_info_base; 1638 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 1639 reg_info_base)) 1640 return false; 1641 1642 // read base register 1643 uint32_t base_address = ReadRegisterUnsigned( 1644 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1645 if (!success) 1646 return false; 1647 1648 base_address = base_address + imm5; 1649 1650 // We use bad_vaddr_context to store base address which is used by H/W 1651 // watchpoint Set the bad_vaddr register with base address used in the 1652 // instruction 1653 bad_vaddr_context.type = eContextInvalid; 1654 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 1655 base_address); 1656 1657 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) { 1658 RegisterValue data_src; 1659 RegisterInfo reg_info_src; 1660 1661 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src, 1662 reg_info_src)) 1663 return false; 1664 1665 Context context; 1666 context.type = eContextPopRegisterOffStack; 1667 context.SetAddress(base_address); 1668 1669 return WriteRegister(context, ®_info_src, data_src); 1670 } 1671 1672 return false; 1673 } 1674 1675 /* Emulate LWM16, LWM32 and LWP instructions. 1676 1677 LWM16 always has stack pointer as a base register (but it is still available 1678 in MCInst as an operand). 1679 LWM32 and LWP can have base register other than stack pointer. 1680 */ 1681 bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) { 1682 bool success = false; 1683 uint32_t dst, base; 1684 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on 1685 // no of regs to store. 1686 uint32_t imm = insn.getOperand(num_operands - 1) 1687 .getImm(); // imm is the last operand in the instruction. 1688 1689 // Base register is second last operand of the instruction. 1690 base = 1691 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 1692 1693 // We are looking for sp based loads so if base is not a stack pointer then 1694 // don't proceed. 1695 if (base != dwarf_sp_mips) 1696 return false; 1697 1698 uint32_t base_address = ReadRegisterUnsigned( 1699 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1700 if (!success) 1701 return false; 1702 1703 base_address = base_address + imm; 1704 1705 RegisterValue data_dst; 1706 RegisterInfo reg_info_dst; 1707 1708 // Total no of registers to be re-stored are num_operands-2. 1709 for (uint32_t i = 0; i < num_operands - 2; i++) { 1710 // Get the register number to be re-stored. 1711 dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg()); 1712 1713 /* 1714 Record only non-volatile loads. 1715 This check is required for LWP instruction because destination operand 1716 could be any register. 1717 LWM16 and LWM32 instruction always has saved registers as destination 1718 operands. 1719 */ 1720 if (!nonvolatile_reg_p(dst)) 1721 return false; 1722 1723 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst, 1724 reg_info_dst)) 1725 return false; 1726 1727 Context context; 1728 context.type = eContextPopRegisterOffStack; 1729 context.SetAddress(base_address + (i * 4)); 1730 1731 if (!WriteRegister(context, ®_info_dst, data_dst)) 1732 return false; 1733 } 1734 1735 return true; 1736 } 1737 1738 bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) { 1739 bool success = false; 1740 int32_t imm5 = insn.getOperand(0).getImm(); 1741 1742 /* JRADDIUSP immediate 1743 * PC <- RA 1744 * SP <- SP + zero_extend(Immediate << 2) 1745 */ 1746 1747 // This instruction operates implicitly on stack pointer, so read <sp> 1748 // register. 1749 int32_t src_opd_val = 1750 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success); 1751 if (!success) 1752 return false; 1753 1754 int32_t ra_val = 1755 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success); 1756 if (!success) 1757 return false; 1758 1759 int32_t result = src_opd_val + imm5; 1760 1761 Context context; 1762 1763 // Update the PC 1764 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1765 ra_val)) 1766 return false; 1767 1768 RegisterInfo reg_info_sp; 1769 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1770 context.SetRegisterPlusOffset(reg_info_sp, imm5); 1771 1772 // We are adjusting stack 1773 context.type = eContextAdjustStackPointer; 1774 1775 // update SP 1776 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, 1777 result); 1778 } 1779 1780 static int IsAdd64bitOverflow(int32_t a, int32_t b) { 1781 int32_t r = (uint32_t)a + (uint32_t)b; 1782 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0); 1783 } 1784 1785 /* 1786 Emulate below MIPS branch instructions. 1787 BEQ, BNE : Branch on condition 1788 BEQL, BNEL : Branch likely 1789 */ 1790 bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) { 1791 bool success = false; 1792 uint32_t rs, rt; 1793 int32_t offset, pc, target = 0, rs_val, rt_val; 1794 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1795 1796 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1797 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1798 offset = insn.getOperand(2).getImm(); 1799 1800 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1801 if (!success) 1802 return false; 1803 1804 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1805 dwarf_zero_mips + rs, 0, &success); 1806 if (!success) 1807 return false; 1808 1809 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1810 dwarf_zero_mips + rt, 0, &success); 1811 if (!success) 1812 return false; 1813 1814 if (op_name.equals_insensitive("BEQ") || op_name.equals_insensitive("BEQL")) { 1815 if (rs_val == rt_val) 1816 target = pc + offset; 1817 else 1818 target = pc + 8; 1819 } else if (op_name.equals_insensitive("BNE") || 1820 op_name.equals_insensitive("BNEL")) { 1821 if (rs_val != rt_val) 1822 target = pc + offset; 1823 else 1824 target = pc + 8; 1825 } 1826 1827 Context context; 1828 context.type = eContextRelativeBranchImmediate; 1829 context.SetImmediate(offset); 1830 1831 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1832 target); 1833 } 1834 1835 /* 1836 Emulate below MIPS branch instructions. 1837 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch 1838 instructions with no delay slot 1839 */ 1840 bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) { 1841 bool success = false; 1842 uint32_t rs, rt; 1843 int32_t offset, pc, target = 0, rs_val, rt_val; 1844 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1845 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 1846 1847 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1848 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1849 offset = insn.getOperand(2).getImm(); 1850 1851 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1852 if (!success) 1853 return false; 1854 1855 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1856 dwarf_zero_mips + rs, 0, &success); 1857 if (!success) 1858 return false; 1859 1860 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1861 dwarf_zero_mips + rt, 0, &success); 1862 if (!success) 1863 return false; 1864 1865 if (op_name.equals_insensitive("BEQC")) { 1866 if (rs_val == rt_val) 1867 target = pc + offset; 1868 else 1869 target = pc + 4; 1870 } else if (op_name.equals_insensitive("BNEC")) { 1871 if (rs_val != rt_val) 1872 target = pc + offset; 1873 else 1874 target = pc + 4; 1875 } else if (op_name.equals_insensitive("BLTC")) { 1876 if (rs_val < rt_val) 1877 target = pc + offset; 1878 else 1879 target = pc + 4; 1880 } else if (op_name.equals_insensitive("BGEC")) { 1881 if (rs_val >= rt_val) 1882 target = pc + offset; 1883 else 1884 target = pc + 4; 1885 } else if (op_name.equals_insensitive("BLTUC")) { 1886 if (rs_val < rt_val) 1887 target = pc + offset; 1888 else 1889 target = pc + 4; 1890 } else if (op_name.equals_insensitive("BGEUC")) { 1891 if ((uint32_t)rs_val >= (uint32_t)rt_val) 1892 target = pc + offset; 1893 else 1894 target = pc + 4; 1895 } else if (op_name.equals_insensitive("BOVC")) { 1896 if (IsAdd64bitOverflow(rs_val, rt_val)) 1897 target = pc + offset; 1898 else 1899 target = pc + 4; 1900 } else if (op_name.equals_insensitive("BNVC")) { 1901 if (!IsAdd64bitOverflow(rs_val, rt_val)) 1902 target = pc + offset; 1903 else 1904 target = pc + 4; 1905 } 1906 1907 Context context; 1908 context.type = eContextRelativeBranchImmediate; 1909 context.SetImmediate(current_inst_size + offset); 1910 1911 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1912 target); 1913 } 1914 1915 /* 1916 Emulate below MIPS conditional branch and link instructions. 1917 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches 1918 */ 1919 bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) { 1920 bool success = false; 1921 uint32_t rs; 1922 int32_t offset, pc, target = 0; 1923 int32_t rs_val; 1924 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1925 1926 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1927 offset = insn.getOperand(1).getImm(); 1928 1929 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1930 if (!success) 1931 return false; 1932 1933 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1934 dwarf_zero_mips + rs, 0, &success); 1935 if (!success) 1936 return false; 1937 1938 if (op_name.equals_insensitive("BLEZALC")) { 1939 if (rs_val <= 0) 1940 target = pc + offset; 1941 else 1942 target = pc + 4; 1943 } else if (op_name.equals_insensitive("BGEZALC")) { 1944 if (rs_val >= 0) 1945 target = pc + offset; 1946 else 1947 target = pc + 4; 1948 } else if (op_name.equals_insensitive("BLTZALC")) { 1949 if (rs_val < 0) 1950 target = pc + offset; 1951 else 1952 target = pc + 4; 1953 } else if (op_name.equals_insensitive("BGTZALC")) { 1954 if (rs_val > 0) 1955 target = pc + offset; 1956 else 1957 target = pc + 4; 1958 } else if (op_name.equals_insensitive("BEQZALC")) { 1959 if (rs_val == 0) 1960 target = pc + offset; 1961 else 1962 target = pc + 4; 1963 } else if (op_name.equals_insensitive("BNEZALC")) { 1964 if (rs_val != 0) 1965 target = pc + offset; 1966 else 1967 target = pc + 4; 1968 } 1969 1970 Context context; 1971 1972 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1973 target)) 1974 return false; 1975 1976 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 1977 pc + 4)) 1978 return false; 1979 1980 return true; 1981 } 1982 1983 /* 1984 Emulate below MIPS Non-Compact conditional branch and link instructions. 1985 BLTZAL, BGEZAL : 1986 BLTZALL, BGEZALL : Branch likely 1987 */ 1988 bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) { 1989 bool success = false; 1990 uint32_t rs; 1991 int32_t offset, pc, target = 0; 1992 int32_t rs_val; 1993 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1994 1995 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1996 offset = insn.getOperand(1).getImm(); 1997 1998 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1999 if (!success) 2000 return false; 2001 2002 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2003 dwarf_zero_mips + rs, 0, &success); 2004 if (!success) 2005 return false; 2006 2007 if (op_name.equals_insensitive("BLTZAL") || 2008 op_name.equals_insensitive("BLTZALL")) { 2009 if ((int32_t)rs_val < 0) 2010 target = pc + offset; 2011 else 2012 target = pc + 8; 2013 } else if (op_name.equals_insensitive("BGEZAL") || 2014 op_name.equals_insensitive("BGEZALL")) { 2015 if ((int32_t)rs_val >= 0) 2016 target = pc + offset; 2017 else 2018 target = pc + 8; 2019 } 2020 2021 Context context; 2022 2023 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2024 target)) 2025 return false; 2026 2027 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2028 pc + 8)) 2029 return false; 2030 2031 return true; 2032 } 2033 2034 /* 2035 Emulate below MIPS branch instructions. 2036 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely 2037 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches 2038 */ 2039 bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) { 2040 bool success = false; 2041 uint32_t rs; 2042 int32_t offset, pc, target = 0; 2043 int32_t rs_val; 2044 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2045 2046 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2047 offset = insn.getOperand(1).getImm(); 2048 2049 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2050 if (!success) 2051 return false; 2052 2053 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2054 dwarf_zero_mips + rs, 0, &success); 2055 if (!success) 2056 return false; 2057 2058 if (op_name.equals_insensitive("BLTZL") || 2059 op_name.equals_insensitive("BLTZ")) { 2060 if (rs_val < 0) 2061 target = pc + offset; 2062 else 2063 target = pc + 8; 2064 } else if (op_name.equals_insensitive("BGEZL") || 2065 op_name.equals_insensitive("BGEZ")) { 2066 if (rs_val >= 0) 2067 target = pc + offset; 2068 else 2069 target = pc + 8; 2070 } else if (op_name.equals_insensitive("BGTZL") || 2071 op_name.equals_insensitive("BGTZ")) { 2072 if (rs_val > 0) 2073 target = pc + offset; 2074 else 2075 target = pc + 8; 2076 } else if (op_name.equals_insensitive("BLEZL") || 2077 op_name.equals_insensitive("BLEZ")) { 2078 if (rs_val <= 0) 2079 target = pc + offset; 2080 else 2081 target = pc + 8; 2082 } 2083 2084 Context context; 2085 context.type = eContextRelativeBranchImmediate; 2086 context.SetImmediate(offset); 2087 2088 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2089 target); 2090 } 2091 2092 /* 2093 Emulate below MIPS branch instructions. 2094 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches 2095 */ 2096 bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) { 2097 bool success = false; 2098 uint32_t rs; 2099 int32_t offset, pc, target = 0; 2100 int32_t rs_val; 2101 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2102 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 2103 2104 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2105 offset = insn.getOperand(1).getImm(); 2106 2107 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2108 if (!success) 2109 return false; 2110 2111 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2112 dwarf_zero_mips + rs, 0, &success); 2113 if (!success) 2114 return false; 2115 2116 if (op_name.equals_insensitive("BLTZC")) { 2117 if (rs_val < 0) 2118 target = pc + offset; 2119 else 2120 target = pc + 4; 2121 } else if (op_name.equals_insensitive("BLEZC")) { 2122 if (rs_val <= 0) 2123 target = pc + offset; 2124 else 2125 target = pc + 4; 2126 } else if (op_name.equals_insensitive("BGEZC")) { 2127 if (rs_val >= 0) 2128 target = pc + offset; 2129 else 2130 target = pc + 4; 2131 } else if (op_name.equals_insensitive("BGTZC")) { 2132 if (rs_val > 0) 2133 target = pc + offset; 2134 else 2135 target = pc + 4; 2136 } else if (op_name.equals_insensitive("BEQZC")) { 2137 if (rs_val == 0) 2138 target = pc + offset; 2139 else 2140 target = pc + 4; 2141 } else if (op_name.equals_insensitive("BNEZC")) { 2142 if (rs_val != 0) 2143 target = pc + offset; 2144 else 2145 target = pc + 4; 2146 } 2147 2148 Context context; 2149 context.type = eContextRelativeBranchImmediate; 2150 context.SetImmediate(current_inst_size + offset); 2151 2152 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2153 target); 2154 } 2155 2156 bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) { 2157 bool success = false; 2158 int32_t offset, pc, target; 2159 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 2160 2161 offset = insn.getOperand(0).getImm(); 2162 2163 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2164 if (!success) 2165 return false; 2166 2167 // unconditional branch 2168 target = pc + offset; 2169 2170 Context context; 2171 context.type = eContextRelativeBranchImmediate; 2172 context.SetImmediate(current_inst_size + offset); 2173 2174 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2175 target); 2176 } 2177 2178 /* 2179 BEQZC, BNEZC are 32 bit compact instructions without a delay slot. 2180 BEQZ16, BNEZ16 are 16 bit instructions with delay slot. 2181 BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot. 2182 */ 2183 bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) { 2184 bool success = false; 2185 int32_t target = 0; 2186 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 2187 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2188 bool update_ra = false; 2189 uint32_t ra_offset = 0; 2190 2191 /* 2192 * BEQZ16 rs, offset 2193 * condition <- (GPR[rs] = 0) 2194 * if condition then 2195 * PC = PC + sign_ext (offset || 0) 2196 * 2197 * BNEZ16 rs, offset 2198 * condition <- (GPR[rs] != 0) 2199 * if condition then 2200 * PC = PC + sign_ext (offset || 0) 2201 * 2202 * BEQZC rs, offset (compact instruction: No delay slot) 2203 * condition <- (GPR[rs] == 0) 2204 * if condition then 2205 * PC = PC + 4 + sign_ext (offset || 0) 2206 */ 2207 2208 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2209 int32_t offset = insn.getOperand(1).getImm(); 2210 2211 int32_t pc = 2212 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2213 if (!success) 2214 return false; 2215 2216 int32_t rs_val = (int32_t)ReadRegisterUnsigned( 2217 eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 2218 if (!success) 2219 return false; 2220 2221 if (op_name.equals_insensitive("BEQZ16_MM")) { 2222 if (rs_val == 0) 2223 target = pc + offset; 2224 else 2225 target = pc + current_inst_size + 2226 m_next_inst_size; // Skip delay slot instruction. 2227 } else if (op_name.equals_insensitive("BNEZ16_MM")) { 2228 if (rs_val != 0) 2229 target = pc + offset; 2230 else 2231 target = pc + current_inst_size + 2232 m_next_inst_size; // Skip delay slot instruction. 2233 } else if (op_name.equals_insensitive("BEQZC_MM")) { 2234 if (rs_val == 0) 2235 target = pc + 4 + offset; 2236 else 2237 target = 2238 pc + 2239 4; // 32 bit instruction and does not have delay slot instruction. 2240 } else if (op_name.equals_insensitive("BNEZC_MM")) { 2241 if (rs_val != 0) 2242 target = pc + 4 + offset; 2243 else 2244 target = 2245 pc + 2246 4; // 32 bit instruction and does not have delay slot instruction. 2247 } else if (op_name.equals_insensitive("BGEZALS_MM")) { 2248 if (rs_val >= 0) 2249 target = pc + offset; 2250 else 2251 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot 2252 2253 update_ra = true; 2254 ra_offset = 6; 2255 } else if (op_name.equals_insensitive("BLTZALS_MM")) { 2256 if (rs_val >= 0) 2257 target = pc + offset; 2258 else 2259 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot 2260 2261 update_ra = true; 2262 ra_offset = 6; 2263 } 2264 2265 Context context; 2266 context.type = eContextRelativeBranchImmediate; 2267 context.SetImmediate(current_inst_size + offset); 2268 2269 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2270 target)) 2271 return false; 2272 2273 if (update_ra) { 2274 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2275 pc + ra_offset)) 2276 return false; 2277 } 2278 return true; 2279 } 2280 2281 /* Emulate micromips jump instructions. 2282 JALR16,JALRS16 2283 */ 2284 bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) { 2285 bool success = false; 2286 uint32_t ra_offset = 0; 2287 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2288 2289 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2290 2291 uint32_t pc = 2292 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2293 if (!success) 2294 return false; 2295 2296 uint32_t rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, 2297 dwarf_zero_mips + rs, 0, &success); 2298 if (!success) 2299 return false; 2300 2301 if (op_name.equals_insensitive("JALR16_MM")) 2302 ra_offset = 6; // 2-byte instruction with 4-byte delay slot. 2303 else if (op_name.equals_insensitive("JALRS16_MM")) 2304 ra_offset = 4; // 2-byte instruction with 2-byte delay slot. 2305 2306 Context context; 2307 2308 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2309 rs_val)) 2310 return false; 2311 2312 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2313 pc + ra_offset)) 2314 return false; 2315 2316 return true; 2317 } 2318 2319 /* Emulate JALS and JALX instructions. 2320 JALS 32 bit instruction with short (2-byte) delay slot. 2321 JALX 32 bit instruction with 4-byte delay slot. 2322 */ 2323 bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) { 2324 bool success = false; 2325 uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0; 2326 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2327 2328 /* 2329 * JALS target 2330 * RA = PC + 6 2331 * offset = sign_ext (offset << 1) 2332 * PC = PC[31-27] | offset 2333 * JALX target 2334 * RA = PC + 8 2335 * offset = sign_ext (offset << 2) 2336 * PC = PC[31-28] | offset 2337 */ 2338 offset = insn.getOperand(0).getImm(); 2339 2340 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2341 if (!success) 2342 return false; 2343 2344 // These are PC-region branches and not PC-relative. 2345 if (op_name.equals_insensitive("JALS_MM")) { 2346 // target address is in the “current” 128 MB-aligned region 2347 target = (pc & 0xF8000000UL) | offset; 2348 ra_offset = 6; 2349 } else if (op_name.equals_insensitive("JALX_MM")) { 2350 // target address is in the “current” 256 MB-aligned region 2351 target = (pc & 0xF0000000UL) | offset; 2352 ra_offset = 8; 2353 } 2354 2355 Context context; 2356 2357 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2358 target)) 2359 return false; 2360 2361 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2362 pc + ra_offset)) 2363 return false; 2364 2365 return true; 2366 } 2367 2368 bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) { 2369 bool success = false; 2370 uint32_t rs = 0, rt = 0; 2371 int32_t pc = 0, rs_val = 0; 2372 2373 /* 2374 JALRS rt, rs 2375 GPR[rt] <- PC + 6 2376 PC <- GPR[rs] 2377 */ 2378 2379 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2380 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 2381 2382 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2383 dwarf_zero_mips + rs, 0, &success); 2384 if (!success) 2385 return false; 2386 2387 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2388 if (!success) 2389 return false; 2390 2391 Context context; 2392 2393 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2394 rs_val)) 2395 return false; 2396 2397 // This is 4-byte instruction with 2-byte delay slot. 2398 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt, 2399 pc + 6)) 2400 return false; 2401 2402 return true; 2403 } 2404 2405 bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst &insn) { 2406 bool success = false; 2407 int32_t offset, pc, target; 2408 2409 /* 2410 * BAL offset 2411 * offset = sign_ext (offset << 2) 2412 * RA = PC + 8 2413 * PC = PC + offset 2414 */ 2415 offset = insn.getOperand(0).getImm(); 2416 2417 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2418 if (!success) 2419 return false; 2420 2421 target = pc + offset; 2422 2423 Context context; 2424 2425 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2426 target)) 2427 return false; 2428 2429 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2430 pc + 8)) 2431 return false; 2432 2433 return true; 2434 } 2435 2436 bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) { 2437 bool success = false; 2438 int32_t offset, pc, target; 2439 2440 /* 2441 * BALC offset 2442 * offset = sign_ext (offset << 2) 2443 * RA = PC + 4 2444 * PC = PC + 4 + offset 2445 */ 2446 offset = insn.getOperand(0).getImm(); 2447 2448 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2449 if (!success) 2450 return false; 2451 2452 target = pc + offset; 2453 2454 Context context; 2455 2456 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2457 target)) 2458 return false; 2459 2460 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2461 pc + 4)) 2462 return false; 2463 2464 return true; 2465 } 2466 2467 bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) { 2468 bool success = false; 2469 int32_t offset, pc, target; 2470 2471 /* 2472 * BC offset 2473 * offset = sign_ext (offset << 2) 2474 * PC = PC + 4 + offset 2475 */ 2476 offset = insn.getOperand(0).getImm(); 2477 2478 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2479 if (!success) 2480 return false; 2481 2482 target = pc + offset; 2483 2484 Context context; 2485 2486 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2487 target); 2488 } 2489 2490 bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) { 2491 bool success = false; 2492 uint32_t offset, pc; 2493 2494 /* 2495 * J offset 2496 * offset = sign_ext (offset << 2) 2497 * PC = PC[63-28] | offset 2498 */ 2499 offset = insn.getOperand(0).getImm(); 2500 2501 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2502 if (!success) 2503 return false; 2504 2505 /* This is a PC-region branch and not PC-relative */ 2506 pc = (pc & 0xF0000000UL) | offset; 2507 2508 Context context; 2509 2510 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc); 2511 } 2512 2513 bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) { 2514 bool success = false; 2515 uint32_t offset, target, pc; 2516 2517 /* 2518 * JAL offset 2519 * offset = sign_ext (offset << 2) 2520 * PC = PC[63-28] | offset 2521 */ 2522 offset = insn.getOperand(0).getImm(); 2523 2524 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2525 if (!success) 2526 return false; 2527 2528 /* This is a PC-region branch and not PC-relative */ 2529 target = (pc & 0xF0000000UL) | offset; 2530 2531 Context context; 2532 2533 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2534 target)) 2535 return false; 2536 2537 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2538 pc + 8)) 2539 return false; 2540 2541 return true; 2542 } 2543 2544 bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) { 2545 bool success = false; 2546 uint32_t rs, rt; 2547 uint32_t pc, rs_val; 2548 2549 /* 2550 * JALR rt, rs 2551 * GPR[rt] = PC + 8 2552 * PC = GPR[rs] 2553 */ 2554 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2555 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 2556 2557 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2558 if (!success) 2559 return false; 2560 2561 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0, 2562 &success); 2563 if (!success) 2564 return false; 2565 2566 Context context; 2567 2568 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2569 rs_val)) 2570 return false; 2571 2572 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt, 2573 pc + 8)) 2574 return false; 2575 2576 return true; 2577 } 2578 2579 bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) { 2580 bool success = false; 2581 uint32_t rt; 2582 int32_t target, offset, pc, rt_val; 2583 2584 /* 2585 * JIALC rt, offset 2586 * offset = sign_ext (offset) 2587 * PC = GPR[rt] + offset 2588 * RA = PC + 4 2589 */ 2590 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2591 offset = insn.getOperand(1).getImm(); 2592 2593 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2594 if (!success) 2595 return false; 2596 2597 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2598 dwarf_zero_mips + rt, 0, &success); 2599 if (!success) 2600 return false; 2601 2602 target = rt_val + offset; 2603 2604 Context context; 2605 2606 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2607 target)) 2608 return false; 2609 2610 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2611 pc + 4)) 2612 return false; 2613 2614 return true; 2615 } 2616 2617 bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) { 2618 bool success = false; 2619 uint32_t rt; 2620 int32_t target, offset, rt_val; 2621 2622 /* 2623 * JIC rt, offset 2624 * offset = sign_ext (offset) 2625 * PC = GPR[rt] + offset 2626 */ 2627 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2628 offset = insn.getOperand(1).getImm(); 2629 2630 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2631 dwarf_zero_mips + rt, 0, &success); 2632 if (!success) 2633 return false; 2634 2635 target = rt_val + offset; 2636 2637 Context context; 2638 2639 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2640 target); 2641 } 2642 2643 bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) { 2644 bool success = false; 2645 uint32_t rs; 2646 uint32_t rs_val; 2647 2648 /* 2649 * JR rs 2650 * PC = GPR[rs] 2651 */ 2652 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2653 2654 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0, 2655 &success); 2656 if (!success) 2657 return false; 2658 2659 Context context; 2660 2661 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2662 rs_val); 2663 } 2664 2665 /* 2666 Emulate Branch on FP True/False 2667 BC1F, BC1FL : Branch on FP False (L stands for branch likely) 2668 BC1T, BC1TL : Branch on FP True (L stands for branch likely) 2669 */ 2670 bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) { 2671 bool success = false; 2672 uint32_t cc, fcsr; 2673 int32_t pc, offset, target = 0; 2674 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2675 2676 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2677 offset = insn.getOperand(1).getImm(); 2678 2679 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2680 if (!success) 2681 return false; 2682 2683 fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success); 2684 if (!success) 2685 return false; 2686 2687 /* fcsr[23], fcsr[25-31] are vaild condition bits */ 2688 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); 2689 2690 if (op_name.equals_insensitive("BC1F") || 2691 op_name.equals_insensitive("BC1FL")) { 2692 if ((fcsr & (1 << cc)) == 0) 2693 target = pc + offset; 2694 else 2695 target = pc + 8; 2696 } else if (op_name.equals_insensitive("BC1T") || 2697 op_name.equals_insensitive("BC1TL")) { 2698 if ((fcsr & (1 << cc)) != 0) 2699 target = pc + offset; 2700 else 2701 target = pc + 8; 2702 } 2703 Context context; 2704 2705 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2706 target); 2707 } 2708 2709 bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) { 2710 bool success = false; 2711 uint32_t ft; 2712 uint32_t ft_val; 2713 int32_t target, pc, offset; 2714 2715 /* 2716 * BC1EQZ ft, offset 2717 * condition <- (FPR[ft].bit0 == 0) 2718 * if condition then 2719 * offset = sign_ext (offset) 2720 * PC = PC + 4 + offset 2721 */ 2722 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2723 offset = insn.getOperand(1).getImm(); 2724 2725 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2726 if (!success) 2727 return false; 2728 2729 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0, 2730 &success); 2731 if (!success) 2732 return false; 2733 2734 if ((ft_val & 1) == 0) 2735 target = pc + 4 + offset; 2736 else 2737 target = pc + 8; 2738 2739 Context context; 2740 2741 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2742 target); 2743 } 2744 2745 bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) { 2746 bool success = false; 2747 uint32_t ft; 2748 uint32_t ft_val; 2749 int32_t target, pc, offset; 2750 2751 /* 2752 * BC1NEZ ft, offset 2753 * condition <- (FPR[ft].bit0 != 0) 2754 * if condition then 2755 * offset = sign_ext (offset) 2756 * PC = PC + 4 + offset 2757 */ 2758 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2759 offset = insn.getOperand(1).getImm(); 2760 2761 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2762 if (!success) 2763 return false; 2764 2765 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0, 2766 &success); 2767 if (!success) 2768 return false; 2769 2770 if ((ft_val & 1) != 0) 2771 target = pc + 4 + offset; 2772 else 2773 target = pc + 8; 2774 2775 Context context; 2776 2777 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2778 target); 2779 } 2780 2781 /* 2782 Emulate MIPS-3D Branch instructions 2783 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes 2784 False/True 2785 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes 2786 False/True 2787 */ 2788 bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) { 2789 bool success = false; 2790 uint32_t cc, fcsr; 2791 int32_t pc, offset, target = 0; 2792 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2793 2794 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2795 offset = insn.getOperand(1).getImm(); 2796 2797 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2798 if (!success) 2799 return false; 2800 2801 fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, 2802 &success); 2803 if (!success) 2804 return false; 2805 2806 /* fcsr[23], fcsr[25-31] are vaild condition bits */ 2807 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); 2808 2809 if (op_name.equals_insensitive("BC1ANY2F")) { 2810 /* if any one bit is 0 */ 2811 if (((fcsr >> cc) & 3) != 3) 2812 target = pc + offset; 2813 else 2814 target = pc + 8; 2815 } else if (op_name.equals_insensitive("BC1ANY2T")) { 2816 /* if any one bit is 1 */ 2817 if (((fcsr >> cc) & 3) != 0) 2818 target = pc + offset; 2819 else 2820 target = pc + 8; 2821 } else if (op_name.equals_insensitive("BC1ANY4F")) { 2822 /* if any one bit is 0 */ 2823 if (((fcsr >> cc) & 0xf) != 0xf) 2824 target = pc + offset; 2825 else 2826 target = pc + 8; 2827 } else if (op_name.equals_insensitive("BC1ANY4T")) { 2828 /* if any one bit is 1 */ 2829 if (((fcsr >> cc) & 0xf) != 0) 2830 target = pc + offset; 2831 else 2832 target = pc + 8; 2833 } 2834 Context context; 2835 2836 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2837 target); 2838 } 2839 2840 bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) { 2841 return Emulate_MSA_Branch_DF(insn, 1, true); 2842 } 2843 2844 bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) { 2845 return Emulate_MSA_Branch_DF(insn, 2, true); 2846 } 2847 2848 bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) { 2849 return Emulate_MSA_Branch_DF(insn, 4, true); 2850 } 2851 2852 bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) { 2853 return Emulate_MSA_Branch_DF(insn, 8, true); 2854 } 2855 2856 bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) { 2857 return Emulate_MSA_Branch_DF(insn, 1, false); 2858 } 2859 2860 bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) { 2861 return Emulate_MSA_Branch_DF(insn, 2, false); 2862 } 2863 2864 bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) { 2865 return Emulate_MSA_Branch_DF(insn, 4, false); 2866 } 2867 2868 bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) { 2869 return Emulate_MSA_Branch_DF(insn, 8, false); 2870 } 2871 2872 bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn, 2873 int element_byte_size, 2874 bool bnz) { 2875 bool success = false, branch_hit = true; 2876 int32_t target = 0; 2877 RegisterValue reg_value; 2878 const uint8_t *ptr = nullptr; 2879 2880 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2881 int32_t offset = insn.getOperand(1).getImm(); 2882 2883 int32_t pc = 2884 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2885 if (!success) 2886 return false; 2887 2888 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value)) 2889 ptr = (const uint8_t *)reg_value.GetBytes(); 2890 else 2891 return false; 2892 2893 for (int i = 0; i < 16 / element_byte_size; i++) { 2894 switch (element_byte_size) { 2895 case 1: 2896 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz)) 2897 branch_hit = false; 2898 break; 2899 case 2: 2900 if ((*(const uint16_t *)ptr == 0 && bnz) || 2901 (*(const uint16_t *)ptr != 0 && !bnz)) 2902 branch_hit = false; 2903 break; 2904 case 4: 2905 if ((*(const uint32_t *)ptr == 0 && bnz) || 2906 (*(const uint32_t *)ptr != 0 && !bnz)) 2907 branch_hit = false; 2908 break; 2909 case 8: 2910 if ((*(const uint64_t *)ptr == 0 && bnz) || 2911 (*(const uint64_t *)ptr != 0 && !bnz)) 2912 branch_hit = false; 2913 break; 2914 } 2915 if (!branch_hit) 2916 break; 2917 ptr = ptr + element_byte_size; 2918 } 2919 2920 if (branch_hit) 2921 target = pc + offset; 2922 else 2923 target = pc + 8; 2924 2925 Context context; 2926 context.type = eContextRelativeBranchImmediate; 2927 2928 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2929 target); 2930 } 2931 2932 bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) { 2933 return Emulate_MSA_Branch_V(insn, true); 2934 } 2935 2936 bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) { 2937 return Emulate_MSA_Branch_V(insn, false); 2938 } 2939 2940 bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn, 2941 bool bnz) { 2942 bool success = false; 2943 int32_t target = 0; 2944 llvm::APInt wr_val = llvm::APInt::getZero(128); 2945 llvm::APInt fail_value = llvm::APInt::getMaxValue(128); 2946 llvm::APInt zero_value = llvm::APInt::getZero(128); 2947 RegisterValue reg_value; 2948 2949 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2950 int32_t offset = insn.getOperand(1).getImm(); 2951 2952 int32_t pc = 2953 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2954 if (!success) 2955 return false; 2956 2957 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value)) 2958 wr_val = reg_value.GetAsUInt128(fail_value); 2959 else 2960 return false; 2961 2962 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || 2963 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz)) 2964 target = pc + offset; 2965 else 2966 target = pc + 8; 2967 2968 Context context; 2969 context.type = eContextRelativeBranchImmediate; 2970 2971 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2972 target); 2973 } 2974 2975 bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) { 2976 bool success = false; 2977 uint32_t base; 2978 int32_t imm, address; 2979 Context bad_vaddr_context; 2980 2981 uint32_t num_operands = insn.getNumOperands(); 2982 base = 2983 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 2984 imm = insn.getOperand(num_operands - 1).getImm(); 2985 2986 RegisterInfo reg_info_base; 2987 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 2988 reg_info_base)) 2989 return false; 2990 2991 /* read base register */ 2992 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2993 dwarf_zero_mips + base, 0, &success); 2994 if (!success) 2995 return false; 2996 2997 /* destination address */ 2998 address = address + imm; 2999 3000 /* Set the bad_vaddr register with base address used in the instruction */ 3001 bad_vaddr_context.type = eContextInvalid; 3002 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 3003 address); 3004 3005 return true; 3006 } 3007 3008 bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) { 3009 bool success = false; 3010 uint32_t base, index; 3011 int32_t address, index_address; 3012 Context bad_vaddr_context; 3013 3014 uint32_t num_operands = insn.getNumOperands(); 3015 base = 3016 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 3017 index = 3018 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg()); 3019 3020 RegisterInfo reg_info_base, reg_info_index; 3021 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 3022 reg_info_base)) 3023 return false; 3024 3025 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index, 3026 reg_info_index)) 3027 return false; 3028 3029 /* read base register */ 3030 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 3031 dwarf_zero_mips + base, 0, &success); 3032 if (!success) 3033 return false; 3034 3035 /* read index register */ 3036 index_address = (int32_t)ReadRegisterUnsigned( 3037 eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success); 3038 if (!success) 3039 return false; 3040 3041 /* destination address */ 3042 address = address + index_address; 3043 3044 /* Set the bad_vaddr register with base address used in the instruction */ 3045 bad_vaddr_context.type = eContextInvalid; 3046 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 3047 address); 3048 3049 return true; 3050 } 3051