1 //===-- EmulateInstructionMIPS64.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 "EmulateInstructionMIPS64.h" 10 11 #include <cstdlib> 12 13 #include "lldb/Core/Address.h" 14 #include "lldb/Core/Opcode.h" 15 #include "lldb/Core/PluginManager.h" 16 #include "lldb/Host/PosixApi.h" 17 #include "lldb/Symbol/UnwindPlan.h" 18 #include "lldb/Utility/ArchSpec.h" 19 #include "lldb/Utility/ConstString.h" 20 #include "lldb/Utility/DataExtractor.h" 21 #include "lldb/Utility/RegisterValue.h" 22 #include "lldb/Utility/Stream.h" 23 #include "llvm-c/Disassembler.h" 24 #include "llvm/MC/MCAsmInfo.h" 25 #include "llvm/MC/MCContext.h" 26 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 27 #include "llvm/MC/MCInst.h" 28 #include "llvm/MC/MCInstrInfo.h" 29 #include "llvm/MC/MCRegisterInfo.h" 30 #include "llvm/MC/MCSubtargetInfo.h" 31 #include "llvm/MC/MCTargetOptions.h" 32 #include "llvm/MC/TargetRegistry.h" 33 #include "llvm/Support/TargetSelect.h" 34 35 #include "llvm/ADT/STLExtras.h" 36 37 #include "Plugins/Process/Utility/InstructionUtils.h" 38 #include "Plugins/Process/Utility/RegisterContext_mips.h" 39 40 using namespace lldb; 41 using namespace lldb_private; 42 43 LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionMIPS64, InstructionMIPS64) 44 45 #define UInt(x) ((uint64_t)x) 46 #define integer int64_t 47 48 // 49 // EmulateInstructionMIPS64 implementation 50 // 51 52 #ifdef __mips__ 53 extern "C" { 54 void LLVMInitializeMipsTargetInfo(); 55 void LLVMInitializeMipsTarget(); 56 void LLVMInitializeMipsAsmPrinter(); 57 void LLVMInitializeMipsTargetMC(); 58 void LLVMInitializeMipsDisassembler(); 59 } 60 #endif 61 62 EmulateInstructionMIPS64::EmulateInstructionMIPS64( 63 const lldb_private::ArchSpec &arch) 64 : EmulateInstruction(arch) { 65 /* Create instance of llvm::MCDisassembler */ 66 std::string Status; 67 llvm::Triple triple = arch.GetTriple(); 68 const llvm::Target *target = 69 llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status); 70 71 /* 72 * If we fail to get the target then we haven't registered it. The 73 * SystemInitializerCommon 74 * does not initialize targets, MCs and disassemblers. However we need the 75 * MCDisassembler 76 * to decode the instructions so that the decoding complexity stays with LLVM. 77 * Initialize the MIPS targets and disassemblers. 78 */ 79 #ifdef __mips__ 80 if (!target) { 81 LLVMInitializeMipsTargetInfo(); 82 LLVMInitializeMipsTarget(); 83 LLVMInitializeMipsAsmPrinter(); 84 LLVMInitializeMipsTargetMC(); 85 LLVMInitializeMipsDisassembler(); 86 target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status); 87 } 88 #endif 89 90 assert(target); 91 92 llvm::StringRef cpu; 93 94 switch (arch.GetCore()) { 95 case ArchSpec::eCore_mips32: 96 case ArchSpec::eCore_mips32el: 97 cpu = "mips32"; 98 break; 99 case ArchSpec::eCore_mips32r2: 100 case ArchSpec::eCore_mips32r2el: 101 cpu = "mips32r2"; 102 break; 103 case ArchSpec::eCore_mips32r3: 104 case ArchSpec::eCore_mips32r3el: 105 cpu = "mips32r3"; 106 break; 107 case ArchSpec::eCore_mips32r5: 108 case ArchSpec::eCore_mips32r5el: 109 cpu = "mips32r5"; 110 break; 111 case ArchSpec::eCore_mips32r6: 112 case ArchSpec::eCore_mips32r6el: 113 cpu = "mips32r6"; 114 break; 115 case ArchSpec::eCore_mips64: 116 case ArchSpec::eCore_mips64el: 117 cpu = "mips64"; 118 break; 119 case ArchSpec::eCore_mips64r2: 120 case ArchSpec::eCore_mips64r2el: 121 cpu = "mips64r2"; 122 break; 123 case ArchSpec::eCore_mips64r3: 124 case ArchSpec::eCore_mips64r3el: 125 cpu = "mips64r3"; 126 break; 127 case ArchSpec::eCore_mips64r5: 128 case ArchSpec::eCore_mips64r5el: 129 cpu = "mips64r5"; 130 break; 131 case ArchSpec::eCore_mips64r6: 132 case ArchSpec::eCore_mips64r6el: 133 cpu = "mips64r6"; 134 break; 135 default: 136 cpu = "generic"; 137 break; 138 } 139 140 std::string features; 141 uint32_t arch_flags = arch.GetFlags(); 142 if (arch_flags & ArchSpec::eMIPSAse_msa) 143 features += "+msa,"; 144 if (arch_flags & ArchSpec::eMIPSAse_dsp) 145 features += "+dsp,"; 146 if (arch_flags & ArchSpec::eMIPSAse_dspr2) 147 features += "+dspr2,"; 148 if (arch_flags & ArchSpec::eMIPSAse_mips16) 149 features += "+mips16,"; 150 if (arch_flags & ArchSpec::eMIPSAse_micromips) 151 features += "+micromips,"; 152 153 m_reg_info.reset(target->createMCRegInfo(triple.getTriple())); 154 assert(m_reg_info.get()); 155 156 m_insn_info.reset(target->createMCInstrInfo()); 157 assert(m_insn_info.get()); 158 159 llvm::MCTargetOptions MCOptions; 160 m_asm_info.reset( 161 target->createMCAsmInfo(*m_reg_info, triple.getTriple(), MCOptions)); 162 m_subtype_info.reset( 163 target->createMCSubtargetInfo(triple.getTriple(), cpu, features)); 164 assert(m_asm_info.get() && m_subtype_info.get()); 165 166 m_context = std::make_unique<llvm::MCContext>( 167 triple, m_asm_info.get(), m_reg_info.get(), m_subtype_info.get()); 168 assert(m_context.get()); 169 170 m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context)); 171 assert(m_disasm.get()); 172 } 173 174 void EmulateInstructionMIPS64::Initialize() { 175 PluginManager::RegisterPlugin(GetPluginNameStatic(), 176 GetPluginDescriptionStatic(), CreateInstance); 177 } 178 179 void EmulateInstructionMIPS64::Terminate() { 180 PluginManager::UnregisterPlugin(CreateInstance); 181 } 182 183 llvm::StringRef EmulateInstructionMIPS64::GetPluginDescriptionStatic() { 184 return "Emulate instructions for the MIPS64 architecture."; 185 } 186 187 EmulateInstruction * 188 EmulateInstructionMIPS64::CreateInstance(const ArchSpec &arch, 189 InstructionType inst_type) { 190 if (EmulateInstructionMIPS64::SupportsEmulatingInstructionsOfTypeStatic( 191 inst_type)) { 192 if (arch.GetTriple().getArch() == llvm::Triple::mips64 || 193 arch.GetTriple().getArch() == llvm::Triple::mips64el) { 194 return new EmulateInstructionMIPS64(arch); 195 } 196 } 197 198 return nullptr; 199 } 200 201 bool EmulateInstructionMIPS64::SetTargetTriple(const ArchSpec &arch) { 202 return arch.GetTriple().getArch() == llvm::Triple::mips64 || 203 arch.GetTriple().getArch() == llvm::Triple::mips64el; 204 } 205 206 const char *EmulateInstructionMIPS64::GetRegisterName(unsigned reg_num, 207 bool alternate_name) { 208 if (alternate_name) { 209 switch (reg_num) { 210 case dwarf_sp_mips64: 211 return "r29"; 212 case dwarf_r30_mips64: 213 return "r30"; 214 case dwarf_ra_mips64: 215 return "r31"; 216 case dwarf_f0_mips64: 217 return "f0"; 218 case dwarf_f1_mips64: 219 return "f1"; 220 case dwarf_f2_mips64: 221 return "f2"; 222 case dwarf_f3_mips64: 223 return "f3"; 224 case dwarf_f4_mips64: 225 return "f4"; 226 case dwarf_f5_mips64: 227 return "f5"; 228 case dwarf_f6_mips64: 229 return "f6"; 230 case dwarf_f7_mips64: 231 return "f7"; 232 case dwarf_f8_mips64: 233 return "f8"; 234 case dwarf_f9_mips64: 235 return "f9"; 236 case dwarf_f10_mips64: 237 return "f10"; 238 case dwarf_f11_mips64: 239 return "f11"; 240 case dwarf_f12_mips64: 241 return "f12"; 242 case dwarf_f13_mips64: 243 return "f13"; 244 case dwarf_f14_mips64: 245 return "f14"; 246 case dwarf_f15_mips64: 247 return "f15"; 248 case dwarf_f16_mips64: 249 return "f16"; 250 case dwarf_f17_mips64: 251 return "f17"; 252 case dwarf_f18_mips64: 253 return "f18"; 254 case dwarf_f19_mips64: 255 return "f19"; 256 case dwarf_f20_mips64: 257 return "f20"; 258 case dwarf_f21_mips64: 259 return "f21"; 260 case dwarf_f22_mips64: 261 return "f22"; 262 case dwarf_f23_mips64: 263 return "f23"; 264 case dwarf_f24_mips64: 265 return "f24"; 266 case dwarf_f25_mips64: 267 return "f25"; 268 case dwarf_f26_mips64: 269 return "f26"; 270 case dwarf_f27_mips64: 271 return "f27"; 272 case dwarf_f28_mips64: 273 return "f28"; 274 case dwarf_f29_mips64: 275 return "f29"; 276 case dwarf_f30_mips64: 277 return "f30"; 278 case dwarf_f31_mips64: 279 return "f31"; 280 case dwarf_w0_mips64: 281 return "w0"; 282 case dwarf_w1_mips64: 283 return "w1"; 284 case dwarf_w2_mips64: 285 return "w2"; 286 case dwarf_w3_mips64: 287 return "w3"; 288 case dwarf_w4_mips64: 289 return "w4"; 290 case dwarf_w5_mips64: 291 return "w5"; 292 case dwarf_w6_mips64: 293 return "w6"; 294 case dwarf_w7_mips64: 295 return "w7"; 296 case dwarf_w8_mips64: 297 return "w8"; 298 case dwarf_w9_mips64: 299 return "w9"; 300 case dwarf_w10_mips64: 301 return "w10"; 302 case dwarf_w11_mips64: 303 return "w11"; 304 case dwarf_w12_mips64: 305 return "w12"; 306 case dwarf_w13_mips64: 307 return "w13"; 308 case dwarf_w14_mips64: 309 return "w14"; 310 case dwarf_w15_mips64: 311 return "w15"; 312 case dwarf_w16_mips64: 313 return "w16"; 314 case dwarf_w17_mips64: 315 return "w17"; 316 case dwarf_w18_mips64: 317 return "w18"; 318 case dwarf_w19_mips64: 319 return "w19"; 320 case dwarf_w20_mips64: 321 return "w20"; 322 case dwarf_w21_mips64: 323 return "w21"; 324 case dwarf_w22_mips64: 325 return "w22"; 326 case dwarf_w23_mips64: 327 return "w23"; 328 case dwarf_w24_mips64: 329 return "w24"; 330 case dwarf_w25_mips64: 331 return "w25"; 332 case dwarf_w26_mips64: 333 return "w26"; 334 case dwarf_w27_mips64: 335 return "w27"; 336 case dwarf_w28_mips64: 337 return "w28"; 338 case dwarf_w29_mips64: 339 return "w29"; 340 case dwarf_w30_mips64: 341 return "w30"; 342 case dwarf_w31_mips64: 343 return "w31"; 344 case dwarf_mir_mips64: 345 return "mir"; 346 case dwarf_mcsr_mips64: 347 return "mcsr"; 348 case dwarf_config5_mips64: 349 return "config5"; 350 default: 351 break; 352 } 353 return nullptr; 354 } 355 356 switch (reg_num) { 357 case dwarf_zero_mips64: 358 return "r0"; 359 case dwarf_r1_mips64: 360 return "r1"; 361 case dwarf_r2_mips64: 362 return "r2"; 363 case dwarf_r3_mips64: 364 return "r3"; 365 case dwarf_r4_mips64: 366 return "r4"; 367 case dwarf_r5_mips64: 368 return "r5"; 369 case dwarf_r6_mips64: 370 return "r6"; 371 case dwarf_r7_mips64: 372 return "r7"; 373 case dwarf_r8_mips64: 374 return "r8"; 375 case dwarf_r9_mips64: 376 return "r9"; 377 case dwarf_r10_mips64: 378 return "r10"; 379 case dwarf_r11_mips64: 380 return "r11"; 381 case dwarf_r12_mips64: 382 return "r12"; 383 case dwarf_r13_mips64: 384 return "r13"; 385 case dwarf_r14_mips64: 386 return "r14"; 387 case dwarf_r15_mips64: 388 return "r15"; 389 case dwarf_r16_mips64: 390 return "r16"; 391 case dwarf_r17_mips64: 392 return "r17"; 393 case dwarf_r18_mips64: 394 return "r18"; 395 case dwarf_r19_mips64: 396 return "r19"; 397 case dwarf_r20_mips64: 398 return "r20"; 399 case dwarf_r21_mips64: 400 return "r21"; 401 case dwarf_r22_mips64: 402 return "r22"; 403 case dwarf_r23_mips64: 404 return "r23"; 405 case dwarf_r24_mips64: 406 return "r24"; 407 case dwarf_r25_mips64: 408 return "r25"; 409 case dwarf_r26_mips64: 410 return "r26"; 411 case dwarf_r27_mips64: 412 return "r27"; 413 case dwarf_gp_mips64: 414 return "gp"; 415 case dwarf_sp_mips64: 416 return "sp"; 417 case dwarf_r30_mips64: 418 return "fp"; 419 case dwarf_ra_mips64: 420 return "ra"; 421 case dwarf_sr_mips64: 422 return "sr"; 423 case dwarf_lo_mips64: 424 return "lo"; 425 case dwarf_hi_mips64: 426 return "hi"; 427 case dwarf_bad_mips64: 428 return "bad"; 429 case dwarf_cause_mips64: 430 return "cause"; 431 case dwarf_pc_mips64: 432 return "pc"; 433 case dwarf_f0_mips64: 434 return "f0"; 435 case dwarf_f1_mips64: 436 return "f1"; 437 case dwarf_f2_mips64: 438 return "f2"; 439 case dwarf_f3_mips64: 440 return "f3"; 441 case dwarf_f4_mips64: 442 return "f4"; 443 case dwarf_f5_mips64: 444 return "f5"; 445 case dwarf_f6_mips64: 446 return "f6"; 447 case dwarf_f7_mips64: 448 return "f7"; 449 case dwarf_f8_mips64: 450 return "f8"; 451 case dwarf_f9_mips64: 452 return "f9"; 453 case dwarf_f10_mips64: 454 return "f10"; 455 case dwarf_f11_mips64: 456 return "f11"; 457 case dwarf_f12_mips64: 458 return "f12"; 459 case dwarf_f13_mips64: 460 return "f13"; 461 case dwarf_f14_mips64: 462 return "f14"; 463 case dwarf_f15_mips64: 464 return "f15"; 465 case dwarf_f16_mips64: 466 return "f16"; 467 case dwarf_f17_mips64: 468 return "f17"; 469 case dwarf_f18_mips64: 470 return "f18"; 471 case dwarf_f19_mips64: 472 return "f19"; 473 case dwarf_f20_mips64: 474 return "f20"; 475 case dwarf_f21_mips64: 476 return "f21"; 477 case dwarf_f22_mips64: 478 return "f22"; 479 case dwarf_f23_mips64: 480 return "f23"; 481 case dwarf_f24_mips64: 482 return "f24"; 483 case dwarf_f25_mips64: 484 return "f25"; 485 case dwarf_f26_mips64: 486 return "f26"; 487 case dwarf_f27_mips64: 488 return "f27"; 489 case dwarf_f28_mips64: 490 return "f28"; 491 case dwarf_f29_mips64: 492 return "f29"; 493 case dwarf_f30_mips64: 494 return "f30"; 495 case dwarf_f31_mips64: 496 return "f31"; 497 case dwarf_fcsr_mips64: 498 return "fcsr"; 499 case dwarf_fir_mips64: 500 return "fir"; 501 case dwarf_w0_mips64: 502 return "w0"; 503 case dwarf_w1_mips64: 504 return "w1"; 505 case dwarf_w2_mips64: 506 return "w2"; 507 case dwarf_w3_mips64: 508 return "w3"; 509 case dwarf_w4_mips64: 510 return "w4"; 511 case dwarf_w5_mips64: 512 return "w5"; 513 case dwarf_w6_mips64: 514 return "w6"; 515 case dwarf_w7_mips64: 516 return "w7"; 517 case dwarf_w8_mips64: 518 return "w8"; 519 case dwarf_w9_mips64: 520 return "w9"; 521 case dwarf_w10_mips64: 522 return "w10"; 523 case dwarf_w11_mips64: 524 return "w11"; 525 case dwarf_w12_mips64: 526 return "w12"; 527 case dwarf_w13_mips64: 528 return "w13"; 529 case dwarf_w14_mips64: 530 return "w14"; 531 case dwarf_w15_mips64: 532 return "w15"; 533 case dwarf_w16_mips64: 534 return "w16"; 535 case dwarf_w17_mips64: 536 return "w17"; 537 case dwarf_w18_mips64: 538 return "w18"; 539 case dwarf_w19_mips64: 540 return "w19"; 541 case dwarf_w20_mips64: 542 return "w20"; 543 case dwarf_w21_mips64: 544 return "w21"; 545 case dwarf_w22_mips64: 546 return "w22"; 547 case dwarf_w23_mips64: 548 return "w23"; 549 case dwarf_w24_mips64: 550 return "w24"; 551 case dwarf_w25_mips64: 552 return "w25"; 553 case dwarf_w26_mips64: 554 return "w26"; 555 case dwarf_w27_mips64: 556 return "w27"; 557 case dwarf_w28_mips64: 558 return "w28"; 559 case dwarf_w29_mips64: 560 return "w29"; 561 case dwarf_w30_mips64: 562 return "w30"; 563 case dwarf_w31_mips64: 564 return "w31"; 565 case dwarf_mcsr_mips64: 566 return "mcsr"; 567 case dwarf_mir_mips64: 568 return "mir"; 569 case dwarf_config5_mips64: 570 return "config5"; 571 } 572 return nullptr; 573 } 574 575 bool EmulateInstructionMIPS64::GetRegisterInfo(RegisterKind reg_kind, 576 uint32_t reg_num, 577 RegisterInfo ®_info) { 578 if (reg_kind == eRegisterKindGeneric) { 579 switch (reg_num) { 580 case LLDB_REGNUM_GENERIC_PC: 581 reg_kind = eRegisterKindDWARF; 582 reg_num = dwarf_pc_mips64; 583 break; 584 case LLDB_REGNUM_GENERIC_SP: 585 reg_kind = eRegisterKindDWARF; 586 reg_num = dwarf_sp_mips64; 587 break; 588 case LLDB_REGNUM_GENERIC_FP: 589 reg_kind = eRegisterKindDWARF; 590 reg_num = dwarf_r30_mips64; 591 break; 592 case LLDB_REGNUM_GENERIC_RA: 593 reg_kind = eRegisterKindDWARF; 594 reg_num = dwarf_ra_mips64; 595 break; 596 case LLDB_REGNUM_GENERIC_FLAGS: 597 reg_kind = eRegisterKindDWARF; 598 reg_num = dwarf_sr_mips64; 599 break; 600 default: 601 return false; 602 } 603 } 604 605 if (reg_kind == eRegisterKindDWARF) { 606 ::memset(®_info, 0, sizeof(RegisterInfo)); 607 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); 608 609 if (reg_num == dwarf_sr_mips64 || reg_num == dwarf_fcsr_mips64 || 610 reg_num == dwarf_fir_mips64 || reg_num == dwarf_mcsr_mips64 || 611 reg_num == dwarf_mir_mips64 || reg_num == dwarf_config5_mips64) { 612 reg_info.byte_size = 4; 613 reg_info.format = eFormatHex; 614 reg_info.encoding = eEncodingUint; 615 } else if ((int)reg_num >= dwarf_zero_mips64 && 616 (int)reg_num <= dwarf_f31_mips64) { 617 reg_info.byte_size = 8; 618 reg_info.format = eFormatHex; 619 reg_info.encoding = eEncodingUint; 620 } else if ((int)reg_num >= dwarf_w0_mips64 && 621 (int)reg_num <= dwarf_w31_mips64) { 622 reg_info.byte_size = 16; 623 reg_info.format = eFormatVectorOfUInt8; 624 reg_info.encoding = eEncodingVector; 625 } else { 626 return false; 627 } 628 629 reg_info.name = GetRegisterName(reg_num, false); 630 reg_info.alt_name = GetRegisterName(reg_num, true); 631 reg_info.kinds[eRegisterKindDWARF] = reg_num; 632 633 switch (reg_num) { 634 case dwarf_r30_mips64: 635 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; 636 break; 637 case dwarf_ra_mips64: 638 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; 639 break; 640 case dwarf_sp_mips64: 641 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; 642 break; 643 case dwarf_pc_mips64: 644 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; 645 break; 646 case dwarf_sr_mips64: 647 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; 648 break; 649 default: 650 break; 651 } 652 return true; 653 } 654 return false; 655 } 656 657 EmulateInstructionMIPS64::MipsOpcode * 658 EmulateInstructionMIPS64::GetOpcodeForInstruction(const char *op_name) { 659 static EmulateInstructionMIPS64::MipsOpcode g_opcodes[] = { 660 // Prologue/Epilogue instructions 661 {"DADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu, 662 "DADDIU rt, rs, immediate"}, 663 {"ADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu, 664 "ADDIU rt, rs, immediate"}, 665 {"SD", &EmulateInstructionMIPS64::Emulate_SD, "SD rt, offset(rs)"}, 666 {"LD", &EmulateInstructionMIPS64::Emulate_LD, "LD rt, offset(base)"}, 667 {"DSUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, 668 "DSUBU rd, rs, rt"}, 669 {"SUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, 670 "SUBU rd, rs, rt"}, 671 {"DADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, 672 "DADDU rd, rs, rt"}, 673 {"ADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, 674 "ADDU rd, rs, rt"}, 675 {"LUI", &EmulateInstructionMIPS64::Emulate_LUI, "LUI rt, immediate"}, 676 677 // Load/Store instructions 678 /* Following list of emulated instructions are required by implementation 679 of hardware watchpoint 680 for MIPS in lldb. As we just need the address accessed by instructions, 681 we have generalised 682 all these instructions in 2 functions depending on their addressing 683 modes */ 684 685 {"LB", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 686 "LB rt, offset(base)"}, 687 {"LBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 688 "LBE rt, offset(base)"}, 689 {"LBU", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 690 "LBU rt, offset(base)"}, 691 {"LBUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 692 "LBUE rt, offset(base)"}, 693 {"LDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 694 "LDC1 ft, offset(base)"}, 695 {"LDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 696 "LDL rt, offset(base)"}, 697 {"LDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 698 "LDR rt, offset(base)"}, 699 {"LLD", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 700 "LLD rt, offset(base)"}, 701 {"LDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 702 "LDC2 rt, offset(base)"}, 703 {"LDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, 704 "LDXC1 fd, index (base)"}, 705 {"LH", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 706 "LH rt, offset(base)"}, 707 {"LHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 708 "LHE rt, offset(base)"}, 709 {"LHU", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 710 "LHU rt, offset(base)"}, 711 {"LHUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 712 "LHUE rt, offset(base)"}, 713 {"LL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 714 "LL rt, offset(base)"}, 715 {"LLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 716 "LLE rt, offset(base)"}, 717 {"LUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, 718 "LUXC1 fd, index (base)"}, 719 {"LW", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 720 "LW rt, offset(rs)"}, 721 {"LWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 722 "LWC1 ft, offset(base)"}, 723 {"LWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 724 "LWC2 rt, offset(base)"}, 725 {"LWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 726 "LWE rt, offset(base)"}, 727 {"LWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 728 "LWL rt, offset(base)"}, 729 {"LWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 730 "LWLE rt, offset(base)"}, 731 {"LWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 732 "LWR rt, offset(base)"}, 733 {"LWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 734 "LWRE rt, offset(base)"}, 735 {"LWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, 736 "LWXC1 fd, index (base)"}, 737 738 {"SB", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 739 "SB rt, offset(base)"}, 740 {"SBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 741 "SBE rt, offset(base)"}, 742 {"SC", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 743 "SC rt, offset(base)"}, 744 {"SCE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 745 "SCE rt, offset(base)"}, 746 {"SCD", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 747 "SCD rt, offset(base)"}, 748 {"SDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 749 "SDL rt, offset(base)"}, 750 {"SDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 751 "SDR rt, offset(base)"}, 752 {"SDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 753 "SDC1 ft, offset(base)"}, 754 {"SDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 755 "SDC2 rt, offset(base)"}, 756 {"SDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, 757 "SDXC1 fs, index (base)"}, 758 {"SH", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 759 "SH rt, offset(base)"}, 760 {"SHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 761 "SHE rt, offset(base)"}, 762 {"SUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, 763 "SUXC1 fs, index (base)"}, 764 {"SW", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 765 "SW rt, offset(rs)"}, 766 {"SWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 767 "SWC1 ft, offset(base)"}, 768 {"SWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 769 "SWC2 rt, offset(base)"}, 770 {"SWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 771 "SWE rt, offset(base)"}, 772 {"SWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 773 "SWL rt, offset(base)"}, 774 {"SWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 775 "SWLE rt, offset(base)"}, 776 {"SWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 777 "SWR rt, offset(base)"}, 778 {"SWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, 779 "SWRE rt, offset(base)"}, 780 {"SWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, 781 "SWXC1 fs, index (base)"}, 782 783 // Branch instructions 784 {"BEQ", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"}, 785 {"BEQ64", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"}, 786 {"BNE", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"}, 787 {"BNE64", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"}, 788 {"BEQL", &EmulateInstructionMIPS64::Emulate_BXX_3ops, 789 "BEQL rs,rt,offset"}, 790 {"BNEL", &EmulateInstructionMIPS64::Emulate_BXX_3ops, 791 "BNEL rs,rt,offset"}, 792 {"BGEZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, 793 "BGEZALL rt,offset"}, 794 {"BAL", &EmulateInstructionMIPS64::Emulate_BAL, "BAL offset"}, 795 {"BGEZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, 796 "BGEZAL rs,offset"}, 797 {"BALC", &EmulateInstructionMIPS64::Emulate_BALC, "BALC offset"}, 798 {"BC", &EmulateInstructionMIPS64::Emulate_BC, "BC offset"}, 799 {"BGEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"}, 800 {"BGEZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"}, 801 {"BLEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C, 802 "BLEZALC rs,offset"}, 803 {"BGEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C, 804 "BGEZALC rs,offset"}, 805 {"BLTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C, 806 "BLTZALC rs,offset"}, 807 {"BGTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C, 808 "BGTZALC rs,offset"}, 809 {"BEQZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C, 810 "BEQZALC rs,offset"}, 811 {"BNEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C, 812 "BNEZALC rs,offset"}, 813 {"BEQC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 814 "BEQC rs,rt,offset"}, 815 {"BEQC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 816 "BEQC rs,rt,offset"}, 817 {"BNEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 818 "BNEC rs,rt,offset"}, 819 {"BNEC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 820 "BNEC rs,rt,offset"}, 821 {"BLTC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 822 "BLTC rs,rt,offset"}, 823 {"BLTC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 824 "BLTC rs,rt,offset"}, 825 {"BGEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 826 "BGEC rs,rt,offset"}, 827 {"BGEC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 828 "BGEC rs,rt,offset"}, 829 {"BLTUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 830 "BLTUC rs,rt,offset"}, 831 {"BLTUC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 832 "BLTUC rs,rt,offset"}, 833 {"BGEUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 834 "BGEUC rs,rt,offset"}, 835 {"BGEUC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 836 "BGEUC rs,rt,offset"}, 837 {"BLTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 838 "BLTZC rt,offset"}, 839 {"BLTZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 840 "BLTZC rt,offset"}, 841 {"BLEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 842 "BLEZC rt,offset"}, 843 {"BLEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 844 "BLEZC rt,offset"}, 845 {"BGEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 846 "BGEZC rt,offset"}, 847 {"BGEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 848 "BGEZC rt,offset"}, 849 {"BGTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 850 "BGTZC rt,offset"}, 851 {"BGTZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 852 "BGTZC rt,offset"}, 853 {"BEQZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 854 "BEQZC rt,offset"}, 855 {"BEQZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 856 "BEQZC rt,offset"}, 857 {"BNEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 858 "BNEZC rt,offset"}, 859 {"BNEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, 860 "BNEZC rt,offset"}, 861 {"BGEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZL rt,offset"}, 862 {"BGTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"}, 863 {"BGTZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"}, 864 {"BGTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZL rt,offset"}, 865 {"BLEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"}, 866 {"BLEZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"}, 867 {"BLEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZL rt,offset"}, 868 {"BLTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"}, 869 {"BLTZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"}, 870 {"BLTZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, 871 "BLTZAL rt,offset"}, 872 {"BLTZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, 873 "BLTZALL rt,offset"}, 874 {"BLTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZL rt,offset"}, 875 {"BOVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 876 "BOVC rs,rt,offset"}, 877 {"BNVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, 878 "BNVC rs,rt,offset"}, 879 {"J", &EmulateInstructionMIPS64::Emulate_J, "J target"}, 880 {"JAL", &EmulateInstructionMIPS64::Emulate_JAL, "JAL target"}, 881 {"JALX", &EmulateInstructionMIPS64::Emulate_JAL, "JALX target"}, 882 {"JALR", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"}, 883 {"JALR64", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"}, 884 {"JALR_HB", &EmulateInstructionMIPS64::Emulate_JALR, "JALR.HB target"}, 885 {"JIALC", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"}, 886 {"JIALC64", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"}, 887 {"JIC", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"}, 888 {"JIC64", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"}, 889 {"JR", &EmulateInstructionMIPS64::Emulate_JR, "JR target"}, 890 {"JR64", &EmulateInstructionMIPS64::Emulate_JR, "JR target"}, 891 {"JR_HB", &EmulateInstructionMIPS64::Emulate_JR, "JR.HB target"}, 892 {"BC1F", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1F cc, offset"}, 893 {"BC1T", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1T cc, offset"}, 894 {"BC1FL", &EmulateInstructionMIPS64::Emulate_FP_branch, 895 "BC1FL cc, offset"}, 896 {"BC1TL", &EmulateInstructionMIPS64::Emulate_FP_branch, 897 "BC1TL cc, offset"}, 898 {"BC1EQZ", &EmulateInstructionMIPS64::Emulate_BC1EQZ, 899 "BC1EQZ ft, offset"}, 900 {"BC1NEZ", &EmulateInstructionMIPS64::Emulate_BC1NEZ, 901 "BC1NEZ ft, offset"}, 902 {"BC1ANY2F", &EmulateInstructionMIPS64::Emulate_3D_branch, 903 "BC1ANY2F cc, offset"}, 904 {"BC1ANY2T", &EmulateInstructionMIPS64::Emulate_3D_branch, 905 "BC1ANY2T cc, offset"}, 906 {"BC1ANY4F", &EmulateInstructionMIPS64::Emulate_3D_branch, 907 "BC1ANY4F cc, offset"}, 908 {"BC1ANY4T", &EmulateInstructionMIPS64::Emulate_3D_branch, 909 "BC1ANY4T cc, offset"}, 910 {"BNZ_B", &EmulateInstructionMIPS64::Emulate_BNZB, "BNZ.b wt,s16"}, 911 {"BNZ_H", &EmulateInstructionMIPS64::Emulate_BNZH, "BNZ.h wt,s16"}, 912 {"BNZ_W", &EmulateInstructionMIPS64::Emulate_BNZW, "BNZ.w wt,s16"}, 913 {"BNZ_D", &EmulateInstructionMIPS64::Emulate_BNZD, "BNZ.d wt,s16"}, 914 {"BZ_B", &EmulateInstructionMIPS64::Emulate_BZB, "BZ.b wt,s16"}, 915 {"BZ_H", &EmulateInstructionMIPS64::Emulate_BZH, "BZ.h wt,s16"}, 916 {"BZ_W", &EmulateInstructionMIPS64::Emulate_BZW, "BZ.w wt,s16"}, 917 {"BZ_D", &EmulateInstructionMIPS64::Emulate_BZD, "BZ.d wt,s16"}, 918 {"BNZ_V", &EmulateInstructionMIPS64::Emulate_BNZV, "BNZ.V wt,s16"}, 919 {"BZ_V", &EmulateInstructionMIPS64::Emulate_BZV, "BZ.V wt,s16"}, 920 }; 921 922 static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes); 923 924 for (size_t i = 0; i < k_num_mips_opcodes; ++i) { 925 if (!strcasecmp(g_opcodes[i].op_name, op_name)) 926 return &g_opcodes[i]; 927 } 928 929 return nullptr; 930 } 931 932 bool EmulateInstructionMIPS64::ReadInstruction() { 933 bool success = false; 934 m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 935 LLDB_INVALID_ADDRESS, &success); 936 if (success) { 937 Context read_inst_context; 938 read_inst_context.type = eContextReadOpcode; 939 read_inst_context.SetNoArgs(); 940 m_opcode.SetOpcode32( 941 ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success), 942 GetByteOrder()); 943 } 944 if (!success) 945 m_addr = LLDB_INVALID_ADDRESS; 946 return success; 947 } 948 949 bool EmulateInstructionMIPS64::EvaluateInstruction(uint32_t evaluate_options) { 950 bool success = false; 951 llvm::MCInst mc_insn; 952 uint64_t insn_size; 953 DataExtractor data; 954 955 /* Keep the complexity of the decode logic with the llvm::MCDisassembler 956 * class. */ 957 if (m_opcode.GetData(data)) { 958 llvm::MCDisassembler::DecodeStatus decode_status; 959 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize()); 960 decode_status = m_disasm->getInstruction(mc_insn, insn_size, raw_insn, 961 m_addr, llvm::nulls()); 962 if (decode_status != llvm::MCDisassembler::Success) 963 return false; 964 } 965 966 /* 967 * mc_insn.getOpcode() returns decoded opcode. However to make use 968 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc". 969 */ 970 const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data(); 971 972 if (op_name == nullptr) 973 return false; 974 975 /* 976 * Decoding has been done already. Just get the call-back function 977 * and emulate the instruction. 978 */ 979 MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name); 980 981 if (opcode_data == nullptr) 982 return false; 983 984 uint64_t old_pc = 0, new_pc = 0; 985 const bool auto_advance_pc = 986 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 987 988 if (auto_advance_pc) { 989 old_pc = 990 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 991 if (!success) 992 return false; 993 } 994 995 /* emulate instruction */ 996 success = (this->*opcode_data->callback)(mc_insn); 997 if (!success) 998 return false; 999 1000 if (auto_advance_pc) { 1001 new_pc = 1002 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1003 if (!success) 1004 return false; 1005 1006 /* If we haven't changed the PC, change it here */ 1007 if (old_pc == new_pc) { 1008 new_pc += 4; 1009 Context context; 1010 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1011 new_pc)) 1012 return false; 1013 } 1014 } 1015 1016 return true; 1017 } 1018 1019 bool EmulateInstructionMIPS64::CreateFunctionEntryUnwind( 1020 UnwindPlan &unwind_plan) { 1021 unwind_plan.Clear(); 1022 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 1023 1024 UnwindPlan::RowSP row(new UnwindPlan::Row); 1025 const bool can_replace = false; 1026 1027 // Our previous Call Frame Address is the stack pointer 1028 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips64, 0); 1029 1030 // Our previous PC is in the RA 1031 row->SetRegisterLocationToRegister(dwarf_pc_mips64, dwarf_ra_mips64, 1032 can_replace); 1033 1034 unwind_plan.AppendRow(row); 1035 1036 // All other registers are the same. 1037 unwind_plan.SetSourceName("EmulateInstructionMIPS64"); 1038 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 1039 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 1040 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 1041 unwind_plan.SetReturnAddressRegister(dwarf_ra_mips64); 1042 1043 return true; 1044 } 1045 1046 bool EmulateInstructionMIPS64::nonvolatile_reg_p(uint64_t regnum) { 1047 switch (regnum) { 1048 case dwarf_r16_mips64: 1049 case dwarf_r17_mips64: 1050 case dwarf_r18_mips64: 1051 case dwarf_r19_mips64: 1052 case dwarf_r20_mips64: 1053 case dwarf_r21_mips64: 1054 case dwarf_r22_mips64: 1055 case dwarf_r23_mips64: 1056 case dwarf_gp_mips64: 1057 case dwarf_sp_mips64: 1058 case dwarf_r30_mips64: 1059 case dwarf_ra_mips64: 1060 return true; 1061 default: 1062 return false; 1063 } 1064 return false; 1065 } 1066 1067 bool EmulateInstructionMIPS64::Emulate_DADDiu(llvm::MCInst &insn) { 1068 // DADDIU rt, rs, immediate 1069 // GPR[rt] <- GPR[rs] + sign_extend(immediate) 1070 1071 uint8_t dst, src; 1072 bool success = false; 1073 const uint32_t imm16 = insn.getOperand(2).getImm(); 1074 int64_t imm = SignedBits(imm16, 15, 0); 1075 1076 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1077 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1078 1079 // If immediate is greater than 2^16 - 1 then clang generate LUI, 1080 // (D)ADDIU,(D)SUBU instructions in prolog. Example lui $1, 0x2 daddiu $1, 1081 // $1, -0x5920 dsubu $sp, $sp, $1 In this case, (D)ADDIU dst and src will be 1082 // same and not equal to sp 1083 if (dst == src) { 1084 Context context; 1085 1086 /* read <src> register */ 1087 const uint64_t src_opd_val = ReadRegisterUnsigned( 1088 eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success); 1089 if (!success) 1090 return false; 1091 1092 /* Check if this is daddiu sp, sp, imm16 */ 1093 if (dst == dwarf_sp_mips64) { 1094 /* 1095 * From the MIPS IV spec: 1096 * 1097 * The term “unsigned” in the instruction name is a misnomer; this 1098 * operation is 64-bit modulo arithmetic that does not trap on overflow. 1099 * It is appropriate for arithmetic which is not signed, such as address 1100 * arithmetic, or integer arithmetic environments that ignore overflow, 1101 * such as “C” language arithmetic. 1102 * 1103 * Assume 2's complement and rely on unsigned overflow here. 1104 */ 1105 uint64_t result = src_opd_val + imm; 1106 RegisterInfo reg_info_sp; 1107 1108 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp)) 1109 context.SetRegisterPlusOffset(reg_info_sp, imm); 1110 1111 /* We are allocating bytes on stack */ 1112 context.type = eContextAdjustStackPointer; 1113 1114 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64, 1115 result); 1116 return true; 1117 } 1118 1119 imm += src_opd_val; 1120 context.SetImmediateSigned(imm); 1121 context.type = eContextImmediate; 1122 1123 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 1124 dwarf_zero_mips64 + dst, imm)) 1125 return false; 1126 } 1127 1128 return true; 1129 } 1130 1131 bool EmulateInstructionMIPS64::Emulate_SD(llvm::MCInst &insn) { 1132 uint64_t address; 1133 RegisterInfo reg_info_base; 1134 RegisterInfo reg_info_src; 1135 bool success = false; 1136 uint32_t imm16 = insn.getOperand(2).getImm(); 1137 uint64_t imm = SignedBits(imm16, 15, 0); 1138 uint32_t src, base; 1139 Context bad_vaddr_context; 1140 1141 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1142 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1143 1144 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base, 1145 reg_info_base) || 1146 !GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src, 1147 reg_info_src)) 1148 return false; 1149 1150 /* read SP */ 1151 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base, 1152 0, &success); 1153 if (!success) 1154 return false; 1155 1156 /* destination address */ 1157 address = address + imm; 1158 1159 /* We look for sp based non-volatile register stores */ 1160 if (nonvolatile_reg_p(src)) { 1161 Context context; 1162 RegisterValue data_src; 1163 context.type = eContextPushRegisterOnStack; 1164 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0); 1165 1166 uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; 1167 Status error; 1168 1169 if (!ReadRegister(®_info_base, data_src)) 1170 return false; 1171 1172 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size, 1173 eByteOrderLittle, error) == 0) 1174 return false; 1175 1176 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size)) 1177 return false; 1178 } 1179 1180 /* Set the bad_vaddr register with base address used in the instruction */ 1181 bad_vaddr_context.type = eContextInvalid; 1182 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64, 1183 address); 1184 1185 return true; 1186 } 1187 1188 bool EmulateInstructionMIPS64::Emulate_LD(llvm::MCInst &insn) { 1189 bool success = false; 1190 uint32_t src, base; 1191 int64_t imm, address; 1192 Context bad_vaddr_context; 1193 1194 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1195 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1196 imm = insn.getOperand(2).getImm(); 1197 1198 RegisterInfo reg_info_base; 1199 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base, 1200 reg_info_base)) 1201 return false; 1202 1203 /* read base register */ 1204 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base, 1205 0, &success); 1206 if (!success) 1207 return false; 1208 1209 /* destination address */ 1210 address = address + imm; 1211 1212 /* Set the bad_vaddr register with base address used in the instruction */ 1213 bad_vaddr_context.type = eContextInvalid; 1214 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64, 1215 address); 1216 1217 if (nonvolatile_reg_p(src)) { 1218 RegisterValue data_src; 1219 RegisterInfo reg_info_src; 1220 1221 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src, 1222 reg_info_src)) 1223 return false; 1224 1225 Context context; 1226 context.type = eContextRegisterLoad; 1227 1228 return WriteRegister(context, ®_info_src, data_src); 1229 } 1230 1231 return false; 1232 } 1233 1234 bool EmulateInstructionMIPS64::Emulate_LUI(llvm::MCInst &insn) { 1235 // LUI rt, immediate 1236 // GPR[rt] <- sign_extend(immediate << 16) 1237 1238 const uint32_t imm32 = insn.getOperand(1).getImm() << 16; 1239 int64_t imm = SignedBits(imm32, 31, 0); 1240 uint8_t rt; 1241 Context context; 1242 1243 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1244 context.SetImmediateSigned(imm); 1245 context.type = eContextImmediate; 1246 1247 return WriteRegisterUnsigned(context, eRegisterKindDWARF, 1248 dwarf_zero_mips64 + rt, imm); 1249 } 1250 1251 bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) { 1252 // DSUBU sp, <src>, <rt> 1253 // DADDU sp, <src>, <rt> 1254 // DADDU dst, sp, <rt> 1255 1256 bool success = false; 1257 uint64_t result; 1258 uint8_t src, dst, rt; 1259 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 1260 1261 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1262 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1263 1264 /* Check if sp is destination register */ 1265 if (dst == dwarf_sp_mips64) { 1266 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg()); 1267 1268 /* read <src> register */ 1269 uint64_t src_opd_val = ReadRegisterUnsigned( 1270 eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success); 1271 if (!success) 1272 return false; 1273 1274 /* read <rt > register */ 1275 uint64_t rt_opd_val = ReadRegisterUnsigned( 1276 eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success); 1277 if (!success) 1278 return false; 1279 1280 if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU")) 1281 result = src_opd_val - rt_opd_val; 1282 else 1283 result = src_opd_val + rt_opd_val; 1284 1285 Context context; 1286 RegisterInfo reg_info_sp; 1287 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp)) 1288 context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val); 1289 1290 /* We are allocating bytes on stack */ 1291 context.type = eContextAdjustStackPointer; 1292 1293 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64, result); 1294 1295 return true; 1296 } else if (src == dwarf_sp_mips64) { 1297 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg()); 1298 1299 /* read <src> register */ 1300 uint64_t src_opd_val = ReadRegisterUnsigned( 1301 eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success); 1302 if (!success) 1303 return false; 1304 1305 /* read <rt> register */ 1306 uint64_t rt_opd_val = ReadRegisterUnsigned( 1307 eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success); 1308 if (!success) 1309 return false; 1310 1311 Context context; 1312 1313 if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU")) 1314 result = src_opd_val - rt_opd_val; 1315 else 1316 result = src_opd_val + rt_opd_val; 1317 1318 context.SetImmediateSigned(result); 1319 context.type = eContextImmediate; 1320 1321 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 1322 dwarf_zero_mips64 + dst, result)) 1323 return false; 1324 } 1325 1326 return true; 1327 } 1328 1329 /* 1330 Emulate below MIPS branch instructions. 1331 BEQ, BNE : Branch on condition 1332 BEQL, BNEL : Branch likely 1333 */ 1334 bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) { 1335 bool success = false; 1336 uint32_t rs, rt; 1337 int64_t offset, pc, rs_val, rt_val, target = 0; 1338 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 1339 1340 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1341 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1342 offset = insn.getOperand(2).getImm(); 1343 1344 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1345 if (!success) 1346 return false; 1347 1348 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1349 dwarf_zero_mips64 + rs, 0, &success); 1350 if (!success) 1351 return false; 1352 1353 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1354 dwarf_zero_mips64 + rt, 0, &success); 1355 if (!success) 1356 return false; 1357 1358 if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL") 1359 || !strcasecmp(op_name, "BEQ64") ) { 1360 if (rs_val == rt_val) 1361 target = pc + offset; 1362 else 1363 target = pc + 8; 1364 } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL") 1365 || !strcasecmp(op_name, "BNE64")) { 1366 if (rs_val != rt_val) 1367 target = pc + offset; 1368 else 1369 target = pc + 8; 1370 } 1371 1372 Context context; 1373 context.type = eContextRelativeBranchImmediate; 1374 context.SetImmediate(offset); 1375 1376 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1377 target); 1378 } 1379 1380 /* 1381 Emulate below MIPS Non-Compact conditional branch and link instructions. 1382 BLTZAL, BGEZAL : 1383 BLTZALL, BGEZALL : Branch likely 1384 */ 1385 bool EmulateInstructionMIPS64::Emulate_Bcond_Link(llvm::MCInst &insn) { 1386 bool success = false; 1387 uint32_t rs; 1388 int64_t offset, pc, target = 0; 1389 int64_t rs_val; 1390 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 1391 1392 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1393 offset = insn.getOperand(1).getImm(); 1394 1395 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1396 if (!success) 1397 return false; 1398 1399 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1400 dwarf_zero_mips64 + rs, 0, &success); 1401 if (!success) 1402 return false; 1403 1404 if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) { 1405 if (rs_val < 0) 1406 target = pc + offset; 1407 else 1408 target = pc + 8; 1409 } else if (!strcasecmp(op_name, "BGEZAL") || 1410 !strcasecmp(op_name, "BGEZALL")) { 1411 if (rs_val >= 0) 1412 target = pc + offset; 1413 else 1414 target = pc + 8; 1415 } 1416 1417 Context context; 1418 1419 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1420 target)) 1421 return false; 1422 1423 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64, 1424 pc + 8)) 1425 return false; 1426 1427 return true; 1428 } 1429 1430 bool EmulateInstructionMIPS64::Emulate_BAL(llvm::MCInst &insn) { 1431 bool success = false; 1432 int64_t offset, pc, target; 1433 1434 /* 1435 * BAL offset 1436 * offset = sign_ext (offset << 2) 1437 * RA = PC + 8 1438 * PC = PC + offset 1439 */ 1440 offset = insn.getOperand(0).getImm(); 1441 1442 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1443 if (!success) 1444 return false; 1445 1446 target = pc + offset; 1447 1448 Context context; 1449 1450 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1451 target)) 1452 return false; 1453 1454 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64, 1455 pc + 8)) 1456 return false; 1457 1458 return true; 1459 } 1460 1461 bool EmulateInstructionMIPS64::Emulate_BALC(llvm::MCInst &insn) { 1462 bool success = false; 1463 int64_t offset, pc, target; 1464 1465 /* 1466 * BALC offset 1467 * offset = sign_ext (offset << 2) 1468 * RA = PC + 4 1469 * PC = PC + 4 + offset 1470 */ 1471 offset = insn.getOperand(0).getImm(); 1472 1473 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1474 if (!success) 1475 return false; 1476 1477 target = pc + offset; 1478 1479 Context context; 1480 1481 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1482 target)) 1483 return false; 1484 1485 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64, 1486 pc + 4)) 1487 return false; 1488 1489 return true; 1490 } 1491 1492 /* 1493 Emulate below MIPS conditional branch and link instructions. 1494 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches 1495 */ 1496 bool EmulateInstructionMIPS64::Emulate_Bcond_Link_C(llvm::MCInst &insn) { 1497 bool success = false; 1498 uint32_t rs; 1499 int64_t offset, pc, rs_val, target = 0; 1500 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 1501 1502 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1503 offset = insn.getOperand(1).getImm(); 1504 1505 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1506 if (!success) 1507 return false; 1508 1509 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1510 dwarf_zero_mips64 + rs, 0, &success); 1511 if (!success) 1512 return false; 1513 1514 if (!strcasecmp(op_name, "BLEZALC")) { 1515 if (rs_val <= 0) 1516 target = pc + offset; 1517 else 1518 target = pc + 4; 1519 } else if (!strcasecmp(op_name, "BGEZALC")) { 1520 if (rs_val >= 0) 1521 target = pc + offset; 1522 else 1523 target = pc + 4; 1524 } else if (!strcasecmp(op_name, "BLTZALC")) { 1525 if (rs_val < 0) 1526 target = pc + offset; 1527 else 1528 target = pc + 4; 1529 } else if (!strcasecmp(op_name, "BGTZALC")) { 1530 if (rs_val > 0) 1531 target = pc + offset; 1532 else 1533 target = pc + 4; 1534 } else if (!strcasecmp(op_name, "BEQZALC")) { 1535 if (rs_val == 0) 1536 target = pc + offset; 1537 else 1538 target = pc + 4; 1539 } else if (!strcasecmp(op_name, "BNEZALC")) { 1540 if (rs_val != 0) 1541 target = pc + offset; 1542 else 1543 target = pc + 4; 1544 } 1545 1546 Context context; 1547 1548 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1549 target)) 1550 return false; 1551 1552 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64, 1553 pc + 4)) 1554 return false; 1555 1556 return true; 1557 } 1558 1559 /* 1560 Emulate below MIPS branch instructions. 1561 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely 1562 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches 1563 */ 1564 bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) { 1565 bool success = false; 1566 uint32_t rs; 1567 int64_t offset, pc, rs_val, target = 0; 1568 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 1569 1570 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1571 offset = insn.getOperand(1).getImm(); 1572 1573 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1574 if (!success) 1575 return false; 1576 1577 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1578 dwarf_zero_mips64 + rs, 0, &success); 1579 if (!success) 1580 return false; 1581 1582 if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ") 1583 || !strcasecmp(op_name, "BLTZ64")) { 1584 if (rs_val < 0) 1585 target = pc + offset; 1586 else 1587 target = pc + 8; 1588 } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ") 1589 || !strcasecmp(op_name, "BGEZ64")) { 1590 if (rs_val >= 0) 1591 target = pc + offset; 1592 else 1593 target = pc + 8; 1594 } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ") 1595 || !strcasecmp(op_name, "BGTZ64")) { 1596 if (rs_val > 0) 1597 target = pc + offset; 1598 else 1599 target = pc + 8; 1600 } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ") 1601 || !strcasecmp(op_name, "BLEZ64")) { 1602 if (rs_val <= 0) 1603 target = pc + offset; 1604 else 1605 target = pc + 8; 1606 } 1607 1608 Context context; 1609 context.type = eContextRelativeBranchImmediate; 1610 context.SetImmediate(offset); 1611 1612 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1613 target); 1614 } 1615 1616 bool EmulateInstructionMIPS64::Emulate_BC(llvm::MCInst &insn) { 1617 bool success = false; 1618 int64_t offset, pc, target; 1619 1620 /* 1621 * BC offset 1622 * offset = sign_ext (offset << 2) 1623 * PC = PC + 4 + offset 1624 */ 1625 offset = insn.getOperand(0).getImm(); 1626 1627 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1628 if (!success) 1629 return false; 1630 1631 target = pc + offset; 1632 1633 Context context; 1634 1635 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1636 target); 1637 } 1638 1639 static int IsAdd64bitOverflow(int64_t a, int64_t b) { 1640 int64_t r = (uint64_t)a + (uint64_t)b; 1641 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0); 1642 } 1643 1644 /* 1645 Emulate below MIPS branch instructions. 1646 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch 1647 instructions with no delay slot 1648 */ 1649 bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) { 1650 bool success = false; 1651 uint32_t rs, rt; 1652 int64_t offset, pc, rs_val, rt_val, target = 0; 1653 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 1654 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 1655 1656 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1657 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1658 offset = insn.getOperand(2).getImm(); 1659 1660 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1661 if (!success) 1662 return false; 1663 1664 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1665 dwarf_zero_mips64 + rs, 0, &success); 1666 if (!success) 1667 return false; 1668 1669 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1670 dwarf_zero_mips64 + rt, 0, &success); 1671 if (!success) 1672 return false; 1673 1674 if (!strcasecmp(op_name, "BEQC") || !strcasecmp(op_name, "BEQC64")) { 1675 if (rs_val == rt_val) 1676 target = pc + offset; 1677 else 1678 target = pc + 4; 1679 } else if (!strcasecmp(op_name, "BNEC") || !strcasecmp(op_name, "BNEC64")) { 1680 if (rs_val != rt_val) 1681 target = pc + offset; 1682 else 1683 target = pc + 4; 1684 } else if (!strcasecmp(op_name, "BLTC") || !strcasecmp(op_name, "BLTC64")) { 1685 if (rs_val < rt_val) 1686 target = pc + offset; 1687 else 1688 target = pc + 4; 1689 } else if (!strcasecmp(op_name, "BGEC64") || !strcasecmp(op_name, "BGEC")) { 1690 if (rs_val >= rt_val) 1691 target = pc + offset; 1692 else 1693 target = pc + 4; 1694 } else if (!strcasecmp(op_name, "BLTUC") || !strcasecmp(op_name, "BLTUC64")) { 1695 if (rs_val < rt_val) 1696 target = pc + offset; 1697 else 1698 target = pc + 4; 1699 } else if (!strcasecmp(op_name, "BGEUC") || !strcasecmp(op_name, "BGEUC64")) { 1700 if ((uint32_t)rs_val >= (uint32_t)rt_val) 1701 target = pc + offset; 1702 else 1703 target = pc + 4; 1704 } else if (!strcasecmp(op_name, "BOVC")) { 1705 if (IsAdd64bitOverflow(rs_val, rt_val)) 1706 target = pc + offset; 1707 else 1708 target = pc + 4; 1709 } else if (!strcasecmp(op_name, "BNVC")) { 1710 if (!IsAdd64bitOverflow(rs_val, rt_val)) 1711 target = pc + offset; 1712 else 1713 target = pc + 4; 1714 } 1715 1716 Context context; 1717 context.type = eContextRelativeBranchImmediate; 1718 context.SetImmediate(current_inst_size + offset); 1719 1720 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1721 target); 1722 } 1723 1724 /* 1725 Emulate below MIPS branch instructions. 1726 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches 1727 */ 1728 bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) { 1729 bool success = false; 1730 uint32_t rs; 1731 int64_t offset, pc, target = 0; 1732 int64_t rs_val; 1733 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 1734 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 1735 1736 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1737 offset = insn.getOperand(1).getImm(); 1738 1739 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1740 if (!success) 1741 return false; 1742 1743 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1744 dwarf_zero_mips64 + rs, 0, &success); 1745 if (!success) 1746 return false; 1747 1748 if (!strcasecmp(op_name, "BLTZC") || !strcasecmp(op_name, "BLTZC64")) { 1749 if (rs_val < 0) 1750 target = pc + offset; 1751 else 1752 target = pc + 4; 1753 } else if (!strcasecmp(op_name, "BLEZC") || !strcasecmp(op_name, "BLEZC64")) { 1754 if (rs_val <= 0) 1755 target = pc + offset; 1756 else 1757 target = pc + 4; 1758 } else if (!strcasecmp(op_name, "BGEZC") || !strcasecmp(op_name, "BGEZC64")) { 1759 if (rs_val >= 0) 1760 target = pc + offset; 1761 else 1762 target = pc + 4; 1763 } else if (!strcasecmp(op_name, "BGTZC") || !strcasecmp(op_name, "BGTZC64")) { 1764 if (rs_val > 0) 1765 target = pc + offset; 1766 else 1767 target = pc + 4; 1768 } else if (!strcasecmp(op_name, "BEQZC") || !strcasecmp(op_name, "BEQZC64")) { 1769 if (rs_val == 0) 1770 target = pc + offset; 1771 else 1772 target = pc + 4; 1773 } else if (!strcasecmp(op_name, "BNEZC") || !strcasecmp(op_name, "BNEZC64")) { 1774 if (rs_val != 0) 1775 target = pc + offset; 1776 else 1777 target = pc + 4; 1778 } 1779 1780 Context context; 1781 context.type = eContextRelativeBranchImmediate; 1782 context.SetImmediate(current_inst_size + offset); 1783 1784 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1785 target); 1786 } 1787 1788 bool EmulateInstructionMIPS64::Emulate_J(llvm::MCInst &insn) { 1789 bool success = false; 1790 uint64_t offset, pc; 1791 1792 /* 1793 * J offset 1794 * offset = sign_ext (offset << 2) 1795 * PC = PC[63-28] | offset 1796 */ 1797 offset = insn.getOperand(0).getImm(); 1798 1799 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1800 if (!success) 1801 return false; 1802 1803 /* This is a PC-region branch and not PC-relative */ 1804 pc = (pc & 0xFFFFFFFFF0000000ULL) | offset; 1805 1806 Context context; 1807 1808 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1809 pc); 1810 } 1811 1812 bool EmulateInstructionMIPS64::Emulate_JAL(llvm::MCInst &insn) { 1813 bool success = false; 1814 uint64_t offset, target, pc; 1815 1816 /* 1817 * JAL offset 1818 * offset = sign_ext (offset << 2) 1819 * PC = PC[63-28] | offset 1820 */ 1821 offset = insn.getOperand(0).getImm(); 1822 1823 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1824 if (!success) 1825 return false; 1826 1827 /* This is a PC-region branch and not PC-relative */ 1828 target = (pc & 0xFFFFFFFFF0000000ULL) | offset; 1829 1830 Context context; 1831 1832 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1833 target)) 1834 return false; 1835 1836 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64, 1837 pc + 8)) 1838 return false; 1839 1840 return true; 1841 } 1842 1843 bool EmulateInstructionMIPS64::Emulate_JALR(llvm::MCInst &insn) { 1844 bool success = false; 1845 uint32_t rs, rt; 1846 uint64_t pc, rs_val; 1847 1848 /* 1849 * JALR rt, rs 1850 * GPR[rt] = PC + 8 1851 * PC = GPR[rs] 1852 */ 1853 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1854 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); 1855 1856 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1857 if (!success) 1858 return false; 1859 1860 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, 1861 &success); 1862 if (!success) 1863 return false; 1864 1865 Context context; 1866 1867 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1868 rs_val)) 1869 return false; 1870 1871 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 1872 dwarf_zero_mips64 + rt, pc + 8)) 1873 return false; 1874 1875 return true; 1876 } 1877 1878 bool EmulateInstructionMIPS64::Emulate_JIALC(llvm::MCInst &insn) { 1879 bool success = false; 1880 uint32_t rt; 1881 int64_t target, offset, pc, rt_val; 1882 1883 /* 1884 * JIALC rt, offset 1885 * offset = sign_ext (offset) 1886 * PC = GPR[rt] + offset 1887 * RA = PC + 4 1888 */ 1889 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1890 offset = insn.getOperand(1).getImm(); 1891 1892 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1893 if (!success) 1894 return false; 1895 1896 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1897 dwarf_zero_mips64 + rt, 0, &success); 1898 if (!success) 1899 return false; 1900 1901 target = rt_val + offset; 1902 1903 Context context; 1904 1905 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1906 target)) 1907 return false; 1908 1909 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64, 1910 pc + 4)) 1911 return false; 1912 1913 return true; 1914 } 1915 1916 bool EmulateInstructionMIPS64::Emulate_JIC(llvm::MCInst &insn) { 1917 bool success = false; 1918 uint32_t rt; 1919 int64_t target, offset, rt_val; 1920 1921 /* 1922 * JIC rt, offset 1923 * offset = sign_ext (offset) 1924 * PC = GPR[rt] + offset 1925 */ 1926 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1927 offset = insn.getOperand(1).getImm(); 1928 1929 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF, 1930 dwarf_zero_mips64 + rt, 0, &success); 1931 if (!success) 1932 return false; 1933 1934 target = rt_val + offset; 1935 1936 Context context; 1937 1938 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1939 target); 1940 } 1941 1942 bool EmulateInstructionMIPS64::Emulate_JR(llvm::MCInst &insn) { 1943 bool success = false; 1944 uint32_t rs; 1945 uint64_t rs_val; 1946 1947 /* 1948 * JR rs 1949 * PC = GPR[rs] 1950 */ 1951 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1952 1953 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, 1954 &success); 1955 if (!success) 1956 return false; 1957 1958 Context context; 1959 1960 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 1961 rs_val); 1962 } 1963 1964 /* 1965 Emulate Branch on FP True/False 1966 BC1F, BC1FL : Branch on FP False (L stands for branch likely) 1967 BC1T, BC1TL : Branch on FP True (L stands for branch likely) 1968 */ 1969 bool EmulateInstructionMIPS64::Emulate_FP_branch(llvm::MCInst &insn) { 1970 bool success = false; 1971 uint32_t cc, fcsr; 1972 int64_t pc, offset, target = 0; 1973 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 1974 1975 /* 1976 * BC1F cc, offset 1977 * condition <- (FPConditionCode(cc) == 0) 1978 * if condition then 1979 * offset = sign_ext (offset) 1980 * PC = PC + offset 1981 */ 1982 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 1983 offset = insn.getOperand(1).getImm(); 1984 1985 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 1986 if (!success) 1987 return false; 1988 1989 fcsr = 1990 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64, 0, &success); 1991 if (!success) 1992 return false; 1993 1994 /* fcsr[23], fcsr[25-31] are vaild condition bits */ 1995 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); 1996 1997 if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) { 1998 if ((fcsr & (1 << cc)) == 0) 1999 target = pc + offset; 2000 else 2001 target = pc + 8; 2002 } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) { 2003 if ((fcsr & (1 << cc)) != 0) 2004 target = pc + offset; 2005 else 2006 target = pc + 8; 2007 } 2008 2009 Context context; 2010 2011 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 2012 target); 2013 } 2014 2015 bool EmulateInstructionMIPS64::Emulate_BC1EQZ(llvm::MCInst &insn) { 2016 bool success = false; 2017 uint32_t ft; 2018 uint64_t ft_val; 2019 int64_t target, pc, offset; 2020 2021 /* 2022 * BC1EQZ ft, offset 2023 * condition <- (FPR[ft].bit0 == 0) 2024 * if condition then 2025 * offset = sign_ext (offset) 2026 * PC = PC + 4 + offset 2027 */ 2028 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2029 offset = insn.getOperand(1).getImm(); 2030 2031 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 2032 if (!success) 2033 return false; 2034 2035 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0, 2036 &success); 2037 if (!success) 2038 return false; 2039 2040 if ((ft_val & 1) == 0) 2041 target = pc + 4 + offset; 2042 else 2043 target = pc + 8; 2044 2045 Context context; 2046 2047 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 2048 target); 2049 } 2050 2051 bool EmulateInstructionMIPS64::Emulate_BC1NEZ(llvm::MCInst &insn) { 2052 bool success = false; 2053 uint32_t ft; 2054 uint64_t ft_val; 2055 int64_t target, pc, offset; 2056 2057 /* 2058 * BC1NEZ ft, offset 2059 * condition <- (FPR[ft].bit0 != 0) 2060 * if condition then 2061 * offset = sign_ext (offset) 2062 * PC = PC + 4 + offset 2063 */ 2064 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2065 offset = insn.getOperand(1).getImm(); 2066 2067 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 2068 if (!success) 2069 return false; 2070 2071 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0, 2072 &success); 2073 if (!success) 2074 return false; 2075 2076 if ((ft_val & 1) != 0) 2077 target = pc + 4 + offset; 2078 else 2079 target = pc + 8; 2080 2081 Context context; 2082 2083 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 2084 target); 2085 } 2086 2087 /* 2088 Emulate MIPS-3D Branch instructions 2089 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes 2090 False/True 2091 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes 2092 False/True 2093 */ 2094 bool EmulateInstructionMIPS64::Emulate_3D_branch(llvm::MCInst &insn) { 2095 bool success = false; 2096 uint32_t cc, fcsr; 2097 int64_t pc, offset, target = 0; 2098 const char *op_name = m_insn_info->getName(insn.getOpcode()).data(); 2099 2100 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2101 offset = insn.getOperand(1).getImm(); 2102 2103 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 2104 if (!success) 2105 return false; 2106 2107 fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64, 2108 0, &success); 2109 if (!success) 2110 return false; 2111 2112 /* fcsr[23], fcsr[25-31] are vaild condition bits */ 2113 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); 2114 2115 if (!strcasecmp(op_name, "BC1ANY2F")) { 2116 /* if any one bit is 0 */ 2117 if (((fcsr >> cc) & 3) != 3) 2118 target = pc + offset; 2119 else 2120 target = pc + 8; 2121 } else if (!strcasecmp(op_name, "BC1ANY2T")) { 2122 /* if any one bit is 1 */ 2123 if (((fcsr >> cc) & 3) != 0) 2124 target = pc + offset; 2125 else 2126 target = pc + 8; 2127 } else if (!strcasecmp(op_name, "BC1ANY4F")) { 2128 /* if any one bit is 0 */ 2129 if (((fcsr >> cc) & 0xf) != 0xf) 2130 target = pc + offset; 2131 else 2132 target = pc + 8; 2133 } else if (!strcasecmp(op_name, "BC1ANY4T")) { 2134 /* if any one bit is 1 */ 2135 if (((fcsr >> cc) & 0xf) != 0) 2136 target = pc + offset; 2137 else 2138 target = pc + 8; 2139 } 2140 2141 Context context; 2142 2143 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 2144 target); 2145 } 2146 2147 bool EmulateInstructionMIPS64::Emulate_BNZB(llvm::MCInst &insn) { 2148 return Emulate_MSA_Branch_DF(insn, 1, true); 2149 } 2150 2151 bool EmulateInstructionMIPS64::Emulate_BNZH(llvm::MCInst &insn) { 2152 return Emulate_MSA_Branch_DF(insn, 2, true); 2153 } 2154 2155 bool EmulateInstructionMIPS64::Emulate_BNZW(llvm::MCInst &insn) { 2156 return Emulate_MSA_Branch_DF(insn, 4, true); 2157 } 2158 2159 bool EmulateInstructionMIPS64::Emulate_BNZD(llvm::MCInst &insn) { 2160 return Emulate_MSA_Branch_DF(insn, 8, true); 2161 } 2162 2163 bool EmulateInstructionMIPS64::Emulate_BZB(llvm::MCInst &insn) { 2164 return Emulate_MSA_Branch_DF(insn, 1, false); 2165 } 2166 2167 bool EmulateInstructionMIPS64::Emulate_BZH(llvm::MCInst &insn) { 2168 return Emulate_MSA_Branch_DF(insn, 2, false); 2169 } 2170 2171 bool EmulateInstructionMIPS64::Emulate_BZW(llvm::MCInst &insn) { 2172 return Emulate_MSA_Branch_DF(insn, 4, false); 2173 } 2174 2175 bool EmulateInstructionMIPS64::Emulate_BZD(llvm::MCInst &insn) { 2176 return Emulate_MSA_Branch_DF(insn, 8, false); 2177 } 2178 2179 bool EmulateInstructionMIPS64::Emulate_MSA_Branch_DF(llvm::MCInst &insn, 2180 int element_byte_size, 2181 bool bnz) { 2182 bool success = false, branch_hit = true; 2183 int64_t target = 0; 2184 RegisterValue reg_value; 2185 const uint8_t *ptr = nullptr; 2186 2187 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2188 int64_t offset = insn.getOperand(1).getImm(); 2189 2190 int64_t pc = 2191 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 2192 if (!success) 2193 return false; 2194 2195 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value)) 2196 ptr = (const uint8_t *)reg_value.GetBytes(); 2197 else 2198 return false; 2199 2200 for (int i = 0; i < 16 / element_byte_size; i++) { 2201 switch (element_byte_size) { 2202 case 1: 2203 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz)) 2204 branch_hit = false; 2205 break; 2206 case 2: 2207 if ((*(const uint16_t *)ptr == 0 && bnz) || 2208 (*(const uint16_t *)ptr != 0 && !bnz)) 2209 branch_hit = false; 2210 break; 2211 case 4: 2212 if ((*(const uint32_t *)ptr == 0 && bnz) || 2213 (*(const uint32_t *)ptr != 0 && !bnz)) 2214 branch_hit = false; 2215 break; 2216 case 8: 2217 if ((*(const uint64_t *)ptr == 0 && bnz) || 2218 (*(const uint64_t *)ptr != 0 && !bnz)) 2219 branch_hit = false; 2220 break; 2221 } 2222 if (!branch_hit) 2223 break; 2224 ptr = ptr + element_byte_size; 2225 } 2226 2227 if (branch_hit) 2228 target = pc + offset; 2229 else 2230 target = pc + 8; 2231 2232 Context context; 2233 context.type = eContextRelativeBranchImmediate; 2234 2235 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 2236 target); 2237 } 2238 2239 bool EmulateInstructionMIPS64::Emulate_BNZV(llvm::MCInst &insn) { 2240 return Emulate_MSA_Branch_V(insn, true); 2241 } 2242 2243 bool EmulateInstructionMIPS64::Emulate_BZV(llvm::MCInst &insn) { 2244 return Emulate_MSA_Branch_V(insn, false); 2245 } 2246 2247 bool EmulateInstructionMIPS64::Emulate_MSA_Branch_V(llvm::MCInst &insn, 2248 bool bnz) { 2249 bool success = false; 2250 int64_t target = 0; 2251 llvm::APInt wr_val = llvm::APInt::getZero(128); 2252 llvm::APInt fail_value = llvm::APInt::getMaxValue(128); 2253 llvm::APInt zero_value = llvm::APInt::getZero(128); 2254 RegisterValue reg_value; 2255 2256 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); 2257 int64_t offset = insn.getOperand(1).getImm(); 2258 2259 int64_t pc = 2260 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success); 2261 if (!success) 2262 return false; 2263 2264 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value)) 2265 wr_val = reg_value.GetAsUInt128(fail_value); 2266 else 2267 return false; 2268 2269 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || 2270 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz)) 2271 target = pc + offset; 2272 else 2273 target = pc + 8; 2274 2275 Context context; 2276 context.type = eContextRelativeBranchImmediate; 2277 2278 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, 2279 target); 2280 } 2281 2282 bool EmulateInstructionMIPS64::Emulate_LDST_Imm(llvm::MCInst &insn) { 2283 bool success = false; 2284 uint32_t base; 2285 int64_t imm, address; 2286 Context bad_vaddr_context; 2287 2288 uint32_t num_operands = insn.getNumOperands(); 2289 base = 2290 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 2291 imm = insn.getOperand(num_operands - 1).getImm(); 2292 2293 RegisterInfo reg_info_base; 2294 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 2295 reg_info_base)) 2296 return false; 2297 2298 /* read base register */ 2299 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0, 2300 &success); 2301 if (!success) 2302 return false; 2303 2304 /* destination address */ 2305 address = address + imm; 2306 2307 /* Set the bad_vaddr register with base address used in the instruction */ 2308 bad_vaddr_context.type = eContextInvalid; 2309 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 2310 address); 2311 2312 return true; 2313 } 2314 2315 bool EmulateInstructionMIPS64::Emulate_LDST_Reg(llvm::MCInst &insn) { 2316 bool success = false; 2317 uint32_t base, index; 2318 int64_t address, index_address; 2319 Context bad_vaddr_context; 2320 2321 uint32_t num_operands = insn.getNumOperands(); 2322 base = 2323 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); 2324 index = 2325 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg()); 2326 2327 RegisterInfo reg_info_base, reg_info_index; 2328 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, 2329 reg_info_base)) 2330 return false; 2331 2332 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index, 2333 reg_info_index)) 2334 return false; 2335 2336 /* read base register */ 2337 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0, 2338 &success); 2339 if (!success) 2340 return false; 2341 2342 /* read index register */ 2343 index_address = ReadRegisterUnsigned(eRegisterKindDWARF, 2344 dwarf_zero_mips + index, 0, &success); 2345 if (!success) 2346 return false; 2347 2348 /* destination address */ 2349 address = address + index_address; 2350 2351 /* Set the bad_vaddr register with base address used in the instruction */ 2352 bad_vaddr_context.type = eContextInvalid; 2353 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, 2354 address); 2355 2356 return true; 2357 } 2358