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 41using namespace lldb; 42using namespace lldb_private; 43 44LLDB_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__ 54extern "C" { 55void LLVMInitializeMipsTargetInfo(); 56void LLVMInitializeMipsTarget(); 57void LLVMInitializeMipsAsmPrinter(); 58void LLVMInitializeMipsTargetMC(); 59void LLVMInitializeMipsDisassembler(); 60} 61#endif 62 63EmulateInstructionMIPS::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 188void EmulateInstructionMIPS::Initialize() { 189 PluginManager::RegisterPlugin(GetPluginNameStatic(), 190 GetPluginDescriptionStatic(), CreateInstance); 191} 192 193void EmulateInstructionMIPS::Terminate() { 194 PluginManager::UnregisterPlugin(CreateInstance); 195} 196 197llvm::StringRef EmulateInstructionMIPS::GetPluginDescriptionStatic() { 198 return "Emulate instructions for the MIPS32 architecture."; 199} 200 201EmulateInstruction * 202EmulateInstructionMIPS::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 215bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) { 216 return arch.GetTriple().getArch() == llvm::Triple::mips || 217 arch.GetTriple().getArch() == llvm::Triple::mipsel; 218} 219 220const 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 589std::optional<RegisterInfo> 590EmulateInstructionMIPS::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 672EmulateInstructionMIPS::MipsOpcode * 673EmulateInstructionMIPS::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 966uint32_t 967EmulateInstructionMIPS::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 987bool 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 1034bool 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 1051bool 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 1126bool 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 1152bool 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 1173bool 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 1225bool 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 RegisterValue::BytesContainer buffer(reg_info_src->byte_size); 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.data(), 1274 reg_info_src->byte_size, eByteOrderLittle, 1275 error) == 0) 1276 return false; 1277 1278 if (!WriteMemory(context, address, buffer.data(), reg_info_src->byte_size)) 1279 return false; 1280 1281 return true; 1282 } 1283 1284 return false; 1285} 1286 1287bool 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 1331bool 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 1410bool 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 1427bool 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 1454bool 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 1488bool 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 RegisterValue::BytesContainer buffer(reg_info_src.byte_size); 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.data(), 1534 reg_info_src.byte_size, eByteOrderLittle, 1535 error) == 0) 1536 return false; 1537 1538 if (!WriteMemory(context, address, buffer.data(), reg_info_src.byte_size)) 1539 return false; 1540 1541 return true; 1542 } 1543 1544 return false; 1545} 1546 1547/* Emulate SWM16,SWM32 and SWP instruction. 1548 1549 SWM16 always has stack pointer as a base register (but it is still available 1550 in MCInst as an operand). 1551 SWM32 and SWP can have base register other than stack pointer. 1552*/ 1553bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) { 1554 bool success = false; 1555 uint32_t src, base; 1556 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on 1557 // no of regs to store. 1558 1559 // Base register is second last operand of the instruction. 1560 base = 1561 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 1562 1563 // We are looking for sp based stores so if base is not a stack pointer then 1564 // don't proceed. 1565 if (base != dwarf_sp_mips) 1566 return false; 1567 1568 // offset is always the last operand. 1569 uint32_t offset = insn.getOperand(num_operands - 1).getImm(); 1570 1571 std::optional<RegisterInfo> reg_info_base = 1572 GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base); 1573 if (!reg_info_base) 1574 return false; 1575 1576 // read SP 1577 uint32_t base_address = ReadRegisterUnsigned( 1578 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1579 if (!success) 1580 return false; 1581 1582 // Resulting base addrss 1583 base_address = base_address + offset; 1584 1585 // Total no of registers to be stored are num_operands-2. 1586 for (uint32_t i = 0; i < num_operands - 2; i++) { 1587 // Get the register number to be stored. 1588 src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg()); 1589 1590 /* 1591 Record only non-volatile stores. 1592 This check is required for SWP instruction because source operand could 1593 be any register. 1594 SWM16 and SWM32 instruction always has saved registers as source 1595 operands. 1596 */ 1597 if (!nonvolatile_reg_p(src)) 1598 return false; 1599 1600 std::optional<RegisterInfo> reg_info_src = 1601 GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src); 1602 if (!reg_info_src) 1603 return false; 1604 1605 Context context; 1606 context.type = eContextPushRegisterOnStack; 1607 context.SetRegisterToRegisterPlusOffset(*reg_info_src, *reg_info_base, 0); 1608 1609 RegisterValue::BytesContainer buffer(reg_info_src->byte_size); 1610 Status error; 1611 1612 std::optional<RegisterValue> data_src = ReadRegister(*reg_info_base); 1613 if (!data_src) 1614 return false; 1615 1616 if (data_src->GetAsMemoryData(*reg_info_src, buffer.data(), 1617 reg_info_src->byte_size, eByteOrderLittle, 1618 error) == 0) 1619 return false; 1620 1621 if (!WriteMemory(context, base_address, buffer.data(), 1622 reg_info_src->byte_size)) 1623 return false; 1624 1625 // Stack address for next register 1626 base_address = base_address + reg_info_src->byte_size; 1627 } 1628 return true; 1629} 1630 1631bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) { 1632 bool success = false; 1633 uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1634 uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1635 uint32_t imm5 = insn.getOperand(2).getImm(); 1636 Context bad_vaddr_context; 1637 1638 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base)) 1639 return false; 1640 1641 // read base register 1642 uint32_t base_address = ReadRegisterUnsigned( 1643 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1644 if (!success) 1645 return false; 1646 1647 base_address = base_address + imm5; 1648 1649 // We use bad_vaddr_context to store base address which is used by H/W 1650 // watchpoint Set the bad_vaddr register with base address used in the 1651 // instruction 1652 bad_vaddr_context.type = eContextInvalid; 1653 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 1654 base_address); 1655 1656 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) { 1657 RegisterValue data_src; 1658 std::optional<RegisterInfo> reg_info_src = 1659 GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src); 1660 if (!reg_info_src) 1661 return false; 1662 1663 Context context; 1664 context.type = eContextPopRegisterOffStack; 1665 context.SetAddress(base_address); 1666 1667 return WriteRegister(context, *reg_info_src, data_src); 1668 } 1669 1670 return false; 1671} 1672 1673/* Emulate LWM16, LWM32 and LWP instructions. 1674 1675 LWM16 always has stack pointer as a base register (but it is still available 1676 in MCInst as an operand). 1677 LWM32 and LWP can have base register other than stack pointer. 1678*/ 1679bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) { 1680 bool success = false; 1681 uint32_t dst, base; 1682 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on 1683 // no of regs to store. 1684 uint32_t imm = insn.getOperand(num_operands - 1) 1685 .getImm(); // imm is the last operand in the instruction. 1686 1687 // Base register is second last operand of the instruction. 1688 base = 1689 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 1690 1691 // We are looking for sp based loads so if base is not a stack pointer then 1692 // don't proceed. 1693 if (base != dwarf_sp_mips) 1694 return false; 1695 1696 uint32_t base_address = ReadRegisterUnsigned( 1697 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1698 if (!success) 1699 return false; 1700 1701 base_address = base_address + imm; 1702 1703 RegisterValue data_dst; 1704 1705 // Total no of registers to be re-stored are num_operands-2. 1706 for (uint32_t i = 0; i < num_operands - 2; i++) { 1707 // Get the register number to be re-stored. 1708 dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg()); 1709 1710 /* 1711 Record only non-volatile loads. 1712 This check is required for LWP instruction because destination operand 1713 could be any register. 1714 LWM16 and LWM32 instruction always has saved registers as destination 1715 operands. 1716 */ 1717 if (!nonvolatile_reg_p(dst)) 1718 return false; 1719 1720 std::optional<RegisterInfo> reg_info_dst = 1721 GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst); 1722 if (!reg_info_dst) 1723 return false; 1724 1725 Context context; 1726 context.type = eContextPopRegisterOffStack; 1727 context.SetAddress(base_address + (i * 4)); 1728 1729 if (!WriteRegister(context, *reg_info_dst, data_dst)) 1730 return false; 1731 } 1732 1733 return true; 1734} 1735 1736bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) { 1737 bool success = false; 1738 int32_t imm5 = insn.getOperand(0).getImm(); 1739 1740 /* JRADDIUSP immediate 1741 * PC <- RA 1742 * SP <- SP + zero_extend(Immediate << 2) 1743 */ 1744 1745 // This instruction operates implicitly on stack pointer, so read <sp> 1746 // register. 1747 int32_t src_opd_val = 1748 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success); 1749 if (!success) 1750 return false; 1751 1752 int32_t ra_val = 1753 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success); 1754 if (!success) 1755 return false; 1756 1757 int32_t result = src_opd_val + imm5; 1758 1759 Context context; 1760 1761 // Update the PC 1762 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1763 ra_val)) 1764 return false; 1765 1766 std::optional<RegisterInfo> reg_info_sp = 1767 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips); 1768 if (reg_info_sp) 1769 context.SetRegisterPlusOffset(*reg_info_sp, imm5); 1770 1771 // We are adjusting stack 1772 context.type = eContextAdjustStackPointer; 1773 1774 // update SP 1775 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, 1776 result); 1777} 1778 1779static int IsAdd64bitOverflow(int32_t a, int32_t b) { 1780 int32_t r = (uint32_t)a + (uint32_t)b; 1781 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0); 1782} 1783 1784/* 1785 Emulate below MIPS branch instructions. 1786 BEQ, BNE : Branch on condition 1787 BEQL, BNEL : Branch likely 1788*/ 1789bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) { 1790 bool success = false; 1791 uint32_t rs, rt; 1792 int32_t offset, pc, target = 0, rs_val, rt_val; 1793 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1794 1795 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1796 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1797 offset = insn.getOperand(2).getImm(); 1798 1799 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1800 if (!success) 1801 return false; 1802 1803 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1804 dwarf_zero_mips + rs, 0, &success); 1805 if (!success) 1806 return false; 1807 1808 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1809 dwarf_zero_mips + rt, 0, &success); 1810 if (!success) 1811 return false; 1812 1813 if (op_name.equals_insensitive("BEQ") || op_name.equals_insensitive("BEQL")) { 1814 if (rs_val == rt_val) 1815 target = pc + offset; 1816 else 1817 target = pc + 8; 1818 } else if (op_name.equals_insensitive("BNE") || 1819 op_name.equals_insensitive("BNEL")) { 1820 if (rs_val != rt_val) 1821 target = pc + offset; 1822 else 1823 target = pc + 8; 1824 } 1825 1826 Context context; 1827 context.type = eContextRelativeBranchImmediate; 1828 context.SetImmediate(offset); 1829 1830 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1831 target); 1832} 1833 1834/* 1835 Emulate below MIPS branch instructions. 1836 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch 1837 instructions with no delay slot 1838*/ 1839bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) { 1840 bool success = false; 1841 uint32_t rs, rt; 1842 int32_t offset, pc, target = 0, rs_val, rt_val; 1843 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1844 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 1845 1846 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1847 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1848 offset = insn.getOperand(2).getImm(); 1849 1850 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1851 if (!success) 1852 return false; 1853 1854 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1855 dwarf_zero_mips + rs, 0, &success); 1856 if (!success) 1857 return false; 1858 1859 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1860 dwarf_zero_mips + rt, 0, &success); 1861 if (!success) 1862 return false; 1863 1864 if (op_name.equals_insensitive("BEQC")) { 1865 if (rs_val == rt_val) 1866 target = pc + offset; 1867 else 1868 target = pc + 4; 1869 } else if (op_name.equals_insensitive("BNEC")) { 1870 if (rs_val != rt_val) 1871 target = pc + offset; 1872 else 1873 target = pc + 4; 1874 } else if (op_name.equals_insensitive("BLTC")) { 1875 if (rs_val < rt_val) 1876 target = pc + offset; 1877 else 1878 target = pc + 4; 1879 } else if (op_name.equals_insensitive("BGEC")) { 1880 if (rs_val >= rt_val) 1881 target = pc + offset; 1882 else 1883 target = pc + 4; 1884 } else if (op_name.equals_insensitive("BLTUC")) { 1885 if (rs_val < rt_val) 1886 target = pc + offset; 1887 else 1888 target = pc + 4; 1889 } else if (op_name.equals_insensitive("BGEUC")) { 1890 if ((uint32_t)rs_val >= (uint32_t)rt_val) 1891 target = pc + offset; 1892 else 1893 target = pc + 4; 1894 } else if (op_name.equals_insensitive("BOVC")) { 1895 if (IsAdd64bitOverflow(rs_val, rt_val)) 1896 target = pc + offset; 1897 else 1898 target = pc + 4; 1899 } else if (op_name.equals_insensitive("BNVC")) { 1900 if (!IsAdd64bitOverflow(rs_val, rt_val)) 1901 target = pc + offset; 1902 else 1903 target = pc + 4; 1904 } 1905 1906 Context context; 1907 context.type = eContextRelativeBranchImmediate; 1908 context.SetImmediate(current_inst_size + offset); 1909 1910 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1911 target); 1912} 1913 1914/* 1915 Emulate below MIPS conditional branch and link instructions. 1916 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches 1917*/ 1918bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) { 1919 bool success = false; 1920 uint32_t rs; 1921 int32_t offset, pc, target = 0; 1922 int32_t rs_val; 1923 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1924 1925 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1926 offset = insn.getOperand(1).getImm(); 1927 1928 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1929 if (!success) 1930 return false; 1931 1932 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1933 dwarf_zero_mips + rs, 0, &success); 1934 if (!success) 1935 return false; 1936 1937 if (op_name.equals_insensitive("BLEZALC")) { 1938 if (rs_val <= 0) 1939 target = pc + offset; 1940 else 1941 target = pc + 4; 1942 } else if (op_name.equals_insensitive("BGEZALC")) { 1943 if (rs_val >= 0) 1944 target = pc + offset; 1945 else 1946 target = pc + 4; 1947 } else if (op_name.equals_insensitive("BLTZALC")) { 1948 if (rs_val < 0) 1949 target = pc + offset; 1950 else 1951 target = pc + 4; 1952 } else if (op_name.equals_insensitive("BGTZALC")) { 1953 if (rs_val > 0) 1954 target = pc + offset; 1955 else 1956 target = pc + 4; 1957 } else if (op_name.equals_insensitive("BEQZALC")) { 1958 if (rs_val == 0) 1959 target = pc + offset; 1960 else 1961 target = pc + 4; 1962 } else if (op_name.equals_insensitive("BNEZALC")) { 1963 if (rs_val != 0) 1964 target = pc + offset; 1965 else 1966 target = pc + 4; 1967 } 1968 1969 Context context; 1970 1971 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 1972 target)) 1973 return false; 1974 1975 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 1976 pc + 4)) 1977 return false; 1978 1979 return true; 1980} 1981 1982/* 1983 Emulate below MIPS Non-Compact conditional branch and link instructions. 1984 BLTZAL, BGEZAL : 1985 BLTZALL, BGEZALL : Branch likely 1986*/ 1987bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) { 1988 bool success = false; 1989 uint32_t rs; 1990 int32_t offset, pc, target = 0; 1991 int32_t rs_val; 1992 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 1993 1994 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1995 offset = insn.getOperand(1).getImm(); 1996 1997 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1998 if (!success) 1999 return false; 2000 2001 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2002 dwarf_zero_mips + rs, 0, &success); 2003 if (!success) 2004 return false; 2005 2006 if (op_name.equals_insensitive("BLTZAL") || 2007 op_name.equals_insensitive("BLTZALL")) { 2008 if ((int32_t)rs_val < 0) 2009 target = pc + offset; 2010 else 2011 target = pc + 8; 2012 } else if (op_name.equals_insensitive("BGEZAL") || 2013 op_name.equals_insensitive("BGEZALL")) { 2014 if ((int32_t)rs_val >= 0) 2015 target = pc + offset; 2016 else 2017 target = pc + 8; 2018 } 2019 2020 Context context; 2021 2022 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2023 target)) 2024 return false; 2025 2026 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2027 pc + 8)) 2028 return false; 2029 2030 return true; 2031} 2032 2033/* 2034 Emulate below MIPS branch instructions. 2035 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely 2036 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches 2037*/ 2038bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) { 2039 bool success = false; 2040 uint32_t rs; 2041 int32_t offset, pc, target = 0; 2042 int32_t rs_val; 2043 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2044 2045 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2046 offset = insn.getOperand(1).getImm(); 2047 2048 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2049 if (!success) 2050 return false; 2051 2052 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2053 dwarf_zero_mips + rs, 0, &success); 2054 if (!success) 2055 return false; 2056 2057 if (op_name.equals_insensitive("BLTZL") || 2058 op_name.equals_insensitive("BLTZ")) { 2059 if (rs_val < 0) 2060 target = pc + offset; 2061 else 2062 target = pc + 8; 2063 } else if (op_name.equals_insensitive("BGEZL") || 2064 op_name.equals_insensitive("BGEZ")) { 2065 if (rs_val >= 0) 2066 target = pc + offset; 2067 else 2068 target = pc + 8; 2069 } else if (op_name.equals_insensitive("BGTZL") || 2070 op_name.equals_insensitive("BGTZ")) { 2071 if (rs_val > 0) 2072 target = pc + offset; 2073 else 2074 target = pc + 8; 2075 } else if (op_name.equals_insensitive("BLEZL") || 2076 op_name.equals_insensitive("BLEZ")) { 2077 if (rs_val <= 0) 2078 target = pc + offset; 2079 else 2080 target = pc + 8; 2081 } 2082 2083 Context context; 2084 context.type = eContextRelativeBranchImmediate; 2085 context.SetImmediate(offset); 2086 2087 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2088 target); 2089} 2090 2091/* 2092 Emulate below MIPS branch instructions. 2093 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches 2094*/ 2095bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) { 2096 bool success = false; 2097 uint32_t rs; 2098 int32_t offset, pc, target = 0; 2099 int32_t rs_val; 2100 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2101 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 2102 2103 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2104 offset = insn.getOperand(1).getImm(); 2105 2106 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2107 if (!success) 2108 return false; 2109 2110 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2111 dwarf_zero_mips + rs, 0, &success); 2112 if (!success) 2113 return false; 2114 2115 if (op_name.equals_insensitive("BLTZC")) { 2116 if (rs_val < 0) 2117 target = pc + offset; 2118 else 2119 target = pc + 4; 2120 } else if (op_name.equals_insensitive("BLEZC")) { 2121 if (rs_val <= 0) 2122 target = pc + offset; 2123 else 2124 target = pc + 4; 2125 } else if (op_name.equals_insensitive("BGEZC")) { 2126 if (rs_val >= 0) 2127 target = pc + offset; 2128 else 2129 target = pc + 4; 2130 } else if (op_name.equals_insensitive("BGTZC")) { 2131 if (rs_val > 0) 2132 target = pc + offset; 2133 else 2134 target = pc + 4; 2135 } else if (op_name.equals_insensitive("BEQZC")) { 2136 if (rs_val == 0) 2137 target = pc + offset; 2138 else 2139 target = pc + 4; 2140 } else if (op_name.equals_insensitive("BNEZC")) { 2141 if (rs_val != 0) 2142 target = pc + offset; 2143 else 2144 target = pc + 4; 2145 } 2146 2147 Context context; 2148 context.type = eContextRelativeBranchImmediate; 2149 context.SetImmediate(current_inst_size + offset); 2150 2151 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2152 target); 2153} 2154 2155bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) { 2156 bool success = false; 2157 int32_t offset, pc, target; 2158 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 2159 2160 offset = insn.getOperand(0).getImm(); 2161 2162 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2163 if (!success) 2164 return false; 2165 2166 // unconditional branch 2167 target = pc + offset; 2168 2169 Context context; 2170 context.type = eContextRelativeBranchImmediate; 2171 context.SetImmediate(current_inst_size + offset); 2172 2173 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2174 target); 2175} 2176 2177/* 2178 BEQZC, BNEZC are 32 bit compact instructions without a delay slot. 2179 BEQZ16, BNEZ16 are 16 bit instructions with delay slot. 2180 BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot. 2181*/ 2182bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) { 2183 bool success = false; 2184 int32_t target = 0; 2185 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 2186 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2187 bool update_ra = false; 2188 uint32_t ra_offset = 0; 2189 2190 /* 2191 * BEQZ16 rs, offset 2192 * condition <- (GPR[rs] = 0) 2193 * if condition then 2194 * PC = PC + sign_ext (offset || 0) 2195 * 2196 * BNEZ16 rs, offset 2197 * condition <- (GPR[rs] != 0) 2198 * if condition then 2199 * PC = PC + sign_ext (offset || 0) 2200 * 2201 * BEQZC rs, offset (compact instruction: No delay slot) 2202 * condition <- (GPR[rs] == 0) 2203 * if condition then 2204 * PC = PC + 4 + sign_ext (offset || 0) 2205 */ 2206 2207 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2208 int32_t offset = insn.getOperand(1).getImm(); 2209 2210 int32_t pc = 2211 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2212 if (!success) 2213 return false; 2214 2215 int32_t rs_val = (int32_t)ReadRegisterUnsigned( 2216 eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 2217 if (!success) 2218 return false; 2219 2220 if (op_name.equals_insensitive("BEQZ16_MM")) { 2221 if (rs_val == 0) 2222 target = pc + offset; 2223 else 2224 target = pc + current_inst_size + 2225 m_next_inst_size; // Skip delay slot instruction. 2226 } else if (op_name.equals_insensitive("BNEZ16_MM")) { 2227 if (rs_val != 0) 2228 target = pc + offset; 2229 else 2230 target = pc + current_inst_size + 2231 m_next_inst_size; // Skip delay slot instruction. 2232 } else if (op_name.equals_insensitive("BEQZC_MM")) { 2233 if (rs_val == 0) 2234 target = pc + 4 + offset; 2235 else 2236 target = 2237 pc + 2238 4; // 32 bit instruction and does not have delay slot instruction. 2239 } else if (op_name.equals_insensitive("BNEZC_MM")) { 2240 if (rs_val != 0) 2241 target = pc + 4 + offset; 2242 else 2243 target = 2244 pc + 2245 4; // 32 bit instruction and does not have delay slot instruction. 2246 } else if (op_name.equals_insensitive("BGEZALS_MM")) { 2247 if (rs_val >= 0) 2248 target = pc + offset; 2249 else 2250 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot 2251 2252 update_ra = true; 2253 ra_offset = 6; 2254 } else if (op_name.equals_insensitive("BLTZALS_MM")) { 2255 if (rs_val >= 0) 2256 target = pc + offset; 2257 else 2258 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot 2259 2260 update_ra = true; 2261 ra_offset = 6; 2262 } 2263 2264 Context context; 2265 context.type = eContextRelativeBranchImmediate; 2266 context.SetImmediate(current_inst_size + offset); 2267 2268 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2269 target)) 2270 return false; 2271 2272 if (update_ra) { 2273 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2274 pc + ra_offset)) 2275 return false; 2276 } 2277 return true; 2278} 2279 2280/* Emulate micromips jump instructions. 2281 JALR16,JALRS16 2282*/ 2283bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) { 2284 bool success = false; 2285 uint32_t ra_offset = 0; 2286 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2287 2288 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2289 2290 uint32_t pc = 2291 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2292 if (!success) 2293 return false; 2294 2295 uint32_t rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, 2296 dwarf_zero_mips + rs, 0, &success); 2297 if (!success) 2298 return false; 2299 2300 if (op_name.equals_insensitive("JALR16_MM")) 2301 ra_offset = 6; // 2-byte instruction with 4-byte delay slot. 2302 else if (op_name.equals_insensitive("JALRS16_MM")) 2303 ra_offset = 4; // 2-byte instruction with 2-byte delay slot. 2304 2305 Context context; 2306 2307 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2308 rs_val)) 2309 return false; 2310 2311 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2312 pc + ra_offset)) 2313 return false; 2314 2315 return true; 2316} 2317 2318/* Emulate JALS and JALX instructions. 2319 JALS 32 bit instruction with short (2-byte) delay slot. 2320 JALX 32 bit instruction with 4-byte delay slot. 2321*/ 2322bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) { 2323 bool success = false; 2324 uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0; 2325 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2326 2327 /* 2328 * JALS target 2329 * RA = PC + 6 2330 * offset = sign_ext (offset << 1) 2331 * PC = PC[31-27] | offset 2332 * JALX target 2333 * RA = PC + 8 2334 * offset = sign_ext (offset << 2) 2335 * PC = PC[31-28] | offset 2336 */ 2337 offset = insn.getOperand(0).getImm(); 2338 2339 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2340 if (!success) 2341 return false; 2342 2343 // These are PC-region branches and not PC-relative. 2344 if (op_name.equals_insensitive("JALS_MM")) { 2345 // target address is in the ���current��� 128 MB-aligned region 2346 target = (pc & 0xF8000000UL) | offset; 2347 ra_offset = 6; 2348 } else if (op_name.equals_insensitive("JALX_MM")) { 2349 // target address is in the ���current��� 256 MB-aligned region 2350 target = (pc & 0xF0000000UL) | offset; 2351 ra_offset = 8; 2352 } 2353 2354 Context context; 2355 2356 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2357 target)) 2358 return false; 2359 2360 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2361 pc + ra_offset)) 2362 return false; 2363 2364 return true; 2365} 2366 2367bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) { 2368 bool success = false; 2369 uint32_t rs = 0, rt = 0; 2370 int32_t pc = 0, rs_val = 0; 2371 2372 /* 2373 JALRS rt, rs 2374 GPR[rt] <- PC + 6 2375 PC <- GPR[rs] 2376 */ 2377 2378 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2379 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 2380 2381 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2382 dwarf_zero_mips + rs, 0, &success); 2383 if (!success) 2384 return false; 2385 2386 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2387 if (!success) 2388 return false; 2389 2390 Context context; 2391 2392 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2393 rs_val)) 2394 return false; 2395 2396 // This is 4-byte instruction with 2-byte delay slot. 2397 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt, 2398 pc + 6)) 2399 return false; 2400 2401 return true; 2402} 2403 2404bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst &insn) { 2405 bool success = false; 2406 int32_t offset, pc, target; 2407 2408 /* 2409 * BAL offset 2410 * offset = sign_ext (offset << 2) 2411 * RA = PC + 8 2412 * PC = PC + offset 2413 */ 2414 offset = insn.getOperand(0).getImm(); 2415 2416 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2417 if (!success) 2418 return false; 2419 2420 target = pc + offset; 2421 2422 Context context; 2423 2424 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2425 target)) 2426 return false; 2427 2428 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2429 pc + 8)) 2430 return false; 2431 2432 return true; 2433} 2434 2435bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) { 2436 bool success = false; 2437 int32_t offset, pc, target; 2438 2439 /* 2440 * BALC offset 2441 * offset = sign_ext (offset << 2) 2442 * RA = PC + 4 2443 * PC = PC + 4 + offset 2444 */ 2445 offset = insn.getOperand(0).getImm(); 2446 2447 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2448 if (!success) 2449 return false; 2450 2451 target = pc + offset; 2452 2453 Context context; 2454 2455 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2456 target)) 2457 return false; 2458 2459 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2460 pc + 4)) 2461 return false; 2462 2463 return true; 2464} 2465 2466bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) { 2467 bool success = false; 2468 int32_t offset, pc, target; 2469 2470 /* 2471 * BC offset 2472 * offset = sign_ext (offset << 2) 2473 * PC = PC + 4 + offset 2474 */ 2475 offset = insn.getOperand(0).getImm(); 2476 2477 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2478 if (!success) 2479 return false; 2480 2481 target = pc + offset; 2482 2483 Context context; 2484 2485 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2486 target); 2487} 2488 2489bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) { 2490 bool success = false; 2491 uint32_t offset, pc; 2492 2493 /* 2494 * J offset 2495 * offset = sign_ext (offset << 2) 2496 * PC = PC[63-28] | offset 2497 */ 2498 offset = insn.getOperand(0).getImm(); 2499 2500 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2501 if (!success) 2502 return false; 2503 2504 /* This is a PC-region branch and not PC-relative */ 2505 pc = (pc & 0xF0000000UL) | offset; 2506 2507 Context context; 2508 2509 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc); 2510} 2511 2512bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) { 2513 bool success = false; 2514 uint32_t offset, target, pc; 2515 2516 /* 2517 * JAL offset 2518 * offset = sign_ext (offset << 2) 2519 * PC = PC[63-28] | offset 2520 */ 2521 offset = insn.getOperand(0).getImm(); 2522 2523 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2524 if (!success) 2525 return false; 2526 2527 /* This is a PC-region branch and not PC-relative */ 2528 target = (pc & 0xF0000000UL) | offset; 2529 2530 Context context; 2531 2532 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2533 target)) 2534 return false; 2535 2536 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2537 pc + 8)) 2538 return false; 2539 2540 return true; 2541} 2542 2543bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) { 2544 bool success = false; 2545 uint32_t rs, rt; 2546 uint32_t pc, rs_val; 2547 2548 /* 2549 * JALR rt, rs 2550 * GPR[rt] = PC + 8 2551 * PC = GPR[rs] 2552 */ 2553 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2554 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 2555 2556 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2557 if (!success) 2558 return false; 2559 2560 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0, 2561 &success); 2562 if (!success) 2563 return false; 2564 2565 Context context; 2566 2567 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2568 rs_val)) 2569 return false; 2570 2571 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt, 2572 pc + 8)) 2573 return false; 2574 2575 return true; 2576} 2577 2578bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) { 2579 bool success = false; 2580 uint32_t rt; 2581 int32_t target, offset, pc, rt_val; 2582 2583 /* 2584 * JIALC rt, offset 2585 * offset = sign_ext (offset) 2586 * PC = GPR[rt] + offset 2587 * RA = PC + 4 2588 */ 2589 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2590 offset = insn.getOperand(1).getImm(); 2591 2592 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2593 if (!success) 2594 return false; 2595 2596 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2597 dwarf_zero_mips + rt, 0, &success); 2598 if (!success) 2599 return false; 2600 2601 target = rt_val + offset; 2602 2603 Context context; 2604 2605 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2606 target)) 2607 return false; 2608 2609 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, 2610 pc + 4)) 2611 return false; 2612 2613 return true; 2614} 2615 2616bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) { 2617 bool success = false; 2618 uint32_t rt; 2619 int32_t target, offset, rt_val; 2620 2621 /* 2622 * JIC rt, offset 2623 * offset = sign_ext (offset) 2624 * PC = GPR[rt] + offset 2625 */ 2626 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2627 offset = insn.getOperand(1).getImm(); 2628 2629 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2630 dwarf_zero_mips + rt, 0, &success); 2631 if (!success) 2632 return false; 2633 2634 target = rt_val + offset; 2635 2636 Context context; 2637 2638 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2639 target); 2640} 2641 2642bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) { 2643 bool success = false; 2644 uint32_t rs; 2645 uint32_t rs_val; 2646 2647 /* 2648 * JR rs 2649 * PC = GPR[rs] 2650 */ 2651 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2652 2653 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0, 2654 &success); 2655 if (!success) 2656 return false; 2657 2658 Context context; 2659 2660 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2661 rs_val); 2662} 2663 2664/* 2665 Emulate Branch on FP True/False 2666 BC1F, BC1FL : Branch on FP False (L stands for branch likely) 2667 BC1T, BC1TL : Branch on FP True (L stands for branch likely) 2668*/ 2669bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) { 2670 bool success = false; 2671 uint32_t cc, fcsr; 2672 int32_t pc, offset, target = 0; 2673 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2674 2675 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2676 offset = insn.getOperand(1).getImm(); 2677 2678 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2679 if (!success) 2680 return false; 2681 2682 fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success); 2683 if (!success) 2684 return false; 2685 2686 /* fcsr[23], fcsr[25-31] are vaild condition bits */ 2687 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); 2688 2689 if (op_name.equals_insensitive("BC1F") || 2690 op_name.equals_insensitive("BC1FL")) { 2691 if ((fcsr & (1 << cc)) == 0) 2692 target = pc + offset; 2693 else 2694 target = pc + 8; 2695 } else if (op_name.equals_insensitive("BC1T") || 2696 op_name.equals_insensitive("BC1TL")) { 2697 if ((fcsr & (1 << cc)) != 0) 2698 target = pc + offset; 2699 else 2700 target = pc + 8; 2701 } 2702 Context context; 2703 2704 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2705 target); 2706} 2707 2708bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) { 2709 bool success = false; 2710 uint32_t ft; 2711 uint32_t ft_val; 2712 int32_t target, pc, offset; 2713 2714 /* 2715 * BC1EQZ ft, offset 2716 * condition <- (FPR[ft].bit0 == 0) 2717 * if condition then 2718 * offset = sign_ext (offset) 2719 * PC = PC + 4 + offset 2720 */ 2721 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2722 offset = insn.getOperand(1).getImm(); 2723 2724 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2725 if (!success) 2726 return false; 2727 2728 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0, 2729 &success); 2730 if (!success) 2731 return false; 2732 2733 if ((ft_val & 1) == 0) 2734 target = pc + 4 + offset; 2735 else 2736 target = pc + 8; 2737 2738 Context context; 2739 2740 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2741 target); 2742} 2743 2744bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) { 2745 bool success = false; 2746 uint32_t ft; 2747 uint32_t ft_val; 2748 int32_t target, pc, offset; 2749 2750 /* 2751 * BC1NEZ ft, offset 2752 * condition <- (FPR[ft].bit0 != 0) 2753 * if condition then 2754 * offset = sign_ext (offset) 2755 * PC = PC + 4 + offset 2756 */ 2757 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2758 offset = insn.getOperand(1).getImm(); 2759 2760 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2761 if (!success) 2762 return false; 2763 2764 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0, 2765 &success); 2766 if (!success) 2767 return false; 2768 2769 if ((ft_val & 1) != 0) 2770 target = pc + 4 + offset; 2771 else 2772 target = pc + 8; 2773 2774 Context context; 2775 2776 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2777 target); 2778} 2779 2780/* 2781 Emulate MIPS-3D Branch instructions 2782 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes 2783 False/True 2784 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes 2785 False/True 2786*/ 2787bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) { 2788 bool success = false; 2789 uint32_t cc, fcsr; 2790 int32_t pc, offset, target = 0; 2791 llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode()); 2792 2793 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2794 offset = insn.getOperand(1).getImm(); 2795 2796 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2797 if (!success) 2798 return false; 2799 2800 fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, 2801 &success); 2802 if (!success) 2803 return false; 2804 2805 /* fcsr[23], fcsr[25-31] are vaild condition bits */ 2806 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); 2807 2808 if (op_name.equals_insensitive("BC1ANY2F")) { 2809 /* if any one bit is 0 */ 2810 if (((fcsr >> cc) & 3) != 3) 2811 target = pc + offset; 2812 else 2813 target = pc + 8; 2814 } else if (op_name.equals_insensitive("BC1ANY2T")) { 2815 /* if any one bit is 1 */ 2816 if (((fcsr >> cc) & 3) != 0) 2817 target = pc + offset; 2818 else 2819 target = pc + 8; 2820 } else if (op_name.equals_insensitive("BC1ANY4F")) { 2821 /* if any one bit is 0 */ 2822 if (((fcsr >> cc) & 0xf) != 0xf) 2823 target = pc + offset; 2824 else 2825 target = pc + 8; 2826 } else if (op_name.equals_insensitive("BC1ANY4T")) { 2827 /* if any one bit is 1 */ 2828 if (((fcsr >> cc) & 0xf) != 0) 2829 target = pc + offset; 2830 else 2831 target = pc + 8; 2832 } 2833 Context context; 2834 2835 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2836 target); 2837} 2838 2839bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) { 2840 return Emulate_MSA_Branch_DF(insn, 1, true); 2841} 2842 2843bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) { 2844 return Emulate_MSA_Branch_DF(insn, 2, true); 2845} 2846 2847bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) { 2848 return Emulate_MSA_Branch_DF(insn, 4, true); 2849} 2850 2851bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) { 2852 return Emulate_MSA_Branch_DF(insn, 8, true); 2853} 2854 2855bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) { 2856 return Emulate_MSA_Branch_DF(insn, 1, false); 2857} 2858 2859bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) { 2860 return Emulate_MSA_Branch_DF(insn, 2, false); 2861} 2862 2863bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) { 2864 return Emulate_MSA_Branch_DF(insn, 4, false); 2865} 2866 2867bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) { 2868 return Emulate_MSA_Branch_DF(insn, 8, false); 2869} 2870 2871bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn, 2872 int element_byte_size, 2873 bool bnz) { 2874 bool success = false, branch_hit = true; 2875 int32_t target = 0; 2876 RegisterValue reg_value; 2877 const uint8_t *ptr = nullptr; 2878 2879 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2880 int32_t offset = insn.getOperand(1).getImm(); 2881 2882 int32_t pc = 2883 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2884 if (!success) 2885 return false; 2886 2887 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value)) 2888 ptr = (const uint8_t *)reg_value.GetBytes(); 2889 else 2890 return false; 2891 2892 for (int i = 0; i < 16 / element_byte_size; i++) { 2893 switch (element_byte_size) { 2894 case 1: 2895 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz)) 2896 branch_hit = false; 2897 break; 2898 case 2: 2899 if ((*(const uint16_t *)ptr == 0 && bnz) || 2900 (*(const uint16_t *)ptr != 0 && !bnz)) 2901 branch_hit = false; 2902 break; 2903 case 4: 2904 if ((*(const uint32_t *)ptr == 0 && bnz) || 2905 (*(const uint32_t *)ptr != 0 && !bnz)) 2906 branch_hit = false; 2907 break; 2908 case 8: 2909 if ((*(const uint64_t *)ptr == 0 && bnz) || 2910 (*(const uint64_t *)ptr != 0 && !bnz)) 2911 branch_hit = false; 2912 break; 2913 } 2914 if (!branch_hit) 2915 break; 2916 ptr = ptr + element_byte_size; 2917 } 2918 2919 if (branch_hit) 2920 target = pc + offset; 2921 else 2922 target = pc + 8; 2923 2924 Context context; 2925 context.type = eContextRelativeBranchImmediate; 2926 2927 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2928 target); 2929} 2930 2931bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) { 2932 return Emulate_MSA_Branch_V(insn, true); 2933} 2934 2935bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) { 2936 return Emulate_MSA_Branch_V(insn, false); 2937} 2938 2939bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn, 2940 bool bnz) { 2941 bool success = false; 2942 int32_t target = 0; 2943 llvm::APInt wr_val = llvm::APInt::getZero(128); 2944 llvm::APInt fail_value = llvm::APInt::getMaxValue(128); 2945 llvm::APInt zero_value = llvm::APInt::getZero(128); 2946 RegisterValue reg_value; 2947 2948 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2949 int32_t offset = insn.getOperand(1).getImm(); 2950 2951 int32_t pc = 2952 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2953 if (!success) 2954 return false; 2955 2956 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value)) 2957 wr_val = reg_value.GetAsUInt128(fail_value); 2958 else 2959 return false; 2960 2961 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || 2962 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz)) 2963 target = pc + offset; 2964 else 2965 target = pc + 8; 2966 2967 Context context; 2968 context.type = eContextRelativeBranchImmediate; 2969 2970 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, 2971 target); 2972} 2973 2974bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) { 2975 bool success = false; 2976 uint32_t base; 2977 int32_t imm, address; 2978 Context bad_vaddr_context; 2979 2980 uint32_t num_operands = insn.getNumOperands(); 2981 base = 2982 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 2983 imm = insn.getOperand(num_operands - 1).getImm(); 2984 2985 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base)) 2986 return false; 2987 2988 /* read base register */ 2989 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 2990 dwarf_zero_mips + base, 0, &success); 2991 if (!success) 2992 return false; 2993 2994 /* destination address */ 2995 address = address + imm; 2996 2997 /* Set the bad_vaddr register with base address used in the instruction */ 2998 bad_vaddr_context.type = eContextInvalid; 2999 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 3000 address); 3001 3002 return true; 3003} 3004 3005bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) { 3006 bool success = false; 3007 uint32_t base, index; 3008 int32_t address, index_address; 3009 Context bad_vaddr_context; 3010 3011 uint32_t num_operands = insn.getNumOperands(); 3012 base = 3013 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 3014 index = 3015 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg()); 3016 3017 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base)) 3018 return false; 3019 3020 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index)) 3021 return false; 3022 3023 /* read base register */ 3024 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, 3025 dwarf_zero_mips + base, 0, &success); 3026 if (!success) 3027 return false; 3028 3029 /* read index register */ 3030 index_address = (int32_t)ReadRegisterUnsigned( 3031 eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success); 3032 if (!success) 3033 return false; 3034 3035 /* destination address */ 3036 address = address + index_address; 3037 3038 /* Set the bad_vaddr register with base address used in the instruction */ 3039 bad_vaddr_context.type = eContextInvalid; 3040 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 3041 address); 3042 3043 return true; 3044} 3045