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