1 //===-- EmulateInstructionMIPS64.cpp -----------------------------*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "EmulateInstructionMIPS64.h"
10 
11 #include <stdlib.h>
12 
13 #include "lldb/Core/Address.h"
14 #include "lldb/Core/Opcode.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Host/PosixApi.h"
17 #include "lldb/Symbol/UnwindPlan.h"
18 #include "lldb/Utility/ArchSpec.h"
19 #include "lldb/Utility/ConstString.h"
20 #include "lldb/Utility/DataExtractor.h"
21 #include "lldb/Utility/RegisterValue.h"
22 #include "lldb/Utility/Stream.h"
23 #include "llvm-c/Disassembler.h"
24 #include "llvm/MC/MCAsmInfo.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
27 #include "llvm/MC/MCInst.h"
28 #include "llvm/MC/MCInstrInfo.h"
29 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/MC/MCSubtargetInfo.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/TargetSelect.h"
33 
34 #include "llvm/ADT/STLExtras.h"
35 
36 #include "Plugins/Process/Utility/InstructionUtils.h"
37 #include "Plugins/Process/Utility/RegisterContext_mips.h"
38 
39 using namespace lldb;
40 using namespace lldb_private;
41 
42 #define UInt(x) ((uint64_t)x)
43 #define integer int64_t
44 
45 //
46 // EmulateInstructionMIPS64 implementation
47 //
48 
49 #ifdef __mips__
50 extern "C" {
51 void LLVMInitializeMipsTargetInfo();
52 void LLVMInitializeMipsTarget();
53 void LLVMInitializeMipsAsmPrinter();
54 void LLVMInitializeMipsTargetMC();
55 void LLVMInitializeMipsDisassembler();
56 }
57 #endif
58 
59 EmulateInstructionMIPS64::EmulateInstructionMIPS64(
60     const lldb_private::ArchSpec &arch)
61     : EmulateInstruction(arch) {
62   /* Create instance of llvm::MCDisassembler */
63   std::string Status;
64   llvm::Triple triple = arch.GetTriple();
65   const llvm::Target *target =
66       llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status);
67 
68 /*
69  * If we fail to get the target then we haven't registered it. The
70  * SystemInitializerCommon
71  * does not initialize targets, MCs and disassemblers. However we need the
72  * MCDisassembler
73  * to decode the instructions so that the decoding complexity stays with LLVM.
74  * Initialize the MIPS targets and disassemblers.
75 */
76 #ifdef __mips__
77   if (!target) {
78     LLVMInitializeMipsTargetInfo();
79     LLVMInitializeMipsTarget();
80     LLVMInitializeMipsAsmPrinter();
81     LLVMInitializeMipsTargetMC();
82     LLVMInitializeMipsDisassembler();
83     target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Status);
84   }
85 #endif
86 
87   assert(target);
88 
89   llvm::StringRef cpu;
90 
91   switch (arch.GetCore()) {
92   case ArchSpec::eCore_mips32:
93   case ArchSpec::eCore_mips32el:
94     cpu = "mips32";
95     break;
96   case ArchSpec::eCore_mips32r2:
97   case ArchSpec::eCore_mips32r2el:
98     cpu = "mips32r2";
99     break;
100   case ArchSpec::eCore_mips32r3:
101   case ArchSpec::eCore_mips32r3el:
102     cpu = "mips32r3";
103     break;
104   case ArchSpec::eCore_mips32r5:
105   case ArchSpec::eCore_mips32r5el:
106     cpu = "mips32r5";
107     break;
108   case ArchSpec::eCore_mips32r6:
109   case ArchSpec::eCore_mips32r6el:
110     cpu = "mips32r6";
111     break;
112   case ArchSpec::eCore_mips64:
113   case ArchSpec::eCore_mips64el:
114     cpu = "mips64";
115     break;
116   case ArchSpec::eCore_mips64r2:
117   case ArchSpec::eCore_mips64r2el:
118     cpu = "mips64r2";
119     break;
120   case ArchSpec::eCore_mips64r3:
121   case ArchSpec::eCore_mips64r3el:
122     cpu = "mips64r3";
123     break;
124   case ArchSpec::eCore_mips64r5:
125   case ArchSpec::eCore_mips64r5el:
126     cpu = "mips64r5";
127     break;
128   case ArchSpec::eCore_mips64r6:
129   case ArchSpec::eCore_mips64r6el:
130     cpu = "mips64r6";
131     break;
132   default:
133     cpu = "generic";
134     break;
135   }
136 
137   std::string features = "";
138   uint32_t arch_flags = arch.GetFlags();
139   if (arch_flags & ArchSpec::eMIPSAse_msa)
140     features += "+msa,";
141   if (arch_flags & ArchSpec::eMIPSAse_dsp)
142     features += "+dsp,";
143   if (arch_flags & ArchSpec::eMIPSAse_dspr2)
144     features += "+dspr2,";
145   if (arch_flags & ArchSpec::eMIPSAse_mips16)
146     features += "+mips16,";
147   if (arch_flags & ArchSpec::eMIPSAse_micromips)
148     features += "+micromips,";
149 
150   m_reg_info.reset(target->createMCRegInfo(triple.getTriple()));
151   assert(m_reg_info.get());
152 
153   m_insn_info.reset(target->createMCInstrInfo());
154   assert(m_insn_info.get());
155 
156   m_asm_info.reset(target->createMCAsmInfo(*m_reg_info, triple.getTriple()));
157   m_subtype_info.reset(
158       target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
159   assert(m_asm_info.get() && m_subtype_info.get());
160 
161   m_context.reset(
162       new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr));
163   assert(m_context.get());
164 
165   m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
166   assert(m_disasm.get());
167 }
168 
169 void EmulateInstructionMIPS64::Initialize() {
170   PluginManager::RegisterPlugin(GetPluginNameStatic(),
171                                 GetPluginDescriptionStatic(), CreateInstance);
172 }
173 
174 void EmulateInstructionMIPS64::Terminate() {
175   PluginManager::UnregisterPlugin(CreateInstance);
176 }
177 
178 ConstString EmulateInstructionMIPS64::GetPluginNameStatic() {
179   ConstString g_plugin_name("lldb.emulate-instruction.mips64");
180   return g_plugin_name;
181 }
182 
183 lldb_private::ConstString EmulateInstructionMIPS64::GetPluginName() {
184   static ConstString g_plugin_name("EmulateInstructionMIPS64");
185   return g_plugin_name;
186 }
187 
188 const char *EmulateInstructionMIPS64::GetPluginDescriptionStatic() {
189   return "Emulate instructions for the MIPS64 architecture.";
190 }
191 
192 EmulateInstruction *
193 EmulateInstructionMIPS64::CreateInstance(const ArchSpec &arch,
194                                          InstructionType inst_type) {
195   if (EmulateInstructionMIPS64::SupportsEmulatingInstructionsOfTypeStatic(
196           inst_type)) {
197     if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
198         arch.GetTriple().getArch() == llvm::Triple::mips64el) {
199       return new EmulateInstructionMIPS64(arch);
200     }
201   }
202 
203   return nullptr;
204 }
205 
206 bool EmulateInstructionMIPS64::SetTargetTriple(const ArchSpec &arch) {
207   return arch.GetTriple().getArch() == llvm::Triple::mips64 ||
208          arch.GetTriple().getArch() == llvm::Triple::mips64el;
209 }
210 
211 const char *EmulateInstructionMIPS64::GetRegisterName(unsigned reg_num,
212                                                       bool alternate_name) {
213   if (alternate_name) {
214     switch (reg_num) {
215     case dwarf_sp_mips64:
216       return "r29";
217     case dwarf_r30_mips64:
218       return "r30";
219     case dwarf_ra_mips64:
220       return "r31";
221     case dwarf_f0_mips64:
222       return "f0";
223     case dwarf_f1_mips64:
224       return "f1";
225     case dwarf_f2_mips64:
226       return "f2";
227     case dwarf_f3_mips64:
228       return "f3";
229     case dwarf_f4_mips64:
230       return "f4";
231     case dwarf_f5_mips64:
232       return "f5";
233     case dwarf_f6_mips64:
234       return "f6";
235     case dwarf_f7_mips64:
236       return "f7";
237     case dwarf_f8_mips64:
238       return "f8";
239     case dwarf_f9_mips64:
240       return "f9";
241     case dwarf_f10_mips64:
242       return "f10";
243     case dwarf_f11_mips64:
244       return "f11";
245     case dwarf_f12_mips64:
246       return "f12";
247     case dwarf_f13_mips64:
248       return "f13";
249     case dwarf_f14_mips64:
250       return "f14";
251     case dwarf_f15_mips64:
252       return "f15";
253     case dwarf_f16_mips64:
254       return "f16";
255     case dwarf_f17_mips64:
256       return "f17";
257     case dwarf_f18_mips64:
258       return "f18";
259     case dwarf_f19_mips64:
260       return "f19";
261     case dwarf_f20_mips64:
262       return "f20";
263     case dwarf_f21_mips64:
264       return "f21";
265     case dwarf_f22_mips64:
266       return "f22";
267     case dwarf_f23_mips64:
268       return "f23";
269     case dwarf_f24_mips64:
270       return "f24";
271     case dwarf_f25_mips64:
272       return "f25";
273     case dwarf_f26_mips64:
274       return "f26";
275     case dwarf_f27_mips64:
276       return "f27";
277     case dwarf_f28_mips64:
278       return "f28";
279     case dwarf_f29_mips64:
280       return "f29";
281     case dwarf_f30_mips64:
282       return "f30";
283     case dwarf_f31_mips64:
284       return "f31";
285     case dwarf_w0_mips64:
286       return "w0";
287     case dwarf_w1_mips64:
288       return "w1";
289     case dwarf_w2_mips64:
290       return "w2";
291     case dwarf_w3_mips64:
292       return "w3";
293     case dwarf_w4_mips64:
294       return "w4";
295     case dwarf_w5_mips64:
296       return "w5";
297     case dwarf_w6_mips64:
298       return "w6";
299     case dwarf_w7_mips64:
300       return "w7";
301     case dwarf_w8_mips64:
302       return "w8";
303     case dwarf_w9_mips64:
304       return "w9";
305     case dwarf_w10_mips64:
306       return "w10";
307     case dwarf_w11_mips64:
308       return "w11";
309     case dwarf_w12_mips64:
310       return "w12";
311     case dwarf_w13_mips64:
312       return "w13";
313     case dwarf_w14_mips64:
314       return "w14";
315     case dwarf_w15_mips64:
316       return "w15";
317     case dwarf_w16_mips64:
318       return "w16";
319     case dwarf_w17_mips64:
320       return "w17";
321     case dwarf_w18_mips64:
322       return "w18";
323     case dwarf_w19_mips64:
324       return "w19";
325     case dwarf_w20_mips64:
326       return "w20";
327     case dwarf_w21_mips64:
328       return "w21";
329     case dwarf_w22_mips64:
330       return "w22";
331     case dwarf_w23_mips64:
332       return "w23";
333     case dwarf_w24_mips64:
334       return "w24";
335     case dwarf_w25_mips64:
336       return "w25";
337     case dwarf_w26_mips64:
338       return "w26";
339     case dwarf_w27_mips64:
340       return "w27";
341     case dwarf_w28_mips64:
342       return "w28";
343     case dwarf_w29_mips64:
344       return "w29";
345     case dwarf_w30_mips64:
346       return "w30";
347     case dwarf_w31_mips64:
348       return "w31";
349     case dwarf_mir_mips64:
350       return "mir";
351     case dwarf_mcsr_mips64:
352       return "mcsr";
353     case dwarf_config5_mips64:
354       return "config5";
355     default:
356       break;
357     }
358     return nullptr;
359   }
360 
361   switch (reg_num) {
362   case dwarf_zero_mips64:
363     return "r0";
364   case dwarf_r1_mips64:
365     return "r1";
366   case dwarf_r2_mips64:
367     return "r2";
368   case dwarf_r3_mips64:
369     return "r3";
370   case dwarf_r4_mips64:
371     return "r4";
372   case dwarf_r5_mips64:
373     return "r5";
374   case dwarf_r6_mips64:
375     return "r6";
376   case dwarf_r7_mips64:
377     return "r7";
378   case dwarf_r8_mips64:
379     return "r8";
380   case dwarf_r9_mips64:
381     return "r9";
382   case dwarf_r10_mips64:
383     return "r10";
384   case dwarf_r11_mips64:
385     return "r11";
386   case dwarf_r12_mips64:
387     return "r12";
388   case dwarf_r13_mips64:
389     return "r13";
390   case dwarf_r14_mips64:
391     return "r14";
392   case dwarf_r15_mips64:
393     return "r15";
394   case dwarf_r16_mips64:
395     return "r16";
396   case dwarf_r17_mips64:
397     return "r17";
398   case dwarf_r18_mips64:
399     return "r18";
400   case dwarf_r19_mips64:
401     return "r19";
402   case dwarf_r20_mips64:
403     return "r20";
404   case dwarf_r21_mips64:
405     return "r21";
406   case dwarf_r22_mips64:
407     return "r22";
408   case dwarf_r23_mips64:
409     return "r23";
410   case dwarf_r24_mips64:
411     return "r24";
412   case dwarf_r25_mips64:
413     return "r25";
414   case dwarf_r26_mips64:
415     return "r26";
416   case dwarf_r27_mips64:
417     return "r27";
418   case dwarf_gp_mips64:
419     return "gp";
420   case dwarf_sp_mips64:
421     return "sp";
422   case dwarf_r30_mips64:
423     return "fp";
424   case dwarf_ra_mips64:
425     return "ra";
426   case dwarf_sr_mips64:
427     return "sr";
428   case dwarf_lo_mips64:
429     return "lo";
430   case dwarf_hi_mips64:
431     return "hi";
432   case dwarf_bad_mips64:
433     return "bad";
434   case dwarf_cause_mips64:
435     return "cause";
436   case dwarf_pc_mips64:
437     return "pc";
438   case dwarf_f0_mips64:
439     return "f0";
440   case dwarf_f1_mips64:
441     return "f1";
442   case dwarf_f2_mips64:
443     return "f2";
444   case dwarf_f3_mips64:
445     return "f3";
446   case dwarf_f4_mips64:
447     return "f4";
448   case dwarf_f5_mips64:
449     return "f5";
450   case dwarf_f6_mips64:
451     return "f6";
452   case dwarf_f7_mips64:
453     return "f7";
454   case dwarf_f8_mips64:
455     return "f8";
456   case dwarf_f9_mips64:
457     return "f9";
458   case dwarf_f10_mips64:
459     return "f10";
460   case dwarf_f11_mips64:
461     return "f11";
462   case dwarf_f12_mips64:
463     return "f12";
464   case dwarf_f13_mips64:
465     return "f13";
466   case dwarf_f14_mips64:
467     return "f14";
468   case dwarf_f15_mips64:
469     return "f15";
470   case dwarf_f16_mips64:
471     return "f16";
472   case dwarf_f17_mips64:
473     return "f17";
474   case dwarf_f18_mips64:
475     return "f18";
476   case dwarf_f19_mips64:
477     return "f19";
478   case dwarf_f20_mips64:
479     return "f20";
480   case dwarf_f21_mips64:
481     return "f21";
482   case dwarf_f22_mips64:
483     return "f22";
484   case dwarf_f23_mips64:
485     return "f23";
486   case dwarf_f24_mips64:
487     return "f24";
488   case dwarf_f25_mips64:
489     return "f25";
490   case dwarf_f26_mips64:
491     return "f26";
492   case dwarf_f27_mips64:
493     return "f27";
494   case dwarf_f28_mips64:
495     return "f28";
496   case dwarf_f29_mips64:
497     return "f29";
498   case dwarf_f30_mips64:
499     return "f30";
500   case dwarf_f31_mips64:
501     return "f31";
502   case dwarf_fcsr_mips64:
503     return "fcsr";
504   case dwarf_fir_mips64:
505     return "fir";
506   case dwarf_w0_mips64:
507     return "w0";
508   case dwarf_w1_mips64:
509     return "w1";
510   case dwarf_w2_mips64:
511     return "w2";
512   case dwarf_w3_mips64:
513     return "w3";
514   case dwarf_w4_mips64:
515     return "w4";
516   case dwarf_w5_mips64:
517     return "w5";
518   case dwarf_w6_mips64:
519     return "w6";
520   case dwarf_w7_mips64:
521     return "w7";
522   case dwarf_w8_mips64:
523     return "w8";
524   case dwarf_w9_mips64:
525     return "w9";
526   case dwarf_w10_mips64:
527     return "w10";
528   case dwarf_w11_mips64:
529     return "w11";
530   case dwarf_w12_mips64:
531     return "w12";
532   case dwarf_w13_mips64:
533     return "w13";
534   case dwarf_w14_mips64:
535     return "w14";
536   case dwarf_w15_mips64:
537     return "w15";
538   case dwarf_w16_mips64:
539     return "w16";
540   case dwarf_w17_mips64:
541     return "w17";
542   case dwarf_w18_mips64:
543     return "w18";
544   case dwarf_w19_mips64:
545     return "w19";
546   case dwarf_w20_mips64:
547     return "w20";
548   case dwarf_w21_mips64:
549     return "w21";
550   case dwarf_w22_mips64:
551     return "w22";
552   case dwarf_w23_mips64:
553     return "w23";
554   case dwarf_w24_mips64:
555     return "w24";
556   case dwarf_w25_mips64:
557     return "w25";
558   case dwarf_w26_mips64:
559     return "w26";
560   case dwarf_w27_mips64:
561     return "w27";
562   case dwarf_w28_mips64:
563     return "w28";
564   case dwarf_w29_mips64:
565     return "w29";
566   case dwarf_w30_mips64:
567     return "w30";
568   case dwarf_w31_mips64:
569     return "w31";
570   case dwarf_mcsr_mips64:
571     return "mcsr";
572   case dwarf_mir_mips64:
573     return "mir";
574   case dwarf_config5_mips64:
575     return "config5";
576   }
577   return nullptr;
578 }
579 
580 bool EmulateInstructionMIPS64::GetRegisterInfo(RegisterKind reg_kind,
581                                                uint32_t reg_num,
582                                                RegisterInfo &reg_info) {
583   if (reg_kind == eRegisterKindGeneric) {
584     switch (reg_num) {
585     case LLDB_REGNUM_GENERIC_PC:
586       reg_kind = eRegisterKindDWARF;
587       reg_num = dwarf_pc_mips64;
588       break;
589     case LLDB_REGNUM_GENERIC_SP:
590       reg_kind = eRegisterKindDWARF;
591       reg_num = dwarf_sp_mips64;
592       break;
593     case LLDB_REGNUM_GENERIC_FP:
594       reg_kind = eRegisterKindDWARF;
595       reg_num = dwarf_r30_mips64;
596       break;
597     case LLDB_REGNUM_GENERIC_RA:
598       reg_kind = eRegisterKindDWARF;
599       reg_num = dwarf_ra_mips64;
600       break;
601     case LLDB_REGNUM_GENERIC_FLAGS:
602       reg_kind = eRegisterKindDWARF;
603       reg_num = dwarf_sr_mips64;
604       break;
605     default:
606       return false;
607     }
608   }
609 
610   if (reg_kind == eRegisterKindDWARF) {
611     ::memset(&reg_info, 0, sizeof(RegisterInfo));
612     ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
613 
614     if (reg_num == dwarf_sr_mips64 || reg_num == dwarf_fcsr_mips64 ||
615         reg_num == dwarf_fir_mips64 || reg_num == dwarf_mcsr_mips64 ||
616         reg_num == dwarf_mir_mips64 || reg_num == dwarf_config5_mips64) {
617       reg_info.byte_size = 4;
618       reg_info.format = eFormatHex;
619       reg_info.encoding = eEncodingUint;
620     } else if ((int)reg_num >= dwarf_zero_mips64 &&
621                (int)reg_num <= dwarf_f31_mips64) {
622       reg_info.byte_size = 8;
623       reg_info.format = eFormatHex;
624       reg_info.encoding = eEncodingUint;
625     } else if ((int)reg_num >= dwarf_w0_mips64 &&
626                (int)reg_num <= dwarf_w31_mips64) {
627       reg_info.byte_size = 16;
628       reg_info.format = eFormatVectorOfUInt8;
629       reg_info.encoding = eEncodingVector;
630     } else {
631       return false;
632     }
633 
634     reg_info.name = GetRegisterName(reg_num, false);
635     reg_info.alt_name = GetRegisterName(reg_num, true);
636     reg_info.kinds[eRegisterKindDWARF] = reg_num;
637 
638     switch (reg_num) {
639     case dwarf_r30_mips64:
640       reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
641       break;
642     case dwarf_ra_mips64:
643       reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
644       break;
645     case dwarf_sp_mips64:
646       reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
647       break;
648     case dwarf_pc_mips64:
649       reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
650       break;
651     case dwarf_sr_mips64:
652       reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
653       break;
654     default:
655       break;
656     }
657     return true;
658   }
659   return false;
660 }
661 
662 EmulateInstructionMIPS64::MipsOpcode *
663 EmulateInstructionMIPS64::GetOpcodeForInstruction(const char *op_name) {
664   static EmulateInstructionMIPS64::MipsOpcode g_opcodes[] = {
665       // Prologue/Epilogue instructions
666       {"DADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu,
667        "DADDIU rt, rs, immediate"},
668       {"ADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu,
669        "ADDIU  rt, rs, immediate"},
670       {"SD", &EmulateInstructionMIPS64::Emulate_SD, "SD     rt, offset(rs)"},
671       {"LD", &EmulateInstructionMIPS64::Emulate_LD, "LD     rt, offset(base)"},
672       {"DSUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
673        "DSUBU  rd, rs, rt"},
674       {"SUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
675        "SUBU   rd, rs, rt"},
676       {"DADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
677        "DADDU  rd, rs, rt"},
678       {"ADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
679        "ADDU   rd, rs, rt"},
680       {"LUI", &EmulateInstructionMIPS64::Emulate_LUI, "LUI    rt, immediate"},
681 
682       // Load/Store  instructions
683       /* Following list of emulated instructions are required by implementation
684          of hardware watchpoint
685          for MIPS in lldb. As we just need the address accessed by instructions,
686          we have generalised
687          all these instructions in 2 functions depending on their addressing
688          modes */
689 
690       {"LB", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
691        "LB    rt, offset(base)"},
692       {"LBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
693        "LBE   rt, offset(base)"},
694       {"LBU", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
695        "LBU   rt, offset(base)"},
696       {"LBUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
697        "LBUE  rt, offset(base)"},
698       {"LDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
699        "LDC1  ft, offset(base)"},
700       {"LDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
701        "LDL   rt, offset(base)"},
702       {"LDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
703        "LDR   rt, offset(base)"},
704       {"LLD", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
705        "LLD   rt, offset(base)"},
706       {"LDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
707        "LDC2  rt, offset(base)"},
708       {"LDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
709        "LDXC1 fd, index (base)"},
710       {"LH", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
711        "LH    rt, offset(base)"},
712       {"LHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
713        "LHE   rt, offset(base)"},
714       {"LHU", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
715        "LHU   rt, offset(base)"},
716       {"LHUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
717        "LHUE  rt, offset(base)"},
718       {"LL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
719        "LL    rt, offset(base)"},
720       {"LLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
721        "LLE   rt, offset(base)"},
722       {"LUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
723        "LUXC1 fd, index (base)"},
724       {"LW", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
725        "LW    rt, offset(rs)"},
726       {"LWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
727        "LWC1  ft, offset(base)"},
728       {"LWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
729        "LWC2  rt, offset(base)"},
730       {"LWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
731        "LWE   rt, offset(base)"},
732       {"LWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
733        "LWL   rt, offset(base)"},
734       {"LWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
735        "LWLE  rt, offset(base)"},
736       {"LWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
737        "LWR   rt, offset(base)"},
738       {"LWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
739        "LWRE  rt, offset(base)"},
740       {"LWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
741        "LWXC1 fd, index (base)"},
742 
743       {"SB", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
744        "SB    rt, offset(base)"},
745       {"SBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
746        "SBE   rt, offset(base)"},
747       {"SC", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
748        "SC    rt, offset(base)"},
749       {"SCE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
750        "SCE   rt, offset(base)"},
751       {"SCD", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
752        "SCD   rt, offset(base)"},
753       {"SDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
754        "SDL   rt, offset(base)"},
755       {"SDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
756        "SDR   rt, offset(base)"},
757       {"SDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
758        "SDC1  ft, offset(base)"},
759       {"SDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
760        "SDC2  rt, offset(base)"},
761       {"SDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
762        "SDXC1 fs, index (base)"},
763       {"SH", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
764        "SH    rt, offset(base)"},
765       {"SHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
766        "SHE   rt, offset(base)"},
767       {"SUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
768        "SUXC1 fs, index (base)"},
769       {"SW", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
770        "SW    rt, offset(rs)"},
771       {"SWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
772        "SWC1  ft, offset(base)"},
773       {"SWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
774        "SWC2  rt, offset(base)"},
775       {"SWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
776        "SWE   rt, offset(base)"},
777       {"SWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
778        "SWL   rt, offset(base)"},
779       {"SWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
780        "SWLE  rt, offset(base)"},
781       {"SWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
782        "SWR   rt, offset(base)"},
783       {"SWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
784        "SWRE  rt, offset(base)"},
785       {"SWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
786        "SWXC1 fs, index (base)"},
787 
788       // Branch instructions
789       {"BEQ", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
790       {"BEQ64", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
791       {"BNE", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"},
792       {"BNE64", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"},
793       {"BEQL", &EmulateInstructionMIPS64::Emulate_BXX_3ops,
794        "BEQL rs,rt,offset"},
795       {"BNEL", &EmulateInstructionMIPS64::Emulate_BXX_3ops,
796        "BNEL rs,rt,offset"},
797       {"BGEZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
798        "BGEZALL rt,offset"},
799       {"BAL", &EmulateInstructionMIPS64::Emulate_BAL, "BAL offset"},
800       {"BGEZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
801        "BGEZAL rs,offset"},
802       {"BALC", &EmulateInstructionMIPS64::Emulate_BALC, "BALC offset"},
803       {"BC", &EmulateInstructionMIPS64::Emulate_BC, "BC offset"},
804       {"BGEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"},
805       {"BGEZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"},
806       {"BLEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
807        "BLEZALC rs,offset"},
808       {"BGEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
809        "BGEZALC rs,offset"},
810       {"BLTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
811        "BLTZALC rs,offset"},
812       {"BGTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
813        "BGTZALC rs,offset"},
814       {"BEQZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
815        "BEQZALC rs,offset"},
816       {"BNEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
817        "BNEZALC rs,offset"},
818       {"BEQC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
819        "BEQC rs,rt,offset"},
820       {"BEQC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
821        "BEQC rs,rt,offset"},
822       {"BNEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
823        "BNEC rs,rt,offset"},
824       {"BNEC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
825        "BNEC rs,rt,offset"},
826       {"BLTC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
827        "BLTC rs,rt,offset"},
828       {"BLTC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
829        "BLTC rs,rt,offset"},
830       {"BGEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
831        "BGEC rs,rt,offset"},
832       {"BGEC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
833        "BGEC rs,rt,offset"},
834       {"BLTUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
835        "BLTUC rs,rt,offset"},
836       {"BLTUC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
837        "BLTUC rs,rt,offset"},
838       {"BGEUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
839        "BGEUC rs,rt,offset"},
840       {"BGEUC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
841        "BGEUC rs,rt,offset"},
842       {"BLTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
843        "BLTZC rt,offset"},
844       {"BLTZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
845        "BLTZC rt,offset"},
846       {"BLEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
847        "BLEZC rt,offset"},
848       {"BLEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
849        "BLEZC rt,offset"},
850       {"BGEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
851        "BGEZC rt,offset"},
852       {"BGEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
853        "BGEZC rt,offset"},
854       {"BGTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
855        "BGTZC rt,offset"},
856       {"BGTZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
857        "BGTZC rt,offset"},
858       {"BEQZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
859        "BEQZC rt,offset"},
860       {"BEQZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
861        "BEQZC rt,offset"},
862       {"BNEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
863        "BNEZC rt,offset"},
864       {"BNEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
865        "BNEZC rt,offset"},
866       {"BGEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZL rt,offset"},
867       {"BGTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"},
868       {"BGTZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"},
869       {"BGTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZL rt,offset"},
870       {"BLEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"},
871       {"BLEZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"},
872       {"BLEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZL rt,offset"},
873       {"BLTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"},
874       {"BLTZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"},
875       {"BLTZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
876        "BLTZAL rt,offset"},
877       {"BLTZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
878        "BLTZALL rt,offset"},
879       {"BLTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZL rt,offset"},
880       {"BOVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
881        "BOVC rs,rt,offset"},
882       {"BNVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
883        "BNVC rs,rt,offset"},
884       {"J", &EmulateInstructionMIPS64::Emulate_J, "J target"},
885       {"JAL", &EmulateInstructionMIPS64::Emulate_JAL, "JAL target"},
886       {"JALX", &EmulateInstructionMIPS64::Emulate_JAL, "JALX target"},
887       {"JALR", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"},
888       {"JALR64", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"},
889       {"JALR_HB", &EmulateInstructionMIPS64::Emulate_JALR, "JALR.HB target"},
890       {"JIALC", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"},
891       {"JIALC64", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"},
892       {"JIC", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"},
893       {"JIC64", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"},
894       {"JR", &EmulateInstructionMIPS64::Emulate_JR, "JR target"},
895       {"JR64", &EmulateInstructionMIPS64::Emulate_JR, "JR target"},
896       {"JR_HB", &EmulateInstructionMIPS64::Emulate_JR, "JR.HB target"},
897       {"BC1F", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1F cc, offset"},
898       {"BC1T", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1T cc, offset"},
899       {"BC1FL", &EmulateInstructionMIPS64::Emulate_FP_branch,
900        "BC1FL cc, offset"},
901       {"BC1TL", &EmulateInstructionMIPS64::Emulate_FP_branch,
902        "BC1TL cc, offset"},
903       {"BC1EQZ", &EmulateInstructionMIPS64::Emulate_BC1EQZ,
904        "BC1EQZ ft, offset"},
905       {"BC1NEZ", &EmulateInstructionMIPS64::Emulate_BC1NEZ,
906        "BC1NEZ ft, offset"},
907       {"BC1ANY2F", &EmulateInstructionMIPS64::Emulate_3D_branch,
908        "BC1ANY2F cc, offset"},
909       {"BC1ANY2T", &EmulateInstructionMIPS64::Emulate_3D_branch,
910        "BC1ANY2T cc, offset"},
911       {"BC1ANY4F", &EmulateInstructionMIPS64::Emulate_3D_branch,
912        "BC1ANY4F cc, offset"},
913       {"BC1ANY4T", &EmulateInstructionMIPS64::Emulate_3D_branch,
914        "BC1ANY4T cc, offset"},
915       {"BNZ_B", &EmulateInstructionMIPS64::Emulate_BNZB, "BNZ.b wt,s16"},
916       {"BNZ_H", &EmulateInstructionMIPS64::Emulate_BNZH, "BNZ.h wt,s16"},
917       {"BNZ_W", &EmulateInstructionMIPS64::Emulate_BNZW, "BNZ.w wt,s16"},
918       {"BNZ_D", &EmulateInstructionMIPS64::Emulate_BNZD, "BNZ.d wt,s16"},
919       {"BZ_B", &EmulateInstructionMIPS64::Emulate_BZB, "BZ.b wt,s16"},
920       {"BZ_H", &EmulateInstructionMIPS64::Emulate_BZH, "BZ.h wt,s16"},
921       {"BZ_W", &EmulateInstructionMIPS64::Emulate_BZW, "BZ.w wt,s16"},
922       {"BZ_D", &EmulateInstructionMIPS64::Emulate_BZD, "BZ.d wt,s16"},
923       {"BNZ_V", &EmulateInstructionMIPS64::Emulate_BNZV, "BNZ.V wt,s16"},
924       {"BZ_V", &EmulateInstructionMIPS64::Emulate_BZV, "BZ.V wt,s16"},
925   };
926 
927   static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
928 
929   for (size_t i = 0; i < k_num_mips_opcodes; ++i) {
930     if (!strcasecmp(g_opcodes[i].op_name, op_name))
931       return &g_opcodes[i];
932   }
933 
934   return nullptr;
935 }
936 
937 bool EmulateInstructionMIPS64::ReadInstruction() {
938   bool success = false;
939   m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
940                                 LLDB_INVALID_ADDRESS, &success);
941   if (success) {
942     Context read_inst_context;
943     read_inst_context.type = eContextReadOpcode;
944     read_inst_context.SetNoArgs();
945     m_opcode.SetOpcode32(
946         ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
947         GetByteOrder());
948   }
949   if (!success)
950     m_addr = LLDB_INVALID_ADDRESS;
951   return success;
952 }
953 
954 bool EmulateInstructionMIPS64::EvaluateInstruction(uint32_t evaluate_options) {
955   bool success = false;
956   llvm::MCInst mc_insn;
957   uint64_t insn_size;
958   DataExtractor data;
959 
960   /* Keep the complexity of the decode logic with the llvm::MCDisassembler
961    * class. */
962   if (m_opcode.GetData(data)) {
963     llvm::MCDisassembler::DecodeStatus decode_status;
964     llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
965     decode_status = m_disasm->getInstruction(
966         mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
967     if (decode_status != llvm::MCDisassembler::Success)
968       return false;
969   }
970 
971   /*
972    * mc_insn.getOpcode() returns decoded opcode. However to make use
973    * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
974   */
975   const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
976 
977   if (op_name == nullptr)
978     return false;
979 
980   /*
981    * Decoding has been done already. Just get the call-back function
982    * and emulate the instruction.
983   */
984   MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
985 
986   if (opcode_data == nullptr)
987     return false;
988 
989   uint64_t old_pc = 0, new_pc = 0;
990   const bool auto_advance_pc =
991       evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
992 
993   if (auto_advance_pc) {
994     old_pc =
995         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
996     if (!success)
997       return false;
998   }
999 
1000   /* emulate instruction */
1001   success = (this->*opcode_data->callback)(mc_insn);
1002   if (!success)
1003     return false;
1004 
1005   if (auto_advance_pc) {
1006     new_pc =
1007         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1008     if (!success)
1009       return false;
1010 
1011     /* If we haven't changed the PC, change it here */
1012     if (old_pc == new_pc) {
1013       new_pc += 4;
1014       Context context;
1015       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1016                                  new_pc))
1017         return false;
1018     }
1019   }
1020 
1021   return true;
1022 }
1023 
1024 bool EmulateInstructionMIPS64::CreateFunctionEntryUnwind(
1025     UnwindPlan &unwind_plan) {
1026   unwind_plan.Clear();
1027   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1028 
1029   UnwindPlan::RowSP row(new UnwindPlan::Row);
1030   const bool can_replace = false;
1031 
1032   // Our previous Call Frame Address is the stack pointer
1033   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips64, 0);
1034 
1035   // Our previous PC is in the RA
1036   row->SetRegisterLocationToRegister(dwarf_pc_mips64, dwarf_ra_mips64,
1037                                      can_replace);
1038 
1039   unwind_plan.AppendRow(row);
1040 
1041   // All other registers are the same.
1042   unwind_plan.SetSourceName("EmulateInstructionMIPS64");
1043   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1044   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1045   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1046   unwind_plan.SetReturnAddressRegister(dwarf_ra_mips64);
1047 
1048   return true;
1049 }
1050 
1051 bool EmulateInstructionMIPS64::nonvolatile_reg_p(uint64_t regnum) {
1052   switch (regnum) {
1053   case dwarf_r16_mips64:
1054   case dwarf_r17_mips64:
1055   case dwarf_r18_mips64:
1056   case dwarf_r19_mips64:
1057   case dwarf_r20_mips64:
1058   case dwarf_r21_mips64:
1059   case dwarf_r22_mips64:
1060   case dwarf_r23_mips64:
1061   case dwarf_gp_mips64:
1062   case dwarf_sp_mips64:
1063   case dwarf_r30_mips64:
1064   case dwarf_ra_mips64:
1065     return true;
1066   default:
1067     return false;
1068   }
1069   return false;
1070 }
1071 
1072 bool EmulateInstructionMIPS64::Emulate_DADDiu(llvm::MCInst &insn) {
1073   // DADDIU rt, rs, immediate
1074   // GPR[rt] <- GPR[rs] + sign_extend(immediate)
1075 
1076   uint8_t dst, src;
1077   bool success = false;
1078   const uint32_t imm16 = insn.getOperand(2).getImm();
1079   int64_t imm = SignedBits(imm16, 15, 0);
1080 
1081   dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1082   src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1083 
1084   // If immediate is greater than 2^16 - 1 then clang generate LUI,
1085   // (D)ADDIU,(D)SUBU instructions in prolog. Example lui    $1, 0x2 daddiu $1,
1086   // $1, -0x5920 dsubu  $sp, $sp, $1 In this case, (D)ADDIU dst and src will be
1087   // same and not equal to sp
1088   if (dst == src) {
1089     Context context;
1090 
1091     /* read <src> register */
1092     const uint64_t src_opd_val = ReadRegisterUnsigned(
1093         eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
1094     if (!success)
1095       return false;
1096 
1097     /* Check if this is daddiu sp, sp, imm16 */
1098     if (dst == dwarf_sp_mips64) {
1099       /*
1100        * From the MIPS IV spec:
1101        *
1102        * The term “unsigned” in the instruction name is a misnomer; this
1103        * operation is 64-bit modulo arithmetic that does not trap on overflow.
1104        * It is appropriate for arithmetic which is not signed, such as address
1105        * arithmetic, or integer arithmetic environments that ignore overflow,
1106        * such as “C” language arithmetic.
1107        *
1108        * Assume 2's complement and rely on unsigned overflow here.
1109        */
1110       uint64_t result = src_opd_val + imm;
1111       RegisterInfo reg_info_sp;
1112 
1113       if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
1114         context.SetRegisterPlusOffset(reg_info_sp, imm);
1115 
1116       /* We are allocating bytes on stack */
1117       context.type = eContextAdjustStackPointer;
1118 
1119       WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64,
1120                             result);
1121       return true;
1122     }
1123 
1124     imm += src_opd_val;
1125     context.SetImmediateSigned(imm);
1126     context.type = eContextImmediate;
1127 
1128     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1129                                dwarf_zero_mips64 + dst, imm))
1130       return false;
1131   }
1132 
1133   return true;
1134 }
1135 
1136 bool EmulateInstructionMIPS64::Emulate_SD(llvm::MCInst &insn) {
1137   uint64_t address;
1138   RegisterInfo reg_info_base;
1139   RegisterInfo reg_info_src;
1140   bool success = false;
1141   uint32_t imm16 = insn.getOperand(2).getImm();
1142   uint64_t imm = SignedBits(imm16, 15, 0);
1143   uint32_t src, base;
1144   Context bad_vaddr_context;
1145 
1146   src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1147   base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1148 
1149   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1150                        reg_info_base) ||
1151       !GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src,
1152                        reg_info_src))
1153     return false;
1154 
1155   /* read SP */
1156   address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1157                                  0, &success);
1158   if (!success)
1159     return false;
1160 
1161   /* destination address */
1162   address = address + imm;
1163 
1164   /* We look for sp based non-volatile register stores */
1165   if (nonvolatile_reg_p(src)) {
1166     Context context;
1167     RegisterValue data_src;
1168     context.type = eContextPushRegisterOnStack;
1169     context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1170 
1171     uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1172     Status error;
1173 
1174     if (!ReadRegister(&reg_info_base, data_src))
1175       return false;
1176 
1177     if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
1178                                  eByteOrderLittle, error) == 0)
1179       return false;
1180 
1181     if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1182       return false;
1183   }
1184 
1185   /* Set the bad_vaddr register with base address used in the instruction */
1186   bad_vaddr_context.type = eContextInvalid;
1187   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64,
1188                         address);
1189 
1190   return true;
1191 }
1192 
1193 bool EmulateInstructionMIPS64::Emulate_LD(llvm::MCInst &insn) {
1194   bool success = false;
1195   uint32_t src, base;
1196   int64_t imm, address;
1197   Context bad_vaddr_context;
1198 
1199   src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1200   base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1201   imm = insn.getOperand(2).getImm();
1202 
1203   RegisterInfo reg_info_base;
1204   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1205                        reg_info_base))
1206     return false;
1207 
1208   /* read base register */
1209   address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1210                                  0, &success);
1211   if (!success)
1212     return false;
1213 
1214   /* destination address */
1215   address = address + imm;
1216 
1217   /* Set the bad_vaddr register with base address used in the instruction */
1218   bad_vaddr_context.type = eContextInvalid;
1219   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64,
1220                         address);
1221 
1222   if (nonvolatile_reg_p(src)) {
1223     RegisterValue data_src;
1224     RegisterInfo reg_info_src;
1225 
1226     if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src,
1227                          reg_info_src))
1228       return false;
1229 
1230     Context context;
1231     context.type = eContextRegisterLoad;
1232 
1233     return WriteRegister(context, &reg_info_src, data_src);
1234   }
1235 
1236   return false;
1237 }
1238 
1239 bool EmulateInstructionMIPS64::Emulate_LUI(llvm::MCInst &insn) {
1240   // LUI rt, immediate
1241   // GPR[rt] <- sign_extend(immediate << 16)
1242 
1243   const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1244   int64_t imm = SignedBits(imm32, 31, 0);
1245   uint8_t rt;
1246   Context context;
1247 
1248   rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1249   context.SetImmediateSigned(imm);
1250   context.type = eContextImmediate;
1251 
1252   return WriteRegisterUnsigned(context, eRegisterKindDWARF,
1253                                dwarf_zero_mips64 + rt, imm);
1254 }
1255 
1256 bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) {
1257   // DSUBU sp, <src>, <rt>
1258   // DADDU sp, <src>, <rt>
1259   // DADDU dst, sp, <rt>
1260 
1261   bool success = false;
1262   uint64_t result;
1263   uint8_t src, dst, rt;
1264   const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1265 
1266   dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1267   src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1268 
1269   /* Check if sp is destination register */
1270   if (dst == dwarf_sp_mips64) {
1271     rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1272 
1273     /* read <src> register */
1274     uint64_t src_opd_val = ReadRegisterUnsigned(
1275         eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
1276     if (!success)
1277       return false;
1278 
1279     /* read <rt > register */
1280     uint64_t rt_opd_val = ReadRegisterUnsigned(
1281         eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
1282     if (!success)
1283       return false;
1284 
1285     if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU"))
1286       result = src_opd_val - rt_opd_val;
1287     else
1288       result = src_opd_val + rt_opd_val;
1289 
1290     Context context;
1291     RegisterInfo reg_info_sp;
1292     if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
1293       context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
1294 
1295     /* We are allocating bytes on stack */
1296     context.type = eContextAdjustStackPointer;
1297 
1298     WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64, result);
1299 
1300     return true;
1301   } else if (src == dwarf_sp_mips64) {
1302     rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1303 
1304     /* read <src> register */
1305     uint64_t src_opd_val = ReadRegisterUnsigned(
1306         eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
1307     if (!success)
1308       return false;
1309 
1310     /* read <rt> register */
1311     uint64_t rt_opd_val = ReadRegisterUnsigned(
1312         eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
1313     if (!success)
1314       return false;
1315 
1316     Context context;
1317 
1318     if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU"))
1319       result = src_opd_val - rt_opd_val;
1320     else
1321       result = src_opd_val + rt_opd_val;
1322 
1323     context.SetImmediateSigned(result);
1324     context.type = eContextImmediate;
1325 
1326     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1327                                dwarf_zero_mips64 + dst, result))
1328       return false;
1329   }
1330 
1331   return true;
1332 }
1333 
1334 /*
1335     Emulate below MIPS branch instructions.
1336     BEQ, BNE : Branch on condition
1337     BEQL, BNEL : Branch likely
1338 */
1339 bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) {
1340   bool success = false;
1341   uint32_t rs, rt;
1342   int64_t offset, pc, rs_val, rt_val, target = 0;
1343   const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1344 
1345   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1346   rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1347   offset = insn.getOperand(2).getImm();
1348 
1349   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1350   if (!success)
1351     return false;
1352 
1353   rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1354                                          dwarf_zero_mips64 + rs, 0, &success);
1355   if (!success)
1356     return false;
1357 
1358   rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1359                                          dwarf_zero_mips64 + rt, 0, &success);
1360   if (!success)
1361     return false;
1362 
1363   if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")
1364        || !strcasecmp(op_name, "BEQ64") ) {
1365     if (rs_val == rt_val)
1366       target = pc + offset;
1367     else
1368       target = pc + 8;
1369   } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")
1370               || !strcasecmp(op_name, "BNE64")) {
1371     if (rs_val != rt_val)
1372       target = pc + offset;
1373     else
1374       target = pc + 8;
1375   }
1376 
1377   Context context;
1378   context.type = eContextRelativeBranchImmediate;
1379   context.SetImmediate(offset);
1380 
1381   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1382                                target);
1383 }
1384 
1385 /*
1386     Emulate below MIPS Non-Compact conditional branch and link instructions.
1387     BLTZAL, BGEZAL      :
1388     BLTZALL, BGEZALL    : Branch likely
1389 */
1390 bool EmulateInstructionMIPS64::Emulate_Bcond_Link(llvm::MCInst &insn) {
1391   bool success = false;
1392   uint32_t rs;
1393   int64_t offset, pc, target = 0;
1394   int64_t rs_val;
1395   const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1396 
1397   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1398   offset = insn.getOperand(1).getImm();
1399 
1400   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1401   if (!success)
1402     return false;
1403 
1404   rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1405                                          dwarf_zero_mips64 + rs, 0, &success);
1406   if (!success)
1407     return false;
1408 
1409   if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
1410     if (rs_val < 0)
1411       target = pc + offset;
1412     else
1413       target = pc + 8;
1414   } else if (!strcasecmp(op_name, "BGEZAL") ||
1415              !strcasecmp(op_name, "BGEZALL")) {
1416     if (rs_val >= 0)
1417       target = pc + offset;
1418     else
1419       target = pc + 8;
1420   }
1421 
1422   Context context;
1423 
1424   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1425                              target))
1426     return false;
1427 
1428   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1429                              pc + 8))
1430     return false;
1431 
1432   return true;
1433 }
1434 
1435 bool EmulateInstructionMIPS64::Emulate_BAL(llvm::MCInst &insn) {
1436   bool success = false;
1437   int64_t offset, pc, target;
1438 
1439   /*
1440    * BAL offset
1441    *      offset = sign_ext (offset << 2)
1442    *      RA = PC + 8
1443    *      PC = PC + offset
1444   */
1445   offset = insn.getOperand(0).getImm();
1446 
1447   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1448   if (!success)
1449     return false;
1450 
1451   target = pc + offset;
1452 
1453   Context context;
1454 
1455   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1456                              target))
1457     return false;
1458 
1459   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1460                              pc + 8))
1461     return false;
1462 
1463   return true;
1464 }
1465 
1466 bool EmulateInstructionMIPS64::Emulate_BALC(llvm::MCInst &insn) {
1467   bool success = false;
1468   int64_t offset, pc, target;
1469 
1470   /*
1471    * BALC offset
1472    *      offset = sign_ext (offset << 2)
1473    *      RA = PC + 4
1474    *      PC = PC + 4 + offset
1475   */
1476   offset = insn.getOperand(0).getImm();
1477 
1478   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1479   if (!success)
1480     return false;
1481 
1482   target = pc + offset;
1483 
1484   Context context;
1485 
1486   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1487                              target))
1488     return false;
1489 
1490   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1491                              pc + 4))
1492     return false;
1493 
1494   return true;
1495 }
1496 
1497 /*
1498     Emulate below MIPS conditional branch and link instructions.
1499     BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1500 */
1501 bool EmulateInstructionMIPS64::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
1502   bool success = false;
1503   uint32_t rs;
1504   int64_t offset, pc, rs_val, target = 0;
1505   const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1506 
1507   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1508   offset = insn.getOperand(1).getImm();
1509 
1510   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1511   if (!success)
1512     return false;
1513 
1514   rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1515                                          dwarf_zero_mips64 + rs, 0, &success);
1516   if (!success)
1517     return false;
1518 
1519   if (!strcasecmp(op_name, "BLEZALC")) {
1520     if (rs_val <= 0)
1521       target = pc + offset;
1522     else
1523       target = pc + 4;
1524   } else if (!strcasecmp(op_name, "BGEZALC")) {
1525     if (rs_val >= 0)
1526       target = pc + offset;
1527     else
1528       target = pc + 4;
1529   } else if (!strcasecmp(op_name, "BLTZALC")) {
1530     if (rs_val < 0)
1531       target = pc + offset;
1532     else
1533       target = pc + 4;
1534   } else if (!strcasecmp(op_name, "BGTZALC")) {
1535     if (rs_val > 0)
1536       target = pc + offset;
1537     else
1538       target = pc + 4;
1539   } else if (!strcasecmp(op_name, "BEQZALC")) {
1540     if (rs_val == 0)
1541       target = pc + offset;
1542     else
1543       target = pc + 4;
1544   } else if (!strcasecmp(op_name, "BNEZALC")) {
1545     if (rs_val != 0)
1546       target = pc + offset;
1547     else
1548       target = pc + 4;
1549   }
1550 
1551   Context context;
1552 
1553   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1554                              target))
1555     return false;
1556 
1557   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1558                              pc + 4))
1559     return false;
1560 
1561   return true;
1562 }
1563 
1564 /*
1565     Emulate below MIPS branch instructions.
1566     BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
1567     BLTZ, BGEZ, BGTZ, BLEZ     : Non-compact branches
1568 */
1569 bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) {
1570   bool success = false;
1571   uint32_t rs;
1572   int64_t offset, pc, rs_val, target = 0;
1573   const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1574 
1575   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1576   offset = insn.getOperand(1).getImm();
1577 
1578   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1579   if (!success)
1580     return false;
1581 
1582   rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1583                                          dwarf_zero_mips64 + rs, 0, &success);
1584   if (!success)
1585     return false;
1586 
1587   if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")
1588        || !strcasecmp(op_name, "BLTZ64")) {
1589     if (rs_val < 0)
1590       target = pc + offset;
1591     else
1592       target = pc + 8;
1593   } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")
1594               || !strcasecmp(op_name, "BGEZ64")) {
1595     if (rs_val >= 0)
1596       target = pc + offset;
1597     else
1598       target = pc + 8;
1599   } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")
1600               || !strcasecmp(op_name, "BGTZ64")) {
1601     if (rs_val > 0)
1602       target = pc + offset;
1603     else
1604       target = pc + 8;
1605   } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")
1606               || !strcasecmp(op_name, "BLEZ64")) {
1607     if (rs_val <= 0)
1608       target = pc + offset;
1609     else
1610       target = pc + 8;
1611   }
1612 
1613   Context context;
1614   context.type = eContextRelativeBranchImmediate;
1615   context.SetImmediate(offset);
1616 
1617   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1618                                target);
1619 }
1620 
1621 bool EmulateInstructionMIPS64::Emulate_BC(llvm::MCInst &insn) {
1622   bool success = false;
1623   int64_t offset, pc, target;
1624 
1625   /*
1626    * BC offset
1627    *      offset = sign_ext (offset << 2)
1628    *      PC = PC + 4 + offset
1629   */
1630   offset = insn.getOperand(0).getImm();
1631 
1632   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1633   if (!success)
1634     return false;
1635 
1636   target = pc + offset;
1637 
1638   Context context;
1639 
1640   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1641                                target);
1642 }
1643 
1644 static int IsAdd64bitOverflow(int64_t a, int64_t b) {
1645   int64_t r = (uint64_t)a + (uint64_t)b;
1646   return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1647 }
1648 
1649 /*
1650     Emulate below MIPS branch instructions.
1651     BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
1652    instructions with no delay slot
1653 */
1654 bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
1655   bool success = false;
1656   uint32_t rs, rt;
1657   int64_t offset, pc, rs_val, rt_val, target = 0;
1658   const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1659   uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1660 
1661   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1662   rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1663   offset = insn.getOperand(2).getImm();
1664 
1665   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1666   if (!success)
1667     return false;
1668 
1669   rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1670                                          dwarf_zero_mips64 + rs, 0, &success);
1671   if (!success)
1672     return false;
1673 
1674   rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1675                                          dwarf_zero_mips64 + rt, 0, &success);
1676   if (!success)
1677     return false;
1678 
1679   if (!strcasecmp(op_name, "BEQC") || !strcasecmp(op_name, "BEQC64")) {
1680     if (rs_val == rt_val)
1681       target = pc + offset;
1682     else
1683       target = pc + 4;
1684   } else if (!strcasecmp(op_name, "BNEC") || !strcasecmp(op_name, "BNEC64")) {
1685     if (rs_val != rt_val)
1686       target = pc + offset;
1687     else
1688       target = pc + 4;
1689   } else if (!strcasecmp(op_name, "BLTC") || !strcasecmp(op_name, "BLTC64")) {
1690     if (rs_val < rt_val)
1691       target = pc + offset;
1692     else
1693       target = pc + 4;
1694   } else if (!strcasecmp(op_name, "BGEC64") || !strcasecmp(op_name, "BGEC")) {
1695     if (rs_val >= rt_val)
1696       target = pc + offset;
1697     else
1698       target = pc + 4;
1699   } else if (!strcasecmp(op_name, "BLTUC") || !strcasecmp(op_name, "BLTUC64")) {
1700     if (rs_val < rt_val)
1701       target = pc + offset;
1702     else
1703       target = pc + 4;
1704   } else if (!strcasecmp(op_name, "BGEUC") || !strcasecmp(op_name, "BGEUC64")) {
1705     if ((uint32_t)rs_val >= (uint32_t)rt_val)
1706       target = pc + offset;
1707     else
1708       target = pc + 4;
1709   } else if (!strcasecmp(op_name, "BOVC")) {
1710     if (IsAdd64bitOverflow(rs_val, rt_val))
1711       target = pc + offset;
1712     else
1713       target = pc + 4;
1714   } else if (!strcasecmp(op_name, "BNVC")) {
1715     if (!IsAdd64bitOverflow(rs_val, rt_val))
1716       target = pc + offset;
1717     else
1718       target = pc + 4;
1719   }
1720 
1721   Context context;
1722   context.type = eContextRelativeBranchImmediate;
1723   context.SetImmediate(current_inst_size + offset);
1724 
1725   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1726                                target);
1727 }
1728 
1729 /*
1730     Emulate below MIPS branch instructions.
1731     BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
1732 */
1733 bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
1734   bool success = false;
1735   uint32_t rs;
1736   int64_t offset, pc, target = 0;
1737   int64_t rs_val;
1738   const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1739   uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1740 
1741   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1742   offset = insn.getOperand(1).getImm();
1743 
1744   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1745   if (!success)
1746     return false;
1747 
1748   rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1749                                          dwarf_zero_mips64 + rs, 0, &success);
1750   if (!success)
1751     return false;
1752 
1753   if (!strcasecmp(op_name, "BLTZC") || !strcasecmp(op_name, "BLTZC64")) {
1754     if (rs_val < 0)
1755       target = pc + offset;
1756     else
1757       target = pc + 4;
1758   } else if (!strcasecmp(op_name, "BLEZC") || !strcasecmp(op_name, "BLEZC64")) {
1759     if (rs_val <= 0)
1760       target = pc + offset;
1761     else
1762       target = pc + 4;
1763   } else if (!strcasecmp(op_name, "BGEZC") || !strcasecmp(op_name, "BGEZC64")) {
1764     if (rs_val >= 0)
1765       target = pc + offset;
1766     else
1767       target = pc + 4;
1768   } else if (!strcasecmp(op_name, "BGTZC") || !strcasecmp(op_name, "BGTZC64")) {
1769     if (rs_val > 0)
1770       target = pc + offset;
1771     else
1772       target = pc + 4;
1773   } else if (!strcasecmp(op_name, "BEQZC") || !strcasecmp(op_name, "BEQZC64")) {
1774     if (rs_val == 0)
1775       target = pc + offset;
1776     else
1777       target = pc + 4;
1778   } else if (!strcasecmp(op_name, "BNEZC") || !strcasecmp(op_name, "BNEZC64")) {
1779     if (rs_val != 0)
1780       target = pc + offset;
1781     else
1782       target = pc + 4;
1783   }
1784 
1785   Context context;
1786   context.type = eContextRelativeBranchImmediate;
1787   context.SetImmediate(current_inst_size + offset);
1788 
1789   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1790                                target);
1791 }
1792 
1793 bool EmulateInstructionMIPS64::Emulate_J(llvm::MCInst &insn) {
1794   bool success = false;
1795   uint64_t offset, pc;
1796 
1797   /*
1798    * J offset
1799    *      offset = sign_ext (offset << 2)
1800    *      PC = PC[63-28] | offset
1801   */
1802   offset = insn.getOperand(0).getImm();
1803 
1804   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1805   if (!success)
1806     return false;
1807 
1808   /* This is a PC-region branch and not PC-relative */
1809   pc = (pc & 0xFFFFFFFFF0000000ULL) | offset;
1810 
1811   Context context;
1812 
1813   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1814                                pc);
1815 }
1816 
1817 bool EmulateInstructionMIPS64::Emulate_JAL(llvm::MCInst &insn) {
1818   bool success = false;
1819   uint64_t offset, target, pc;
1820 
1821   /*
1822    * JAL offset
1823    *      offset = sign_ext (offset << 2)
1824    *      PC = PC[63-28] | offset
1825   */
1826   offset = insn.getOperand(0).getImm();
1827 
1828   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1829   if (!success)
1830     return false;
1831 
1832   /* This is a PC-region branch and not PC-relative */
1833   target = (pc & 0xFFFFFFFFF0000000ULL) | offset;
1834 
1835   Context context;
1836 
1837   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1838                              target))
1839     return false;
1840 
1841   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1842                              pc + 8))
1843     return false;
1844 
1845   return true;
1846 }
1847 
1848 bool EmulateInstructionMIPS64::Emulate_JALR(llvm::MCInst &insn) {
1849   bool success = false;
1850   uint32_t rs, rt;
1851   uint64_t pc, rs_val;
1852 
1853   /*
1854    * JALR rt, rs
1855    *      GPR[rt] = PC + 8
1856    *      PC = GPR[rs]
1857   */
1858   rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1859   rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1860 
1861   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1862   if (!success)
1863     return false;
1864 
1865   rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0,
1866                                 &success);
1867   if (!success)
1868     return false;
1869 
1870   Context context;
1871 
1872   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1873                              rs_val))
1874     return false;
1875 
1876   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1877                              dwarf_zero_mips64 + rt, pc + 8))
1878     return false;
1879 
1880   return true;
1881 }
1882 
1883 bool EmulateInstructionMIPS64::Emulate_JIALC(llvm::MCInst &insn) {
1884   bool success = false;
1885   uint32_t rt;
1886   int64_t target, offset, pc, rt_val;
1887 
1888   /*
1889    * JIALC rt, offset
1890    *      offset = sign_ext (offset)
1891    *      PC = GPR[rt] + offset
1892    *      RA = PC + 4
1893   */
1894   rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1895   offset = insn.getOperand(1).getImm();
1896 
1897   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1898   if (!success)
1899     return false;
1900 
1901   rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1902                                          dwarf_zero_mips64 + rt, 0, &success);
1903   if (!success)
1904     return false;
1905 
1906   target = rt_val + offset;
1907 
1908   Context context;
1909 
1910   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1911                              target))
1912     return false;
1913 
1914   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1915                              pc + 4))
1916     return false;
1917 
1918   return true;
1919 }
1920 
1921 bool EmulateInstructionMIPS64::Emulate_JIC(llvm::MCInst &insn) {
1922   bool success = false;
1923   uint32_t rt;
1924   int64_t target, offset, rt_val;
1925 
1926   /*
1927    * JIC rt, offset
1928    *      offset = sign_ext (offset)
1929    *      PC = GPR[rt] + offset
1930   */
1931   rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1932   offset = insn.getOperand(1).getImm();
1933 
1934   rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1935                                          dwarf_zero_mips64 + rt, 0, &success);
1936   if (!success)
1937     return false;
1938 
1939   target = rt_val + offset;
1940 
1941   Context context;
1942 
1943   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1944                                target);
1945 }
1946 
1947 bool EmulateInstructionMIPS64::Emulate_JR(llvm::MCInst &insn) {
1948   bool success = false;
1949   uint32_t rs;
1950   uint64_t rs_val;
1951 
1952   /*
1953    * JR rs
1954    *      PC = GPR[rs]
1955   */
1956   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1957 
1958   rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0,
1959                                 &success);
1960   if (!success)
1961     return false;
1962 
1963   Context context;
1964 
1965   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1966                                rs_val);
1967 }
1968 
1969 /*
1970     Emulate Branch on FP True/False
1971     BC1F, BC1FL :   Branch on FP False (L stands for branch likely)
1972     BC1T, BC1TL :   Branch on FP True  (L stands for branch likely)
1973 */
1974 bool EmulateInstructionMIPS64::Emulate_FP_branch(llvm::MCInst &insn) {
1975   bool success = false;
1976   uint32_t cc, fcsr;
1977   int64_t pc, offset, target = 0;
1978   const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1979 
1980   /*
1981    * BC1F cc, offset
1982    *  condition <- (FPConditionCode(cc) == 0)
1983    *      if condition then
1984    *          offset = sign_ext (offset)
1985    *          PC = PC + offset
1986   */
1987   cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1988   offset = insn.getOperand(1).getImm();
1989 
1990   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1991   if (!success)
1992     return false;
1993 
1994   fcsr =
1995       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64, 0, &success);
1996   if (!success)
1997     return false;
1998 
1999   /* fcsr[23], fcsr[25-31] are vaild condition bits */
2000   fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2001 
2002   if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
2003     if ((fcsr & (1 << cc)) == 0)
2004       target = pc + offset;
2005     else
2006       target = pc + 8;
2007   } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
2008     if ((fcsr & (1 << cc)) != 0)
2009       target = pc + offset;
2010     else
2011       target = pc + 8;
2012   }
2013 
2014   Context context;
2015 
2016   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2017                                target);
2018 }
2019 
2020 bool EmulateInstructionMIPS64::Emulate_BC1EQZ(llvm::MCInst &insn) {
2021   bool success = false;
2022   uint32_t ft;
2023   uint64_t ft_val;
2024   int64_t target, pc, offset;
2025 
2026   /*
2027    * BC1EQZ ft, offset
2028    *  condition <- (FPR[ft].bit0 == 0)
2029    *      if condition then
2030    *          offset = sign_ext (offset)
2031    *          PC = PC + 4 + offset
2032   */
2033   ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2034   offset = insn.getOperand(1).getImm();
2035 
2036   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2037   if (!success)
2038     return false;
2039 
2040   ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0,
2041                                 &success);
2042   if (!success)
2043     return false;
2044 
2045   if ((ft_val & 1) == 0)
2046     target = pc + 4 + offset;
2047   else
2048     target = pc + 8;
2049 
2050   Context context;
2051 
2052   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2053                                target);
2054 }
2055 
2056 bool EmulateInstructionMIPS64::Emulate_BC1NEZ(llvm::MCInst &insn) {
2057   bool success = false;
2058   uint32_t ft;
2059   uint64_t ft_val;
2060   int64_t target, pc, offset;
2061 
2062   /*
2063    * BC1NEZ ft, offset
2064    *  condition <- (FPR[ft].bit0 != 0)
2065    *      if condition then
2066    *          offset = sign_ext (offset)
2067    *          PC = PC + 4 + offset
2068   */
2069   ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2070   offset = insn.getOperand(1).getImm();
2071 
2072   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2073   if (!success)
2074     return false;
2075 
2076   ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0,
2077                                 &success);
2078   if (!success)
2079     return false;
2080 
2081   if ((ft_val & 1) != 0)
2082     target = pc + 4 + offset;
2083   else
2084     target = pc + 8;
2085 
2086   Context context;
2087 
2088   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2089                                target);
2090 }
2091 
2092 /*
2093     Emulate MIPS-3D Branch instructions
2094     BC1ANY2F, BC1ANY2T  : Branch on Any of Two Floating Point Condition Codes
2095    False/True
2096     BC1ANY4F, BC1ANY4T  : Branch on Any of Four Floating Point Condition Codes
2097    False/True
2098 */
2099 bool EmulateInstructionMIPS64::Emulate_3D_branch(llvm::MCInst &insn) {
2100   bool success = false;
2101   uint32_t cc, fcsr;
2102   int64_t pc, offset, target = 0;
2103   const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2104 
2105   cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2106   offset = insn.getOperand(1).getImm();
2107 
2108   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2109   if (!success)
2110     return false;
2111 
2112   fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64,
2113                                         0, &success);
2114   if (!success)
2115     return false;
2116 
2117   /* fcsr[23], fcsr[25-31] are vaild condition bits */
2118   fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2119 
2120   if (!strcasecmp(op_name, "BC1ANY2F")) {
2121     /* if any one bit is 0 */
2122     if (((fcsr >> cc) & 3) != 3)
2123       target = pc + offset;
2124     else
2125       target = pc + 8;
2126   } else if (!strcasecmp(op_name, "BC1ANY2T")) {
2127     /* if any one bit is 1 */
2128     if (((fcsr >> cc) & 3) != 0)
2129       target = pc + offset;
2130     else
2131       target = pc + 8;
2132   } else if (!strcasecmp(op_name, "BC1ANY4F")) {
2133     /* if any one bit is 0 */
2134     if (((fcsr >> cc) & 0xf) != 0xf)
2135       target = pc + offset;
2136     else
2137       target = pc + 8;
2138   } else if (!strcasecmp(op_name, "BC1ANY4T")) {
2139     /* if any one bit is 1 */
2140     if (((fcsr >> cc) & 0xf) != 0)
2141       target = pc + offset;
2142     else
2143       target = pc + 8;
2144   }
2145 
2146   Context context;
2147 
2148   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2149                                target);
2150 }
2151 
2152 bool EmulateInstructionMIPS64::Emulate_BNZB(llvm::MCInst &insn) {
2153   return Emulate_MSA_Branch_DF(insn, 1, true);
2154 }
2155 
2156 bool EmulateInstructionMIPS64::Emulate_BNZH(llvm::MCInst &insn) {
2157   return Emulate_MSA_Branch_DF(insn, 2, true);
2158 }
2159 
2160 bool EmulateInstructionMIPS64::Emulate_BNZW(llvm::MCInst &insn) {
2161   return Emulate_MSA_Branch_DF(insn, 4, true);
2162 }
2163 
2164 bool EmulateInstructionMIPS64::Emulate_BNZD(llvm::MCInst &insn) {
2165   return Emulate_MSA_Branch_DF(insn, 8, true);
2166 }
2167 
2168 bool EmulateInstructionMIPS64::Emulate_BZB(llvm::MCInst &insn) {
2169   return Emulate_MSA_Branch_DF(insn, 1, false);
2170 }
2171 
2172 bool EmulateInstructionMIPS64::Emulate_BZH(llvm::MCInst &insn) {
2173   return Emulate_MSA_Branch_DF(insn, 2, false);
2174 }
2175 
2176 bool EmulateInstructionMIPS64::Emulate_BZW(llvm::MCInst &insn) {
2177   return Emulate_MSA_Branch_DF(insn, 4, false);
2178 }
2179 
2180 bool EmulateInstructionMIPS64::Emulate_BZD(llvm::MCInst &insn) {
2181   return Emulate_MSA_Branch_DF(insn, 8, false);
2182 }
2183 
2184 bool EmulateInstructionMIPS64::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
2185                                                      int element_byte_size,
2186                                                      bool bnz) {
2187   bool success = false, branch_hit = true;
2188   int64_t target = 0;
2189   RegisterValue reg_value;
2190   const uint8_t *ptr = nullptr;
2191 
2192   uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2193   int64_t offset = insn.getOperand(1).getImm();
2194 
2195   int64_t pc =
2196       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2197   if (!success)
2198     return false;
2199 
2200   if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
2201     ptr = (const uint8_t *)reg_value.GetBytes();
2202   else
2203     return false;
2204 
2205   for (int i = 0; i < 16 / element_byte_size; i++) {
2206     switch (element_byte_size) {
2207     case 1:
2208       if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2209         branch_hit = false;
2210       break;
2211     case 2:
2212       if ((*(const uint16_t *)ptr == 0 && bnz) ||
2213           (*(const uint16_t *)ptr != 0 && !bnz))
2214         branch_hit = false;
2215       break;
2216     case 4:
2217       if ((*(const uint32_t *)ptr == 0 && bnz) ||
2218           (*(const uint32_t *)ptr != 0 && !bnz))
2219         branch_hit = false;
2220       break;
2221     case 8:
2222       if ((*(const uint64_t *)ptr == 0 && bnz) ||
2223           (*(const uint64_t *)ptr != 0 && !bnz))
2224         branch_hit = false;
2225       break;
2226     }
2227     if (!branch_hit)
2228       break;
2229     ptr = ptr + element_byte_size;
2230   }
2231 
2232   if (branch_hit)
2233     target = pc + offset;
2234   else
2235     target = pc + 8;
2236 
2237   Context context;
2238   context.type = eContextRelativeBranchImmediate;
2239 
2240   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2241                                target);
2242 }
2243 
2244 bool EmulateInstructionMIPS64::Emulate_BNZV(llvm::MCInst &insn) {
2245   return Emulate_MSA_Branch_V(insn, true);
2246 }
2247 
2248 bool EmulateInstructionMIPS64::Emulate_BZV(llvm::MCInst &insn) {
2249   return Emulate_MSA_Branch_V(insn, false);
2250 }
2251 
2252 bool EmulateInstructionMIPS64::Emulate_MSA_Branch_V(llvm::MCInst &insn,
2253                                                     bool bnz) {
2254   bool success = false;
2255   int64_t target = 0;
2256   llvm::APInt wr_val = llvm::APInt::getNullValue(128);
2257   llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
2258   llvm::APInt zero_value = llvm::APInt::getNullValue(128);
2259   RegisterValue reg_value;
2260 
2261   uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2262   int64_t offset = insn.getOperand(1).getImm();
2263 
2264   int64_t pc =
2265       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2266   if (!success)
2267     return false;
2268 
2269   if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
2270     wr_val = reg_value.GetAsUInt128(fail_value);
2271   else
2272     return false;
2273 
2274   if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
2275       (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2276     target = pc + offset;
2277   else
2278     target = pc + 8;
2279 
2280   Context context;
2281   context.type = eContextRelativeBranchImmediate;
2282 
2283   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2284                                target);
2285 }
2286 
2287 bool EmulateInstructionMIPS64::Emulate_LDST_Imm(llvm::MCInst &insn) {
2288   bool success = false;
2289   uint32_t base;
2290   int64_t imm, address;
2291   Context bad_vaddr_context;
2292 
2293   uint32_t num_operands = insn.getNumOperands();
2294   base =
2295       m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2296   imm = insn.getOperand(num_operands - 1).getImm();
2297 
2298   RegisterInfo reg_info_base;
2299   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
2300                        reg_info_base))
2301     return false;
2302 
2303   /* read base register */
2304   address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
2305                                  &success);
2306   if (!success)
2307     return false;
2308 
2309   /* destination address */
2310   address = address + imm;
2311 
2312   /* Set the bad_vaddr register with base address used in the instruction */
2313   bad_vaddr_context.type = eContextInvalid;
2314   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
2315                         address);
2316 
2317   return true;
2318 }
2319 
2320 bool EmulateInstructionMIPS64::Emulate_LDST_Reg(llvm::MCInst &insn) {
2321   bool success = false;
2322   uint32_t base, index;
2323   int64_t address, index_address;
2324   Context bad_vaddr_context;
2325 
2326   uint32_t num_operands = insn.getNumOperands();
2327   base =
2328       m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2329   index =
2330       m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
2331 
2332   RegisterInfo reg_info_base, reg_info_index;
2333   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
2334                        reg_info_base))
2335     return false;
2336 
2337   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
2338                        reg_info_index))
2339     return false;
2340 
2341   /* read base register */
2342   address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
2343                                  &success);
2344   if (!success)
2345     return false;
2346 
2347   /* read index register */
2348   index_address = ReadRegisterUnsigned(eRegisterKindDWARF,
2349                                        dwarf_zero_mips + index, 0, &success);
2350   if (!success)
2351     return false;
2352 
2353   /* destination address */
2354   address = address + index_address;
2355 
2356   /* Set the bad_vaddr register with base address used in the instruction */
2357   bad_vaddr_context.type = eContextInvalid;
2358   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
2359                         address);
2360 
2361   return true;
2362 }
2363