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