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