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