1 //===-- EmulateInstructionMIPS64.cpp -------------------------------*- C++
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #include "EmulateInstructionMIPS64.h"
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/Host/PosixApi.h"
23 #include "lldb/Symbol/UnwindPlan.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"
35 #include "llvm/ADT/STLExtras.h"
37 #include "Plugins/Process/Utility/InstructionUtils.h"
38 #include "Plugins/Process/Utility/RegisterContext_mips.h"
41 using namespace lldb_private;
43 #define UInt(x) ((uint64_t)x)
44 #define integer int64_t
46 //----------------------------------------------------------------------
48 // EmulateInstructionMIPS64 implementation
50 //----------------------------------------------------------------------
54 void LLVMInitializeMipsTargetInfo();
55 void LLVMInitializeMipsTarget();
56 void LLVMInitializeMipsAsmPrinter();
57 void LLVMInitializeMipsTargetMC();
58 void LLVMInitializeMipsDisassembler();
62 EmulateInstructionMIPS64::EmulateInstructionMIPS64(
63 const lldb_private::ArchSpec &arch)
64 : EmulateInstruction(arch) {
65 /* Create instance of llvm::MCDisassembler */
67 llvm::Triple triple = arch.GetTriple();
68 const llvm::Target *target =
69 llvm::TargetRegistry::lookupTarget(triple.getTriple(), Error);
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
76 * to decode the instructions so that the decoding complexity stays with LLVM.
77 * Initialize the MIPS targets and disassemblers.
81 LLVMInitializeMipsTargetInfo();
82 LLVMInitializeMipsTarget();
83 LLVMInitializeMipsAsmPrinter();
84 LLVMInitializeMipsTargetMC();
85 LLVMInitializeMipsDisassembler();
86 target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Error);
94 switch (arch.GetCore()) {
95 case ArchSpec::eCore_mips32:
96 case ArchSpec::eCore_mips32el:
99 case ArchSpec::eCore_mips32r2:
100 case ArchSpec::eCore_mips32r2el:
103 case ArchSpec::eCore_mips32r3:
104 case ArchSpec::eCore_mips32r3el:
107 case ArchSpec::eCore_mips32r5:
108 case ArchSpec::eCore_mips32r5el:
111 case ArchSpec::eCore_mips32r6:
112 case ArchSpec::eCore_mips32r6el:
115 case ArchSpec::eCore_mips64:
116 case ArchSpec::eCore_mips64el:
119 case ArchSpec::eCore_mips64r2:
120 case ArchSpec::eCore_mips64r2el:
123 case ArchSpec::eCore_mips64r3:
124 case ArchSpec::eCore_mips64r3el:
127 case ArchSpec::eCore_mips64r5:
128 case ArchSpec::eCore_mips64r5el:
131 case ArchSpec::eCore_mips64r6:
132 case ArchSpec::eCore_mips64r6el:
140 std::string features = "";
141 uint32_t arch_flags = arch.GetFlags();
142 if (arch_flags & ArchSpec::eMIPSAse_msa)
144 if (arch_flags & ArchSpec::eMIPSAse_dsp)
146 if (arch_flags & ArchSpec::eMIPSAse_dspr2)
147 features += "+dspr2,";
148 if (arch_flags & ArchSpec::eMIPSAse_mips16)
149 features += "+mips16,";
150 if (arch_flags & ArchSpec::eMIPSAse_micromips)
151 features += "+micromips,";
153 m_reg_info.reset(target->createMCRegInfo(triple.getTriple()));
154 assert(m_reg_info.get());
156 m_insn_info.reset(target->createMCInstrInfo());
157 assert(m_insn_info.get());
159 m_asm_info.reset(target->createMCAsmInfo(*m_reg_info, triple.getTriple()));
160 m_subtype_info.reset(
161 target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
162 assert(m_asm_info.get() && m_subtype_info.get());
165 new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr));
166 assert(m_context.get());
168 m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
169 assert(m_disasm.get());
172 void EmulateInstructionMIPS64::Initialize() {
173 PluginManager::RegisterPlugin(GetPluginNameStatic(),
174 GetPluginDescriptionStatic(), CreateInstance);
177 void EmulateInstructionMIPS64::Terminate() {
178 PluginManager::UnregisterPlugin(CreateInstance);
181 ConstString EmulateInstructionMIPS64::GetPluginNameStatic() {
182 ConstString g_plugin_name("lldb.emulate-instruction.mips64");
183 return g_plugin_name;
186 lldb_private::ConstString EmulateInstructionMIPS64::GetPluginName() {
187 static ConstString g_plugin_name("EmulateInstructionMIPS64");
188 return g_plugin_name;
191 const char *EmulateInstructionMIPS64::GetPluginDescriptionStatic() {
192 return "Emulate instructions for the MIPS64 architecture.";
196 EmulateInstructionMIPS64::CreateInstance(const ArchSpec &arch,
197 InstructionType inst_type) {
198 if (EmulateInstructionMIPS64::SupportsEmulatingInstructionsOfTypeStatic(
200 if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
201 arch.GetTriple().getArch() == llvm::Triple::mips64el) {
202 std::auto_ptr<EmulateInstructionMIPS64> emulate_insn_ap(
203 new EmulateInstructionMIPS64(arch));
204 if (emulate_insn_ap.get())
205 return emulate_insn_ap.release();
212 bool EmulateInstructionMIPS64::SetTargetTriple(const ArchSpec &arch) {
213 if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
214 arch.GetTriple().getArch() == llvm::Triple::mips64el)
219 const char *EmulateInstructionMIPS64::GetRegisterName(unsigned reg_num,
220 bool alternate_name) {
221 if (alternate_name) {
223 case dwarf_sp_mips64:
225 case dwarf_r30_mips64:
227 case dwarf_ra_mips64:
229 case dwarf_f0_mips64:
231 case dwarf_f1_mips64:
233 case dwarf_f2_mips64:
235 case dwarf_f3_mips64:
237 case dwarf_f4_mips64:
239 case dwarf_f5_mips64:
241 case dwarf_f6_mips64:
243 case dwarf_f7_mips64:
245 case dwarf_f8_mips64:
247 case dwarf_f9_mips64:
249 case dwarf_f10_mips64:
251 case dwarf_f11_mips64:
253 case dwarf_f12_mips64:
255 case dwarf_f13_mips64:
257 case dwarf_f14_mips64:
259 case dwarf_f15_mips64:
261 case dwarf_f16_mips64:
263 case dwarf_f17_mips64:
265 case dwarf_f18_mips64:
267 case dwarf_f19_mips64:
269 case dwarf_f20_mips64:
271 case dwarf_f21_mips64:
273 case dwarf_f22_mips64:
275 case dwarf_f23_mips64:
277 case dwarf_f24_mips64:
279 case dwarf_f25_mips64:
281 case dwarf_f26_mips64:
283 case dwarf_f27_mips64:
285 case dwarf_f28_mips64:
287 case dwarf_f29_mips64:
289 case dwarf_f30_mips64:
291 case dwarf_f31_mips64:
293 case dwarf_w0_mips64:
295 case dwarf_w1_mips64:
297 case dwarf_w2_mips64:
299 case dwarf_w3_mips64:
301 case dwarf_w4_mips64:
303 case dwarf_w5_mips64:
305 case dwarf_w6_mips64:
307 case dwarf_w7_mips64:
309 case dwarf_w8_mips64:
311 case dwarf_w9_mips64:
313 case dwarf_w10_mips64:
315 case dwarf_w11_mips64:
317 case dwarf_w12_mips64:
319 case dwarf_w13_mips64:
321 case dwarf_w14_mips64:
323 case dwarf_w15_mips64:
325 case dwarf_w16_mips64:
327 case dwarf_w17_mips64:
329 case dwarf_w18_mips64:
331 case dwarf_w19_mips64:
333 case dwarf_w20_mips64:
335 case dwarf_w21_mips64:
337 case dwarf_w22_mips64:
339 case dwarf_w23_mips64:
341 case dwarf_w24_mips64:
343 case dwarf_w25_mips64:
345 case dwarf_w26_mips64:
347 case dwarf_w27_mips64:
349 case dwarf_w28_mips64:
351 case dwarf_w29_mips64:
353 case dwarf_w30_mips64:
355 case dwarf_w31_mips64:
357 case dwarf_mir_mips64:
359 case dwarf_mcsr_mips64:
361 case dwarf_config5_mips64:
370 case dwarf_zero_mips64:
372 case dwarf_r1_mips64:
374 case dwarf_r2_mips64:
376 case dwarf_r3_mips64:
378 case dwarf_r4_mips64:
380 case dwarf_r5_mips64:
382 case dwarf_r6_mips64:
384 case dwarf_r7_mips64:
386 case dwarf_r8_mips64:
388 case dwarf_r9_mips64:
390 case dwarf_r10_mips64:
392 case dwarf_r11_mips64:
394 case dwarf_r12_mips64:
396 case dwarf_r13_mips64:
398 case dwarf_r14_mips64:
400 case dwarf_r15_mips64:
402 case dwarf_r16_mips64:
404 case dwarf_r17_mips64:
406 case dwarf_r18_mips64:
408 case dwarf_r19_mips64:
410 case dwarf_r20_mips64:
412 case dwarf_r21_mips64:
414 case dwarf_r22_mips64:
416 case dwarf_r23_mips64:
418 case dwarf_r24_mips64:
420 case dwarf_r25_mips64:
422 case dwarf_r26_mips64:
424 case dwarf_r27_mips64:
426 case dwarf_gp_mips64:
428 case dwarf_sp_mips64:
430 case dwarf_r30_mips64:
432 case dwarf_ra_mips64:
434 case dwarf_sr_mips64:
436 case dwarf_lo_mips64:
438 case dwarf_hi_mips64:
440 case dwarf_bad_mips64:
442 case dwarf_cause_mips64:
444 case dwarf_pc_mips64:
446 case dwarf_f0_mips64:
448 case dwarf_f1_mips64:
450 case dwarf_f2_mips64:
452 case dwarf_f3_mips64:
454 case dwarf_f4_mips64:
456 case dwarf_f5_mips64:
458 case dwarf_f6_mips64:
460 case dwarf_f7_mips64:
462 case dwarf_f8_mips64:
464 case dwarf_f9_mips64:
466 case dwarf_f10_mips64:
468 case dwarf_f11_mips64:
470 case dwarf_f12_mips64:
472 case dwarf_f13_mips64:
474 case dwarf_f14_mips64:
476 case dwarf_f15_mips64:
478 case dwarf_f16_mips64:
480 case dwarf_f17_mips64:
482 case dwarf_f18_mips64:
484 case dwarf_f19_mips64:
486 case dwarf_f20_mips64:
488 case dwarf_f21_mips64:
490 case dwarf_f22_mips64:
492 case dwarf_f23_mips64:
494 case dwarf_f24_mips64:
496 case dwarf_f25_mips64:
498 case dwarf_f26_mips64:
500 case dwarf_f27_mips64:
502 case dwarf_f28_mips64:
504 case dwarf_f29_mips64:
506 case dwarf_f30_mips64:
508 case dwarf_f31_mips64:
510 case dwarf_fcsr_mips64:
512 case dwarf_fir_mips64:
514 case dwarf_w0_mips64:
516 case dwarf_w1_mips64:
518 case dwarf_w2_mips64:
520 case dwarf_w3_mips64:
522 case dwarf_w4_mips64:
524 case dwarf_w5_mips64:
526 case dwarf_w6_mips64:
528 case dwarf_w7_mips64:
530 case dwarf_w8_mips64:
532 case dwarf_w9_mips64:
534 case dwarf_w10_mips64:
536 case dwarf_w11_mips64:
538 case dwarf_w12_mips64:
540 case dwarf_w13_mips64:
542 case dwarf_w14_mips64:
544 case dwarf_w15_mips64:
546 case dwarf_w16_mips64:
548 case dwarf_w17_mips64:
550 case dwarf_w18_mips64:
552 case dwarf_w19_mips64:
554 case dwarf_w20_mips64:
556 case dwarf_w21_mips64:
558 case dwarf_w22_mips64:
560 case dwarf_w23_mips64:
562 case dwarf_w24_mips64:
564 case dwarf_w25_mips64:
566 case dwarf_w26_mips64:
568 case dwarf_w27_mips64:
570 case dwarf_w28_mips64:
572 case dwarf_w29_mips64:
574 case dwarf_w30_mips64:
576 case dwarf_w31_mips64:
578 case dwarf_mcsr_mips64:
580 case dwarf_mir_mips64:
582 case dwarf_config5_mips64:
588 bool EmulateInstructionMIPS64::GetRegisterInfo(RegisterKind reg_kind,
590 RegisterInfo ®_info) {
591 if (reg_kind == eRegisterKindGeneric) {
593 case LLDB_REGNUM_GENERIC_PC:
594 reg_kind = eRegisterKindDWARF;
595 reg_num = dwarf_pc_mips64;
597 case LLDB_REGNUM_GENERIC_SP:
598 reg_kind = eRegisterKindDWARF;
599 reg_num = dwarf_sp_mips64;
601 case LLDB_REGNUM_GENERIC_FP:
602 reg_kind = eRegisterKindDWARF;
603 reg_num = dwarf_r30_mips64;
605 case LLDB_REGNUM_GENERIC_RA:
606 reg_kind = eRegisterKindDWARF;
607 reg_num = dwarf_ra_mips64;
609 case LLDB_REGNUM_GENERIC_FLAGS:
610 reg_kind = eRegisterKindDWARF;
611 reg_num = dwarf_sr_mips64;
618 if (reg_kind == eRegisterKindDWARF) {
619 ::memset(®_info, 0, sizeof(RegisterInfo));
620 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
622 if (reg_num == dwarf_sr_mips64 || reg_num == dwarf_fcsr_mips64 ||
623 reg_num == dwarf_fir_mips64 || reg_num == dwarf_mcsr_mips64 ||
624 reg_num == dwarf_mir_mips64 || reg_num == dwarf_config5_mips64) {
625 reg_info.byte_size = 4;
626 reg_info.format = eFormatHex;
627 reg_info.encoding = eEncodingUint;
628 } else if ((int)reg_num >= dwarf_zero_mips64 &&
629 (int)reg_num <= dwarf_f31_mips64) {
630 reg_info.byte_size = 8;
631 reg_info.format = eFormatHex;
632 reg_info.encoding = eEncodingUint;
633 } else if ((int)reg_num >= dwarf_w0_mips64 &&
634 (int)reg_num <= dwarf_w31_mips64) {
635 reg_info.byte_size = 16;
636 reg_info.format = eFormatVectorOfUInt8;
637 reg_info.encoding = eEncodingVector;
642 reg_info.name = GetRegisterName(reg_num, false);
643 reg_info.alt_name = GetRegisterName(reg_num, true);
644 reg_info.kinds[eRegisterKindDWARF] = reg_num;
647 case dwarf_r30_mips64:
648 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
650 case dwarf_ra_mips64:
651 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
653 case dwarf_sp_mips64:
654 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
656 case dwarf_pc_mips64:
657 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
659 case dwarf_sr_mips64:
660 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
670 EmulateInstructionMIPS64::MipsOpcode *
671 EmulateInstructionMIPS64::GetOpcodeForInstruction(const char *op_name) {
672 static EmulateInstructionMIPS64::MipsOpcode g_opcodes[] = {
673 //----------------------------------------------------------------------
674 // Prologue/Epilogue instructions
675 //----------------------------------------------------------------------
676 {"DADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu,
677 "DADDIU rt, rs, immediate"},
678 {"ADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu,
679 "ADDIU rt, rs, immediate"},
680 {"SD", &EmulateInstructionMIPS64::Emulate_SD, "SD rt, offset(rs)"},
681 {"LD", &EmulateInstructionMIPS64::Emulate_LD, "LD rt, offset(base)"},
682 {"DSUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
684 {"SUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
686 {"DADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
688 {"ADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
690 {"LUI", &EmulateInstructionMIPS64::Emulate_LUI, "LUI rt, immediate"},
692 //----------------------------------------------------------------------
693 // Load/Store instructions
694 //----------------------------------------------------------------------
695 /* Following list of emulated instructions are required by implementation
696 of hardware watchpoint
697 for MIPS in lldb. As we just need the address accessed by instructions,
699 all these instructions in 2 functions depending on their addressing
702 {"LB", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
703 "LB rt, offset(base)"},
704 {"LBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
705 "LBE rt, offset(base)"},
706 {"LBU", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
707 "LBU rt, offset(base)"},
708 {"LBUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
709 "LBUE rt, offset(base)"},
710 {"LDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
711 "LDC1 ft, offset(base)"},
712 {"LDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
713 "LDL rt, offset(base)"},
714 {"LDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
715 "LDR rt, offset(base)"},
716 {"LLD", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
717 "LLD rt, offset(base)"},
718 {"LDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
719 "LDC2 rt, offset(base)"},
720 {"LDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
721 "LDXC1 fd, index (base)"},
722 {"LH", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
723 "LH rt, offset(base)"},
724 {"LHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
725 "LHE rt, offset(base)"},
726 {"LHU", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
727 "LHU rt, offset(base)"},
728 {"LHUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
729 "LHUE rt, offset(base)"},
730 {"LL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
731 "LL rt, offset(base)"},
732 {"LLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
733 "LLE rt, offset(base)"},
734 {"LUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
735 "LUXC1 fd, index (base)"},
736 {"LW", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
737 "LW rt, offset(rs)"},
738 {"LWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
739 "LWC1 ft, offset(base)"},
740 {"LWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
741 "LWC2 rt, offset(base)"},
742 {"LWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
743 "LWE rt, offset(base)"},
744 {"LWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
745 "LWL rt, offset(base)"},
746 {"LWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
747 "LWLE rt, offset(base)"},
748 {"LWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
749 "LWR rt, offset(base)"},
750 {"LWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
751 "LWRE rt, offset(base)"},
752 {"LWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
753 "LWXC1 fd, index (base)"},
755 {"SB", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
756 "SB rt, offset(base)"},
757 {"SBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
758 "SBE rt, offset(base)"},
759 {"SC", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
760 "SC rt, offset(base)"},
761 {"SCE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
762 "SCE rt, offset(base)"},
763 {"SCD", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
764 "SCD rt, offset(base)"},
765 {"SDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
766 "SDL rt, offset(base)"},
767 {"SDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
768 "SDR rt, offset(base)"},
769 {"SDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
770 "SDC1 ft, offset(base)"},
771 {"SDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
772 "SDC2 rt, offset(base)"},
773 {"SDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
774 "SDXC1 fs, index (base)"},
775 {"SH", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
776 "SH rt, offset(base)"},
777 {"SHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
778 "SHE rt, offset(base)"},
779 {"SUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
780 "SUXC1 fs, index (base)"},
781 {"SW", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
782 "SW rt, offset(rs)"},
783 {"SWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
784 "SWC1 ft, offset(base)"},
785 {"SWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
786 "SWC2 rt, offset(base)"},
787 {"SWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
788 "SWE rt, offset(base)"},
789 {"SWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
790 "SWL rt, offset(base)"},
791 {"SWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
792 "SWLE rt, offset(base)"},
793 {"SWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
794 "SWR rt, offset(base)"},
795 {"SWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
796 "SWRE rt, offset(base)"},
797 {"SWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
798 "SWXC1 fs, index (base)"},
800 //----------------------------------------------------------------------
801 // Branch instructions
802 //----------------------------------------------------------------------
803 {"BEQ", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
804 {"BNE", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"},
805 {"BEQL", &EmulateInstructionMIPS64::Emulate_BXX_3ops,
806 "BEQL rs,rt,offset"},
807 {"BNEL", &EmulateInstructionMIPS64::Emulate_BXX_3ops,
808 "BNEL rs,rt,offset"},
809 {"BGEZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
810 "BGEZALL rt,offset"},
811 {"BAL", &EmulateInstructionMIPS64::Emulate_BAL, "BAL offset"},
812 {"BGEZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
814 {"BALC", &EmulateInstructionMIPS64::Emulate_BALC, "BALC offset"},
815 {"BC", &EmulateInstructionMIPS64::Emulate_BC, "BC offset"},
816 {"BGEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"},
817 {"BLEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
818 "BLEZALC rs,offset"},
819 {"BGEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
820 "BGEZALC rs,offset"},
821 {"BLTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
822 "BLTZALC rs,offset"},
823 {"BGTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
824 "BGTZALC rs,offset"},
825 {"BEQZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
826 "BEQZALC rs,offset"},
827 {"BNEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
828 "BNEZALC rs,offset"},
829 {"BEQC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
830 "BEQC rs,rt,offset"},
831 {"BNEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
832 "BNEC rs,rt,offset"},
833 {"BLTC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
834 "BLTC rs,rt,offset"},
835 {"BGEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
836 "BGEC rs,rt,offset"},
837 {"BLTUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
838 "BLTUC rs,rt,offset"},
839 {"BGEUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
840 "BGEUC rs,rt,offset"},
841 {"BLTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
843 {"BLEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
845 {"BGEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
847 {"BGTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
849 {"BEQZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
851 {"BNEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
853 {"BGEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZL rt,offset"},
854 {"BGTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"},
855 {"BGTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZL rt,offset"},
856 {"BLEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"},
857 {"BLEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZL rt,offset"},
858 {"BLTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"},
859 {"BLTZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
861 {"BLTZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
862 "BLTZALL rt,offset"},
863 {"BLTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZL rt,offset"},
864 {"BOVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
865 "BOVC rs,rt,offset"},
866 {"BNVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
867 "BNVC rs,rt,offset"},
868 {"J", &EmulateInstructionMIPS64::Emulate_J, "J target"},
869 {"JAL", &EmulateInstructionMIPS64::Emulate_JAL, "JAL target"},
870 {"JALX", &EmulateInstructionMIPS64::Emulate_JAL, "JALX target"},
871 {"JALR", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"},
872 {"JALR64", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"},
873 {"JALR_HB", &EmulateInstructionMIPS64::Emulate_JALR, "JALR.HB target"},
874 {"JIALC", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"},
875 {"JIC", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"},
876 {"JR", &EmulateInstructionMIPS64::Emulate_JR, "JR target"},
877 {"JR_HB", &EmulateInstructionMIPS64::Emulate_JR, "JR.HB target"},
878 {"BC1F", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1F cc, offset"},
879 {"BC1T", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1T cc, offset"},
880 {"BC1FL", &EmulateInstructionMIPS64::Emulate_FP_branch,
882 {"BC1TL", &EmulateInstructionMIPS64::Emulate_FP_branch,
884 {"BC1EQZ", &EmulateInstructionMIPS64::Emulate_BC1EQZ,
885 "BC1EQZ ft, offset"},
886 {"BC1NEZ", &EmulateInstructionMIPS64::Emulate_BC1NEZ,
887 "BC1NEZ ft, offset"},
888 {"BC1ANY2F", &EmulateInstructionMIPS64::Emulate_3D_branch,
889 "BC1ANY2F cc, offset"},
890 {"BC1ANY2T", &EmulateInstructionMIPS64::Emulate_3D_branch,
891 "BC1ANY2T cc, offset"},
892 {"BC1ANY4F", &EmulateInstructionMIPS64::Emulate_3D_branch,
893 "BC1ANY4F cc, offset"},
894 {"BC1ANY4T", &EmulateInstructionMIPS64::Emulate_3D_branch,
895 "BC1ANY4T cc, offset"},
896 {"BNZ_B", &EmulateInstructionMIPS64::Emulate_BNZB, "BNZ.b wt,s16"},
897 {"BNZ_H", &EmulateInstructionMIPS64::Emulate_BNZH, "BNZ.h wt,s16"},
898 {"BNZ_W", &EmulateInstructionMIPS64::Emulate_BNZW, "BNZ.w wt,s16"},
899 {"BNZ_D", &EmulateInstructionMIPS64::Emulate_BNZD, "BNZ.d wt,s16"},
900 {"BZ_B", &EmulateInstructionMIPS64::Emulate_BZB, "BZ.b wt,s16"},
901 {"BZ_H", &EmulateInstructionMIPS64::Emulate_BZH, "BZ.h wt,s16"},
902 {"BZ_W", &EmulateInstructionMIPS64::Emulate_BZW, "BZ.w wt,s16"},
903 {"BZ_D", &EmulateInstructionMIPS64::Emulate_BZD, "BZ.d wt,s16"},
904 {"BNZ_V", &EmulateInstructionMIPS64::Emulate_BNZV, "BNZ.V wt,s16"},
905 {"BZ_V", &EmulateInstructionMIPS64::Emulate_BZV, "BZ.V wt,s16"},
908 static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
910 for (size_t i = 0; i < k_num_mips_opcodes; ++i) {
911 if (!strcasecmp(g_opcodes[i].op_name, op_name))
912 return &g_opcodes[i];
918 bool EmulateInstructionMIPS64::ReadInstruction() {
919 bool success = false;
920 m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
921 LLDB_INVALID_ADDRESS, &success);
923 Context read_inst_context;
924 read_inst_context.type = eContextReadOpcode;
925 read_inst_context.SetNoArgs();
926 m_opcode.SetOpcode32(
927 ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
931 m_addr = LLDB_INVALID_ADDRESS;
935 bool EmulateInstructionMIPS64::EvaluateInstruction(uint32_t evaluate_options) {
936 bool success = false;
937 llvm::MCInst mc_insn;
941 /* Keep the complexity of the decode logic with the llvm::MCDisassembler
943 if (m_opcode.GetData(data)) {
944 llvm::MCDisassembler::DecodeStatus decode_status;
945 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
946 decode_status = m_disasm->getInstruction(
947 mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
948 if (decode_status != llvm::MCDisassembler::Success)
953 * mc_insn.getOpcode() returns decoded opcode. However to make use
954 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
956 const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
962 * Decoding has been done already. Just get the call-back function
963 * and emulate the instruction.
965 MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
967 if (opcode_data == NULL)
970 uint64_t old_pc = 0, new_pc = 0;
971 const bool auto_advance_pc =
972 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
974 if (auto_advance_pc) {
976 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
981 /* emulate instruction */
982 success = (this->*opcode_data->callback)(mc_insn);
986 if (auto_advance_pc) {
988 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
992 /* If we haven't changed the PC, change it here */
993 if (old_pc == new_pc) {
996 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1005 bool EmulateInstructionMIPS64::CreateFunctionEntryUnwind(
1006 UnwindPlan &unwind_plan) {
1007 unwind_plan.Clear();
1008 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1010 UnwindPlan::RowSP row(new UnwindPlan::Row);
1011 const bool can_replace = false;
1013 // Our previous Call Frame Address is the stack pointer
1014 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips64, 0);
1016 // Our previous PC is in the RA
1017 row->SetRegisterLocationToRegister(dwarf_pc_mips64, dwarf_ra_mips64,
1020 unwind_plan.AppendRow(row);
1022 // All other registers are the same.
1023 unwind_plan.SetSourceName("EmulateInstructionMIPS64");
1024 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1025 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1026 unwind_plan.SetReturnAddressRegister(dwarf_ra_mips64);
1031 bool EmulateInstructionMIPS64::nonvolatile_reg_p(uint64_t regnum) {
1033 case dwarf_r16_mips64:
1034 case dwarf_r17_mips64:
1035 case dwarf_r18_mips64:
1036 case dwarf_r19_mips64:
1037 case dwarf_r20_mips64:
1038 case dwarf_r21_mips64:
1039 case dwarf_r22_mips64:
1040 case dwarf_r23_mips64:
1041 case dwarf_gp_mips64:
1042 case dwarf_sp_mips64:
1043 case dwarf_r30_mips64:
1044 case dwarf_ra_mips64:
1052 bool EmulateInstructionMIPS64::Emulate_DADDiu(llvm::MCInst &insn) {
1053 // DADDIU rt, rs, immediate
1054 // GPR[rt] <- GPR[rs] + sign_extend(immediate)
1057 bool success = false;
1058 const uint32_t imm16 = insn.getOperand(2).getImm();
1059 int64_t imm = SignedBits(imm16, 15, 0);
1061 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1062 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1064 // If immediate is greater than 2^16 - 1 then clang generate
1065 // LUI, (D)ADDIU,(D)SUBU instructions in prolog.
1068 // daddiu $1, $1, -0x5920
1069 // dsubu $sp, $sp, $1
1070 // In this case, (D)ADDIU dst and src will be same and not equal to sp
1074 /* read <src> register */
1075 const int64_t src_opd_val = ReadRegisterUnsigned(
1076 eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
1080 /* Check if this is daddiu sp, sp, imm16 */
1081 if (dst == dwarf_sp_mips64) {
1082 uint64_t result = src_opd_val + imm;
1083 RegisterInfo reg_info_sp;
1085 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
1086 context.SetRegisterPlusOffset(reg_info_sp, imm);
1088 /* We are allocating bytes on stack */
1089 context.type = eContextAdjustStackPointer;
1091 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64,
1097 context.SetImmediateSigned(imm);
1098 context.type = eContextImmediate;
1100 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1101 dwarf_zero_mips64 + dst, imm))
1108 bool EmulateInstructionMIPS64::Emulate_SD(llvm::MCInst &insn) {
1110 RegisterInfo reg_info_base;
1111 RegisterInfo reg_info_src;
1112 bool success = false;
1113 uint32_t imm16 = insn.getOperand(2).getImm();
1114 uint64_t imm = SignedBits(imm16, 15, 0);
1116 Context bad_vaddr_context;
1118 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1119 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1121 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1123 !GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src,
1128 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1133 /* destination address */
1134 address = address + imm;
1136 /* We look for sp based non-volatile register stores */
1137 if (nonvolatile_reg_p(src)) {
1139 RegisterValue data_src;
1140 context.type = eContextPushRegisterOnStack;
1141 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1143 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1146 if (!ReadRegister(®_info_base, data_src))
1149 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1150 eByteOrderLittle, error) == 0)
1153 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1157 /* Set the bad_vaddr register with base address used in the instruction */
1158 bad_vaddr_context.type = eContextInvalid;
1159 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64,
1165 bool EmulateInstructionMIPS64::Emulate_LD(llvm::MCInst &insn) {
1166 bool success = false;
1168 int64_t imm, address;
1169 Context bad_vaddr_context;
1171 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1172 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1173 imm = insn.getOperand(2).getImm();
1175 RegisterInfo reg_info_base;
1176 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1180 /* read base register */
1181 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1186 /* destination address */
1187 address = address + imm;
1189 /* Set the bad_vaddr register with base address used in the instruction */
1190 bad_vaddr_context.type = eContextInvalid;
1191 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64,
1194 if (nonvolatile_reg_p(src)) {
1195 RegisterValue data_src;
1196 RegisterInfo reg_info_src;
1198 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src,
1203 context.type = eContextRegisterLoad;
1205 if (!WriteRegister(context, ®_info_src, data_src))
1214 bool EmulateInstructionMIPS64::Emulate_LUI(llvm::MCInst &insn) {
1215 // LUI rt, immediate
1216 // GPR[rt] <- sign_extend(immediate << 16)
1218 const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1219 int64_t imm = SignedBits(imm32, 31, 0);
1223 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1224 context.SetImmediateSigned(imm);
1225 context.type = eContextImmediate;
1227 if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips64 + rt,
1234 bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) {
1235 // DSUBU sp, <src>, <rt>
1236 // DADDU sp, <src>, <rt>
1237 // DADDU dst, sp, <rt>
1239 bool success = false;
1241 uint8_t src, dst, rt;
1242 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1244 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1245 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1247 /* Check if sp is destination register */
1248 if (dst == dwarf_sp_mips64) {
1249 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1251 /* read <src> register */
1252 uint64_t src_opd_val = ReadRegisterUnsigned(
1253 eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
1257 /* read <rt > register */
1258 uint64_t rt_opd_val = ReadRegisterUnsigned(
1259 eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
1263 if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU"))
1264 result = src_opd_val - rt_opd_val;
1266 result = src_opd_val + rt_opd_val;
1269 RegisterInfo reg_info_sp;
1270 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
1271 context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
1273 /* We are allocating bytes on stack */
1274 context.type = eContextAdjustStackPointer;
1276 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64, result);
1279 } else if (src == dwarf_sp_mips64) {
1280 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1282 /* read <src> register */
1283 uint64_t src_opd_val = ReadRegisterUnsigned(
1284 eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
1288 /* read <rt> register */
1289 uint64_t rt_opd_val = ReadRegisterUnsigned(
1290 eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
1296 if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU"))
1297 result = src_opd_val - rt_opd_val;
1299 result = src_opd_val + rt_opd_val;
1301 context.SetImmediateSigned(result);
1302 context.type = eContextImmediate;
1304 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1305 dwarf_zero_mips64 + dst, result))
1313 Emulate below MIPS branch instructions.
1314 BEQ, BNE : Branch on condition
1315 BEQL, BNEL : Branch likely
1317 bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) {
1318 bool success = false;
1320 int64_t offset, pc, rs_val, rt_val, target = 0;
1321 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1323 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1324 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1325 offset = insn.getOperand(2).getImm();
1327 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1331 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1332 dwarf_zero_mips64 + rs, 0, &success);
1336 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1337 dwarf_zero_mips64 + rt, 0, &success);
1341 if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) {
1342 if (rs_val == rt_val)
1343 target = pc + offset;
1346 } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) {
1347 if (rs_val != rt_val)
1348 target = pc + offset;
1354 context.type = eContextRelativeBranchImmediate;
1355 context.SetImmediate(offset);
1357 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1365 Emulate below MIPS Non-Compact conditional branch and link instructions.
1367 BLTZALL, BGEZALL : Branch likely
1369 bool EmulateInstructionMIPS64::Emulate_Bcond_Link(llvm::MCInst &insn) {
1370 bool success = false;
1372 int64_t offset, pc, target = 0;
1374 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1376 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1377 offset = insn.getOperand(1).getImm();
1379 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1383 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1384 dwarf_zero_mips64 + rs, 0, &success);
1388 if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
1390 target = pc + offset;
1393 } else if (!strcasecmp(op_name, "BGEZAL") ||
1394 !strcasecmp(op_name, "BGEZALL")) {
1396 target = pc + offset;
1403 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1407 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1414 bool EmulateInstructionMIPS64::Emulate_BAL(llvm::MCInst &insn) {
1415 bool success = false;
1416 int64_t offset, pc, target;
1420 * offset = sign_ext (offset << 2)
1424 offset = insn.getOperand(0).getImm();
1426 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1430 target = pc + offset;
1434 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1438 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1445 bool EmulateInstructionMIPS64::Emulate_BALC(llvm::MCInst &insn) {
1446 bool success = false;
1447 int64_t offset, pc, target;
1451 * offset = sign_ext (offset << 2)
1453 * PC = PC + 4 + offset
1455 offset = insn.getOperand(0).getImm();
1457 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1461 target = pc + offset;
1465 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1469 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1477 Emulate below MIPS conditional branch and link instructions.
1478 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1480 bool EmulateInstructionMIPS64::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
1481 bool success = false;
1483 int64_t offset, pc, rs_val, target = 0;
1484 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1486 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1487 offset = insn.getOperand(1).getImm();
1489 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1493 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1494 dwarf_zero_mips64 + rs, 0, &success);
1498 if (!strcasecmp(op_name, "BLEZALC")) {
1500 target = pc + offset;
1503 } else if (!strcasecmp(op_name, "BGEZALC")) {
1505 target = pc + offset;
1508 } else if (!strcasecmp(op_name, "BLTZALC")) {
1510 target = pc + offset;
1513 } else if (!strcasecmp(op_name, "BGTZALC")) {
1515 target = pc + offset;
1518 } else if (!strcasecmp(op_name, "BEQZALC")) {
1520 target = pc + offset;
1523 } else if (!strcasecmp(op_name, "BNEZALC")) {
1525 target = pc + offset;
1532 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1536 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1544 Emulate below MIPS branch instructions.
1545 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
1546 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
1548 bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) {
1549 bool success = false;
1551 int64_t offset, pc, rs_val, target = 0;
1552 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1554 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1555 offset = insn.getOperand(1).getImm();
1557 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1561 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1562 dwarf_zero_mips64 + rs, 0, &success);
1566 if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) {
1568 target = pc + offset;
1571 } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) {
1573 target = pc + offset;
1576 } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) {
1578 target = pc + offset;
1581 } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) {
1583 target = pc + offset;
1589 context.type = eContextRelativeBranchImmediate;
1590 context.SetImmediate(offset);
1592 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1599 bool EmulateInstructionMIPS64::Emulate_BC(llvm::MCInst &insn) {
1600 bool success = false;
1601 int64_t offset, pc, target;
1605 * offset = sign_ext (offset << 2)
1606 * PC = PC + 4 + offset
1608 offset = insn.getOperand(0).getImm();
1610 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1614 target = pc + offset;
1618 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1625 static int IsAdd64bitOverflow(int64_t a, int64_t b) {
1626 int64_t r = (uint64_t)a + (uint64_t)b;
1627 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1631 Emulate below MIPS branch instructions.
1632 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
1633 instructions with no delay slot
1635 bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
1636 bool success = false;
1638 int64_t offset, pc, rs_val, rt_val, target = 0;
1639 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1640 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1642 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1643 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1644 offset = insn.getOperand(2).getImm();
1646 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1650 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1651 dwarf_zero_mips64 + rs, 0, &success);
1655 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1656 dwarf_zero_mips64 + rt, 0, &success);
1660 if (!strcasecmp(op_name, "BEQC")) {
1661 if (rs_val == rt_val)
1662 target = pc + offset;
1665 } else if (!strcasecmp(op_name, "BNEC")) {
1666 if (rs_val != rt_val)
1667 target = pc + offset;
1670 } else if (!strcasecmp(op_name, "BLTC")) {
1671 if (rs_val < rt_val)
1672 target = pc + offset;
1675 } else if (!strcasecmp(op_name, "BGEC")) {
1676 if (rs_val >= rt_val)
1677 target = pc + offset;
1680 } else if (!strcasecmp(op_name, "BLTUC")) {
1681 if (rs_val < rt_val)
1682 target = pc + offset;
1685 } else if (!strcasecmp(op_name, "BGEUC")) {
1686 if ((uint32_t)rs_val >= (uint32_t)rt_val)
1687 target = pc + offset;
1690 } else if (!strcasecmp(op_name, "BOVC")) {
1691 if (IsAdd64bitOverflow(rs_val, rt_val))
1692 target = pc + offset;
1695 } else if (!strcasecmp(op_name, "BNVC")) {
1696 if (!IsAdd64bitOverflow(rs_val, rt_val))
1697 target = pc + offset;
1703 context.type = eContextRelativeBranchImmediate;
1704 context.SetImmediate(current_inst_size + offset);
1706 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1714 Emulate below MIPS branch instructions.
1715 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
1717 bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
1718 bool success = false;
1720 int64_t offset, pc, target = 0;
1722 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1723 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1725 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1726 offset = insn.getOperand(1).getImm();
1728 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1732 rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1733 dwarf_zero_mips64 + rs, 0, &success);
1737 if (!strcasecmp(op_name, "BLTZC")) {
1739 target = pc + offset;
1742 } else if (!strcasecmp(op_name, "BLEZC")) {
1744 target = pc + offset;
1747 } else if (!strcasecmp(op_name, "BGEZC")) {
1749 target = pc + offset;
1752 } else if (!strcasecmp(op_name, "BGTZC")) {
1754 target = pc + offset;
1757 } else if (!strcasecmp(op_name, "BEQZC")) {
1759 target = pc + offset;
1762 } else if (!strcasecmp(op_name, "BNEZC")) {
1764 target = pc + offset;
1770 context.type = eContextRelativeBranchImmediate;
1771 context.SetImmediate(current_inst_size + offset);
1773 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1780 bool EmulateInstructionMIPS64::Emulate_J(llvm::MCInst &insn) {
1781 bool success = false;
1782 uint64_t offset, pc;
1786 * offset = sign_ext (offset << 2)
1787 * PC = PC[63-28] | offset
1789 offset = insn.getOperand(0).getImm();
1791 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1795 /* This is a PC-region branch and not PC-relative */
1796 pc = (pc & 0xFFFFFFFFF0000000ULL) | offset;
1800 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, pc))
1806 bool EmulateInstructionMIPS64::Emulate_JAL(llvm::MCInst &insn) {
1807 bool success = false;
1808 uint64_t offset, target, pc;
1812 * offset = sign_ext (offset << 2)
1813 * PC = PC[63-28] | offset
1815 offset = insn.getOperand(0).getImm();
1817 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1821 /* This is a PC-region branch and not PC-relative */
1822 target = (pc & 0xFFFFFFFFF0000000ULL) | offset;
1826 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1830 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1837 bool EmulateInstructionMIPS64::Emulate_JALR(llvm::MCInst &insn) {
1838 bool success = false;
1840 uint64_t pc, rs_val;
1847 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1848 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1850 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1854 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0,
1861 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1865 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1866 dwarf_zero_mips64 + rt, pc + 8))
1872 bool EmulateInstructionMIPS64::Emulate_JIALC(llvm::MCInst &insn) {
1873 bool success = false;
1875 int64_t target, offset, pc, rt_val;
1879 * offset = sign_ext (offset)
1880 * PC = GPR[rt] + offset
1883 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1884 offset = insn.getOperand(1).getImm();
1886 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1890 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1891 dwarf_zero_mips64 + rt, 0, &success);
1895 target = rt_val + offset;
1899 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1903 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1910 bool EmulateInstructionMIPS64::Emulate_JIC(llvm::MCInst &insn) {
1911 bool success = false;
1913 int64_t target, offset, rt_val;
1917 * offset = sign_ext (offset)
1918 * PC = GPR[rt] + offset
1920 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1921 offset = insn.getOperand(1).getImm();
1923 rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1924 dwarf_zero_mips64 + rt, 0, &success);
1928 target = rt_val + offset;
1932 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1939 bool EmulateInstructionMIPS64::Emulate_JR(llvm::MCInst &insn) {
1940 bool success = false;
1948 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1950 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0,
1957 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1965 Emulate Branch on FP True/False
1966 BC1F, BC1FL : Branch on FP False (L stands for branch likely)
1967 BC1T, BC1TL : Branch on FP True (L stands for branch likely)
1969 bool EmulateInstructionMIPS64::Emulate_FP_branch(llvm::MCInst &insn) {
1970 bool success = false;
1972 int64_t pc, offset, target = 0;
1973 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1977 * condition <- (FPConditionCode(cc) == 0)
1979 * offset = sign_ext (offset)
1982 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1983 offset = insn.getOperand(1).getImm();
1985 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1990 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64, 0, &success);
1994 /* fcsr[23], fcsr[25-31] are vaild condition bits */
1995 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
1997 if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
1998 if ((fcsr & (1 << cc)) == 0)
1999 target = pc + offset;
2002 } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
2003 if ((fcsr & (1 << cc)) != 0)
2004 target = pc + offset;
2011 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2018 bool EmulateInstructionMIPS64::Emulate_BC1EQZ(llvm::MCInst &insn) {
2019 bool success = false;
2022 int64_t target, pc, offset;
2026 * condition <- (FPR[ft].bit0 == 0)
2028 * offset = sign_ext (offset)
2029 * PC = PC + 4 + offset
2031 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2032 offset = insn.getOperand(1).getImm();
2034 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2038 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0,
2043 if ((ft_val & 1) == 0)
2044 target = pc + 4 + offset;
2050 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2057 bool EmulateInstructionMIPS64::Emulate_BC1NEZ(llvm::MCInst &insn) {
2058 bool success = false;
2061 int64_t target, pc, offset;
2065 * condition <- (FPR[ft].bit0 != 0)
2067 * offset = sign_ext (offset)
2068 * PC = PC + 4 + offset
2070 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2071 offset = insn.getOperand(1).getImm();
2073 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2077 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0,
2082 if ((ft_val & 1) != 0)
2083 target = pc + 4 + offset;
2089 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2097 Emulate MIPS-3D Branch instructions
2098 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
2100 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
2103 bool EmulateInstructionMIPS64::Emulate_3D_branch(llvm::MCInst &insn) {
2104 bool success = false;
2106 int64_t pc, offset, target = 0;
2107 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2109 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2110 offset = insn.getOperand(1).getImm();
2112 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2116 fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64,
2121 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2122 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2124 if (!strcasecmp(op_name, "BC1ANY2F")) {
2125 /* if any one bit is 0 */
2126 if (((fcsr >> cc) & 3) != 3)
2127 target = pc + offset;
2130 } else if (!strcasecmp(op_name, "BC1ANY2T")) {
2131 /* if any one bit is 1 */
2132 if (((fcsr >> cc) & 3) != 0)
2133 target = pc + offset;
2136 } else if (!strcasecmp(op_name, "BC1ANY4F")) {
2137 /* if any one bit is 0 */
2138 if (((fcsr >> cc) & 0xf) != 0xf)
2139 target = pc + offset;
2142 } else if (!strcasecmp(op_name, "BC1ANY4T")) {
2143 /* if any one bit is 1 */
2144 if (((fcsr >> cc) & 0xf) != 0)
2145 target = pc + offset;
2152 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2159 bool EmulateInstructionMIPS64::Emulate_BNZB(llvm::MCInst &insn) {
2160 return Emulate_MSA_Branch_DF(insn, 1, true);
2163 bool EmulateInstructionMIPS64::Emulate_BNZH(llvm::MCInst &insn) {
2164 return Emulate_MSA_Branch_DF(insn, 2, true);
2167 bool EmulateInstructionMIPS64::Emulate_BNZW(llvm::MCInst &insn) {
2168 return Emulate_MSA_Branch_DF(insn, 4, true);
2171 bool EmulateInstructionMIPS64::Emulate_BNZD(llvm::MCInst &insn) {
2172 return Emulate_MSA_Branch_DF(insn, 8, true);
2175 bool EmulateInstructionMIPS64::Emulate_BZB(llvm::MCInst &insn) {
2176 return Emulate_MSA_Branch_DF(insn, 1, false);
2179 bool EmulateInstructionMIPS64::Emulate_BZH(llvm::MCInst &insn) {
2180 return Emulate_MSA_Branch_DF(insn, 2, false);
2183 bool EmulateInstructionMIPS64::Emulate_BZW(llvm::MCInst &insn) {
2184 return Emulate_MSA_Branch_DF(insn, 4, false);
2187 bool EmulateInstructionMIPS64::Emulate_BZD(llvm::MCInst &insn) {
2188 return Emulate_MSA_Branch_DF(insn, 8, false);
2191 bool EmulateInstructionMIPS64::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
2192 int element_byte_size,
2194 bool success = false, branch_hit = true;
2196 RegisterValue reg_value;
2197 const uint8_t *ptr = NULL;
2199 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2200 int64_t offset = insn.getOperand(1).getImm();
2203 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2207 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
2208 ptr = (const uint8_t *)reg_value.GetBytes();
2212 for (int i = 0; i < 16 / element_byte_size; i++) {
2213 switch (element_byte_size) {
2215 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2219 if ((*(const uint16_t *)ptr == 0 && bnz) ||
2220 (*(const uint16_t *)ptr != 0 && !bnz))
2224 if ((*(const uint32_t *)ptr == 0 && bnz) ||
2225 (*(const uint32_t *)ptr != 0 && !bnz))
2229 if ((*(const uint64_t *)ptr == 0 && bnz) ||
2230 (*(const uint64_t *)ptr != 0 && !bnz))
2236 ptr = ptr + element_byte_size;
2240 target = pc + offset;
2245 context.type = eContextRelativeBranchImmediate;
2247 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2254 bool EmulateInstructionMIPS64::Emulate_BNZV(llvm::MCInst &insn) {
2255 return Emulate_MSA_Branch_V(insn, true);
2258 bool EmulateInstructionMIPS64::Emulate_BZV(llvm::MCInst &insn) {
2259 return Emulate_MSA_Branch_V(insn, false);
2262 bool EmulateInstructionMIPS64::Emulate_MSA_Branch_V(llvm::MCInst &insn,
2264 bool success = false;
2266 llvm::APInt wr_val = llvm::APInt::getNullValue(128);
2267 llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
2268 llvm::APInt zero_value = llvm::APInt::getNullValue(128);
2269 RegisterValue reg_value;
2271 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2272 int64_t offset = insn.getOperand(1).getImm();
2275 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2279 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
2280 wr_val = reg_value.GetAsUInt128(fail_value);
2284 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
2285 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2286 target = pc + offset;
2291 context.type = eContextRelativeBranchImmediate;
2293 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2300 bool EmulateInstructionMIPS64::Emulate_LDST_Imm(llvm::MCInst &insn) {
2301 bool success = false;
2303 int64_t imm, address;
2304 Context bad_vaddr_context;
2306 uint32_t num_operands = insn.getNumOperands();
2308 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2309 imm = insn.getOperand(num_operands - 1).getImm();
2311 RegisterInfo reg_info_base;
2312 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
2316 /* read base register */
2317 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
2322 /* destination address */
2323 address = address + imm;
2325 /* Set the bad_vaddr register with base address used in the instruction */
2326 bad_vaddr_context.type = eContextInvalid;
2327 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
2333 bool EmulateInstructionMIPS64::Emulate_LDST_Reg(llvm::MCInst &insn) {
2334 bool success = false;
2335 uint32_t base, index;
2336 int64_t address, index_address;
2337 Context bad_vaddr_context;
2339 uint32_t num_operands = insn.getNumOperands();
2341 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2343 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
2345 RegisterInfo reg_info_base, reg_info_index;
2346 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
2350 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
2354 /* read base register */
2355 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
2360 /* read index register */
2361 index_address = ReadRegisterUnsigned(eRegisterKindDWARF,
2362 dwarf_zero_mips + index, 0, &success);
2366 /* destination address */
2367 address = address + index_address;
2369 /* Set the bad_vaddr register with base address used in the instruction */
2370 bad_vaddr_context.type = eContextInvalid;
2371 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,