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