]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
Merge ^/head r285284 through r285340.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Instruction / MIPS / EmulateInstructionMIPS.cpp
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
38 using namespace lldb;
39 using namespace lldb_private;
40
41 #define UInt(x) ((uint64_t)x)
42 #define integer int64_t
43
44
45 //----------------------------------------------------------------------
46 //
47 // EmulateInstructionMIPS implementation
48 //
49 //----------------------------------------------------------------------
50
51 #ifdef __mips__
52 extern "C" {
53     void LLVMInitializeMipsTargetInfo ();
54     void LLVMInitializeMipsTarget ();
55     void LLVMInitializeMipsAsmPrinter ();
56     void LLVMInitializeMipsTargetMC ();
57     void LLVMInitializeMipsDisassembler ();
58 }
59 #endif
60
61 EmulateInstructionMIPS::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
144 void
145 EmulateInstructionMIPS::Initialize ()
146 {
147     PluginManager::RegisterPlugin (GetPluginNameStatic (),
148                                    GetPluginDescriptionStatic (),
149                                    CreateInstance);
150 }
151
152 void
153 EmulateInstructionMIPS::Terminate ()
154 {
155     PluginManager::UnregisterPlugin (CreateInstance);
156 }
157
158 ConstString
159 EmulateInstructionMIPS::GetPluginNameStatic ()
160 {
161     ConstString g_plugin_name ("lldb.emulate-instruction.mips32");
162     return g_plugin_name;
163 }
164
165 lldb_private::ConstString
166 EmulateInstructionMIPS::GetPluginName()
167 {
168     static ConstString g_plugin_name ("EmulateInstructionMIPS");
169     return g_plugin_name;
170 }
171
172 const char *
173 EmulateInstructionMIPS::GetPluginDescriptionStatic ()
174 {
175     return "Emulate instructions for the MIPS32 architecture.";
176 }
177
178 EmulateInstruction *
179 EmulateInstructionMIPS::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
195 bool
196 EmulateInstructionMIPS::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
204 const char *
205 EmulateInstructionMIPS::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
330 bool
331 EmulateInstructionMIPS::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
387 EmulateInstructionMIPS::MipsOpcode*
388 EmulateInstructionMIPS::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
474 bool 
475 EmulateInstructionMIPS::ReadInstruction ()
476 {
477     bool success = false;
478     m_addr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
479     if (success)
480     {
481         Context read_inst_context;
482         read_inst_context.type = eContextReadOpcode;
483         read_inst_context.SetNoArgs ();
484         m_opcode.SetOpcode32 (ReadMemoryUnsigned (read_inst_context, m_addr, 4, 0, &success), GetByteOrder());
485     }
486     if (!success)
487         m_addr = LLDB_INVALID_ADDRESS;
488     return success;
489 }
490
491 bool
492 EmulateInstructionMIPS::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
561 bool
562 EmulateInstructionMIPS::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
586 bool
587 EmulateInstructionMIPS::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
610 bool
611 EmulateInstructionMIPS::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
646 bool
647 EmulateInstructionMIPS::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
699 bool
700 EmulateInstructionMIPS::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
727 bool
728 EmulateInstructionMIPS::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
770 bool
771 EmulateInstructionMIPS::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
813 bool
814 EmulateInstructionMIPS::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
856 bool
857 EmulateInstructionMIPS::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
899 bool
900 EmulateInstructionMIPS::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
938 bool
939 EmulateInstructionMIPS::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
977 bool
978 EmulateInstructionMIPS::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
1016 bool
1017 EmulateInstructionMIPS::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
1055 bool
1056 EmulateInstructionMIPS::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
1094 bool
1095 EmulateInstructionMIPS::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
1133 bool
1134 EmulateInstructionMIPS::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
1172 bool
1173 EmulateInstructionMIPS::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
1214 bool
1215 EmulateInstructionMIPS::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
1245 bool
1246 EmulateInstructionMIPS::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
1276 bool
1277 EmulateInstructionMIPS::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
1319 bool
1320 EmulateInstructionMIPS::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
1362 bool
1363 EmulateInstructionMIPS::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
1406 bool
1407 EmulateInstructionMIPS::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
1449 bool
1450 EmulateInstructionMIPS::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
1492 bool
1493 EmulateInstructionMIPS::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
1535 bool
1536 EmulateInstructionMIPS::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
1578 bool
1579 EmulateInstructionMIPS::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
1620 bool
1621 EmulateInstructionMIPS::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
1662 bool
1663 EmulateInstructionMIPS::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
1700 bool
1701 EmulateInstructionMIPS::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
1727 bool
1728 EmulateInstructionMIPS::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
1770 bool
1771 EmulateInstructionMIPS::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
1813 bool
1814 EmulateInstructionMIPS::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
1857 bool
1858 EmulateInstructionMIPS::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
1901 bool
1902 EmulateInstructionMIPS::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
1945 bool
1946 EmulateInstructionMIPS::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
1989 bool
1990 EmulateInstructionMIPS::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
2028 bool
2029 EmulateInstructionMIPS::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
2067 bool
2068 EmulateInstructionMIPS::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
2106 bool
2107 EmulateInstructionMIPS::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
2145 bool
2146 EmulateInstructionMIPS::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
2184 bool
2185 EmulateInstructionMIPS::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
2223 static int
2224 IsAdd64bitOverflow (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
2230 bool
2231 EmulateInstructionMIPS::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
2274 bool
2275 EmulateInstructionMIPS::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
2318 bool
2319 EmulateInstructionMIPS::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
2346 bool
2347 EmulateInstructionMIPS::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
2377 bool
2378 EmulateInstructionMIPS::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
2411 bool
2412 EmulateInstructionMIPS::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
2448 bool
2449 EmulateInstructionMIPS::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
2477 bool
2478 EmulateInstructionMIPS::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
2502 bool
2503 EmulateInstructionMIPS::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
2543 bool
2544 EmulateInstructionMIPS::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
2584 bool
2585 EmulateInstructionMIPS::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
2625 bool
2626 EmulateInstructionMIPS::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
2666 bool
2667 EmulateInstructionMIPS::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
2705 bool
2706 EmulateInstructionMIPS::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
2744 bool
2745 EmulateInstructionMIPS::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
2787 bool
2788 EmulateInstructionMIPS::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
2830 bool
2831 EmulateInstructionMIPS::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
2875 bool
2876 EmulateInstructionMIPS::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 }