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