1 //===-- EmulateInstructionMIPS.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 "EmulateInstructionMIPS.h"
11 
12 #include <stdlib.h>
13 
14 #include "llvm-c/Disassembler.h"
15 #include "llvm/Support/TargetSelect.h"
16 #include "llvm/Support/TargetRegistry.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/MC/MCContext.h"
24 #include "lldb/Core/Address.h"
25 #include "lldb/Core/Opcode.h"
26 #include "lldb/Core/ArchSpec.h"
27 #include "lldb/Core/ConstString.h"
28 #include "lldb/Core/PluginManager.h"
29 #include "lldb/Core/DataExtractor.h"
30 #include "lldb/Core/Stream.h"
31 #include "lldb/Symbol/UnwindPlan.h"
32 #include "lldb/Target/Target.h"
33 
34 #include "llvm/ADT/STLExtras.h"
35 
36 #include "Plugins/Process/Utility/InstructionUtils.h"
37 #include "Plugins/Process/Utility/RegisterContext_mips.h"  //mips32 has same registers nos as mips64
38 
39 using namespace lldb;
40 using namespace lldb_private;
41 
42 #define UInt(x) ((uint64_t)x)
43 #define integer int64_t
44 
45 
46 //----------------------------------------------------------------------
47 //
48 // EmulateInstructionMIPS 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 EmulateInstructionMIPS::EmulateInstructionMIPS (const lldb_private::ArchSpec &arch) :
63     EmulateInstruction (arch)
64 {
65     /* Create instance of llvm::MCDisassembler */
66     std::string Error;
67     llvm::Triple triple = arch.GetTriple();
68     const llvm::Target *target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error);
69 
70     /*
71      * If we fail to get the target then we haven't registered it. The SystemInitializerCommon
72      * does not initialize targets, MCs and disassemblers. However we need the MCDisassembler
73      * to decode the instructions so that the decoding complexity stays with LLVM.
74      * Initialize the MIPS targets and disassemblers.
75     */
76 #ifdef __mips__
77     if (!target)
78     {
79         LLVMInitializeMipsTargetInfo ();
80         LLVMInitializeMipsTarget ();
81         LLVMInitializeMipsAsmPrinter ();
82         LLVMInitializeMipsTargetMC ();
83         LLVMInitializeMipsDisassembler ();
84         target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error);
85     }
86 #endif
87 
88     assert (target);
89 
90     llvm::StringRef cpu;
91 
92     switch (arch.GetCore())
93     {
94         case ArchSpec::eCore_mips32:
95         case ArchSpec::eCore_mips32el:
96             cpu = "mips32"; break;
97         case ArchSpec::eCore_mips32r2:
98         case ArchSpec::eCore_mips32r2el:
99             cpu = "mips32r2"; break;
100         case ArchSpec::eCore_mips32r3:
101         case ArchSpec::eCore_mips32r3el:
102             cpu = "mips32r3"; break;
103         case ArchSpec::eCore_mips32r5:
104         case ArchSpec::eCore_mips32r5el:
105             cpu = "mips32r5"; break;
106         case ArchSpec::eCore_mips32r6:
107         case ArchSpec::eCore_mips32r6el:
108             cpu = "mips32r6"; break;
109         case ArchSpec::eCore_mips64:
110         case ArchSpec::eCore_mips64el:
111             cpu = "mips64"; break;
112         case ArchSpec::eCore_mips64r2:
113         case ArchSpec::eCore_mips64r2el:
114             cpu = "mips64r2"; break;
115         case ArchSpec::eCore_mips64r3:
116         case ArchSpec::eCore_mips64r3el:
117             cpu = "mips64r3"; break;
118         case ArchSpec::eCore_mips64r5:
119         case ArchSpec::eCore_mips64r5el:
120             cpu = "mips64r5"; break;
121         case ArchSpec::eCore_mips64r6:
122         case ArchSpec::eCore_mips64r6el:
123             cpu = "mips64r6"; break;
124         default:
125             cpu = "generic"; break;
126     }
127 
128     std::string features = "";
129     uint32_t arch_flags = arch.GetFlags ();
130     if (arch_flags & ArchSpec::eMIPSAse_msa)
131         features += "+msa,";
132     if (arch_flags & ArchSpec::eMIPSAse_dsp)
133         features += "+dsp,";
134     if (arch_flags & ArchSpec::eMIPSAse_dspr2)
135         features += "+dspr2,";
136 
137     m_reg_info.reset (target->createMCRegInfo (triple.getTriple()));
138     assert (m_reg_info.get());
139 
140     m_insn_info.reset (target->createMCInstrInfo());
141     assert (m_insn_info.get());
142 
143     m_asm_info.reset (target->createMCAsmInfo (*m_reg_info, triple.getTriple()));
144     m_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, features));
145     assert (m_asm_info.get() && m_subtype_info.get());
146 
147     m_context.reset (new llvm::MCContext (m_asm_info.get(), m_reg_info.get(), nullptr));
148     assert (m_context.get());
149 
150     m_disasm.reset (target->createMCDisassembler (*m_subtype_info, *m_context));
151     assert (m_disasm.get());
152 
153     /* Create alternate disassembler for microMIPS */
154     if (arch_flags & ArchSpec::eMIPSAse_mips16)
155         features += "+mips16,";
156     else if (arch_flags & ArchSpec::eMIPSAse_micromips)
157         features += "+micromips,";
158 
159     m_alt_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, features));
160     assert (m_alt_subtype_info.get());
161 
162     m_alt_disasm.reset (target->createMCDisassembler (*m_alt_subtype_info, *m_context));
163     assert (m_alt_disasm.get());
164 
165     m_next_inst_size = 0;
166     m_use_alt_disaasm = false;
167 }
168 
169 void
170 EmulateInstructionMIPS::Initialize ()
171 {
172     PluginManager::RegisterPlugin (GetPluginNameStatic (),
173                                    GetPluginDescriptionStatic (),
174                                    CreateInstance);
175 }
176 
177 void
178 EmulateInstructionMIPS::Terminate ()
179 {
180     PluginManager::UnregisterPlugin (CreateInstance);
181 }
182 
183 ConstString
184 EmulateInstructionMIPS::GetPluginNameStatic ()
185 {
186     ConstString g_plugin_name ("lldb.emulate-instruction.mips32");
187     return g_plugin_name;
188 }
189 
190 lldb_private::ConstString
191 EmulateInstructionMIPS::GetPluginName()
192 {
193     static ConstString g_plugin_name ("EmulateInstructionMIPS");
194     return g_plugin_name;
195 }
196 
197 const char *
198 EmulateInstructionMIPS::GetPluginDescriptionStatic ()
199 {
200     return "Emulate instructions for the MIPS32 architecture.";
201 }
202 
203 EmulateInstruction *
204 EmulateInstructionMIPS::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
205 {
206     if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
207     {
208         if (arch.GetTriple().getArch() == llvm::Triple::mips
209             || arch.GetTriple().getArch() == llvm::Triple::mipsel)
210         {
211             std::auto_ptr<EmulateInstructionMIPS> emulate_insn_ap (new EmulateInstructionMIPS (arch));
212             if (emulate_insn_ap.get())
213                 return emulate_insn_ap.release();
214         }
215     }
216 
217     return NULL;
218 }
219 
220 bool
221 EmulateInstructionMIPS::SetTargetTriple (const ArchSpec &arch)
222 {
223     if (arch.GetTriple().getArch () == llvm::Triple::mips
224         || arch.GetTriple().getArch () == llvm::Triple::mipsel)
225         return true;
226     return false;
227 }
228 
229 const char *
230 EmulateInstructionMIPS::GetRegisterName (unsigned reg_num, bool alternate_name)
231 {
232     if (alternate_name)
233     {
234         switch (reg_num)
235         {
236             case dwarf_sp_mips:          return "r29";
237             case dwarf_r30_mips:         return "r30";
238             case dwarf_ra_mips:          return "r31";
239             case dwarf_f0_mips:          return "f0";
240             case dwarf_f1_mips:          return "f1";
241             case dwarf_f2_mips:          return "f2";
242             case dwarf_f3_mips:          return "f3";
243             case dwarf_f4_mips:          return "f4";
244             case dwarf_f5_mips:          return "f5";
245             case dwarf_f6_mips:          return "f6";
246             case dwarf_f7_mips:          return "f7";
247             case dwarf_f8_mips:          return "f8";
248             case dwarf_f9_mips:          return "f9";
249             case dwarf_f10_mips:         return "f10";
250             case dwarf_f11_mips:         return "f11";
251             case dwarf_f12_mips:         return "f12";
252             case dwarf_f13_mips:         return "f13";
253             case dwarf_f14_mips:         return "f14";
254             case dwarf_f15_mips:         return "f15";
255             case dwarf_f16_mips:         return "f16";
256             case dwarf_f17_mips:         return "f17";
257             case dwarf_f18_mips:         return "f18";
258             case dwarf_f19_mips:         return "f19";
259             case dwarf_f20_mips:         return "f20";
260             case dwarf_f21_mips:         return "f21";
261             case dwarf_f22_mips:         return "f22";
262             case dwarf_f23_mips:         return "f23";
263             case dwarf_f24_mips:         return "f24";
264             case dwarf_f25_mips:         return "f25";
265             case dwarf_f26_mips:         return "f26";
266             case dwarf_f27_mips:         return "f27";
267             case dwarf_f28_mips:         return "f28";
268             case dwarf_f29_mips:         return "f29";
269             case dwarf_f30_mips:         return "f30";
270             case dwarf_f31_mips:         return "f31";
271             case dwarf_w0_mips:          return "w0";
272             case dwarf_w1_mips:          return "w1";
273             case dwarf_w2_mips:          return "w2";
274             case dwarf_w3_mips:          return "w3";
275             case dwarf_w4_mips:          return "w4";
276             case dwarf_w5_mips:          return "w5";
277             case dwarf_w6_mips:          return "w6";
278             case dwarf_w7_mips:          return "w7";
279             case dwarf_w8_mips:          return "w8";
280             case dwarf_w9_mips:          return "w9";
281             case dwarf_w10_mips:         return "w10";
282             case dwarf_w11_mips:         return "w11";
283             case dwarf_w12_mips:         return "w12";
284             case dwarf_w13_mips:         return "w13";
285             case dwarf_w14_mips:         return "w14";
286             case dwarf_w15_mips:         return "w15";
287             case dwarf_w16_mips:         return "w16";
288             case dwarf_w17_mips:         return "w17";
289             case dwarf_w18_mips:         return "w18";
290             case dwarf_w19_mips:         return "w19";
291             case dwarf_w20_mips:         return "w20";
292             case dwarf_w21_mips:         return "w21";
293             case dwarf_w22_mips:         return "w22";
294             case dwarf_w23_mips:         return "w23";
295             case dwarf_w24_mips:         return "w24";
296             case dwarf_w25_mips:         return "w25";
297             case dwarf_w26_mips:         return "w26";
298             case dwarf_w27_mips:         return "w27";
299             case dwarf_w28_mips:         return "w28";
300             case dwarf_w29_mips:         return "w29";
301             case dwarf_w30_mips:         return "w30";
302             case dwarf_w31_mips:         return "w31";
303             case dwarf_mir_mips:         return "mir";
304             case dwarf_mcsr_mips:        return "mcsr";
305             case dwarf_config5_mips:     return "config5";
306             default:
307                 break;
308         }
309         return nullptr;
310     }
311 
312     switch (reg_num)
313     {
314         case dwarf_zero_mips:         return "r0";
315         case dwarf_r1_mips:           return "r1";
316         case dwarf_r2_mips:           return "r2";
317         case dwarf_r3_mips:           return "r3";
318         case dwarf_r4_mips:           return "r4";
319         case dwarf_r5_mips:           return "r5";
320         case dwarf_r6_mips:           return "r6";
321         case dwarf_r7_mips:           return "r7";
322         case dwarf_r8_mips:           return "r8";
323         case dwarf_r9_mips:           return "r9";
324         case dwarf_r10_mips:          return "r10";
325         case dwarf_r11_mips:          return "r11";
326         case dwarf_r12_mips:          return "r12";
327         case dwarf_r13_mips:          return "r13";
328         case dwarf_r14_mips:          return "r14";
329         case dwarf_r15_mips:          return "r15";
330         case dwarf_r16_mips:          return "r16";
331         case dwarf_r17_mips:          return "r17";
332         case dwarf_r18_mips:          return "r18";
333         case dwarf_r19_mips:          return "r19";
334         case dwarf_r20_mips:          return "r20";
335         case dwarf_r21_mips:          return "r21";
336         case dwarf_r22_mips:          return "r22";
337         case dwarf_r23_mips:          return "r23";
338         case dwarf_r24_mips:          return "r24";
339         case dwarf_r25_mips:          return "r25";
340         case dwarf_r26_mips:          return "r26";
341         case dwarf_r27_mips:          return "r27";
342         case dwarf_gp_mips:           return "gp";
343         case dwarf_sp_mips:           return "sp";
344         case dwarf_r30_mips:          return "fp";
345         case dwarf_ra_mips:           return "ra";
346         case dwarf_sr_mips:           return "sr";
347         case dwarf_lo_mips:           return "lo";
348         case dwarf_hi_mips:           return "hi";
349         case dwarf_bad_mips:          return "bad";
350         case dwarf_cause_mips:        return "cause";
351         case dwarf_pc_mips:           return "pc";
352         case dwarf_f0_mips:           return "f0";
353         case dwarf_f1_mips:           return "f1";
354         case dwarf_f2_mips:           return "f2";
355         case dwarf_f3_mips:           return "f3";
356         case dwarf_f4_mips:           return "f4";
357         case dwarf_f5_mips:           return "f5";
358         case dwarf_f6_mips:           return "f6";
359         case dwarf_f7_mips:           return "f7";
360         case dwarf_f8_mips:           return "f8";
361         case dwarf_f9_mips:           return "f9";
362         case dwarf_f10_mips:          return "f10";
363         case dwarf_f11_mips:          return "f11";
364         case dwarf_f12_mips:          return "f12";
365         case dwarf_f13_mips:          return "f13";
366         case dwarf_f14_mips:          return "f14";
367         case dwarf_f15_mips:          return "f15";
368         case dwarf_f16_mips:          return "f16";
369         case dwarf_f17_mips:          return "f17";
370         case dwarf_f18_mips:          return "f18";
371         case dwarf_f19_mips:          return "f19";
372         case dwarf_f20_mips:          return "f20";
373         case dwarf_f21_mips:          return "f21";
374         case dwarf_f22_mips:          return "f22";
375         case dwarf_f23_mips:          return "f23";
376         case dwarf_f24_mips:          return "f24";
377         case dwarf_f25_mips:          return "f25";
378         case dwarf_f26_mips:          return "f26";
379         case dwarf_f27_mips:          return "f27";
380         case dwarf_f28_mips:          return "f28";
381         case dwarf_f29_mips:          return "f29";
382         case dwarf_f30_mips:          return "f30";
383         case dwarf_f31_mips:          return "f31";
384         case dwarf_fcsr_mips:         return "fcsr";
385         case dwarf_fir_mips:          return "fir";
386         case dwarf_w0_mips:           return "w0";
387         case dwarf_w1_mips:           return "w1";
388         case dwarf_w2_mips:           return "w2";
389         case dwarf_w3_mips:           return "w3";
390         case dwarf_w4_mips:           return "w4";
391         case dwarf_w5_mips:           return "w5";
392         case dwarf_w6_mips:           return "w6";
393         case dwarf_w7_mips:           return "w7";
394         case dwarf_w8_mips:           return "w8";
395         case dwarf_w9_mips:           return "w9";
396         case dwarf_w10_mips:          return "w10";
397         case dwarf_w11_mips:          return "w11";
398         case dwarf_w12_mips:          return "w12";
399         case dwarf_w13_mips:          return "w13";
400         case dwarf_w14_mips:          return "w14";
401         case dwarf_w15_mips:          return "w15";
402         case dwarf_w16_mips:          return "w16";
403         case dwarf_w17_mips:          return "w17";
404         case dwarf_w18_mips:          return "w18";
405         case dwarf_w19_mips:          return "w19";
406         case dwarf_w20_mips:          return "w20";
407         case dwarf_w21_mips:          return "w21";
408         case dwarf_w22_mips:          return "w22";
409         case dwarf_w23_mips:          return "w23";
410         case dwarf_w24_mips:          return "w24";
411         case dwarf_w25_mips:          return "w25";
412         case dwarf_w26_mips:          return "w26";
413         case dwarf_w27_mips:          return "w27";
414         case dwarf_w28_mips:          return "w28";
415         case dwarf_w29_mips:          return "w29";
416         case dwarf_w30_mips:          return "w30";
417         case dwarf_w31_mips:          return "w31";
418         case dwarf_mcsr_mips:         return "mcsr";
419         case dwarf_mir_mips:          return "mir";
420         case dwarf_config5_mips:      return "config5";
421     }
422     return nullptr;
423 }
424 
425 bool
426 EmulateInstructionMIPS::GetRegisterInfo (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
427 {
428     if (reg_kind == eRegisterKindGeneric)
429     {
430         switch (reg_num)
431         {
432             case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc_mips; break;
433             case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp_mips; break;
434             case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r30_mips; break;
435             case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_ra_mips; break;
436             case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sr_mips; break;
437             default:
438                 return false;
439         }
440     }
441 
442     if (reg_kind == eRegisterKindDWARF)
443     {
444        ::memset (&reg_info, 0, sizeof(RegisterInfo));
445        ::memset (reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
446 
447        if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips || reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips || reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips)
448        {
449            reg_info.byte_size = 4;
450            reg_info.format = eFormatHex;
451            reg_info.encoding = eEncodingUint;
452        }
453        else if ((int)reg_num >= dwarf_zero_mips && (int)reg_num <= dwarf_f31_mips)
454        {
455            reg_info.byte_size = 4;
456            reg_info.format = eFormatHex;
457            reg_info.encoding = eEncodingUint;
458        }
459        else if ((int)reg_num >= dwarf_w0_mips && (int)reg_num <= dwarf_w31_mips)
460        {
461            reg_info.byte_size = 16;
462            reg_info.format = eFormatVectorOfUInt8;
463            reg_info.encoding = eEncodingVector;
464        }
465        else
466        {
467            return false;
468        }
469 
470        reg_info.name = GetRegisterName (reg_num, false);
471        reg_info.alt_name = GetRegisterName (reg_num, true);
472        reg_info.kinds[eRegisterKindDWARF] = reg_num;
473 
474        switch (reg_num)
475        {
476            case dwarf_r30_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; break;
477            case dwarf_ra_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; break;
478            case dwarf_sp_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; break;
479            case dwarf_pc_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; break;
480            case dwarf_sr_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; break;
481            default: break;
482        }
483        return true;
484     }
485     return false;
486 }
487 
488 EmulateInstructionMIPS::MipsOpcode*
489 EmulateInstructionMIPS::GetOpcodeForInstruction (const char *op_name)
490 {
491     static EmulateInstructionMIPS::MipsOpcode
492     g_opcodes[] =
493     {
494         //----------------------------------------------------------------------
495         // Prologue/Epilogue instructions
496         //----------------------------------------------------------------------
497         { "ADDiu",      &EmulateInstructionMIPS::Emulate_ADDiu,       "ADDIU rt, rs, immediate"    },
498         { "SW",         &EmulateInstructionMIPS::Emulate_SW,          "SW rt, offset(rs)"          },
499         { "LW",         &EmulateInstructionMIPS::Emulate_LW,          "LW rt, offset(base)"        },
500         { "SUBU",       &EmulateInstructionMIPS::Emulate_SUBU_ADDU,   "SUBU rd, rs, rt"            },
501         { "ADDU",       &EmulateInstructionMIPS::Emulate_SUBU_ADDU,   "ADDU rd, rs, rt"            },
502         { "LUI",        &EmulateInstructionMIPS::Emulate_LUI,          "LUI rt, immediate"          },
503 
504         //----------------------------------------------------------------------
505         // MicroMIPS Prologue/Epilogue instructions
506         //----------------------------------------------------------------------
507         { "ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP,     "ADDIU immediate"            },
508         { "ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5,     "ADDIUS5 rd,immediate"       },
509         { "SWSP_MM",    &EmulateInstructionMIPS::Emulate_SWSP,        "SWSP rt,offset(sp)"         },
510         { "SWM16_MM",   &EmulateInstructionMIPS::Emulate_SWM16_32,    "SWM16 reglist,offset(sp)"   },
511         { "SWM32_MM",   &EmulateInstructionMIPS::Emulate_SWM16_32,    "SWM32 reglist,offset(base)" },
512         { "SWP_MM",     &EmulateInstructionMIPS::Emulate_SWM16_32,    "SWP rs1,offset(base)"       },
513         { "LWSP_MM",    &EmulateInstructionMIPS::Emulate_LWSP,        "LWSP rt,offset(sp)"         },
514         { "LWM16_MM",   &EmulateInstructionMIPS::Emulate_LWM16_32,    "LWM16 reglist,offset(sp)"   },
515         { "LWM32_MM",   &EmulateInstructionMIPS::Emulate_LWM16_32,    "LWM32 reglist,offset(base)" },
516         { "LWP_MM",     &EmulateInstructionMIPS::Emulate_LWM16_32,    "LWP rd,offset(base)"        },
517         { "JRADDIUSP",  &EmulateInstructionMIPS::Emulate_JRADDIUSP,   "JRADDIUSP immediate"        },
518         //----------------------------------------------------------------------
519 
520         // Load/Store  instructions
521         //----------------------------------------------------------------------
522         /* Following list of emulated instructions are required by implementation of hardware watchpoint
523            for MIPS in lldb. As we just need the address accessed by instructions, we have generalised
524            all these instructions in 2 functions depending on their addressing modes */
525 
526         { "LB",         &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LB    rt, offset(base)" },
527         { "LBE",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LBE   rt, offset(base)" },
528         { "LBU",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LBU   rt, offset(base)" },
529         { "LBUE",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LBUE  rt, offset(base)" },
530         { "LDC1",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LDC1  ft, offset(base)" },
531         { "LD",         &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LD    rt, offset(base)" },
532         { "LDL",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LDL   rt, offset(base)" },
533         { "LDR",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LDR   rt, offset(base)" },
534         { "LLD",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LLD   rt, offset(base)" },
535         { "LDC2",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LDC2  rt, offset(base)" },
536         { "LDXC1",      &EmulateInstructionMIPS::Emulate_LDST_Reg,          "LDXC1 fd, index (base)" },
537         { "LH",         &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LH    rt, offset(base)" },
538         { "LHE",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LHE   rt, offset(base)" },
539         { "LHU",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LHU   rt, offset(base)" },
540         { "LHUE",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LHUE  rt, offset(base)" },
541         { "LL",         &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LL    rt, offset(base)" },
542         { "LLE",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LLE   rt, offset(base)" },
543         { "LUXC1",      &EmulateInstructionMIPS::Emulate_LDST_Reg,          "LUXC1 fd, index (base)" },
544         { "LW",         &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LW    rt, offset(base)" },
545         { "LWC1",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LWC1  ft, offset(base)" },
546         { "LWC2",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LWC2  rt, offset(base)" },
547         { "LWE",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LWE   rt, offset(base)" },
548         { "LWL",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LWL   rt, offset(base)" },
549         { "LWLE",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LWLE  rt, offset(base)" },
550         { "LWR",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LWR   rt, offset(base)" },
551         { "LWRE",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LWRE  rt, offset(base)" },
552         { "LWXC1",      &EmulateInstructionMIPS::Emulate_LDST_Reg,          "LWXC1 fd, index (base)" },
553         { "LLX",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LLX   rt, offset(base)" },
554         { "LLXE",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LLXE  rt, offset(base)" },
555         { "LLDX",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "LLDX  rt, offset(base)" },
556 
557         { "SB",         &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SB    rt, offset(base)" },
558         { "SBE",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SBE   rt, offset(base)" },
559         { "SC",         &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SC    rt, offset(base)" },
560         { "SCE",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SCE   rt, offset(base)" },
561         { "SCD",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SCD   rt, offset(base)" },
562         { "SD",         &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SD    rt, offset(base)" },
563         { "SDL",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SDL   rt, offset(base)" },
564         { "SDR",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SDR   rt, offset(base)" },
565         { "SDC1",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SDC1  ft, offset(base)" },
566         { "SDC2",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SDC2  rt, offset(base)" },
567         { "SDXC1",      &EmulateInstructionMIPS::Emulate_LDST_Reg,          "SDXC1 fs, index(base)"  },
568         { "SH",         &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SH    rt, offset(base)" },
569         { "SHE",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SHE   rt, offset(base)" },
570         { "SUXC1",      &EmulateInstructionMIPS::Emulate_LDST_Reg,          "SUXC1 fs, index (base)" },
571         { "SWC1",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SWC1  ft, offset(base)" },
572         { "SWC2",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SWC2  rt, offset(base)" },
573         { "SWE",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SWE   rt, offset(base)" },
574         { "SWL",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SWL   rt, offset(base)" },
575         { "SWLE",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SWLE  rt, offset(base)" },
576         { "SWR",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SWR   rt, offset(base)" },
577         { "SWRE",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SWRE  rt, offset(base)" },
578         { "SWXC1",      &EmulateInstructionMIPS::Emulate_LDST_Reg,          "SWXC1 fs, index (base)" },
579         { "SCX",        &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SCX   rt, offset(base)" },
580         { "SCXE",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SCXE  rt, offset(base)" },
581         { "SCDX",       &EmulateInstructionMIPS::Emulate_LDST_Imm,          "SCDX  rt, offset(base)" },
582 
583         //----------------------------------------------------------------------
584         // MicroMIPS Load/Store instructions
585         //----------------------------------------------------------------------
586         { "LBU16_MM",      &EmulateInstructionMIPS::Emulate_LDST_Imm,       "LBU16 rt, decoded_offset(base)"       },
587         { "LHU16_MM",      &EmulateInstructionMIPS::Emulate_LDST_Imm,       "LHU16 rt, left_shifted_offset(base)"  },
588         { "LW16_MM",       &EmulateInstructionMIPS::Emulate_LDST_Imm,       "LW16  rt, left_shifted_offset(base)"  },
589         { "LWGP_MM",       &EmulateInstructionMIPS::Emulate_LDST_Imm,       "LWGP  rt, left_shifted_offset(gp)"    },
590         { "SH16_MM",       &EmulateInstructionMIPS::Emulate_LDST_Imm,       "SH16  rt, left_shifted_offset(base)"  },
591         { "SW16_MM",       &EmulateInstructionMIPS::Emulate_LDST_Imm,       "SW16  rt, left_shifted_offset(base)"  },
592         { "SW_MM",         &EmulateInstructionMIPS::Emulate_LDST_Imm,       "SWSP  rt, left_shifted_offset(base)"  },
593         { "SB16_MM",       &EmulateInstructionMIPS::Emulate_LDST_Imm,       "SB16  rt, offset(base)"               },
594 
595         //----------------------------------------------------------------------
596         // Branch instructions
597         //----------------------------------------------------------------------
598         { "BEQ",        &EmulateInstructionMIPS::Emulate_BXX_3ops,    "BEQ rs,rt,offset"          },
599         { "BNE",        &EmulateInstructionMIPS::Emulate_BXX_3ops,    "BNE rs,rt,offset"          },
600         { "BEQL",       &EmulateInstructionMIPS::Emulate_BXX_3ops,    "BEQL rs,rt,offset"         },
601         { "BNEL",       &EmulateInstructionMIPS::Emulate_BXX_3ops,    "BNEL rs,rt,offset"         },
602         { "BGEZALL",    &EmulateInstructionMIPS::Emulate_Bcond_Link,  "BGEZALL rt,offset"         },
603         { "BAL",        &EmulateInstructionMIPS::Emulate_BAL,         "BAL offset"                },
604         { "BGEZAL",     &EmulateInstructionMIPS::Emulate_Bcond_Link,  "BGEZAL rs,offset"          },
605         { "BALC",       &EmulateInstructionMIPS::Emulate_BALC,        "BALC offset"               },
606         { "BC",         &EmulateInstructionMIPS::Emulate_BC,          "BC offset"                 },
607         { "BGEZ",       &EmulateInstructionMIPS::Emulate_BXX_2ops,    "BGEZ rs,offset"            },
608         { "BLEZALC",    &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BLEZALC rs,offset"         },
609         { "BGEZALC",    &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BGEZALC rs,offset"         },
610         { "BLTZALC",    &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BLTZALC rs,offset"         },
611         { "BGTZALC",    &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BGTZALC rs,offset"         },
612         { "BEQZALC",    &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BEQZALC rs,offset"         },
613         { "BNEZALC",    &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BNEZALC rs,offset"         },
614         { "BEQC",       &EmulateInstructionMIPS::Emulate_BXX_3ops_C,  "BEQC rs,rt,offset"         },
615         { "BNEC",       &EmulateInstructionMIPS::Emulate_BXX_3ops_C,  "BNEC rs,rt,offset"         },
616         { "BLTC",       &EmulateInstructionMIPS::Emulate_BXX_3ops_C,  "BLTC rs,rt,offset"         },
617         { "BGEC",       &EmulateInstructionMIPS::Emulate_BXX_3ops_C,  "BGEC rs,rt,offset"         },
618         { "BLTUC",      &EmulateInstructionMIPS::Emulate_BXX_3ops_C,  "BLTUC rs,rt,offset"        },
619         { "BGEUC",      &EmulateInstructionMIPS::Emulate_BXX_3ops_C,  "BGEUC rs,rt,offset"        },
620         { "BLTZC",      &EmulateInstructionMIPS::Emulate_BXX_2ops_C,  "BLTZC rt,offset"           },
621         { "BLEZC",      &EmulateInstructionMIPS::Emulate_BXX_2ops_C,  "BLEZC rt,offset"           },
622         { "BGEZC",      &EmulateInstructionMIPS::Emulate_BXX_2ops_C,  "BGEZC rt,offset"           },
623         { "BGTZC",      &EmulateInstructionMIPS::Emulate_BXX_2ops_C,  "BGTZC rt,offset"           },
624         { "BEQZC",      &EmulateInstructionMIPS::Emulate_BXX_2ops_C,  "BEQZC rt,offset"           },
625         { "BNEZC",      &EmulateInstructionMIPS::Emulate_BXX_2ops_C,  "BNEZC rt,offset"           },
626         { "BGEZL",      &EmulateInstructionMIPS::Emulate_BXX_2ops,    "BGEZL rt,offset"           },
627         { "BGTZ",       &EmulateInstructionMIPS::Emulate_BXX_2ops,    "BGTZ rt,offset"            },
628         { "BGTZL",      &EmulateInstructionMIPS::Emulate_BXX_2ops,    "BGTZL rt,offset"           },
629         { "BLEZ",       &EmulateInstructionMIPS::Emulate_BXX_2ops,    "BLEZ rt,offset"            },
630         { "BLEZL",      &EmulateInstructionMIPS::Emulate_BXX_2ops,    "BLEZL rt,offset"           },
631         { "BLTZ",       &EmulateInstructionMIPS::Emulate_BXX_2ops,    "BLTZ rt,offset"            },
632         { "BLTZAL",     &EmulateInstructionMIPS::Emulate_Bcond_Link,  "BLTZAL rt,offset"          },
633         { "BLTZALL",    &EmulateInstructionMIPS::Emulate_Bcond_Link,  "BLTZALL rt,offset"         },
634         { "BLTZL",      &EmulateInstructionMIPS::Emulate_BXX_2ops,    "BLTZL rt,offset"           },
635         { "BOVC",       &EmulateInstructionMIPS::Emulate_BXX_3ops_C,  "BOVC rs,rt,offset"         },
636         { "BNVC",       &EmulateInstructionMIPS::Emulate_BXX_3ops_C,  "BNVC rs,rt,offset"         },
637         { "J",          &EmulateInstructionMIPS::Emulate_J,           "J target"                  },
638         { "JAL",        &EmulateInstructionMIPS::Emulate_JAL,         "JAL target"                },
639         { "JALX",       &EmulateInstructionMIPS::Emulate_JAL,         "JALX target"               },
640         { "JALR",       &EmulateInstructionMIPS::Emulate_JALR,        "JALR target"               },
641         { "JALR_HB",    &EmulateInstructionMIPS::Emulate_JALR,        "JALR.HB target"            },
642         { "JIALC",      &EmulateInstructionMIPS::Emulate_JIALC,       "JIALC rt,offset"           },
643         { "JIC",        &EmulateInstructionMIPS::Emulate_JIC,         "JIC rt,offset"             },
644         { "JR",         &EmulateInstructionMIPS::Emulate_JR,          "JR target"                 },
645         { "JR_HB",      &EmulateInstructionMIPS::Emulate_JR,          "JR.HB target"              },
646         { "BC1F",       &EmulateInstructionMIPS::Emulate_FP_branch,   "BC1F cc, offset"           },
647         { "BC1T",       &EmulateInstructionMIPS::Emulate_FP_branch,   "BC1T cc, offset"           },
648         { "BC1FL",      &EmulateInstructionMIPS::Emulate_FP_branch,   "BC1FL cc, offset"          },
649         { "BC1TL",      &EmulateInstructionMIPS::Emulate_FP_branch,   "BC1TL cc, offset"          },
650         { "BC1EQZ",     &EmulateInstructionMIPS::Emulate_BC1EQZ,      "BC1EQZ ft, offset"         },
651         { "BC1NEZ",     &EmulateInstructionMIPS::Emulate_BC1NEZ,      "BC1NEZ ft, offset"         },
652         { "BC1ANY2F",   &EmulateInstructionMIPS::Emulate_3D_branch,   "BC1ANY2F cc, offset"       },
653         { "BC1ANY2T",   &EmulateInstructionMIPS::Emulate_3D_branch,   "BC1ANY2T cc, offset"       },
654         { "BC1ANY4F",   &EmulateInstructionMIPS::Emulate_3D_branch,   "BC1ANY4F cc, offset"       },
655         { "BC1ANY4T",   &EmulateInstructionMIPS::Emulate_3D_branch,   "BC1ANY4T cc, offset"       },
656         { "BNZ_B",      &EmulateInstructionMIPS::Emulate_BNZB,        "BNZ.b wt,s16"              },
657         { "BNZ_H",      &EmulateInstructionMIPS::Emulate_BNZH,        "BNZ.h wt,s16"              },
658         { "BNZ_W",      &EmulateInstructionMIPS::Emulate_BNZW,        "BNZ.w wt,s16"              },
659         { "BNZ_D",      &EmulateInstructionMIPS::Emulate_BNZD,        "BNZ.d wt,s16"              },
660         { "BZ_B",       &EmulateInstructionMIPS::Emulate_BZB,         "BZ.b wt,s16"               },
661         { "BZ_H",       &EmulateInstructionMIPS::Emulate_BZH,         "BZ.h wt,s16"               },
662         { "BZ_W",       &EmulateInstructionMIPS::Emulate_BZW,         "BZ.w wt,s16"               },
663         { "BZ_D",       &EmulateInstructionMIPS::Emulate_BZD,         "BZ.d wt,s16"               },
664         { "BNZ_V",      &EmulateInstructionMIPS::Emulate_BNZV,        "BNZ.V wt,s16"              },
665         { "BZ_V",       &EmulateInstructionMIPS::Emulate_BZV,         "BZ.V wt,s16"               },
666 
667         //----------------------------------------------------------------------
668         // MicroMIPS Branch instructions
669         //----------------------------------------------------------------------
670         { "B16_MM",     &EmulateInstructionMIPS::Emulate_B16_MM,        "B16 offset"              },
671         { "BEQZ16_MM",  &EmulateInstructionMIPS::Emulate_Branch_MM,     "BEQZ16 rs, offset"       },
672         { "BNEZ16_MM",  &EmulateInstructionMIPS::Emulate_Branch_MM,     "BNEZ16 rs, offset"       },
673         { "BEQZC_MM",   &EmulateInstructionMIPS::Emulate_Branch_MM,     "BEQZC rs, offset"        },
674         { "BNEZC_MM",   &EmulateInstructionMIPS::Emulate_Branch_MM,     "BNEZC rs, offset"        },
675         { "BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,     "BGEZALS rs, offset"      },
676         { "BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,     "BLTZALS rs, offset"      },
677         { "JALR16_MM",  &EmulateInstructionMIPS::Emulate_JALRx16_MM,    "JALR16 rs"               },
678         { "JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM,    "JALRS16 rs"              },
679         { "JR16_MM",    &EmulateInstructionMIPS::Emulate_JR,            "JR16 rs rs"              },
680         { "JRC16_MM",   &EmulateInstructionMIPS::Emulate_JR,            "JRC16 rs rs"             },
681         { "JALS_MM",    &EmulateInstructionMIPS::Emulate_JALx,          "JALS target"             },
682         { "JALX_MM",    &EmulateInstructionMIPS::Emulate_JALx,          "JALX target"             },
683         { "JALRS_MM",   &EmulateInstructionMIPS::Emulate_JALRS,         "JALRS rt, rs"            },
684     };
685 
686     static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
687 
688     for (size_t i = 0; i < k_num_mips_opcodes; ++i)
689     {
690         if (! strcasecmp (g_opcodes[i].op_name, op_name))
691             return &g_opcodes[i];
692     }
693 
694     return NULL;
695 }
696 
697 uint32_t
698 EmulateInstructionMIPS::GetSizeOfInstruction (lldb_private::DataExtractor& data, uint64_t inst_addr)
699 {
700     uint64_t next_inst_size = 0;
701     llvm::MCInst mc_insn;
702     llvm::MCDisassembler::DecodeStatus decode_status;
703     llvm::ArrayRef<uint8_t> raw_insn (data.GetDataStart(), data.GetByteSize());
704 
705     if (m_use_alt_disaasm)
706         decode_status = m_alt_disasm->getInstruction (mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls(), llvm::nulls());
707     else
708         decode_status = m_disasm->getInstruction (mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls(), llvm::nulls());
709 
710     if (decode_status != llvm::MCDisassembler::Success)
711         return false;
712 
713     return m_insn_info->get(mc_insn.getOpcode()).getSize();
714 }
715 
716 bool
717 EmulateInstructionMIPS::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
718 {
719     m_use_alt_disaasm = false;
720 
721     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
722     {
723         if (inst_addr.GetAddressClass() == eAddressClassCodeAlternateISA)
724         {
725             Error error;
726             lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
727 
728             /*
729              * The address belongs to microMIPS function. To find the size of
730              * next instruction use microMIPS disassembler.
731             */
732              m_use_alt_disaasm = true;
733 
734             uint32_t current_inst_size = insn_opcode.GetByteSize();
735             uint8_t buf[sizeof(uint32_t)];
736             uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size;
737             Address next_addr (next_inst_addr);
738 
739             const size_t bytes_read = target->ReadMemory (next_addr,      /* Address of next instruction */
740                                                           true,           /* prefer_file_cache */
741                                                           buf,
742                                                           sizeof(uint32_t),
743                                                           error,
744                                                           &load_addr);
745 
746             if (bytes_read == 0)
747                 return true;
748 
749             DataExtractor data (buf, sizeof(uint32_t), GetByteOrder(), GetAddressByteSize());
750             m_next_inst_size = GetSizeOfInstruction (data, next_inst_addr);
751             return true;
752         }
753         else
754         {
755             /*
756              * If the address class is not eAddressClassCodeAlternateISA then
757              * the function is not microMIPS. In this case instruction size is
758              * always 4 bytes.
759             */
760             m_next_inst_size = 4;
761             return true;
762         }
763     }
764     return false;
765 }
766 
767 bool
768 EmulateInstructionMIPS::ReadInstruction ()
769 {
770     bool success = false;
771     m_addr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
772     if (success)
773     {
774         Context read_inst_context;
775         read_inst_context.type = eContextReadOpcode;
776         read_inst_context.SetNoArgs ();
777         m_opcode.SetOpcode32 (ReadMemoryUnsigned (read_inst_context, m_addr, 4, 0, &success), GetByteOrder());
778     }
779     if (!success)
780         m_addr = LLDB_INVALID_ADDRESS;
781     return success;
782 }
783 
784 bool
785 EmulateInstructionMIPS::EvaluateInstruction (uint32_t evaluate_options)
786 {
787     bool success = false;
788     llvm::MCInst mc_insn;
789     uint64_t insn_size;
790     DataExtractor data;
791 
792     /* Keep the complexity of the decode logic with the llvm::MCDisassembler class. */
793     if (m_opcode.GetData (data))
794     {
795         llvm::MCDisassembler::DecodeStatus decode_status;
796         llvm::ArrayRef<uint8_t> raw_insn (data.GetDataStart(), data.GetByteSize());
797         if (m_use_alt_disaasm)
798             decode_status = m_alt_disasm->getInstruction (mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
799         else
800             decode_status = m_disasm->getInstruction (mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
801 
802         if (decode_status != llvm::MCDisassembler::Success)
803             return false;
804     }
805 
806     /*
807      * mc_insn.getOpcode() returns decoded opcode. However to make use
808      * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
809     */
810     const char *op_name = m_insn_info->getName (mc_insn.getOpcode ());
811 
812     if (op_name == NULL)
813         return false;
814 
815     /*
816      * Decoding has been done already. Just get the call-back function
817      * and emulate the instruction.
818     */
819     MipsOpcode *opcode_data = GetOpcodeForInstruction (op_name);
820 
821     if (opcode_data == NULL)
822         return false;
823 
824     uint64_t old_pc = 0, new_pc = 0;
825     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
826 
827     if (auto_advance_pc)
828     {
829         old_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
830         if (!success)
831             return false;
832     }
833 
834     /* emulate instruction */
835     success = (this->*opcode_data->callback) (mc_insn);
836     if (!success)
837         return false;
838 
839     if (auto_advance_pc)
840     {
841         new_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
842         if (!success)
843             return false;
844 
845         /* If we haven't changed the PC, change it here */
846         if (old_pc == new_pc)
847         {
848             new_pc += 4;
849             Context context;
850             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, new_pc))
851                 return false;
852         }
853     }
854 
855     return true;
856 }
857 
858 bool
859 EmulateInstructionMIPS::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
860 {
861     unwind_plan.Clear();
862     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
863 
864     UnwindPlan::RowSP row(new UnwindPlan::Row);
865     const bool can_replace = false;
866 
867     // Our previous Call Frame Address is the stack pointer
868     row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0);
869 
870     // Our previous PC is in the RA
871     row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace);
872 
873     unwind_plan.AppendRow (row);
874 
875     // All other registers are the same.
876     unwind_plan.SetSourceName ("EmulateInstructionMIPS");
877     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
878     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
879     unwind_plan.SetReturnAddressRegister (dwarf_ra_mips);
880 
881     return true;
882 }
883 
884 bool
885 EmulateInstructionMIPS::nonvolatile_reg_p (uint32_t regnum)
886 {
887     switch (regnum)
888     {
889         case dwarf_r16_mips:
890         case dwarf_r17_mips:
891         case dwarf_r18_mips:
892         case dwarf_r19_mips:
893         case dwarf_r20_mips:
894         case dwarf_r21_mips:
895         case dwarf_r22_mips:
896         case dwarf_r23_mips:
897         case dwarf_gp_mips:
898         case dwarf_sp_mips:
899         case dwarf_r30_mips:
900         case dwarf_ra_mips:
901             return true;
902         default:
903             return false;
904     }
905     return false;
906 }
907 
908 bool
909 EmulateInstructionMIPS::Emulate_ADDiu (llvm::MCInst& insn)
910 {
911     // ADDIU rt, rs, immediate
912     // GPR[rt] <- GPR[rs] + sign_extend(immediate)
913 
914     uint8_t dst, src;
915     bool success = false;
916     const uint32_t imm16 = insn.getOperand(2).getImm();
917     int64_t imm = SignedBits(imm16, 15, 0);
918 
919     dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
920     src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
921 
922     // If immediate value is greater then 2^16 - 1 then clang generate
923     // LUI, ADDIU, SUBU instructions in prolog.
924     // Example
925     // lui    $1, 0x2
926     // addiu $1, $1, -0x5920
927     // subu  $sp, $sp, $1
928     // In this case, ADDIU dst and src will be same and not equal to sp
929     if (dst == src)
930     {
931         Context context;
932 
933         /* read <src> register */
934         const int64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
935         if (!success)
936             return false;
937 
938         /* Check if this is daddiu sp, sp, imm16 */
939         if (dst == dwarf_sp_mips)
940         {
941             uint64_t result = src_opd_val + imm;
942             RegisterInfo reg_info_sp;
943 
944             if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
945                 context.SetRegisterPlusOffset (reg_info_sp, imm);
946 
947             /* We are allocating bytes on stack */
948             context.type = eContextAdjustStackPointer;
949 
950             WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result);
951             return true;
952         }
953 
954         imm += src_opd_val;
955         context.SetImmediateSigned (imm);
956         context.type = eContextImmediate;
957 
958         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + dst, imm))
959             return false;
960     }
961 
962     return true;
963 }
964 
965 bool
966 EmulateInstructionMIPS::Emulate_SW (llvm::MCInst& insn)
967 {
968     bool success = false;
969     uint32_t imm16 = insn.getOperand(2).getImm();
970     uint32_t imm = SignedBits(imm16, 15, 0);
971     uint32_t src, base;
972     int32_t address;
973     Context bad_vaddr_context;
974 
975     RegisterInfo reg_info_base;
976 
977     src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
978     base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
979 
980     if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
981         return false;
982 
983     /* read base register */
984     address = (int32_t)ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
985     if (!success)
986         return false;
987 
988     /* destination address */
989     address = address + imm;
990 
991     /* Set the bad_vaddr register with base address used in the instruction */
992     bad_vaddr_context.type = eContextInvalid;
993     WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
994 
995     /* We look for sp based non-volatile register stores */
996     if (nonvolatile_reg_p (src))
997     {
998 
999         RegisterInfo reg_info_src;
1000 
1001         if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src))
1002             return false;
1003 
1004         Context context;
1005         RegisterValue data_src;
1006         context.type = eContextPushRegisterOnStack;
1007         context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0);
1008 
1009         uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
1010         Error error;
1011 
1012         if (!ReadRegister (&reg_info_base, data_src))
1013             return false;
1014 
1015         if (data_src.GetAsMemoryData (&reg_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0)
1016             return false;
1017 
1018         if (!WriteMemory (context, address, buffer, reg_info_src.byte_size))
1019             return false;
1020 
1021         return true;
1022     }
1023 
1024     return false;
1025 }
1026 
1027 bool
1028 EmulateInstructionMIPS::Emulate_LW (llvm::MCInst& insn)
1029 {
1030   bool success =false;
1031     uint32_t src, base;
1032     int32_t imm, address;
1033     Context bad_vaddr_context;
1034 
1035     src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
1036     base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
1037     imm = insn.getOperand(2).getImm();
1038 
1039     RegisterInfo reg_info_base;
1040     if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
1041         return false;
1042 
1043     /* read base register */
1044     address = (int32_t)ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1045     if (!success)
1046         return false;
1047 
1048     /* destination address */
1049     address = address + imm;
1050 
1051     /* Set the bad_vaddr register with base address used in the instruction */
1052     bad_vaddr_context.type = eContextInvalid;
1053     WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
1054 
1055     if (nonvolatile_reg_p (src))
1056     {
1057         RegisterValue data_src;
1058         RegisterInfo reg_info_src;
1059 
1060         if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src))
1061             return false;
1062 
1063         Context context;
1064         context.type = eContextPopRegisterOffStack;
1065         context.SetAddress (address);
1066 
1067         if (!WriteRegister (context, &reg_info_src, data_src))
1068             return false;
1069 
1070         return true;
1071     }
1072 
1073     return false;
1074 }
1075 
1076 bool
1077 EmulateInstructionMIPS::Emulate_SUBU_ADDU (llvm::MCInst& insn)
1078 {
1079      // SUBU sp, <src>, <rt>
1080      // ADDU sp, <src>, <rt>
1081      // ADDU dst, sp, <rt>
1082 
1083     bool success = false;
1084     uint64_t result;
1085     uint8_t src, dst, rt;
1086     const char *op_name = m_insn_info->getName (insn.getOpcode ());
1087 
1088     dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
1089     src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
1090 
1091     /* Check if sp is destination register */
1092     if (dst == dwarf_sp_mips)
1093     {
1094         rt = m_reg_info->getEncodingValue (insn.getOperand(2).getReg());
1095 
1096         /* read <src> register */
1097         uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1098        if (!success)
1099            return false;
1100 
1101         /* read <rt > register */
1102         uint64_t rt_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1103         if (!success)
1104             return false;
1105 
1106         if (!strcasecmp (op_name, "SUBU"))
1107             result = src_opd_val - rt_opd_val;
1108         else
1109             result = src_opd_val + rt_opd_val;
1110 
1111         Context context;
1112         RegisterInfo reg_info_sp;
1113         if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1114             context.SetRegisterPlusOffset (reg_info_sp, rt_opd_val);
1115 
1116         /* We are allocating bytes on stack */
1117         context.type = eContextAdjustStackPointer;
1118 
1119         WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result);
1120 
1121         return true;
1122     }
1123     else if (src == dwarf_sp_mips)
1124     {
1125         rt = m_reg_info->getEncodingValue (insn.getOperand(2).getReg());
1126 
1127         /* read <src> register */
1128         uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1129         if (!success)
1130             return false;
1131 
1132        /* read <rt> register */
1133        uint64_t rt_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1134        if (!success)
1135            return false;
1136 
1137        Context context;
1138 
1139        if (!strcasecmp (op_name, "SUBU"))
1140            result = src_opd_val - rt_opd_val;
1141        else
1142            result = src_opd_val + rt_opd_val;
1143 
1144        context.SetImmediateSigned (result);
1145        context.type = eContextImmediate;
1146 
1147        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + dst, result))
1148            return false;
1149     }
1150 
1151     return true;
1152 }
1153 
1154 bool
1155 EmulateInstructionMIPS::Emulate_LUI (llvm::MCInst& insn)
1156 {
1157     // LUI rt, immediate
1158     // GPR[rt] <- sign_extend(immediate << 16)
1159 
1160     const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1161     int64_t imm = SignedBits(imm32, 31, 0);
1162     uint8_t rt;
1163     Context context;
1164 
1165     rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
1166     context.SetImmediateSigned (imm);
1167     context.type = eContextImmediate;
1168 
1169     if (WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, imm))
1170         return true;
1171 
1172     return false;
1173 }
1174 
1175 bool
1176 EmulateInstructionMIPS::Emulate_ADDIUSP (llvm::MCInst& insn)
1177 {
1178     bool success = false;
1179     const uint32_t imm9 = insn.getOperand(0).getImm();
1180     uint64_t result;
1181 
1182     // This instruction operates implicitly on stack pointer, so read <sp> register.
1183     uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1184     if (!success)
1185         return false;
1186 
1187     result = src_opd_val + imm9;
1188 
1189     Context context;
1190     RegisterInfo reg_info_sp;
1191     if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1192         context.SetRegisterPlusOffset (reg_info_sp, imm9);
1193 
1194     // We are adjusting the stack.
1195     context.type = eContextAdjustStackPointer;
1196 
1197     WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result);
1198     return true;
1199 }
1200 
1201 bool
1202 EmulateInstructionMIPS::Emulate_ADDIUS5 (llvm::MCInst& insn)
1203 {
1204     bool success = false;
1205     uint32_t base;
1206     const uint32_t imm4 = insn.getOperand(2).getImm();
1207     uint64_t result;
1208 
1209     // The source and destination register is same for this instruction.
1210     base = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
1211 
1212     // We are looking for stack adjustment only
1213     if (base == dwarf_sp_mips)
1214     {
1215         // Read stack pointer register
1216         uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1217         if (!success)
1218             return false;
1219 
1220         result = src_opd_val + imm4;
1221 
1222         Context context;
1223         RegisterInfo reg_info_sp;
1224         if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1225             context.SetRegisterPlusOffset (reg_info_sp, imm4);
1226 
1227         // We are adjusting the stack.
1228         context.type = eContextAdjustStackPointer;
1229 
1230         WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result);
1231     }
1232 
1233     return true;
1234 }
1235 
1236 bool
1237 EmulateInstructionMIPS::Emulate_SWSP (llvm::MCInst& insn)
1238 {
1239     bool success = false;
1240     uint32_t imm5 = insn.getOperand(2).getImm();
1241     uint32_t src, base;
1242     Context bad_vaddr_context;
1243     uint32_t address;
1244 
1245     src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
1246     base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
1247 
1248     RegisterInfo reg_info_base;
1249 
1250     if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
1251         return false;
1252 
1253     // read base register
1254     address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1255     if (!success)
1256         return false;
1257 
1258     // destination address
1259     address = address + imm5;
1260 
1261     // We use bad_vaddr_context to store base address which is used by H/W watchpoint
1262     // Set the bad_vaddr register with base address used in the instruction
1263     bad_vaddr_context.type = eContextInvalid;
1264     WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
1265 
1266     // We look for sp based non-volatile register stores.
1267     if (base == dwarf_sp_mips && nonvolatile_reg_p (src))
1268     {
1269         RegisterInfo reg_info_src = {};
1270         Context context;
1271         RegisterValue data_src;
1272         context.type = eContextPushRegisterOnStack;
1273         context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0);
1274 
1275         uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
1276         Error error;
1277 
1278         if (!ReadRegister (&reg_info_base, data_src))
1279             return false;
1280 
1281         if (data_src.GetAsMemoryData (&reg_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0)
1282             return false;
1283 
1284         if (!WriteMemory (context, address, buffer, reg_info_src.byte_size))
1285             return false;
1286 
1287         return true;
1288     }
1289 
1290     return false;
1291 }
1292 
1293 /* Emulate SWM16,SWM32 and SWP instruction.
1294 
1295    SWM16 always has stack pointer as a base register (but it is still available in MCInst as an operand).
1296    SWM32 and SWP can have base register other than stack pointer.
1297 */
1298 bool
1299 EmulateInstructionMIPS::Emulate_SWM16_32 (llvm::MCInst& insn)
1300 {
1301     bool success = false;
1302     uint32_t src, base;
1303     uint32_t num_operands = insn.getNumOperands();  // No of operands vary based on no of regs to store.
1304 
1305     // Base register is second last operand of the instruction.
1306     base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
1307 
1308     // We are looking for sp based stores so if base is not a stack pointer then don't proceed.
1309     if (base != dwarf_sp_mips)
1310         return false;
1311 
1312     // offset is always the last operand.
1313     uint32_t offset = insn.getOperand(num_operands-1).getImm();
1314 
1315     RegisterInfo reg_info_base;
1316     RegisterInfo reg_info_src;
1317 
1318     if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
1319         return false;
1320 
1321     // read SP
1322     uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1323     if (!success)
1324         return false;
1325 
1326     // Resulting base addrss
1327     base_address = base_address + offset;
1328 
1329     // Total no of registers to be stored are num_operands-2.
1330     for (uint32_t i = 0; i < num_operands - 2; i++)
1331     {
1332         // Get the register number to be stored.
1333         src = m_reg_info->getEncodingValue (insn.getOperand(i).getReg());
1334 
1335         /*
1336             Record only non-volatile stores.
1337             This check is required for SWP instruction because source operand could be any register.
1338             SWM16 and SWM32 instruction always has saved registers as source operands.
1339         */
1340         if (!nonvolatile_reg_p (src))
1341             return false;
1342 
1343         if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src))
1344             return false;
1345 
1346         Context context;
1347         RegisterValue data_src;
1348         context.type = eContextPushRegisterOnStack;
1349         context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0);
1350 
1351         uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
1352         Error error;
1353 
1354         if (!ReadRegister (&reg_info_base, data_src))
1355             return false;
1356 
1357         if (data_src.GetAsMemoryData (&reg_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0)
1358             return false;
1359 
1360         if (!WriteMemory (context, base_address, buffer, reg_info_src.byte_size))
1361             return false;
1362 
1363         // Stack address for next register
1364         base_address = base_address + reg_info_src.byte_size;
1365     }
1366     return true;
1367 }
1368 
1369 bool
1370 EmulateInstructionMIPS::Emulate_LWSP (llvm::MCInst& insn)
1371 {
1372     bool success = false;
1373     uint32_t src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
1374     uint32_t base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
1375     uint32_t imm5 = insn.getOperand(2).getImm();
1376     Context bad_vaddr_context;
1377 
1378     RegisterInfo reg_info_base;
1379     if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
1380         return false;
1381 
1382     // read base register
1383     uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1384     if (!success)
1385         return false;
1386 
1387     base_address = base_address + imm5;
1388 
1389     // We use bad_vaddr_context to store base address which is used by H/W watchpoint
1390     // Set the bad_vaddr register with base address used in the instruction
1391     bad_vaddr_context.type = eContextInvalid;
1392     WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, base_address);
1393 
1394     if (base == dwarf_sp_mips && nonvolatile_reg_p (src))
1395     {
1396         RegisterValue data_src;
1397         RegisterInfo reg_info_src;
1398 
1399         if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src))
1400             return false;
1401 
1402         Context context;
1403         context.type = eContextPopRegisterOffStack;
1404         context.SetAddress (base_address);
1405 
1406         if (!WriteRegister (context, &reg_info_src, data_src))
1407             return false;
1408 
1409         return true;
1410     }
1411 
1412     return false;
1413 }
1414 
1415 /* Emulate LWM16, LWM32 and LWP instructions.
1416 
1417    LWM16 always has stack pointer as a base register (but it is still available in MCInst as an operand).
1418    LWM32 and LWP can have base register other than stack pointer.
1419 */
1420 bool
1421 EmulateInstructionMIPS::Emulate_LWM16_32 (llvm::MCInst& insn)
1422 {
1423     bool success = false;
1424     uint32_t dst, base;
1425     uint32_t num_operands = insn.getNumOperands();  // No of operands vary based on no of regs to store.
1426     uint32_t imm = insn.getOperand(num_operands-1).getImm();    // imm is the last operand in the instruction.
1427 
1428     // Base register is second last operand of the instruction.
1429     base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
1430 
1431     // We are looking for sp based loads so if base is not a stack pointer then don't proceed.
1432     if (base != dwarf_sp_mips)
1433         return false;
1434 
1435     uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1436     if (!success)
1437         return false;
1438 
1439     base_address = base_address + imm;
1440 
1441     RegisterValue data_dst;
1442     RegisterInfo reg_info_dst;
1443 
1444     // Total no of registers to be re-stored are num_operands-2.
1445     for (uint32_t i = 0; i < num_operands - 2; i++)
1446     {
1447         // Get the register number to be re-stored.
1448         dst = m_reg_info->getEncodingValue (insn.getOperand(i).getReg());
1449 
1450         /*
1451             Record only non-volatile loads.
1452             This check is required for LWP instruction because destination operand could be any register.
1453             LWM16 and LWM32 instruction always has saved registers as destination operands.
1454         */
1455         if (!nonvolatile_reg_p (dst))
1456             return false;
1457 
1458         if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + dst, reg_info_dst))
1459             return false;
1460 
1461         Context context;
1462         context.type = eContextPopRegisterOffStack;
1463         context.SetAddress (base_address + (i*4));
1464 
1465         if (!WriteRegister (context, &reg_info_dst, data_dst))
1466             return false;
1467     }
1468 
1469     return true;
1470 }
1471 
1472 bool
1473 EmulateInstructionMIPS::Emulate_JRADDIUSP (llvm::MCInst& insn)
1474 {
1475     bool success = false;
1476     int32_t imm5 = insn.getOperand(0).getImm();
1477 
1478     /* JRADDIUSP immediate
1479     *       PC <- RA
1480     *       SP <- SP + zero_extend(Immediate << 2)
1481     */
1482 
1483     // This instruction operates implicitly on stack pointer, so read <sp> register.
1484     int32_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1485     if (!success)
1486         return false;
1487 
1488     int32_t ra_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
1489     if (!success)
1490         return false;
1491 
1492     int32_t result = src_opd_val + imm5;
1493 
1494     Context context;
1495 
1496     // Update the PC
1497     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, ra_val))
1498         return false;
1499 
1500     RegisterInfo reg_info_sp;
1501     if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1502         context.SetRegisterPlusOffset (reg_info_sp, imm5);
1503 
1504     // We are adjusting stack
1505     context.type = eContextAdjustStackPointer;
1506 
1507     // update SP
1508     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result))
1509         return false;
1510 
1511     return true;
1512 }
1513 
1514 static int
1515 IsAdd64bitOverflow (int32_t a, int32_t b)
1516 {
1517   int32_t r = (uint32_t) a + (uint32_t) b;
1518   return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1519 }
1520 
1521 /*
1522     Emulate below MIPS branch instructions.
1523     BEQ, BNE : Branch on condition
1524     BEQL, BNEL : Branch likely
1525 */
1526 bool
1527 EmulateInstructionMIPS::Emulate_BXX_3ops (llvm::MCInst& insn)
1528 {
1529     bool success = false;
1530     uint32_t rs, rt;
1531     int32_t offset, pc, target = 0, rs_val, rt_val;
1532     const char *op_name = m_insn_info->getName (insn.getOpcode ());
1533 
1534     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
1535     rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
1536     offset = insn.getOperand(2).getImm();
1537 
1538     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1539     if (!success)
1540         return false;
1541 
1542     rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
1543     if (!success)
1544         return false;
1545 
1546     rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1547     if (!success)
1548         return false;
1549 
1550     if (!strcasecmp (op_name, "BEQ") ||
1551         !strcasecmp (op_name, "BEQL"))
1552     {
1553         if (rs_val == rt_val)
1554             target = pc + offset;
1555         else
1556             target = pc + 8;
1557     }
1558     else if (!strcasecmp (op_name, "BNE") ||
1559              !strcasecmp (op_name, "BNEL"))
1560     {
1561         if (rs_val != rt_val)
1562             target = pc + offset;
1563         else
1564             target = pc + 8;
1565     }
1566 
1567     Context context;
1568     context.type = eContextRelativeBranchImmediate;
1569     context.SetImmediate (offset);
1570 
1571     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
1572         return false;
1573 
1574     return true;
1575 }
1576 
1577 /*
1578     Emulate below MIPS branch instructions.
1579     BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch instructions with no delay slot
1580 */
1581 bool
1582 EmulateInstructionMIPS::Emulate_BXX_3ops_C (llvm::MCInst& insn)
1583 {
1584     bool success = false;
1585     uint32_t rs, rt;
1586     int32_t offset, pc, target = 0, rs_val, rt_val;
1587     const char *op_name = m_insn_info->getName (insn.getOpcode ());
1588     uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1589 
1590     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
1591     rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
1592     offset = insn.getOperand(2).getImm();
1593 
1594     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1595     if (!success)
1596         return false;
1597 
1598     rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
1599     if (!success)
1600         return false;
1601 
1602     rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1603     if (!success)
1604         return false;
1605 
1606     if (!strcasecmp (op_name, "BEQC"))
1607     {
1608         if (rs_val == rt_val)
1609             target = pc + offset;
1610         else
1611             target = pc + 4;
1612     }
1613     else if (!strcasecmp (op_name, "BNEC"))
1614     {
1615         if (rs_val != rt_val)
1616             target = pc + offset;
1617         else
1618             target = pc + 4;
1619     }
1620     else if (!strcasecmp (op_name, "BLTC"))
1621     {
1622         if (rs_val < rt_val)
1623             target = pc + offset;
1624         else
1625             target = pc + 4;
1626     }
1627     else if (!strcasecmp (op_name, "BGEC"))
1628     {
1629         if (rs_val >= rt_val)
1630             target = pc  + offset;
1631         else
1632             target = pc + 4;
1633     }
1634     else if (!strcasecmp (op_name, "BLTUC"))
1635     {
1636         if (rs_val < rt_val)
1637             target = pc + offset;
1638         else
1639             target = pc + 4;
1640     }
1641     else if (!strcasecmp (op_name, "BGEUC"))
1642     {
1643         if ((uint32_t)rs_val >= (uint32_t)rt_val)
1644             target = pc + offset;
1645         else
1646             target = pc + 4;
1647     }
1648     else if (!strcasecmp (op_name, "BOVC"))
1649     {
1650         if (IsAdd64bitOverflow (rs_val, rt_val))
1651             target = pc + offset;
1652         else
1653             target = pc + 4;
1654     }
1655     else if (!strcasecmp (op_name, "BNVC"))
1656     {
1657         if (!IsAdd64bitOverflow (rs_val, rt_val))
1658             target = pc + offset;
1659         else
1660             target = pc + 4;
1661     }
1662 
1663     Context context;
1664     context.type = eContextRelativeBranchImmediate;
1665     context.SetImmediate (current_inst_size + offset);
1666 
1667     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
1668         return false;
1669 
1670     return true;
1671 }
1672 
1673 /*
1674     Emulate below MIPS conditional branch and link instructions.
1675     BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1676 */
1677 bool
1678 EmulateInstructionMIPS::Emulate_Bcond_Link_C (llvm::MCInst& insn)
1679 {
1680     bool success = false;
1681     uint32_t rs;
1682     int32_t offset, pc, target = 0;
1683     int32_t rs_val;
1684     const char *op_name = m_insn_info->getName (insn.getOpcode ());
1685 
1686     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
1687     offset = insn.getOperand(1).getImm();
1688 
1689     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1690     if (!success)
1691         return false;
1692 
1693     rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
1694     if (!success)
1695         return false;
1696 
1697     if (!strcasecmp (op_name, "BLEZALC"))
1698     {
1699         if (rs_val <= 0)
1700             target = pc + offset;
1701         else
1702             target = pc + 4;
1703     }
1704     else if (!strcasecmp (op_name, "BGEZALC"))
1705     {
1706         if (rs_val >= 0)
1707             target = pc + offset;
1708         else
1709             target = pc + 4;
1710     }
1711     else if (!strcasecmp (op_name, "BLTZALC"))
1712     {
1713         if (rs_val < 0)
1714             target = pc + offset;
1715         else
1716             target = pc + 4;
1717     }
1718     else if (!strcasecmp (op_name, "BGTZALC"))
1719     {
1720         if (rs_val > 0)
1721             target = pc + offset;
1722         else
1723             target = pc + 4;
1724     }
1725     else if (!strcasecmp (op_name, "BEQZALC"))
1726     {
1727         if (rs_val == 0)
1728             target = pc + offset;
1729         else
1730             target = pc + 4;
1731     }
1732     else if (!strcasecmp (op_name, "BNEZALC"))
1733     {
1734         if (rs_val != 0)
1735             target = pc + offset;
1736         else
1737             target = pc + 4;
1738     }
1739 
1740     Context context;
1741 
1742     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
1743         return false;
1744 
1745     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4))
1746         return false;
1747 
1748     return true;
1749 }
1750 
1751 /*
1752     Emulate below MIPS Non-Compact conditional branch and link instructions.
1753     BLTZAL, BGEZAL      :
1754     BLTZALL, BGEZALL    : Branch likely
1755 */
1756 bool
1757 EmulateInstructionMIPS::Emulate_Bcond_Link (llvm::MCInst& insn)
1758 {
1759     bool success = false;
1760     uint32_t rs;
1761     int32_t offset, pc, target = 0;
1762     int32_t rs_val;
1763     const char *op_name = m_insn_info->getName (insn.getOpcode ());
1764 
1765     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
1766     offset = insn.getOperand(1).getImm();
1767 
1768     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1769     if (!success)
1770         return false;
1771 
1772     rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
1773     if (!success)
1774         return false;
1775 
1776     if (!strcasecmp (op_name, "BLTZAL") ||
1777         !strcasecmp (op_name, "BLTZALL"))
1778     {
1779         if ((int32_t) rs_val < 0)
1780             target = pc + offset;
1781         else
1782             target = pc + 8;
1783     }
1784     else if (!strcasecmp (op_name, "BGEZAL") ||
1785              !strcasecmp (op_name, "BGEZALL"))
1786     {
1787         if ((int32_t) rs_val >= 0)
1788             target = pc + offset;
1789         else
1790             target = pc + 8;
1791     }
1792 
1793     Context context;
1794 
1795     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
1796         return false;
1797 
1798     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8))
1799         return false;
1800 
1801     return true;
1802 }
1803 
1804 /*
1805     Emulate below MIPS branch instructions.
1806     BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
1807     BLTZ, BGEZ, BGTZ, BLEZ     : Non-compact branches
1808 */
1809 bool
1810 EmulateInstructionMIPS::Emulate_BXX_2ops (llvm::MCInst& insn)
1811 {
1812     bool success = false;
1813     uint32_t rs;
1814     int32_t offset, pc, target = 0;
1815     int32_t rs_val;
1816     const char *op_name = m_insn_info->getName (insn.getOpcode ());
1817 
1818     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
1819     offset = insn.getOperand(1).getImm();
1820 
1821     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1822     if (!success)
1823         return false;
1824 
1825     rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
1826     if (!success)
1827         return false;
1828 
1829     if (!strcasecmp (op_name, "BLTZL") ||
1830         !strcasecmp (op_name, "BLTZ"))
1831     {
1832         if (rs_val < 0)
1833             target = pc + offset;
1834         else
1835             target = pc + 8;
1836     }
1837     else if (!strcasecmp (op_name, "BGEZL") ||
1838              !strcasecmp (op_name, "BGEZ"))
1839     {
1840         if (rs_val >= 0)
1841             target = pc + offset;
1842         else
1843             target = pc + 8;
1844     }
1845     else if (!strcasecmp (op_name, "BGTZL") ||
1846              !strcasecmp (op_name, "BGTZ"))
1847     {
1848         if (rs_val > 0)
1849             target = pc + offset;
1850         else
1851             target = pc + 8;
1852     }
1853     else if (!strcasecmp (op_name, "BLEZL") ||
1854              !strcasecmp (op_name, "BLEZ"))
1855     {
1856         if (rs_val <= 0)
1857             target = pc + offset;
1858         else
1859             target = pc + 8;
1860     }
1861 
1862     Context context;
1863     context.type = eContextRelativeBranchImmediate;
1864     context.SetImmediate (offset);
1865 
1866     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
1867         return false;
1868 
1869     return true;
1870 }
1871 
1872 /*
1873     Emulate below MIPS branch instructions.
1874     BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
1875 */
1876 bool
1877 EmulateInstructionMIPS::Emulate_BXX_2ops_C (llvm::MCInst& insn)
1878 {
1879     bool success = false;
1880     uint32_t rs;
1881     int32_t offset, pc, target = 0;
1882     int32_t rs_val;
1883     const char *op_name = m_insn_info->getName (insn.getOpcode ());
1884     uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1885 
1886     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
1887     offset = insn.getOperand(1).getImm();
1888 
1889     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1890     if (!success)
1891         return false;
1892 
1893     rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
1894     if (!success)
1895         return false;
1896 
1897     if (!strcasecmp (op_name, "BLTZC"))
1898     {
1899         if (rs_val < 0)
1900             target = pc + offset;
1901         else
1902             target = pc + 4;
1903     }
1904     else if (!strcasecmp (op_name, "BLEZC"))
1905     {
1906         if (rs_val <= 0)
1907             target = pc + offset;
1908         else
1909             target = pc + 4;
1910     }
1911     else if (!strcasecmp (op_name, "BGEZC"))
1912     {
1913         if (rs_val >= 0)
1914             target = pc + offset;
1915         else
1916             target = pc + 4;
1917     }
1918     else if (!strcasecmp (op_name, "BGTZC"))
1919     {
1920         if (rs_val > 0)
1921             target = pc + offset;
1922         else
1923             target = pc + 4;
1924     }
1925     else if (!strcasecmp (op_name, "BEQZC"))
1926     {
1927         if (rs_val == 0)
1928             target = pc + offset;
1929         else
1930             target = pc + 4;
1931     }
1932     else if (!strcasecmp (op_name, "BNEZC"))
1933     {
1934         if (rs_val != 0)
1935             target = pc + offset;
1936         else
1937             target = pc + 4;
1938     }
1939 
1940     Context context;
1941     context.type = eContextRelativeBranchImmediate;
1942     context.SetImmediate (current_inst_size + offset);
1943 
1944     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
1945         return false;
1946 
1947     return true;
1948 }
1949 
1950 bool
1951 EmulateInstructionMIPS::Emulate_B16_MM (llvm::MCInst& insn)
1952 {
1953     bool success = false;
1954     int32_t offset, pc, target;
1955     uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1956 
1957     offset = insn.getOperand(0).getImm();
1958 
1959     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1960     if (!success)
1961         return false;
1962 
1963     // unconditional branch
1964     target = pc + offset;
1965 
1966     Context context;
1967     context.type = eContextRelativeBranchImmediate;
1968     context.SetImmediate (current_inst_size + offset);
1969 
1970     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
1971         return false;
1972 
1973     return true;
1974 }
1975 
1976 /*
1977    BEQZC, BNEZC are 32 bit compact instructions without a delay slot.
1978    BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
1979    BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
1980 */
1981 bool
1982 EmulateInstructionMIPS::Emulate_Branch_MM (llvm::MCInst& insn)
1983 {
1984     bool success = false;
1985     int32_t target = 0;
1986     uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1987     const char *op_name = m_insn_info->getName (insn.getOpcode ());
1988     bool update_ra = false;
1989     uint32_t ra_offset = 0;
1990 
1991     /*
1992      * BEQZ16 rs, offset
1993      *      condition <- (GPR[rs] = 0)
1994      *      if condition then
1995      *          PC = PC + sign_ext (offset || 0)
1996      *
1997      * BNEZ16 rs, offset
1998      *      condition <- (GPR[rs] != 0)
1999      *      if condition then
2000      *          PC = PC + sign_ext (offset || 0)
2001      *
2002      * BEQZC rs, offset     (compact instruction: No delay slot)
2003      *      condition <- (GPR[rs] == 0)
2004      *      if condition then
2005      *         PC = PC + 4 + sign_ext (offset || 0)
2006     */
2007 
2008     uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2009     int32_t offset = insn.getOperand(1).getImm();
2010 
2011     int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2012     if (!success)
2013         return false;
2014 
2015     int32_t rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
2016     if (!success)
2017         return false;
2018 
2019     if (!strcasecmp (op_name, "BEQZ16_MM"))
2020     {
2021         if (rs_val == 0)
2022             target = pc + offset;
2023         else
2024             target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction.
2025     }
2026     else if (!strcasecmp (op_name, "BNEZ16_MM"))
2027     {
2028         if (rs_val != 0)
2029             target = pc + offset;
2030         else
2031             target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction.
2032     }
2033     else if (!strcasecmp (op_name, "BEQZC_MM"))
2034     {
2035         if (rs_val == 0)
2036             target = pc + 4 + offset;
2037         else
2038             target = pc + 4;         // 32 bit instruction and does not have delay slot instruction.
2039     }
2040     else if (!strcasecmp (op_name, "BNEZC_MM"))
2041     {
2042         if (rs_val != 0)
2043             target = pc + 4 + offset;
2044         else
2045             target = pc + 4;         // 32 bit instruction and does not have delay slot instruction.
2046     }
2047     else if (!strcasecmp (op_name, "BGEZALS_MM"))
2048     {
2049         if (rs_val >= 0)
2050             target = pc + offset;
2051         else
2052             target = pc + 6;        // 32 bit instruction with short (2-byte) delay slot
2053 
2054         update_ra = true;
2055         ra_offset = 6;
2056     }
2057     else if (!strcasecmp (op_name, "BLTZALS_MM"))
2058     {
2059         if (rs_val >= 0)
2060             target = pc + offset;
2061         else
2062             target = pc + 6;        // 32 bit instruction with short (2-byte) delay slot
2063 
2064         update_ra = true;
2065         ra_offset = 6;
2066     }
2067 
2068     Context context;
2069     context.type = eContextRelativeBranchImmediate;
2070     context.SetImmediate (current_inst_size + offset);
2071 
2072     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2073         return false;
2074 
2075     if (update_ra)
2076     {
2077         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
2078             return false;
2079     }
2080     return true;
2081 }
2082 
2083 /* Emulate micromips jump instructions.
2084    JALR16,JALRS16
2085 */
2086 bool
2087 EmulateInstructionMIPS::Emulate_JALRx16_MM (llvm::MCInst& insn)
2088 {
2089     bool success = false;
2090     uint32_t ra_offset = 0;
2091     const char *op_name = m_insn_info->getName (insn.getOpcode ());
2092 
2093     uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2094 
2095     uint32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2096     if (!success)
2097         return false;
2098 
2099     uint32_t rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
2100     if (!success)
2101         return false;
2102 
2103     if (!strcasecmp (op_name, "JALR16_MM"))
2104         ra_offset = 6;      // 2-byte instruction with 4-byte delay slot.
2105     else if (!strcasecmp (op_name, "JALRS16_MM"))
2106         ra_offset = 4;      // 2-byte instruction with 2-byte delay slot.
2107 
2108     Context context;
2109 
2110     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
2111         return false;
2112 
2113     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
2114         return false;
2115 
2116     return true;
2117 }
2118 
2119 /* Emulate JALS and JALX instructions.
2120     JALS 32 bit instruction with short (2-byte) delay slot.
2121     JALX 32 bit instruction with 4-byte delay slot.
2122 */
2123 bool
2124 EmulateInstructionMIPS::Emulate_JALx (llvm::MCInst& insn)
2125 {
2126     bool success = false;
2127     uint32_t offset=0, target=0, pc=0, ra_offset=0;
2128     const char *op_name = m_insn_info->getName (insn.getOpcode ());
2129 
2130     /*
2131      * JALS target
2132      *      RA = PC + 6
2133      *      offset = sign_ext (offset << 1)
2134      *      PC = PC[31-27] | offset
2135      * JALX target
2136      *      RA = PC + 8
2137      *      offset = sign_ext (offset << 2)
2138      *      PC = PC[31-28] | offset
2139     */
2140     offset = insn.getOperand(0).getImm();
2141 
2142     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2143     if (!success)
2144         return false;
2145 
2146     // These are PC-region branches and not PC-relative.
2147     if (!strcasecmp (op_name, "JALS_MM"))
2148     {
2149         // target address is in the “current” 128 MB-aligned region
2150         target = (pc & 0xF8000000UL) | offset;
2151         ra_offset = 6;
2152     }
2153     else if (!strcasecmp (op_name, "JALX_MM"))
2154     {
2155         // target address is in the “current” 256 MB-aligned region
2156         target = (pc & 0xF0000000UL) | offset;
2157         ra_offset = 8;
2158     }
2159 
2160     Context context;
2161 
2162     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2163         return false;
2164 
2165     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
2166         return false;
2167 
2168     return true;
2169 }
2170 
2171 bool
2172 EmulateInstructionMIPS::Emulate_JALRS (llvm::MCInst& insn)
2173 {
2174     bool success = false;
2175     uint32_t rs=0, rt=0;
2176     int32_t pc=0, rs_val=0;
2177 
2178     /*
2179         JALRS rt, rs
2180             GPR[rt] <- PC + 6
2181             PC <- GPR[rs]
2182     */
2183 
2184     rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2185     rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
2186 
2187     rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
2188     if (!success)
2189         return false;
2190 
2191     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2192     if (!success)
2193         return false;
2194 
2195     Context context;
2196 
2197     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
2198         return false;
2199 
2200     // This is 4-byte instruction with 2-byte delay slot.
2201     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, pc + 6))
2202         return false;
2203 
2204     return true;
2205 }
2206 
2207 bool
2208 EmulateInstructionMIPS::Emulate_BAL (llvm::MCInst& insn)
2209 {
2210     bool success = false;
2211     int32_t offset, pc, target;
2212 
2213     /*
2214      * BAL offset
2215      *      offset = sign_ext (offset << 2)
2216      *      RA = PC + 8
2217      *      PC = PC + offset
2218     */
2219     offset = insn.getOperand(0).getImm();
2220 
2221     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2222     if (!success)
2223         return false;
2224 
2225     target = pc + offset;
2226 
2227     Context context;
2228 
2229     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2230         return false;
2231 
2232     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8))
2233         return false;
2234 
2235     return true;
2236 }
2237 
2238 bool
2239 EmulateInstructionMIPS::Emulate_BALC (llvm::MCInst& insn)
2240 {
2241     bool success = false;
2242     int32_t offset, pc, target;
2243 
2244     /*
2245      * BALC offset
2246      *      offset = sign_ext (offset << 2)
2247      *      RA = PC + 4
2248      *      PC = PC + 4 + offset
2249     */
2250     offset = insn.getOperand(0).getImm();
2251 
2252     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2253     if (!success)
2254         return false;
2255 
2256     target = pc + offset;
2257 
2258     Context context;
2259 
2260     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2261         return false;
2262 
2263     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4))
2264         return false;
2265 
2266     return true;
2267 }
2268 
2269 bool
2270 EmulateInstructionMIPS::Emulate_BC (llvm::MCInst& insn)
2271 {
2272     bool success = false;
2273     int32_t offset, pc, target;
2274 
2275     /*
2276      * BC offset
2277      *      offset = sign_ext (offset << 2)
2278      *      PC = PC + 4 + offset
2279     */
2280     offset = insn.getOperand(0).getImm();
2281 
2282     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2283     if (!success)
2284         return false;
2285 
2286     target = pc + offset;
2287 
2288     Context context;
2289 
2290     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2291         return false;
2292 
2293     return true;
2294 }
2295 
2296 bool
2297 EmulateInstructionMIPS::Emulate_J (llvm::MCInst& insn)
2298 {
2299     bool success = false;
2300     uint32_t offset, pc;
2301 
2302     /*
2303      * J offset
2304      *      offset = sign_ext (offset << 2)
2305      *      PC = PC[63-28] | offset
2306     */
2307     offset = insn.getOperand(0).getImm();
2308 
2309     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2310     if (!success)
2311         return false;
2312 
2313     /* This is a PC-region branch and not PC-relative */
2314     pc = (pc & 0xF0000000UL) | offset;
2315 
2316     Context context;
2317 
2318     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, pc))
2319         return false;
2320 
2321     return true;
2322 }
2323 
2324 bool
2325 EmulateInstructionMIPS::Emulate_JAL (llvm::MCInst& insn)
2326 {
2327     bool success = false;
2328     uint32_t offset, target, pc;
2329 
2330     /*
2331      * JAL offset
2332      *      offset = sign_ext (offset << 2)
2333      *      PC = PC[63-28] | offset
2334     */
2335     offset = insn.getOperand(0).getImm();
2336 
2337     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2338     if (!success)
2339         return false;
2340 
2341     /* This is a PC-region branch and not PC-relative */
2342     target = (pc & 0xF0000000UL) | offset;
2343 
2344     Context context;
2345 
2346     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2347         return false;
2348 
2349     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8))
2350         return false;
2351 
2352     return true;
2353 }
2354 
2355 bool
2356 EmulateInstructionMIPS::Emulate_JALR (llvm::MCInst& insn)
2357 {
2358     bool success = false;
2359     uint32_t rs, rt;
2360     uint32_t pc, rs_val;
2361 
2362     /*
2363      * JALR rt, rs
2364      *      GPR[rt] = PC + 8
2365      *      PC = GPR[rs]
2366     */
2367     rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2368     rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
2369 
2370     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2371     if (!success)
2372         return false;
2373 
2374     rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
2375     if (!success)
2376         return false;
2377 
2378     Context context;
2379 
2380     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
2381         return false;
2382 
2383     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, pc + 8))
2384         return false;
2385 
2386     return true;
2387 }
2388 
2389 bool
2390 EmulateInstructionMIPS::Emulate_JIALC (llvm::MCInst& insn)
2391 {
2392     bool success = false;
2393     uint32_t rt;
2394     int32_t target, offset, pc, rt_val;
2395 
2396     /*
2397      * JIALC rt, offset
2398      *      offset = sign_ext (offset)
2399      *      PC = GPR[rt] + offset
2400      *      RA = PC + 4
2401     */
2402     rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2403     offset = insn.getOperand(1).getImm();
2404 
2405     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2406     if (!success)
2407         return false;
2408 
2409     rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
2410     if (!success)
2411         return false;
2412 
2413     target = rt_val + offset;
2414 
2415     Context context;
2416 
2417     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2418         return false;
2419 
2420     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4))
2421         return false;
2422 
2423     return true;
2424 }
2425 
2426 bool
2427 EmulateInstructionMIPS::Emulate_JIC (llvm::MCInst& insn)
2428 {
2429     bool success = false;
2430     uint32_t rt;
2431     int32_t target, offset, rt_val;
2432 
2433     /*
2434      * JIC rt, offset
2435      *      offset = sign_ext (offset)
2436      *      PC = GPR[rt] + offset
2437     */
2438     rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2439     offset = insn.getOperand(1).getImm();
2440 
2441     rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
2442     if (!success)
2443         return false;
2444 
2445     target = rt_val + offset;
2446 
2447     Context context;
2448 
2449     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2450         return false;
2451 
2452     return true;
2453 }
2454 
2455 bool
2456 EmulateInstructionMIPS::Emulate_JR (llvm::MCInst& insn)
2457 {
2458     bool success = false;
2459     uint32_t rs;
2460     uint32_t rs_val;
2461 
2462     /*
2463      * JR rs
2464      *      PC = GPR[rs]
2465     */
2466     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2467 
2468     rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
2469     if (!success)
2470         return false;
2471 
2472     Context context;
2473 
2474     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
2475         return false;
2476 
2477     return true;
2478 }
2479 
2480 /*
2481     Emulate Branch on FP True/False
2482     BC1F, BC1FL :   Branch on FP False (L stands for branch likely)
2483     BC1T, BC1TL :   Branch on FP True  (L stands for branch likely)
2484 */
2485 bool
2486 EmulateInstructionMIPS::Emulate_FP_branch (llvm::MCInst& insn)
2487 {
2488     bool success = false;
2489     uint32_t cc, fcsr;
2490     int32_t pc, offset, target = 0;
2491     const char *op_name = m_insn_info->getName (insn.getOpcode ());
2492 
2493     cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2494     offset = insn.getOperand(1).getImm();
2495 
2496     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2497     if (!success)
2498         return false;
2499 
2500     fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
2501     if (!success)
2502         return false;
2503 
2504     /* fcsr[23], fcsr[25-31] are vaild condition bits */
2505     fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2506 
2507     if (!strcasecmp (op_name, "BC1F") ||
2508         !strcasecmp (op_name, "BC1FL"))
2509     {
2510         if ((fcsr & (1 << cc)) == 0)
2511             target = pc + offset;
2512         else
2513             target = pc + 8;
2514     }
2515     else if (!strcasecmp (op_name, "BC1T") ||
2516              !strcasecmp (op_name, "BC1TL"))
2517     {
2518         if ((fcsr & (1 << cc)) != 0)
2519             target = pc + offset;
2520         else
2521             target = pc + 8;
2522     }
2523     Context context;
2524 
2525     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2526         return false;
2527 
2528     return true;
2529 }
2530 
2531 bool
2532 EmulateInstructionMIPS::Emulate_BC1EQZ (llvm::MCInst& insn)
2533 {
2534     bool success = false;
2535     uint32_t ft;
2536     uint32_t ft_val;
2537     int32_t target, pc, offset;
2538 
2539     /*
2540      * BC1EQZ ft, offset
2541      *  condition <- (FPR[ft].bit0 == 0)
2542      *      if condition then
2543      *          offset = sign_ext (offset)
2544      *          PC = PC + 4 + offset
2545     */
2546     ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2547     offset = insn.getOperand(1).getImm();
2548 
2549     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2550     if (!success)
2551         return false;
2552 
2553     ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + ft, 0, &success);
2554     if (!success)
2555         return false;
2556 
2557     if ((ft_val & 1) == 0)
2558         target = pc + 4 + offset;
2559     else
2560         target = pc + 8;
2561 
2562     Context context;
2563 
2564     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2565         return false;
2566 
2567     return true;
2568 }
2569 
2570 bool
2571 EmulateInstructionMIPS::Emulate_BC1NEZ (llvm::MCInst& insn)
2572 {
2573     bool success = false;
2574     uint32_t ft;
2575     uint32_t ft_val;
2576     int32_t target, pc, offset;
2577 
2578     /*
2579      * BC1NEZ ft, offset
2580      *  condition <- (FPR[ft].bit0 != 0)
2581      *      if condition then
2582      *          offset = sign_ext (offset)
2583      *          PC = PC + 4 + offset
2584     */
2585     ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2586     offset = insn.getOperand(1).getImm();
2587 
2588     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2589     if (!success)
2590         return false;
2591 
2592     ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + ft, 0, &success);
2593     if (!success)
2594         return false;
2595 
2596     if ((ft_val & 1) != 0)
2597         target = pc + 4 + offset;
2598     else
2599         target = pc + 8;
2600 
2601     Context context;
2602 
2603     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2604         return false;
2605 
2606     return true;
2607 }
2608 
2609 /*
2610     Emulate MIPS-3D Branch instructions
2611     BC1ANY2F, BC1ANY2T  : Branch on Any of Two Floating Point Condition Codes False/True
2612     BC1ANY4F, BC1ANY4T  : Branch on Any of Four Floating Point Condition Codes False/True
2613 */
2614 bool
2615 EmulateInstructionMIPS::Emulate_3D_branch (llvm::MCInst& insn)
2616 {
2617     bool success = false;
2618     uint32_t cc, fcsr;
2619     int32_t pc, offset, target = 0;
2620     const char *op_name = m_insn_info->getName (insn.getOpcode ());
2621 
2622     cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2623     offset = insn.getOperand(1).getImm();
2624 
2625     pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2626     if (!success)
2627         return false;
2628 
2629     fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
2630     if (!success)
2631         return false;
2632 
2633     /* fcsr[23], fcsr[25-31] are vaild condition bits */
2634     fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2635 
2636     if (!strcasecmp (op_name, "BC1ANY2F"))
2637     {
2638         /* if any one bit is 0 */
2639         if (((fcsr >> cc) & 3) != 3)
2640             target = pc + offset;
2641         else
2642             target = pc + 8;
2643     }
2644     else if (!strcasecmp (op_name, "BC1ANY2T"))
2645     {
2646         /* if any one bit is 1 */
2647         if (((fcsr >> cc) & 3) != 0)
2648             target = pc + offset;
2649         else
2650             target = pc + 8;
2651     }
2652     else if (!strcasecmp (op_name, "BC1ANY4F"))
2653     {
2654         /* if any one bit is 0 */
2655         if (((fcsr >> cc) & 0xf) != 0xf)
2656             target = pc + offset;
2657         else
2658             target = pc + 8;
2659     }
2660     else if (!strcasecmp (op_name, "BC1ANY4T"))
2661     {
2662         /* if any one bit is 1 */
2663         if (((fcsr >> cc) & 0xf) != 0)
2664             target = pc + offset;
2665         else
2666             target = pc + 8;
2667     }
2668     Context context;
2669 
2670     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2671         return false;
2672 
2673     return true;
2674 }
2675 
2676 bool
2677 EmulateInstructionMIPS::Emulate_BNZB (llvm::MCInst& insn)
2678 {
2679     return Emulate_MSA_Branch_DF(insn, 1, true);
2680 }
2681 
2682 bool
2683 EmulateInstructionMIPS::Emulate_BNZH (llvm::MCInst& insn)
2684 {
2685     return Emulate_MSA_Branch_DF(insn, 2, true);
2686 }
2687 
2688 bool
2689 EmulateInstructionMIPS::Emulate_BNZW (llvm::MCInst& insn)
2690 {
2691     return Emulate_MSA_Branch_DF(insn, 4, true);
2692 }
2693 
2694 bool
2695 EmulateInstructionMIPS::Emulate_BNZD (llvm::MCInst& insn)
2696 {
2697     return Emulate_MSA_Branch_DF(insn, 8, true);
2698 }
2699 
2700 bool
2701 EmulateInstructionMIPS::Emulate_BZB (llvm::MCInst& insn)
2702 {
2703     return Emulate_MSA_Branch_DF(insn, 1, false);
2704 }
2705 
2706 bool
2707 EmulateInstructionMIPS::Emulate_BZH (llvm::MCInst& insn)
2708 {
2709     return Emulate_MSA_Branch_DF(insn, 2, false);
2710 }
2711 
2712 bool
2713 EmulateInstructionMIPS::Emulate_BZW (llvm::MCInst& insn)
2714 {
2715     return Emulate_MSA_Branch_DF(insn, 4, false);
2716 }
2717 
2718 bool
2719 EmulateInstructionMIPS::Emulate_BZD (llvm::MCInst& insn)
2720 {
2721     return Emulate_MSA_Branch_DF(insn, 8, false);
2722 }
2723 
2724 bool
2725 EmulateInstructionMIPS::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_byte_size, bool bnz)
2726 {
2727     bool success = false, branch_hit = true;
2728     int32_t target = 0;
2729     RegisterValue reg_value;
2730     const uint8_t *ptr = NULL;
2731 
2732     uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2733     int32_t offset = insn.getOperand(1).getImm();
2734 
2735     int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2736     if (!success)
2737         return false;
2738 
2739     if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2740         ptr = (const uint8_t *)reg_value.GetBytes();
2741     else
2742         return false;
2743 
2744     for(int i = 0; i < 16 / element_byte_size; i++)
2745     {
2746         switch(element_byte_size)
2747         {
2748             case 1:
2749                 if((*ptr == 0 && bnz) || (*ptr != 0 && !bnz) )
2750                     branch_hit = false;
2751                 break;
2752             case 2:
2753                 if ((*(const uint16_t *)ptr == 0 && bnz) || (*(const uint16_t *)ptr != 0 && !bnz))
2754                     branch_hit = false;
2755                 break;
2756             case 4:
2757                 if ((*(const uint32_t *)ptr == 0 && bnz) || (*(const uint32_t *)ptr != 0 && !bnz))
2758                     branch_hit = false;
2759                 break;
2760             case 8:
2761                 if ((*(const uint64_t *)ptr == 0 && bnz) || (*(const uint64_t *)ptr != 0 && !bnz))
2762                     branch_hit = false;
2763                 break;
2764         }
2765         if(!branch_hit)
2766            break;
2767         ptr = ptr + element_byte_size;
2768     }
2769 
2770     if(branch_hit)
2771         target = pc + offset;
2772     else
2773         target = pc + 8;
2774 
2775     Context context;
2776     context.type = eContextRelativeBranchImmediate;
2777 
2778     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2779         return false;
2780 
2781     return true;
2782 }
2783 
2784 bool
2785 EmulateInstructionMIPS::Emulate_BNZV (llvm::MCInst& insn)
2786 {
2787     return Emulate_MSA_Branch_V (insn, true);
2788 }
2789 
2790 bool
2791 EmulateInstructionMIPS::Emulate_BZV (llvm::MCInst& insn)
2792 {
2793     return Emulate_MSA_Branch_V (insn, false);
2794 }
2795 
2796 bool
2797 EmulateInstructionMIPS::Emulate_MSA_Branch_V (llvm::MCInst& insn, bool bnz)
2798 {
2799     bool success = false;
2800     int32_t target = 0;
2801     llvm::APInt wr_val = llvm::APInt::getNullValue(128);
2802     llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
2803     llvm::APInt zero_value = llvm::APInt::getNullValue(128);
2804     RegisterValue reg_value;
2805 
2806     uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
2807     int32_t offset = insn.getOperand(1).getImm();
2808 
2809     int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2810     if (!success)
2811         return false;
2812 
2813     if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2814         wr_val = reg_value.GetAsUInt128(fail_value);
2815     else
2816         return false;
2817 
2818     if((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2819         target = pc + offset;
2820     else
2821         target = pc + 8;
2822 
2823     Context context;
2824     context.type = eContextRelativeBranchImmediate;
2825 
2826     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
2827         return false;
2828 
2829     return true;
2830 }
2831 
2832 bool
2833 EmulateInstructionMIPS::Emulate_LDST_Imm (llvm::MCInst& insn)
2834 {
2835     bool success = false;
2836     uint32_t base;
2837     int32_t imm, address;
2838     Context bad_vaddr_context;
2839 
2840     uint32_t num_operands = insn.getNumOperands();
2841     base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
2842     imm = insn.getOperand(num_operands-1).getImm();
2843 
2844     RegisterInfo reg_info_base;
2845     if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
2846         return false;
2847 
2848     /* read base register */
2849     address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
2850     if (!success)
2851         return false;
2852 
2853     /* destination address */
2854     address = address + imm;
2855 
2856     /* Set the bad_vaddr register with base address used in the instruction */
2857     bad_vaddr_context.type = eContextInvalid;
2858     WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
2859 
2860     return true;
2861 }
2862 
2863 bool
2864 EmulateInstructionMIPS::Emulate_LDST_Reg (llvm::MCInst& insn)
2865 {
2866     bool success = false;
2867     uint32_t base, index;
2868     int32_t address, index_address;
2869     Context bad_vaddr_context;
2870 
2871     uint32_t num_operands = insn.getNumOperands();
2872     base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
2873     index = m_reg_info->getEncodingValue (insn.getOperand(num_operands-1).getReg());
2874 
2875     RegisterInfo reg_info_base, reg_info_index;
2876     if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
2877         return false;
2878 
2879     if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + index, reg_info_index))
2880         return false;
2881 
2882     /* read base register */
2883     address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
2884     if (!success)
2885         return false;
2886 
2887     /* read index register */
2888     index_address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
2889     if (!success)
2890         return false;
2891 
2892     /* destination address */
2893     address = address + index_address;
2894 
2895     /* Set the bad_vaddr register with base address used in the instruction */
2896     bad_vaddr_context.type = eContextInvalid;
2897     WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
2898 
2899     return true;
2900 }
2901