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