Bug Summary

File:tools/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
Location:line 1157, column 13
Description:Function call argument is an uninitialized value

Annotated Source Code

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