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