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