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