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