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