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