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