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(llvm::StringRef 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   for (MipsOpcode &opcode : g_opcodes) {
923     if (op_name.equals_insensitive(opcode.op_name))
924       return &opcode;
925   }
926   return nullptr;
927 }
928 
929 bool EmulateInstructionMIPS64::ReadInstruction() {
930   bool success = false;
931   m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
932                                 LLDB_INVALID_ADDRESS, &success);
933   if (success) {
934     Context read_inst_context;
935     read_inst_context.type = eContextReadOpcode;
936     read_inst_context.SetNoArgs();
937     m_opcode.SetOpcode32(
938         ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
939         GetByteOrder());
940   }
941   if (!success)
942     m_addr = LLDB_INVALID_ADDRESS;
943   return success;
944 }
945 
946 bool EmulateInstructionMIPS64::EvaluateInstruction(uint32_t evaluate_options) {
947   bool success = false;
948   llvm::MCInst mc_insn;
949   uint64_t insn_size;
950   DataExtractor data;
951 
952   /* Keep the complexity of the decode logic with the llvm::MCDisassembler
953    * class. */
954   if (m_opcode.GetData(data)) {
955     llvm::MCDisassembler::DecodeStatus decode_status;
956     llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
957     decode_status = m_disasm->getInstruction(mc_insn, insn_size, raw_insn,
958                                              m_addr, llvm::nulls());
959     if (decode_status != llvm::MCDisassembler::Success)
960       return false;
961   }
962 
963   /*
964    * mc_insn.getOpcode() returns decoded opcode. However to make use
965    * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
966   */
967   llvm::StringRef op_name = m_insn_info->getName(mc_insn.getOpcode());
968 
969   /*
970    * Decoding has been done already. Just get the call-back function
971    * and emulate the instruction.
972   */
973   MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
974 
975   if (opcode_data == nullptr)
976     return false;
977 
978   uint64_t old_pc = 0, new_pc = 0;
979   const bool auto_advance_pc =
980       evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
981 
982   if (auto_advance_pc) {
983     old_pc =
984         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
985     if (!success)
986       return false;
987   }
988 
989   /* emulate instruction */
990   success = (this->*opcode_data->callback)(mc_insn);
991   if (!success)
992     return false;
993 
994   if (auto_advance_pc) {
995     new_pc =
996         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
997     if (!success)
998       return false;
999 
1000     /* If we haven't changed the PC, change it here */
1001     if (old_pc == new_pc) {
1002       new_pc += 4;
1003       Context context;
1004       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1005                                  new_pc))
1006         return false;
1007     }
1008   }
1009 
1010   return true;
1011 }
1012 
1013 bool EmulateInstructionMIPS64::CreateFunctionEntryUnwind(
1014     UnwindPlan &unwind_plan) {
1015   unwind_plan.Clear();
1016   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1017 
1018   UnwindPlan::RowSP row(new UnwindPlan::Row);
1019   const bool can_replace = false;
1020 
1021   // Our previous Call Frame Address is the stack pointer
1022   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips64, 0);
1023 
1024   // Our previous PC is in the RA
1025   row->SetRegisterLocationToRegister(dwarf_pc_mips64, dwarf_ra_mips64,
1026                                      can_replace);
1027 
1028   unwind_plan.AppendRow(row);
1029 
1030   // All other registers are the same.
1031   unwind_plan.SetSourceName("EmulateInstructionMIPS64");
1032   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1033   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1034   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1035   unwind_plan.SetReturnAddressRegister(dwarf_ra_mips64);
1036 
1037   return true;
1038 }
1039 
1040 bool EmulateInstructionMIPS64::nonvolatile_reg_p(uint64_t regnum) {
1041   switch (regnum) {
1042   case dwarf_r16_mips64:
1043   case dwarf_r17_mips64:
1044   case dwarf_r18_mips64:
1045   case dwarf_r19_mips64:
1046   case dwarf_r20_mips64:
1047   case dwarf_r21_mips64:
1048   case dwarf_r22_mips64:
1049   case dwarf_r23_mips64:
1050   case dwarf_gp_mips64:
1051   case dwarf_sp_mips64:
1052   case dwarf_r30_mips64:
1053   case dwarf_ra_mips64:
1054     return true;
1055   default:
1056     return false;
1057   }
1058   return false;
1059 }
1060 
1061 bool EmulateInstructionMIPS64::Emulate_DADDiu(llvm::MCInst &insn) {
1062   // DADDIU rt, rs, immediate
1063   // GPR[rt] <- GPR[rs] + sign_extend(immediate)
1064 
1065   uint8_t dst, src;
1066   bool success = false;
1067   const uint32_t imm16 = insn.getOperand(2).getImm();
1068   int64_t imm = SignedBits(imm16, 15, 0);
1069 
1070   dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1071   src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1072 
1073   // If immediate is greater than 2^16 - 1 then clang generate LUI,
1074   // (D)ADDIU,(D)SUBU instructions in prolog. Example lui    $1, 0x2 daddiu $1,
1075   // $1, -0x5920 dsubu  $sp, $sp, $1 In this case, (D)ADDIU dst and src will be
1076   // same and not equal to sp
1077   if (dst == src) {
1078     Context context;
1079 
1080     /* read <src> register */
1081     const uint64_t src_opd_val = ReadRegisterUnsigned(
1082         eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
1083     if (!success)
1084       return false;
1085 
1086     /* Check if this is daddiu sp, sp, imm16 */
1087     if (dst == dwarf_sp_mips64) {
1088       /*
1089        * From the MIPS IV spec:
1090        *
1091        * The term “unsigned” in the instruction name is a misnomer; this
1092        * operation is 64-bit modulo arithmetic that does not trap on overflow.
1093        * It is appropriate for arithmetic which is not signed, such as address
1094        * arithmetic, or integer arithmetic environments that ignore overflow,
1095        * such as “C” language arithmetic.
1096        *
1097        * Assume 2's complement and rely on unsigned overflow here.
1098        */
1099       uint64_t result = src_opd_val + imm;
1100       RegisterInfo reg_info_sp;
1101 
1102       if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
1103         context.SetRegisterPlusOffset(reg_info_sp, imm);
1104 
1105       /* We are allocating bytes on stack */
1106       context.type = eContextAdjustStackPointer;
1107 
1108       WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64,
1109                             result);
1110       return true;
1111     }
1112 
1113     imm += src_opd_val;
1114     context.SetImmediateSigned(imm);
1115     context.type = eContextImmediate;
1116 
1117     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1118                                dwarf_zero_mips64 + dst, imm))
1119       return false;
1120   }
1121 
1122   return true;
1123 }
1124 
1125 bool EmulateInstructionMIPS64::Emulate_SD(llvm::MCInst &insn) {
1126   uint64_t address;
1127   RegisterInfo reg_info_base;
1128   RegisterInfo reg_info_src;
1129   bool success = false;
1130   uint32_t imm16 = insn.getOperand(2).getImm();
1131   uint64_t imm = SignedBits(imm16, 15, 0);
1132   uint32_t src, base;
1133   Context bad_vaddr_context;
1134 
1135   src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1136   base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1137 
1138   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1139                        reg_info_base) ||
1140       !GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src,
1141                        reg_info_src))
1142     return false;
1143 
1144   /* read SP */
1145   address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1146                                  0, &success);
1147   if (!success)
1148     return false;
1149 
1150   /* destination address */
1151   address = address + imm;
1152 
1153   /* We look for sp based non-volatile register stores */
1154   if (nonvolatile_reg_p(src)) {
1155     Context context;
1156     RegisterValue data_src;
1157     context.type = eContextPushRegisterOnStack;
1158     context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1159 
1160     uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1161     Status error;
1162 
1163     if (!ReadRegister(&reg_info_base, data_src))
1164       return false;
1165 
1166     if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
1167                                  eByteOrderLittle, error) == 0)
1168       return false;
1169 
1170     if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1171       return false;
1172   }
1173 
1174   /* Set the bad_vaddr register with base address used in the instruction */
1175   bad_vaddr_context.type = eContextInvalid;
1176   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64,
1177                         address);
1178 
1179   return true;
1180 }
1181 
1182 bool EmulateInstructionMIPS64::Emulate_LD(llvm::MCInst &insn) {
1183   bool success = false;
1184   uint32_t src, base;
1185   int64_t imm, address;
1186   Context bad_vaddr_context;
1187 
1188   src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1189   base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1190   imm = insn.getOperand(2).getImm();
1191 
1192   RegisterInfo reg_info_base;
1193   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1194                        reg_info_base))
1195     return false;
1196 
1197   /* read base register */
1198   address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base,
1199                                  0, &success);
1200   if (!success)
1201     return false;
1202 
1203   /* destination address */
1204   address = address + imm;
1205 
1206   /* Set the bad_vaddr register with base address used in the instruction */
1207   bad_vaddr_context.type = eContextInvalid;
1208   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64,
1209                         address);
1210 
1211   if (nonvolatile_reg_p(src)) {
1212     RegisterValue data_src;
1213     RegisterInfo reg_info_src;
1214 
1215     if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src,
1216                          reg_info_src))
1217       return false;
1218 
1219     Context context;
1220     context.type = eContextRegisterLoad;
1221 
1222     return WriteRegister(context, &reg_info_src, data_src);
1223   }
1224 
1225   return false;
1226 }
1227 
1228 bool EmulateInstructionMIPS64::Emulate_LUI(llvm::MCInst &insn) {
1229   // LUI rt, immediate
1230   // GPR[rt] <- sign_extend(immediate << 16)
1231 
1232   const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1233   int64_t imm = SignedBits(imm32, 31, 0);
1234   uint8_t rt;
1235   Context context;
1236 
1237   rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1238   context.SetImmediateSigned(imm);
1239   context.type = eContextImmediate;
1240 
1241   return WriteRegisterUnsigned(context, eRegisterKindDWARF,
1242                                dwarf_zero_mips64 + rt, imm);
1243 }
1244 
1245 bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) {
1246   // DSUBU sp, <src>, <rt>
1247   // DADDU sp, <src>, <rt>
1248   // DADDU dst, sp, <rt>
1249 
1250   bool success = false;
1251   uint64_t result;
1252   uint8_t src, dst, rt;
1253   llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1254 
1255   dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1256   src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1257 
1258   /* Check if sp is destination register */
1259   if (dst == dwarf_sp_mips64) {
1260     rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1261 
1262     /* read <src> register */
1263     uint64_t src_opd_val = ReadRegisterUnsigned(
1264         eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
1265     if (!success)
1266       return false;
1267 
1268     /* read <rt > register */
1269     uint64_t rt_opd_val = ReadRegisterUnsigned(
1270         eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
1271     if (!success)
1272       return false;
1273 
1274     if (op_name.equals_insensitive("DSUBU") ||
1275         op_name.equals_insensitive("SUBU"))
1276       result = src_opd_val - rt_opd_val;
1277     else
1278       result = src_opd_val + rt_opd_val;
1279 
1280     Context context;
1281     RegisterInfo reg_info_sp;
1282     if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
1283       context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
1284 
1285     /* We are allocating bytes on stack */
1286     context.type = eContextAdjustStackPointer;
1287 
1288     WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64, result);
1289 
1290     return true;
1291   } else if (src == dwarf_sp_mips64) {
1292     rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1293 
1294     /* read <src> register */
1295     uint64_t src_opd_val = ReadRegisterUnsigned(
1296         eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
1297     if (!success)
1298       return false;
1299 
1300     /* read <rt> register */
1301     uint64_t rt_opd_val = ReadRegisterUnsigned(
1302         eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
1303     if (!success)
1304       return false;
1305 
1306     Context context;
1307 
1308     if (op_name.equals_insensitive("DSUBU") ||
1309         op_name.equals_insensitive("SUBU"))
1310       result = src_opd_val - rt_opd_val;
1311     else
1312       result = src_opd_val + rt_opd_val;
1313 
1314     context.SetImmediateSigned(result);
1315     context.type = eContextImmediate;
1316 
1317     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1318                                dwarf_zero_mips64 + dst, result))
1319       return false;
1320   }
1321 
1322   return true;
1323 }
1324 
1325 /*
1326     Emulate below MIPS branch instructions.
1327     BEQ, BNE : Branch on condition
1328     BEQL, BNEL : Branch likely
1329 */
1330 bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) {
1331   bool success = false;
1332   uint32_t rs, rt;
1333   int64_t offset, pc, rs_val, rt_val, target = 0;
1334   llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1335 
1336   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1337   rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1338   offset = insn.getOperand(2).getImm();
1339 
1340   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1341   if (!success)
1342     return false;
1343 
1344   rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1345                                          dwarf_zero_mips64 + rs, 0, &success);
1346   if (!success)
1347     return false;
1348 
1349   rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1350                                          dwarf_zero_mips64 + rt, 0, &success);
1351   if (!success)
1352     return false;
1353 
1354   if (op_name.equals_insensitive("BEQ") || op_name.equals_insensitive("BEQL") ||
1355       op_name.equals_insensitive("BEQ64")) {
1356     if (rs_val == rt_val)
1357       target = pc + offset;
1358     else
1359       target = pc + 8;
1360   } else if (op_name.equals_insensitive("BNE") ||
1361              op_name.equals_insensitive("BNEL") ||
1362              op_name.equals_insensitive("BNE64")) {
1363     if (rs_val != rt_val)
1364       target = pc + offset;
1365     else
1366       target = pc + 8;
1367   }
1368 
1369   Context context;
1370   context.type = eContextRelativeBranchImmediate;
1371   context.SetImmediate(offset);
1372 
1373   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1374                                target);
1375 }
1376 
1377 /*
1378     Emulate below MIPS Non-Compact conditional branch and link instructions.
1379     BLTZAL, BGEZAL      :
1380     BLTZALL, BGEZALL    : Branch likely
1381 */
1382 bool EmulateInstructionMIPS64::Emulate_Bcond_Link(llvm::MCInst &insn) {
1383   bool success = false;
1384   uint32_t rs;
1385   int64_t offset, pc, target = 0;
1386   int64_t rs_val;
1387   llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1388 
1389   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1390   offset = insn.getOperand(1).getImm();
1391 
1392   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1393   if (!success)
1394     return false;
1395 
1396   rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1397                                          dwarf_zero_mips64 + rs, 0, &success);
1398   if (!success)
1399     return false;
1400 
1401   if (op_name.equals_insensitive("BLTZAL") ||
1402       op_name.equals_insensitive("BLTZALL")) {
1403     if (rs_val < 0)
1404       target = pc + offset;
1405     else
1406       target = pc + 8;
1407   } else if (op_name.equals_insensitive("BGEZAL") ||
1408              op_name.equals_insensitive("BGEZALL")) {
1409     if (rs_val >= 0)
1410       target = pc + offset;
1411     else
1412       target = pc + 8;
1413   }
1414 
1415   Context context;
1416 
1417   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1418                              target))
1419     return false;
1420 
1421   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1422                              pc + 8))
1423     return false;
1424 
1425   return true;
1426 }
1427 
1428 bool EmulateInstructionMIPS64::Emulate_BAL(llvm::MCInst &insn) {
1429   bool success = false;
1430   int64_t offset, pc, target;
1431 
1432   /*
1433    * BAL offset
1434    *      offset = sign_ext (offset << 2)
1435    *      RA = PC + 8
1436    *      PC = PC + offset
1437   */
1438   offset = insn.getOperand(0).getImm();
1439 
1440   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1441   if (!success)
1442     return false;
1443 
1444   target = pc + offset;
1445 
1446   Context context;
1447 
1448   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1449                              target))
1450     return false;
1451 
1452   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1453                              pc + 8))
1454     return false;
1455 
1456   return true;
1457 }
1458 
1459 bool EmulateInstructionMIPS64::Emulate_BALC(llvm::MCInst &insn) {
1460   bool success = false;
1461   int64_t offset, pc, target;
1462 
1463   /*
1464    * BALC offset
1465    *      offset = sign_ext (offset << 2)
1466    *      RA = PC + 4
1467    *      PC = PC + 4 + offset
1468   */
1469   offset = insn.getOperand(0).getImm();
1470 
1471   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1472   if (!success)
1473     return false;
1474 
1475   target = pc + offset;
1476 
1477   Context context;
1478 
1479   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1480                              target))
1481     return false;
1482 
1483   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1484                              pc + 4))
1485     return false;
1486 
1487   return true;
1488 }
1489 
1490 /*
1491     Emulate below MIPS conditional branch and link instructions.
1492     BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1493 */
1494 bool EmulateInstructionMIPS64::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
1495   bool success = false;
1496   uint32_t rs;
1497   int64_t offset, pc, rs_val, target = 0;
1498   llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1499 
1500   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1501   offset = insn.getOperand(1).getImm();
1502 
1503   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1504   if (!success)
1505     return false;
1506 
1507   rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1508                                          dwarf_zero_mips64 + rs, 0, &success);
1509   if (!success)
1510     return false;
1511 
1512   if (op_name.equals_insensitive("BLEZALC")) {
1513     if (rs_val <= 0)
1514       target = pc + offset;
1515     else
1516       target = pc + 4;
1517   } else if (op_name.equals_insensitive("BGEZALC")) {
1518     if (rs_val >= 0)
1519       target = pc + offset;
1520     else
1521       target = pc + 4;
1522   } else if (op_name.equals_insensitive("BLTZALC")) {
1523     if (rs_val < 0)
1524       target = pc + offset;
1525     else
1526       target = pc + 4;
1527   } else if (op_name.equals_insensitive("BGTZALC")) {
1528     if (rs_val > 0)
1529       target = pc + offset;
1530     else
1531       target = pc + 4;
1532   } else if (op_name.equals_insensitive("BEQZALC")) {
1533     if (rs_val == 0)
1534       target = pc + offset;
1535     else
1536       target = pc + 4;
1537   } else if (op_name.equals_insensitive("BNEZALC")) {
1538     if (rs_val != 0)
1539       target = pc + offset;
1540     else
1541       target = pc + 4;
1542   }
1543 
1544   Context context;
1545 
1546   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1547                              target))
1548     return false;
1549 
1550   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1551                              pc + 4))
1552     return false;
1553 
1554   return true;
1555 }
1556 
1557 /*
1558     Emulate below MIPS branch instructions.
1559     BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
1560     BLTZ, BGEZ, BGTZ, BLEZ     : Non-compact branches
1561 */
1562 bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) {
1563   bool success = false;
1564   uint32_t rs;
1565   int64_t offset, pc, rs_val, target = 0;
1566   llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1567 
1568   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1569   offset = insn.getOperand(1).getImm();
1570 
1571   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1572   if (!success)
1573     return false;
1574 
1575   rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1576                                          dwarf_zero_mips64 + rs, 0, &success);
1577   if (!success)
1578     return false;
1579 
1580   if (op_name.equals_insensitive("BLTZL") ||
1581       op_name.equals_insensitive("BLTZ") ||
1582       op_name.equals_insensitive("BLTZ64")) {
1583     if (rs_val < 0)
1584       target = pc + offset;
1585     else
1586       target = pc + 8;
1587   } else if (op_name.equals_insensitive("BGEZL") ||
1588              op_name.equals_insensitive("BGEZ") ||
1589              op_name.equals_insensitive("BGEZ64")) {
1590     if (rs_val >= 0)
1591       target = pc + offset;
1592     else
1593       target = pc + 8;
1594   } else if (op_name.equals_insensitive("BGTZL") ||
1595              op_name.equals_insensitive("BGTZ") ||
1596              op_name.equals_insensitive("BGTZ64")) {
1597     if (rs_val > 0)
1598       target = pc + offset;
1599     else
1600       target = pc + 8;
1601   } else if (op_name.equals_insensitive("BLEZL") ||
1602              op_name.equals_insensitive("BLEZ") ||
1603              op_name.equals_insensitive("BLEZ64")) {
1604     if (rs_val <= 0)
1605       target = pc + offset;
1606     else
1607       target = pc + 8;
1608   }
1609 
1610   Context context;
1611   context.type = eContextRelativeBranchImmediate;
1612   context.SetImmediate(offset);
1613 
1614   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1615                                target);
1616 }
1617 
1618 bool EmulateInstructionMIPS64::Emulate_BC(llvm::MCInst &insn) {
1619   bool success = false;
1620   int64_t offset, pc, target;
1621 
1622   /*
1623    * BC offset
1624    *      offset = sign_ext (offset << 2)
1625    *      PC = PC + 4 + offset
1626   */
1627   offset = insn.getOperand(0).getImm();
1628 
1629   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1630   if (!success)
1631     return false;
1632 
1633   target = pc + offset;
1634 
1635   Context context;
1636 
1637   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1638                                target);
1639 }
1640 
1641 static int IsAdd64bitOverflow(int64_t a, int64_t b) {
1642   int64_t r = (uint64_t)a + (uint64_t)b;
1643   return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1644 }
1645 
1646 /*
1647     Emulate below MIPS branch instructions.
1648     BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
1649    instructions with no delay slot
1650 */
1651 bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
1652   bool success = false;
1653   uint32_t rs, rt;
1654   int64_t offset, pc, rs_val, rt_val, target = 0;
1655   llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1656   uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1657 
1658   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1659   rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1660   offset = insn.getOperand(2).getImm();
1661 
1662   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1663   if (!success)
1664     return false;
1665 
1666   rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1667                                          dwarf_zero_mips64 + rs, 0, &success);
1668   if (!success)
1669     return false;
1670 
1671   rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1672                                          dwarf_zero_mips64 + rt, 0, &success);
1673   if (!success)
1674     return false;
1675 
1676   if (op_name.equals_insensitive("BEQC") ||
1677       op_name.equals_insensitive("BEQC64")) {
1678     if (rs_val == rt_val)
1679       target = pc + offset;
1680     else
1681       target = pc + 4;
1682   } else if (op_name.equals_insensitive("BNEC") ||
1683              op_name.equals_insensitive("BNEC64")) {
1684     if (rs_val != rt_val)
1685       target = pc + offset;
1686     else
1687       target = pc + 4;
1688   } else if (op_name.equals_insensitive("BLTC") ||
1689              op_name.equals_insensitive("BLTC64")) {
1690     if (rs_val < rt_val)
1691       target = pc + offset;
1692     else
1693       target = pc + 4;
1694   } else if (op_name.equals_insensitive("BGEC64") ||
1695              op_name.equals_insensitive("BGEC")) {
1696     if (rs_val >= rt_val)
1697       target = pc + offset;
1698     else
1699       target = pc + 4;
1700   } else if (op_name.equals_insensitive("BLTUC") ||
1701              op_name.equals_insensitive("BLTUC64")) {
1702     if (rs_val < rt_val)
1703       target = pc + offset;
1704     else
1705       target = pc + 4;
1706   } else if (op_name.equals_insensitive("BGEUC") ||
1707              op_name.equals_insensitive("BGEUC64")) {
1708     if ((uint32_t)rs_val >= (uint32_t)rt_val)
1709       target = pc + offset;
1710     else
1711       target = pc + 4;
1712   } else if (op_name.equals_insensitive("BOVC")) {
1713     if (IsAdd64bitOverflow(rs_val, rt_val))
1714       target = pc + offset;
1715     else
1716       target = pc + 4;
1717   } else if (op_name.equals_insensitive("BNVC")) {
1718     if (!IsAdd64bitOverflow(rs_val, rt_val))
1719       target = pc + offset;
1720     else
1721       target = pc + 4;
1722   }
1723 
1724   Context context;
1725   context.type = eContextRelativeBranchImmediate;
1726   context.SetImmediate(current_inst_size + offset);
1727 
1728   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1729                                target);
1730 }
1731 
1732 /*
1733     Emulate below MIPS branch instructions.
1734     BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
1735 */
1736 bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
1737   bool success = false;
1738   uint32_t rs;
1739   int64_t offset, pc, target = 0;
1740   int64_t rs_val;
1741   llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1742   uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1743 
1744   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1745   offset = insn.getOperand(1).getImm();
1746 
1747   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1748   if (!success)
1749     return false;
1750 
1751   rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1752                                          dwarf_zero_mips64 + rs, 0, &success);
1753   if (!success)
1754     return false;
1755 
1756   if (op_name.equals_insensitive("BLTZC") ||
1757       op_name.equals_insensitive("BLTZC64")) {
1758     if (rs_val < 0)
1759       target = pc + offset;
1760     else
1761       target = pc + 4;
1762   } else if (op_name.equals_insensitive("BLEZC") ||
1763              op_name.equals_insensitive("BLEZC64")) {
1764     if (rs_val <= 0)
1765       target = pc + offset;
1766     else
1767       target = pc + 4;
1768   } else if (op_name.equals_insensitive("BGEZC") ||
1769              op_name.equals_insensitive("BGEZC64")) {
1770     if (rs_val >= 0)
1771       target = pc + offset;
1772     else
1773       target = pc + 4;
1774   } else if (op_name.equals_insensitive("BGTZC") ||
1775              op_name.equals_insensitive("BGTZC64")) {
1776     if (rs_val > 0)
1777       target = pc + offset;
1778     else
1779       target = pc + 4;
1780   } else if (op_name.equals_insensitive("BEQZC") ||
1781              op_name.equals_insensitive("BEQZC64")) {
1782     if (rs_val == 0)
1783       target = pc + offset;
1784     else
1785       target = pc + 4;
1786   } else if (op_name.equals_insensitive("BNEZC") ||
1787              op_name.equals_insensitive("BNEZC64")) {
1788     if (rs_val != 0)
1789       target = pc + offset;
1790     else
1791       target = pc + 4;
1792   }
1793 
1794   Context context;
1795   context.type = eContextRelativeBranchImmediate;
1796   context.SetImmediate(current_inst_size + offset);
1797 
1798   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1799                                target);
1800 }
1801 
1802 bool EmulateInstructionMIPS64::Emulate_J(llvm::MCInst &insn) {
1803   bool success = false;
1804   uint64_t offset, pc;
1805 
1806   /*
1807    * J offset
1808    *      offset = sign_ext (offset << 2)
1809    *      PC = PC[63-28] | offset
1810   */
1811   offset = insn.getOperand(0).getImm();
1812 
1813   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1814   if (!success)
1815     return false;
1816 
1817   /* This is a PC-region branch and not PC-relative */
1818   pc = (pc & 0xFFFFFFFFF0000000ULL) | offset;
1819 
1820   Context context;
1821 
1822   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1823                                pc);
1824 }
1825 
1826 bool EmulateInstructionMIPS64::Emulate_JAL(llvm::MCInst &insn) {
1827   bool success = false;
1828   uint64_t offset, target, pc;
1829 
1830   /*
1831    * JAL offset
1832    *      offset = sign_ext (offset << 2)
1833    *      PC = PC[63-28] | offset
1834   */
1835   offset = insn.getOperand(0).getImm();
1836 
1837   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1838   if (!success)
1839     return false;
1840 
1841   /* This is a PC-region branch and not PC-relative */
1842   target = (pc & 0xFFFFFFFFF0000000ULL) | offset;
1843 
1844   Context context;
1845 
1846   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1847                              target))
1848     return false;
1849 
1850   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1851                              pc + 8))
1852     return false;
1853 
1854   return true;
1855 }
1856 
1857 bool EmulateInstructionMIPS64::Emulate_JALR(llvm::MCInst &insn) {
1858   bool success = false;
1859   uint32_t rs, rt;
1860   uint64_t pc, rs_val;
1861 
1862   /*
1863    * JALR rt, rs
1864    *      GPR[rt] = PC + 8
1865    *      PC = GPR[rs]
1866   */
1867   rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1868   rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1869 
1870   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1871   if (!success)
1872     return false;
1873 
1874   rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0,
1875                                 &success);
1876   if (!success)
1877     return false;
1878 
1879   Context context;
1880 
1881   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1882                              rs_val))
1883     return false;
1884 
1885   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1886                              dwarf_zero_mips64 + rt, pc + 8))
1887     return false;
1888 
1889   return true;
1890 }
1891 
1892 bool EmulateInstructionMIPS64::Emulate_JIALC(llvm::MCInst &insn) {
1893   bool success = false;
1894   uint32_t rt;
1895   int64_t target, offset, pc, rt_val;
1896 
1897   /*
1898    * JIALC rt, offset
1899    *      offset = sign_ext (offset)
1900    *      PC = GPR[rt] + offset
1901    *      RA = PC + 4
1902   */
1903   rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1904   offset = insn.getOperand(1).getImm();
1905 
1906   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
1907   if (!success)
1908     return false;
1909 
1910   rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1911                                          dwarf_zero_mips64 + rt, 0, &success);
1912   if (!success)
1913     return false;
1914 
1915   target = rt_val + offset;
1916 
1917   Context context;
1918 
1919   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1920                              target))
1921     return false;
1922 
1923   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
1924                              pc + 4))
1925     return false;
1926 
1927   return true;
1928 }
1929 
1930 bool EmulateInstructionMIPS64::Emulate_JIC(llvm::MCInst &insn) {
1931   bool success = false;
1932   uint32_t rt;
1933   int64_t target, offset, rt_val;
1934 
1935   /*
1936    * JIC rt, offset
1937    *      offset = sign_ext (offset)
1938    *      PC = GPR[rt] + offset
1939   */
1940   rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1941   offset = insn.getOperand(1).getImm();
1942 
1943   rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1944                                          dwarf_zero_mips64 + rt, 0, &success);
1945   if (!success)
1946     return false;
1947 
1948   target = rt_val + offset;
1949 
1950   Context context;
1951 
1952   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1953                                target);
1954 }
1955 
1956 bool EmulateInstructionMIPS64::Emulate_JR(llvm::MCInst &insn) {
1957   bool success = false;
1958   uint32_t rs;
1959   uint64_t rs_val;
1960 
1961   /*
1962    * JR rs
1963    *      PC = GPR[rs]
1964   */
1965   rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1966 
1967   rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0,
1968                                 &success);
1969   if (!success)
1970     return false;
1971 
1972   Context context;
1973 
1974   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
1975                                rs_val);
1976 }
1977 
1978 /*
1979     Emulate Branch on FP True/False
1980     BC1F, BC1FL :   Branch on FP False (L stands for branch likely)
1981     BC1T, BC1TL :   Branch on FP True  (L stands for branch likely)
1982 */
1983 bool EmulateInstructionMIPS64::Emulate_FP_branch(llvm::MCInst &insn) {
1984   bool success = false;
1985   uint32_t cc, fcsr;
1986   int64_t pc, offset, target = 0;
1987   llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
1988 
1989   /*
1990    * BC1F cc, offset
1991    *  condition <- (FPConditionCode(cc) == 0)
1992    *      if condition then
1993    *          offset = sign_ext (offset)
1994    *          PC = PC + offset
1995   */
1996   cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1997   offset = insn.getOperand(1).getImm();
1998 
1999   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2000   if (!success)
2001     return false;
2002 
2003   fcsr =
2004       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64, 0, &success);
2005   if (!success)
2006     return false;
2007 
2008   /* fcsr[23], fcsr[25-31] are vaild condition bits */
2009   fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2010 
2011   if (op_name.equals_insensitive("BC1F") ||
2012       op_name.equals_insensitive("BC1FL")) {
2013     if ((fcsr & (1 << cc)) == 0)
2014       target = pc + offset;
2015     else
2016       target = pc + 8;
2017   } else if (op_name.equals_insensitive("BC1T") ||
2018              op_name.equals_insensitive("BC1TL")) {
2019     if ((fcsr & (1 << cc)) != 0)
2020       target = pc + offset;
2021     else
2022       target = pc + 8;
2023   }
2024 
2025   Context context;
2026 
2027   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2028                                target);
2029 }
2030 
2031 bool EmulateInstructionMIPS64::Emulate_BC1EQZ(llvm::MCInst &insn) {
2032   bool success = false;
2033   uint32_t ft;
2034   uint64_t ft_val;
2035   int64_t target, pc, offset;
2036 
2037   /*
2038    * BC1EQZ ft, offset
2039    *  condition <- (FPR[ft].bit0 == 0)
2040    *      if condition then
2041    *          offset = sign_ext (offset)
2042    *          PC = PC + 4 + offset
2043   */
2044   ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2045   offset = insn.getOperand(1).getImm();
2046 
2047   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2048   if (!success)
2049     return false;
2050 
2051   ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0,
2052                                 &success);
2053   if (!success)
2054     return false;
2055 
2056   if ((ft_val & 1) == 0)
2057     target = pc + 4 + offset;
2058   else
2059     target = pc + 8;
2060 
2061   Context context;
2062 
2063   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2064                                target);
2065 }
2066 
2067 bool EmulateInstructionMIPS64::Emulate_BC1NEZ(llvm::MCInst &insn) {
2068   bool success = false;
2069   uint32_t ft;
2070   uint64_t ft_val;
2071   int64_t target, pc, offset;
2072 
2073   /*
2074    * BC1NEZ ft, offset
2075    *  condition <- (FPR[ft].bit0 != 0)
2076    *      if condition then
2077    *          offset = sign_ext (offset)
2078    *          PC = PC + 4 + offset
2079   */
2080   ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2081   offset = insn.getOperand(1).getImm();
2082 
2083   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2084   if (!success)
2085     return false;
2086 
2087   ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0,
2088                                 &success);
2089   if (!success)
2090     return false;
2091 
2092   if ((ft_val & 1) != 0)
2093     target = pc + 4 + offset;
2094   else
2095     target = pc + 8;
2096 
2097   Context context;
2098 
2099   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2100                                target);
2101 }
2102 
2103 /*
2104     Emulate MIPS-3D Branch instructions
2105     BC1ANY2F, BC1ANY2T  : Branch on Any of Two Floating Point Condition Codes
2106    False/True
2107     BC1ANY4F, BC1ANY4T  : Branch on Any of Four Floating Point Condition Codes
2108    False/True
2109 */
2110 bool EmulateInstructionMIPS64::Emulate_3D_branch(llvm::MCInst &insn) {
2111   bool success = false;
2112   uint32_t cc, fcsr;
2113   int64_t pc, offset, target = 0;
2114   llvm::StringRef op_name = m_insn_info->getName(insn.getOpcode());
2115 
2116   cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2117   offset = insn.getOperand(1).getImm();
2118 
2119   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2120   if (!success)
2121     return false;
2122 
2123   fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64,
2124                                         0, &success);
2125   if (!success)
2126     return false;
2127 
2128   /* fcsr[23], fcsr[25-31] are vaild condition bits */
2129   fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2130 
2131   if (op_name.equals_insensitive("BC1ANY2F")) {
2132     /* if any one bit is 0 */
2133     if (((fcsr >> cc) & 3) != 3)
2134       target = pc + offset;
2135     else
2136       target = pc + 8;
2137   } else if (op_name.equals_insensitive("BC1ANY2T")) {
2138     /* if any one bit is 1 */
2139     if (((fcsr >> cc) & 3) != 0)
2140       target = pc + offset;
2141     else
2142       target = pc + 8;
2143   } else if (op_name.equals_insensitive("BC1ANY4F")) {
2144     /* if any one bit is 0 */
2145     if (((fcsr >> cc) & 0xf) != 0xf)
2146       target = pc + offset;
2147     else
2148       target = pc + 8;
2149   } else if (op_name.equals_insensitive("BC1ANY4T")) {
2150     /* if any one bit is 1 */
2151     if (((fcsr >> cc) & 0xf) != 0)
2152       target = pc + offset;
2153     else
2154       target = pc + 8;
2155   }
2156 
2157   Context context;
2158 
2159   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2160                                target);
2161 }
2162 
2163 bool EmulateInstructionMIPS64::Emulate_BNZB(llvm::MCInst &insn) {
2164   return Emulate_MSA_Branch_DF(insn, 1, true);
2165 }
2166 
2167 bool EmulateInstructionMIPS64::Emulate_BNZH(llvm::MCInst &insn) {
2168   return Emulate_MSA_Branch_DF(insn, 2, true);
2169 }
2170 
2171 bool EmulateInstructionMIPS64::Emulate_BNZW(llvm::MCInst &insn) {
2172   return Emulate_MSA_Branch_DF(insn, 4, true);
2173 }
2174 
2175 bool EmulateInstructionMIPS64::Emulate_BNZD(llvm::MCInst &insn) {
2176   return Emulate_MSA_Branch_DF(insn, 8, true);
2177 }
2178 
2179 bool EmulateInstructionMIPS64::Emulate_BZB(llvm::MCInst &insn) {
2180   return Emulate_MSA_Branch_DF(insn, 1, false);
2181 }
2182 
2183 bool EmulateInstructionMIPS64::Emulate_BZH(llvm::MCInst &insn) {
2184   return Emulate_MSA_Branch_DF(insn, 2, false);
2185 }
2186 
2187 bool EmulateInstructionMIPS64::Emulate_BZW(llvm::MCInst &insn) {
2188   return Emulate_MSA_Branch_DF(insn, 4, false);
2189 }
2190 
2191 bool EmulateInstructionMIPS64::Emulate_BZD(llvm::MCInst &insn) {
2192   return Emulate_MSA_Branch_DF(insn, 8, false);
2193 }
2194 
2195 bool EmulateInstructionMIPS64::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
2196                                                      int element_byte_size,
2197                                                      bool bnz) {
2198   bool success = false, branch_hit = true;
2199   int64_t target = 0;
2200   RegisterValue reg_value;
2201   const uint8_t *ptr = nullptr;
2202 
2203   uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2204   int64_t offset = insn.getOperand(1).getImm();
2205 
2206   int64_t pc =
2207       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2208   if (!success)
2209     return false;
2210 
2211   if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
2212     ptr = (const uint8_t *)reg_value.GetBytes();
2213   else
2214     return false;
2215 
2216   for (int i = 0; i < 16 / element_byte_size; i++) {
2217     switch (element_byte_size) {
2218     case 1:
2219       if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2220         branch_hit = false;
2221       break;
2222     case 2:
2223       if ((*(const uint16_t *)ptr == 0 && bnz) ||
2224           (*(const uint16_t *)ptr != 0 && !bnz))
2225         branch_hit = false;
2226       break;
2227     case 4:
2228       if ((*(const uint32_t *)ptr == 0 && bnz) ||
2229           (*(const uint32_t *)ptr != 0 && !bnz))
2230         branch_hit = false;
2231       break;
2232     case 8:
2233       if ((*(const uint64_t *)ptr == 0 && bnz) ||
2234           (*(const uint64_t *)ptr != 0 && !bnz))
2235         branch_hit = false;
2236       break;
2237     }
2238     if (!branch_hit)
2239       break;
2240     ptr = ptr + element_byte_size;
2241   }
2242 
2243   if (branch_hit)
2244     target = pc + offset;
2245   else
2246     target = pc + 8;
2247 
2248   Context context;
2249   context.type = eContextRelativeBranchImmediate;
2250 
2251   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2252                                target);
2253 }
2254 
2255 bool EmulateInstructionMIPS64::Emulate_BNZV(llvm::MCInst &insn) {
2256   return Emulate_MSA_Branch_V(insn, true);
2257 }
2258 
2259 bool EmulateInstructionMIPS64::Emulate_BZV(llvm::MCInst &insn) {
2260   return Emulate_MSA_Branch_V(insn, false);
2261 }
2262 
2263 bool EmulateInstructionMIPS64::Emulate_MSA_Branch_V(llvm::MCInst &insn,
2264                                                     bool bnz) {
2265   bool success = false;
2266   int64_t target = 0;
2267   llvm::APInt wr_val = llvm::APInt::getZero(128);
2268   llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
2269   llvm::APInt zero_value = llvm::APInt::getZero(128);
2270   RegisterValue reg_value;
2271 
2272   uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2273   int64_t offset = insn.getOperand(1).getImm();
2274 
2275   int64_t pc =
2276       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
2277   if (!success)
2278     return false;
2279 
2280   if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
2281     wr_val = reg_value.GetAsUInt128(fail_value);
2282   else
2283     return false;
2284 
2285   if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
2286       (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2287     target = pc + offset;
2288   else
2289     target = pc + 8;
2290 
2291   Context context;
2292   context.type = eContextRelativeBranchImmediate;
2293 
2294   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
2295                                target);
2296 }
2297 
2298 bool EmulateInstructionMIPS64::Emulate_LDST_Imm(llvm::MCInst &insn) {
2299   bool success = false;
2300   uint32_t base;
2301   int64_t imm, address;
2302   Context bad_vaddr_context;
2303 
2304   uint32_t num_operands = insn.getNumOperands();
2305   base =
2306       m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2307   imm = insn.getOperand(num_operands - 1).getImm();
2308 
2309   RegisterInfo reg_info_base;
2310   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
2311                        reg_info_base))
2312     return false;
2313 
2314   /* read base register */
2315   address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
2316                                  &success);
2317   if (!success)
2318     return false;
2319 
2320   /* destination address */
2321   address = address + imm;
2322 
2323   /* Set the bad_vaddr register with base address used in the instruction */
2324   bad_vaddr_context.type = eContextInvalid;
2325   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
2326                         address);
2327 
2328   return true;
2329 }
2330 
2331 bool EmulateInstructionMIPS64::Emulate_LDST_Reg(llvm::MCInst &insn) {
2332   bool success = false;
2333   uint32_t base, index;
2334   int64_t address, index_address;
2335   Context bad_vaddr_context;
2336 
2337   uint32_t num_operands = insn.getNumOperands();
2338   base =
2339       m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2340   index =
2341       m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
2342 
2343   RegisterInfo reg_info_base, reg_info_index;
2344   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
2345                        reg_info_base))
2346     return false;
2347 
2348   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
2349                        reg_info_index))
2350     return false;
2351 
2352   /* read base register */
2353   address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
2354                                  &success);
2355   if (!success)
2356     return false;
2357 
2358   /* read index register */
2359   index_address = ReadRegisterUnsigned(eRegisterKindDWARF,
2360                                        dwarf_zero_mips + index, 0, &success);
2361   if (!success)
2362     return false;
2363 
2364   /* destination address */
2365   address = address + index_address;
2366 
2367   /* Set the bad_vaddr register with base address used in the instruction */
2368   bad_vaddr_context.type = eContextInvalid;
2369   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
2370                         address);
2371 
2372   return true;
2373 }
2374