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