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