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