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 <stdlib.h>
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>(m_asm_info.get(),
163 m_reg_info.get(), nullptr);
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 true, /* prefer_file_cache */
1022 buf, sizeof(uint32_t), error, &load_addr);
1023
1024 if (bytes_read == 0)
1025 return true;
1026
1027 DataExtractor data(buf, sizeof(uint32_t), GetByteOrder(),
1028 GetAddressByteSize());
1029 m_next_inst_size = GetSizeOfInstruction(data, next_inst_addr);
1030 return true;
1031 } else {
1032 /*
1033 * If the address class is not AddressClass::eCodeAlternateISA then
1034 * the function is not microMIPS. In this case instruction size is
1035 * always 4 bytes.
1036 */
1037 m_next_inst_size = 4;
1038 return true;
1039 }
1040 }
1041 return false;
1042 }
1043
ReadInstruction()1044 bool EmulateInstructionMIPS::ReadInstruction() {
1045 bool success = false;
1046 m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
1047 LLDB_INVALID_ADDRESS, &success);
1048 if (success) {
1049 Context read_inst_context;
1050 read_inst_context.type = eContextReadOpcode;
1051 read_inst_context.SetNoArgs();
1052 m_opcode.SetOpcode32(
1053 ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
1054 GetByteOrder());
1055 }
1056 if (!success)
1057 m_addr = LLDB_INVALID_ADDRESS;
1058 return success;
1059 }
1060
EvaluateInstruction(uint32_t evaluate_options)1061 bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options) {
1062 bool success = false;
1063 llvm::MCInst mc_insn;
1064 uint64_t insn_size;
1065 DataExtractor data;
1066
1067 /* Keep the complexity of the decode logic with the llvm::MCDisassembler
1068 * class. */
1069 if (m_opcode.GetData(data)) {
1070 llvm::MCDisassembler::DecodeStatus decode_status;
1071 llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
1072 if (m_use_alt_disaasm)
1073 decode_status = m_alt_disasm->getInstruction(mc_insn, insn_size, raw_insn,
1074 m_addr, llvm::nulls());
1075 else
1076 decode_status = m_disasm->getInstruction(mc_insn, insn_size, raw_insn,
1077 m_addr, llvm::nulls());
1078
1079 if (decode_status != llvm::MCDisassembler::Success)
1080 return false;
1081 }
1082
1083 /*
1084 * mc_insn.getOpcode() returns decoded opcode. However to make use
1085 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
1086 */
1087 const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
1088
1089 if (op_name == nullptr)
1090 return false;
1091
1092 /*
1093 * Decoding has been done already. Just get the call-back function
1094 * and emulate the instruction.
1095 */
1096 MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
1097
1098 if (opcode_data == nullptr)
1099 return false;
1100
1101 uint64_t old_pc = 0, new_pc = 0;
1102 const bool auto_advance_pc =
1103 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
1104
1105 if (auto_advance_pc) {
1106 old_pc =
1107 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1108 if (!success)
1109 return false;
1110 }
1111
1112 /* emulate instruction */
1113 success = (this->*opcode_data->callback)(mc_insn);
1114 if (!success)
1115 return false;
1116
1117 if (auto_advance_pc) {
1118 new_pc =
1119 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1120 if (!success)
1121 return false;
1122
1123 /* If we haven't changed the PC, change it here */
1124 if (old_pc == new_pc) {
1125 new_pc += 4;
1126 Context context;
1127 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1128 new_pc))
1129 return false;
1130 }
1131 }
1132
1133 return true;
1134 }
1135
CreateFunctionEntryUnwind(UnwindPlan & unwind_plan)1136 bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
1137 UnwindPlan &unwind_plan) {
1138 unwind_plan.Clear();
1139 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1140
1141 UnwindPlan::RowSP row(new UnwindPlan::Row);
1142 const bool can_replace = false;
1143
1144 // Our previous Call Frame Address is the stack pointer
1145 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0);
1146
1147 // Our previous PC is in the RA
1148 row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace);
1149
1150 unwind_plan.AppendRow(row);
1151
1152 // All other registers are the same.
1153 unwind_plan.SetSourceName("EmulateInstructionMIPS");
1154 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1155 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1156 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1157 unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
1158
1159 return true;
1160 }
1161
nonvolatile_reg_p(uint32_t regnum)1162 bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) {
1163 switch (regnum) {
1164 case dwarf_r16_mips:
1165 case dwarf_r17_mips:
1166 case dwarf_r18_mips:
1167 case dwarf_r19_mips:
1168 case dwarf_r20_mips:
1169 case dwarf_r21_mips:
1170 case dwarf_r22_mips:
1171 case dwarf_r23_mips:
1172 case dwarf_gp_mips:
1173 case dwarf_sp_mips:
1174 case dwarf_r30_mips:
1175 case dwarf_ra_mips:
1176 return true;
1177 default:
1178 return false;
1179 }
1180 return false;
1181 }
1182
Emulate_ADDiu(llvm::MCInst & insn)1183 bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) {
1184 // ADDIU rt, rs, immediate
1185 // GPR[rt] <- GPR[rs] + sign_extend(immediate)
1186
1187 uint8_t dst, src;
1188 bool success = false;
1189 const uint32_t imm16 = insn.getOperand(2).getImm();
1190 int64_t imm = SignedBits(imm16, 15, 0);
1191
1192 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1193 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1194
1195 // If immediate value is greater then 2^16 - 1 then clang generate LUI,
1196 // ADDIU, SUBU instructions in prolog. Example lui $1, 0x2 addiu $1, $1,
1197 // -0x5920 subu $sp, $sp, $1 In this case, ADDIU dst and src will be same
1198 // and not equal to sp
1199 if (dst == src) {
1200 Context context;
1201
1202 /* read <src> register */
1203 const int64_t src_opd_val = ReadRegisterUnsigned(
1204 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1205 if (!success)
1206 return false;
1207
1208 /* Check if this is daddiu sp, sp, imm16 */
1209 if (dst == dwarf_sp_mips) {
1210 uint64_t result = src_opd_val + imm;
1211 RegisterInfo reg_info_sp;
1212
1213 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1214 context.SetRegisterPlusOffset(reg_info_sp, imm);
1215
1216 /* We are allocating bytes on stack */
1217 context.type = eContextAdjustStackPointer;
1218
1219 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1220 return true;
1221 }
1222
1223 imm += src_opd_val;
1224 context.SetImmediateSigned(imm);
1225 context.type = eContextImmediate;
1226
1227 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1228 dwarf_zero_mips + dst, imm))
1229 return false;
1230 }
1231
1232 return true;
1233 }
1234
Emulate_SW(llvm::MCInst & insn)1235 bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) {
1236 bool success = false;
1237 uint32_t imm16 = insn.getOperand(2).getImm();
1238 uint32_t imm = SignedBits(imm16, 15, 0);
1239 uint32_t src, base;
1240 int32_t address;
1241 Context bad_vaddr_context;
1242
1243 RegisterInfo reg_info_base;
1244
1245 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1246 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1247
1248 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1249 reg_info_base))
1250 return false;
1251
1252 /* read base register */
1253 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1254 dwarf_zero_mips + base, 0, &success);
1255 if (!success)
1256 return false;
1257
1258 /* destination address */
1259 address = address + imm;
1260
1261 /* Set the bad_vaddr register with base address used in the instruction */
1262 bad_vaddr_context.type = eContextInvalid;
1263 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1264 address);
1265
1266 /* We look for sp based non-volatile register stores */
1267 if (nonvolatile_reg_p(src)) {
1268
1269 RegisterInfo reg_info_src;
1270
1271 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1272 reg_info_src))
1273 return false;
1274
1275 Context context;
1276 RegisterValue data_src;
1277 context.type = eContextPushRegisterOnStack;
1278 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1279
1280 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1281 Status error;
1282
1283 if (!ReadRegister(®_info_base, data_src))
1284 return false;
1285
1286 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1287 eByteOrderLittle, error) == 0)
1288 return false;
1289
1290 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1291 return false;
1292
1293 return true;
1294 }
1295
1296 return false;
1297 }
1298
Emulate_LW(llvm::MCInst & insn)1299 bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) {
1300 bool success = false;
1301 uint32_t src, base;
1302 int32_t imm, address;
1303 Context bad_vaddr_context;
1304
1305 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1306 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1307 imm = insn.getOperand(2).getImm();
1308
1309 RegisterInfo reg_info_base;
1310 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1311 reg_info_base))
1312 return false;
1313
1314 /* read base register */
1315 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1316 dwarf_zero_mips + base, 0, &success);
1317 if (!success)
1318 return false;
1319
1320 /* destination address */
1321 address = address + imm;
1322
1323 /* Set the bad_vaddr register with base address used in the instruction */
1324 bad_vaddr_context.type = eContextInvalid;
1325 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1326 address);
1327
1328 if (nonvolatile_reg_p(src)) {
1329 RegisterValue data_src;
1330 RegisterInfo reg_info_src;
1331
1332 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1333 reg_info_src))
1334 return false;
1335
1336 Context context;
1337 context.type = eContextPopRegisterOffStack;
1338 context.SetAddress(address);
1339
1340 return WriteRegister(context, ®_info_src, data_src);
1341 }
1342
1343 return false;
1344 }
1345
Emulate_SUBU_ADDU(llvm::MCInst & insn)1346 bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) {
1347 // SUBU sp, <src>, <rt>
1348 // ADDU sp, <src>, <rt>
1349 // ADDU dst, sp, <rt>
1350
1351 bool success = false;
1352 uint64_t result;
1353 uint8_t src, dst, rt;
1354 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1355
1356 dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1357 src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1358
1359 /* Check if sp is destination register */
1360 if (dst == dwarf_sp_mips) {
1361 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1362
1363 /* read <src> register */
1364 uint64_t src_opd_val = ReadRegisterUnsigned(
1365 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1366 if (!success)
1367 return false;
1368
1369 /* read <rt > register */
1370 uint64_t rt_opd_val = ReadRegisterUnsigned(
1371 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1372 if (!success)
1373 return false;
1374
1375 if (!strcasecmp(op_name, "SUBU"))
1376 result = src_opd_val - rt_opd_val;
1377 else
1378 result = src_opd_val + rt_opd_val;
1379
1380 Context context;
1381 RegisterInfo reg_info_sp;
1382 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1383 context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
1384
1385 /* We are allocating bytes on stack */
1386 context.type = eContextAdjustStackPointer;
1387
1388 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1389
1390 return true;
1391 } else if (src == dwarf_sp_mips) {
1392 rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1393
1394 /* read <src> register */
1395 uint64_t src_opd_val = ReadRegisterUnsigned(
1396 eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1397 if (!success)
1398 return false;
1399
1400 /* read <rt> register */
1401 uint64_t rt_opd_val = ReadRegisterUnsigned(
1402 eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1403 if (!success)
1404 return false;
1405
1406 Context context;
1407
1408 if (!strcasecmp(op_name, "SUBU"))
1409 result = src_opd_val - rt_opd_val;
1410 else
1411 result = src_opd_val + rt_opd_val;
1412
1413 context.SetImmediateSigned(result);
1414 context.type = eContextImmediate;
1415
1416 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1417 dwarf_zero_mips + dst, result))
1418 return false;
1419 }
1420
1421 return true;
1422 }
1423
Emulate_LUI(llvm::MCInst & insn)1424 bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) {
1425 // LUI rt, immediate
1426 // GPR[rt] <- sign_extend(immediate << 16)
1427
1428 const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1429 int64_t imm = SignedBits(imm32, 31, 0);
1430 uint8_t rt;
1431 Context context;
1432
1433 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1434 context.SetImmediateSigned(imm);
1435 context.type = eContextImmediate;
1436
1437 return WriteRegisterUnsigned(context, eRegisterKindDWARF,
1438 dwarf_zero_mips + rt, imm);
1439 }
1440
Emulate_ADDIUSP(llvm::MCInst & insn)1441 bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) {
1442 bool success = false;
1443 const uint32_t imm9 = insn.getOperand(0).getImm();
1444 uint64_t result;
1445
1446 // This instruction operates implicitly on stack pointer, so read <sp>
1447 // register.
1448 uint64_t src_opd_val =
1449 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1450 if (!success)
1451 return false;
1452
1453 result = src_opd_val + imm9;
1454
1455 Context context;
1456 RegisterInfo reg_info_sp;
1457 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1458 context.SetRegisterPlusOffset(reg_info_sp, imm9);
1459
1460 // We are adjusting the stack.
1461 context.type = eContextAdjustStackPointer;
1462
1463 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1464 return true;
1465 }
1466
Emulate_ADDIUS5(llvm::MCInst & insn)1467 bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) {
1468 bool success = false;
1469 uint32_t base;
1470 const uint32_t imm4 = insn.getOperand(2).getImm();
1471 uint64_t result;
1472
1473 // The source and destination register is same for this instruction.
1474 base = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1475
1476 // We are looking for stack adjustment only
1477 if (base == dwarf_sp_mips) {
1478 // Read stack pointer register
1479 uint64_t src_opd_val = ReadRegisterUnsigned(
1480 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1481 if (!success)
1482 return false;
1483
1484 result = src_opd_val + imm4;
1485
1486 Context context;
1487 RegisterInfo reg_info_sp;
1488 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1489 context.SetRegisterPlusOffset(reg_info_sp, imm4);
1490
1491 // We are adjusting the stack.
1492 context.type = eContextAdjustStackPointer;
1493
1494 WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1495 }
1496
1497 return true;
1498 }
1499
Emulate_SWSP(llvm::MCInst & insn)1500 bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) {
1501 bool success = false;
1502 uint32_t imm5 = insn.getOperand(2).getImm();
1503 uint32_t src, base;
1504 Context bad_vaddr_context;
1505 uint32_t address;
1506
1507 src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1508 base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1509
1510 RegisterInfo reg_info_base;
1511
1512 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1513 reg_info_base))
1514 return false;
1515
1516 // read base register
1517 address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
1518 &success);
1519 if (!success)
1520 return false;
1521
1522 // destination address
1523 address = address + imm5;
1524
1525 // We use bad_vaddr_context to store base address which is used by H/W
1526 // watchpoint Set the bad_vaddr register with base address used in the
1527 // instruction
1528 bad_vaddr_context.type = eContextInvalid;
1529 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1530 address);
1531
1532 // We look for sp based non-volatile register stores.
1533 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1534 RegisterInfo reg_info_src = {};
1535 Context context;
1536 RegisterValue data_src;
1537 context.type = eContextPushRegisterOnStack;
1538 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1539
1540 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1541 Status error;
1542
1543 if (!ReadRegister(®_info_base, data_src))
1544 return false;
1545
1546 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1547 eByteOrderLittle, error) == 0)
1548 return false;
1549
1550 if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1551 return false;
1552
1553 return true;
1554 }
1555
1556 return false;
1557 }
1558
1559 /* Emulate SWM16,SWM32 and SWP instruction.
1560
1561 SWM16 always has stack pointer as a base register (but it is still available
1562 in MCInst as an operand).
1563 SWM32 and SWP can have base register other than stack pointer.
1564 */
Emulate_SWM16_32(llvm::MCInst & insn)1565 bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) {
1566 bool success = false;
1567 uint32_t src, base;
1568 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1569 // no of regs to store.
1570
1571 // Base register is second last operand of the instruction.
1572 base =
1573 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1574
1575 // We are looking for sp based stores so if base is not a stack pointer then
1576 // don't proceed.
1577 if (base != dwarf_sp_mips)
1578 return false;
1579
1580 // offset is always the last operand.
1581 uint32_t offset = insn.getOperand(num_operands - 1).getImm();
1582
1583 RegisterInfo reg_info_base;
1584 RegisterInfo reg_info_src;
1585
1586 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1587 reg_info_base))
1588 return false;
1589
1590 // read SP
1591 uint32_t base_address = ReadRegisterUnsigned(
1592 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1593 if (!success)
1594 return false;
1595
1596 // Resulting base addrss
1597 base_address = base_address + offset;
1598
1599 // Total no of registers to be stored are num_operands-2.
1600 for (uint32_t i = 0; i < num_operands - 2; i++) {
1601 // Get the register number to be stored.
1602 src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1603
1604 /*
1605 Record only non-volatile stores.
1606 This check is required for SWP instruction because source operand could
1607 be any register.
1608 SWM16 and SWM32 instruction always has saved registers as source
1609 operands.
1610 */
1611 if (!nonvolatile_reg_p(src))
1612 return false;
1613
1614 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1615 reg_info_src))
1616 return false;
1617
1618 Context context;
1619 RegisterValue data_src;
1620 context.type = eContextPushRegisterOnStack;
1621 context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1622
1623 uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1624 Status error;
1625
1626 if (!ReadRegister(®_info_base, data_src))
1627 return false;
1628
1629 if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size,
1630 eByteOrderLittle, error) == 0)
1631 return false;
1632
1633 if (!WriteMemory(context, base_address, buffer, reg_info_src.byte_size))
1634 return false;
1635
1636 // Stack address for next register
1637 base_address = base_address + reg_info_src.byte_size;
1638 }
1639 return true;
1640 }
1641
Emulate_LWSP(llvm::MCInst & insn)1642 bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) {
1643 bool success = false;
1644 uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1645 uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1646 uint32_t imm5 = insn.getOperand(2).getImm();
1647 Context bad_vaddr_context;
1648
1649 RegisterInfo reg_info_base;
1650 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1651 reg_info_base))
1652 return false;
1653
1654 // read base register
1655 uint32_t base_address = ReadRegisterUnsigned(
1656 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1657 if (!success)
1658 return false;
1659
1660 base_address = base_address + imm5;
1661
1662 // We use bad_vaddr_context to store base address which is used by H/W
1663 // watchpoint Set the bad_vaddr register with base address used in the
1664 // instruction
1665 bad_vaddr_context.type = eContextInvalid;
1666 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1667 base_address);
1668
1669 if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1670 RegisterValue data_src;
1671 RegisterInfo reg_info_src;
1672
1673 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1674 reg_info_src))
1675 return false;
1676
1677 Context context;
1678 context.type = eContextPopRegisterOffStack;
1679 context.SetAddress(base_address);
1680
1681 return WriteRegister(context, ®_info_src, data_src);
1682 }
1683
1684 return false;
1685 }
1686
1687 /* Emulate LWM16, LWM32 and LWP instructions.
1688
1689 LWM16 always has stack pointer as a base register (but it is still available
1690 in MCInst as an operand).
1691 LWM32 and LWP can have base register other than stack pointer.
1692 */
Emulate_LWM16_32(llvm::MCInst & insn)1693 bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) {
1694 bool success = false;
1695 uint32_t dst, base;
1696 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1697 // no of regs to store.
1698 uint32_t imm = insn.getOperand(num_operands - 1)
1699 .getImm(); // imm is the last operand in the instruction.
1700
1701 // Base register is second last operand of the instruction.
1702 base =
1703 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1704
1705 // We are looking for sp based loads so if base is not a stack pointer then
1706 // don't proceed.
1707 if (base != dwarf_sp_mips)
1708 return false;
1709
1710 uint32_t base_address = ReadRegisterUnsigned(
1711 eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1712 if (!success)
1713 return false;
1714
1715 base_address = base_address + imm;
1716
1717 RegisterValue data_dst;
1718 RegisterInfo reg_info_dst;
1719
1720 // Total no of registers to be re-stored are num_operands-2.
1721 for (uint32_t i = 0; i < num_operands - 2; i++) {
1722 // Get the register number to be re-stored.
1723 dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1724
1725 /*
1726 Record only non-volatile loads.
1727 This check is required for LWP instruction because destination operand
1728 could be any register.
1729 LWM16 and LWM32 instruction always has saved registers as destination
1730 operands.
1731 */
1732 if (!nonvolatile_reg_p(dst))
1733 return false;
1734
1735 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst,
1736 reg_info_dst))
1737 return false;
1738
1739 Context context;
1740 context.type = eContextPopRegisterOffStack;
1741 context.SetAddress(base_address + (i * 4));
1742
1743 if (!WriteRegister(context, ®_info_dst, data_dst))
1744 return false;
1745 }
1746
1747 return true;
1748 }
1749
Emulate_JRADDIUSP(llvm::MCInst & insn)1750 bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) {
1751 bool success = false;
1752 int32_t imm5 = insn.getOperand(0).getImm();
1753
1754 /* JRADDIUSP immediate
1755 * PC <- RA
1756 * SP <- SP + zero_extend(Immediate << 2)
1757 */
1758
1759 // This instruction operates implicitly on stack pointer, so read <sp>
1760 // register.
1761 int32_t src_opd_val =
1762 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1763 if (!success)
1764 return false;
1765
1766 int32_t ra_val =
1767 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
1768 if (!success)
1769 return false;
1770
1771 int32_t result = src_opd_val + imm5;
1772
1773 Context context;
1774
1775 // Update the PC
1776 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1777 ra_val))
1778 return false;
1779
1780 RegisterInfo reg_info_sp;
1781 if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1782 context.SetRegisterPlusOffset(reg_info_sp, imm5);
1783
1784 // We are adjusting stack
1785 context.type = eContextAdjustStackPointer;
1786
1787 // update SP
1788 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips,
1789 result);
1790 }
1791
IsAdd64bitOverflow(int32_t a,int32_t b)1792 static int IsAdd64bitOverflow(int32_t a, int32_t b) {
1793 int32_t r = (uint32_t)a + (uint32_t)b;
1794 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1795 }
1796
1797 /*
1798 Emulate below MIPS branch instructions.
1799 BEQ, BNE : Branch on condition
1800 BEQL, BNEL : Branch likely
1801 */
Emulate_BXX_3ops(llvm::MCInst & insn)1802 bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) {
1803 bool success = false;
1804 uint32_t rs, rt;
1805 int32_t offset, pc, target = 0, rs_val, rt_val;
1806 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1807
1808 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1809 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1810 offset = insn.getOperand(2).getImm();
1811
1812 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1813 if (!success)
1814 return false;
1815
1816 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1817 dwarf_zero_mips + rs, 0, &success);
1818 if (!success)
1819 return false;
1820
1821 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1822 dwarf_zero_mips + rt, 0, &success);
1823 if (!success)
1824 return false;
1825
1826 if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) {
1827 if (rs_val == rt_val)
1828 target = pc + offset;
1829 else
1830 target = pc + 8;
1831 } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) {
1832 if (rs_val != rt_val)
1833 target = pc + offset;
1834 else
1835 target = pc + 8;
1836 }
1837
1838 Context context;
1839 context.type = eContextRelativeBranchImmediate;
1840 context.SetImmediate(offset);
1841
1842 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1843 target);
1844 }
1845
1846 /*
1847 Emulate below MIPS branch instructions.
1848 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
1849 instructions with no delay slot
1850 */
Emulate_BXX_3ops_C(llvm::MCInst & insn)1851 bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
1852 bool success = false;
1853 uint32_t rs, rt;
1854 int32_t offset, pc, target = 0, rs_val, rt_val;
1855 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1856 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1857
1858 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1859 rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1860 offset = insn.getOperand(2).getImm();
1861
1862 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1863 if (!success)
1864 return false;
1865
1866 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1867 dwarf_zero_mips + rs, 0, &success);
1868 if (!success)
1869 return false;
1870
1871 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1872 dwarf_zero_mips + rt, 0, &success);
1873 if (!success)
1874 return false;
1875
1876 if (!strcasecmp(op_name, "BEQC")) {
1877 if (rs_val == rt_val)
1878 target = pc + offset;
1879 else
1880 target = pc + 4;
1881 } else if (!strcasecmp(op_name, "BNEC")) {
1882 if (rs_val != rt_val)
1883 target = pc + offset;
1884 else
1885 target = pc + 4;
1886 } else if (!strcasecmp(op_name, "BLTC")) {
1887 if (rs_val < rt_val)
1888 target = pc + offset;
1889 else
1890 target = pc + 4;
1891 } else if (!strcasecmp(op_name, "BGEC")) {
1892 if (rs_val >= rt_val)
1893 target = pc + offset;
1894 else
1895 target = pc + 4;
1896 } else if (!strcasecmp(op_name, "BLTUC")) {
1897 if (rs_val < rt_val)
1898 target = pc + offset;
1899 else
1900 target = pc + 4;
1901 } else if (!strcasecmp(op_name, "BGEUC")) {
1902 if ((uint32_t)rs_val >= (uint32_t)rt_val)
1903 target = pc + offset;
1904 else
1905 target = pc + 4;
1906 } else if (!strcasecmp(op_name, "BOVC")) {
1907 if (IsAdd64bitOverflow(rs_val, rt_val))
1908 target = pc + offset;
1909 else
1910 target = pc + 4;
1911 } else if (!strcasecmp(op_name, "BNVC")) {
1912 if (!IsAdd64bitOverflow(rs_val, rt_val))
1913 target = pc + offset;
1914 else
1915 target = pc + 4;
1916 }
1917
1918 Context context;
1919 context.type = eContextRelativeBranchImmediate;
1920 context.SetImmediate(current_inst_size + offset);
1921
1922 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1923 target);
1924 }
1925
1926 /*
1927 Emulate below MIPS conditional branch and link instructions.
1928 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1929 */
Emulate_Bcond_Link_C(llvm::MCInst & insn)1930 bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
1931 bool success = false;
1932 uint32_t rs;
1933 int32_t offset, pc, target = 0;
1934 int32_t rs_val;
1935 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1936
1937 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1938 offset = insn.getOperand(1).getImm();
1939
1940 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1941 if (!success)
1942 return false;
1943
1944 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1945 dwarf_zero_mips + rs, 0, &success);
1946 if (!success)
1947 return false;
1948
1949 if (!strcasecmp(op_name, "BLEZALC")) {
1950 if (rs_val <= 0)
1951 target = pc + offset;
1952 else
1953 target = pc + 4;
1954 } else if (!strcasecmp(op_name, "BGEZALC")) {
1955 if (rs_val >= 0)
1956 target = pc + offset;
1957 else
1958 target = pc + 4;
1959 } else if (!strcasecmp(op_name, "BLTZALC")) {
1960 if (rs_val < 0)
1961 target = pc + offset;
1962 else
1963 target = pc + 4;
1964 } else if (!strcasecmp(op_name, "BGTZALC")) {
1965 if (rs_val > 0)
1966 target = pc + offset;
1967 else
1968 target = pc + 4;
1969 } else if (!strcasecmp(op_name, "BEQZALC")) {
1970 if (rs_val == 0)
1971 target = pc + offset;
1972 else
1973 target = pc + 4;
1974 } else if (!strcasecmp(op_name, "BNEZALC")) {
1975 if (rs_val != 0)
1976 target = pc + offset;
1977 else
1978 target = pc + 4;
1979 }
1980
1981 Context context;
1982
1983 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1984 target))
1985 return false;
1986
1987 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
1988 pc + 4))
1989 return false;
1990
1991 return true;
1992 }
1993
1994 /*
1995 Emulate below MIPS Non-Compact conditional branch and link instructions.
1996 BLTZAL, BGEZAL :
1997 BLTZALL, BGEZALL : Branch likely
1998 */
Emulate_Bcond_Link(llvm::MCInst & insn)1999 bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) {
2000 bool success = false;
2001 uint32_t rs;
2002 int32_t offset, pc, target = 0;
2003 int32_t rs_val;
2004 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2005
2006 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2007 offset = insn.getOperand(1).getImm();
2008
2009 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2010 if (!success)
2011 return false;
2012
2013 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2014 dwarf_zero_mips + rs, 0, &success);
2015 if (!success)
2016 return false;
2017
2018 if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
2019 if ((int32_t)rs_val < 0)
2020 target = pc + offset;
2021 else
2022 target = pc + 8;
2023 } else if (!strcasecmp(op_name, "BGEZAL") ||
2024 !strcasecmp(op_name, "BGEZALL")) {
2025 if ((int32_t)rs_val >= 0)
2026 target = pc + offset;
2027 else
2028 target = pc + 8;
2029 }
2030
2031 Context context;
2032
2033 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2034 target))
2035 return false;
2036
2037 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2038 pc + 8))
2039 return false;
2040
2041 return true;
2042 }
2043
2044 /*
2045 Emulate below MIPS branch instructions.
2046 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
2047 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
2048 */
Emulate_BXX_2ops(llvm::MCInst & insn)2049 bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) {
2050 bool success = false;
2051 uint32_t rs;
2052 int32_t offset, pc, target = 0;
2053 int32_t rs_val;
2054 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2055
2056 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2057 offset = insn.getOperand(1).getImm();
2058
2059 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2060 if (!success)
2061 return false;
2062
2063 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2064 dwarf_zero_mips + rs, 0, &success);
2065 if (!success)
2066 return false;
2067
2068 if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) {
2069 if (rs_val < 0)
2070 target = pc + offset;
2071 else
2072 target = pc + 8;
2073 } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) {
2074 if (rs_val >= 0)
2075 target = pc + offset;
2076 else
2077 target = pc + 8;
2078 } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) {
2079 if (rs_val > 0)
2080 target = pc + offset;
2081 else
2082 target = pc + 8;
2083 } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) {
2084 if (rs_val <= 0)
2085 target = pc + offset;
2086 else
2087 target = pc + 8;
2088 }
2089
2090 Context context;
2091 context.type = eContextRelativeBranchImmediate;
2092 context.SetImmediate(offset);
2093
2094 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2095 target);
2096 }
2097
2098 /*
2099 Emulate below MIPS branch instructions.
2100 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
2101 */
Emulate_BXX_2ops_C(llvm::MCInst & insn)2102 bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
2103 bool success = false;
2104 uint32_t rs;
2105 int32_t offset, pc, target = 0;
2106 int32_t rs_val;
2107 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2108 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2109
2110 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2111 offset = insn.getOperand(1).getImm();
2112
2113 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2114 if (!success)
2115 return false;
2116
2117 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2118 dwarf_zero_mips + rs, 0, &success);
2119 if (!success)
2120 return false;
2121
2122 if (!strcasecmp(op_name, "BLTZC")) {
2123 if (rs_val < 0)
2124 target = pc + offset;
2125 else
2126 target = pc + 4;
2127 } else if (!strcasecmp(op_name, "BLEZC")) {
2128 if (rs_val <= 0)
2129 target = pc + offset;
2130 else
2131 target = pc + 4;
2132 } else if (!strcasecmp(op_name, "BGEZC")) {
2133 if (rs_val >= 0)
2134 target = pc + offset;
2135 else
2136 target = pc + 4;
2137 } else if (!strcasecmp(op_name, "BGTZC")) {
2138 if (rs_val > 0)
2139 target = pc + offset;
2140 else
2141 target = pc + 4;
2142 } else if (!strcasecmp(op_name, "BEQZC")) {
2143 if (rs_val == 0)
2144 target = pc + offset;
2145 else
2146 target = pc + 4;
2147 } else if (!strcasecmp(op_name, "BNEZC")) {
2148 if (rs_val != 0)
2149 target = pc + offset;
2150 else
2151 target = pc + 4;
2152 }
2153
2154 Context context;
2155 context.type = eContextRelativeBranchImmediate;
2156 context.SetImmediate(current_inst_size + offset);
2157
2158 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2159 target);
2160 }
2161
Emulate_B16_MM(llvm::MCInst & insn)2162 bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) {
2163 bool success = false;
2164 int32_t offset, pc, target;
2165 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2166
2167 offset = insn.getOperand(0).getImm();
2168
2169 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2170 if (!success)
2171 return false;
2172
2173 // unconditional branch
2174 target = pc + offset;
2175
2176 Context context;
2177 context.type = eContextRelativeBranchImmediate;
2178 context.SetImmediate(current_inst_size + offset);
2179
2180 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2181 target);
2182 }
2183
2184 /*
2185 BEQZC, BNEZC are 32 bit compact instructions without a delay slot.
2186 BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
2187 BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
2188 */
Emulate_Branch_MM(llvm::MCInst & insn)2189 bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) {
2190 bool success = false;
2191 int32_t target = 0;
2192 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2193 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2194 bool update_ra = false;
2195 uint32_t ra_offset = 0;
2196
2197 /*
2198 * BEQZ16 rs, offset
2199 * condition <- (GPR[rs] = 0)
2200 * if condition then
2201 * PC = PC + sign_ext (offset || 0)
2202 *
2203 * BNEZ16 rs, offset
2204 * condition <- (GPR[rs] != 0)
2205 * if condition then
2206 * PC = PC + sign_ext (offset || 0)
2207 *
2208 * BEQZC rs, offset (compact instruction: No delay slot)
2209 * condition <- (GPR[rs] == 0)
2210 * if condition then
2211 * PC = PC + 4 + sign_ext (offset || 0)
2212 */
2213
2214 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2215 int32_t offset = insn.getOperand(1).getImm();
2216
2217 int32_t pc =
2218 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2219 if (!success)
2220 return false;
2221
2222 int32_t rs_val = (int32_t)ReadRegisterUnsigned(
2223 eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
2224 if (!success)
2225 return false;
2226
2227 if (!strcasecmp(op_name, "BEQZ16_MM")) {
2228 if (rs_val == 0)
2229 target = pc + offset;
2230 else
2231 target = pc + current_inst_size +
2232 m_next_inst_size; // Skip delay slot instruction.
2233 } else if (!strcasecmp(op_name, "BNEZ16_MM")) {
2234 if (rs_val != 0)
2235 target = pc + offset;
2236 else
2237 target = pc + current_inst_size +
2238 m_next_inst_size; // Skip delay slot instruction.
2239 } else if (!strcasecmp(op_name, "BEQZC_MM")) {
2240 if (rs_val == 0)
2241 target = pc + 4 + offset;
2242 else
2243 target =
2244 pc +
2245 4; // 32 bit instruction and does not have delay slot instruction.
2246 } else if (!strcasecmp(op_name, "BNEZC_MM")) {
2247 if (rs_val != 0)
2248 target = pc + 4 + offset;
2249 else
2250 target =
2251 pc +
2252 4; // 32 bit instruction and does not have delay slot instruction.
2253 } else if (!strcasecmp(op_name, "BGEZALS_MM")) {
2254 if (rs_val >= 0)
2255 target = pc + offset;
2256 else
2257 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2258
2259 update_ra = true;
2260 ra_offset = 6;
2261 } else if (!strcasecmp(op_name, "BLTZALS_MM")) {
2262 if (rs_val >= 0)
2263 target = pc + offset;
2264 else
2265 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2266
2267 update_ra = true;
2268 ra_offset = 6;
2269 }
2270
2271 Context context;
2272 context.type = eContextRelativeBranchImmediate;
2273 context.SetImmediate(current_inst_size + offset);
2274
2275 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2276 target))
2277 return false;
2278
2279 if (update_ra) {
2280 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2281 pc + ra_offset))
2282 return false;
2283 }
2284 return true;
2285 }
2286
2287 /* Emulate micromips jump instructions.
2288 JALR16,JALRS16
2289 */
Emulate_JALRx16_MM(llvm::MCInst & insn)2290 bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) {
2291 bool success = false;
2292 uint32_t ra_offset = 0;
2293 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2294
2295 uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2296
2297 uint32_t pc =
2298 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2299 if (!success)
2300 return false;
2301
2302 uint32_t rs_val = ReadRegisterUnsigned(eRegisterKindDWARF,
2303 dwarf_zero_mips + rs, 0, &success);
2304 if (!success)
2305 return false;
2306
2307 if (!strcasecmp(op_name, "JALR16_MM"))
2308 ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
2309 else if (!strcasecmp(op_name, "JALRS16_MM"))
2310 ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
2311
2312 Context context;
2313
2314 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2315 rs_val))
2316 return false;
2317
2318 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2319 pc + ra_offset))
2320 return false;
2321
2322 return true;
2323 }
2324
2325 /* Emulate JALS and JALX instructions.
2326 JALS 32 bit instruction with short (2-byte) delay slot.
2327 JALX 32 bit instruction with 4-byte delay slot.
2328 */
Emulate_JALx(llvm::MCInst & insn)2329 bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) {
2330 bool success = false;
2331 uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0;
2332 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2333
2334 /*
2335 * JALS target
2336 * RA = PC + 6
2337 * offset = sign_ext (offset << 1)
2338 * PC = PC[31-27] | offset
2339 * JALX target
2340 * RA = PC + 8
2341 * offset = sign_ext (offset << 2)
2342 * PC = PC[31-28] | offset
2343 */
2344 offset = insn.getOperand(0).getImm();
2345
2346 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2347 if (!success)
2348 return false;
2349
2350 // These are PC-region branches and not PC-relative.
2351 if (!strcasecmp(op_name, "JALS_MM")) {
2352 // target address is in the “current” 128 MB-aligned region
2353 target = (pc & 0xF8000000UL) | offset;
2354 ra_offset = 6;
2355 } else if (!strcasecmp(op_name, "JALX_MM")) {
2356 // target address is in the “current” 256 MB-aligned region
2357 target = (pc & 0xF0000000UL) | offset;
2358 ra_offset = 8;
2359 }
2360
2361 Context context;
2362
2363 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2364 target))
2365 return false;
2366
2367 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2368 pc + ra_offset))
2369 return false;
2370
2371 return true;
2372 }
2373
Emulate_JALRS(llvm::MCInst & insn)2374 bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) {
2375 bool success = false;
2376 uint32_t rs = 0, rt = 0;
2377 int32_t pc = 0, rs_val = 0;
2378
2379 /*
2380 JALRS rt, rs
2381 GPR[rt] <- PC + 6
2382 PC <- GPR[rs]
2383 */
2384
2385 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2386 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2387
2388 rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2389 dwarf_zero_mips + rs, 0, &success);
2390 if (!success)
2391 return false;
2392
2393 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2394 if (!success)
2395 return false;
2396
2397 Context context;
2398
2399 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2400 rs_val))
2401 return false;
2402
2403 // This is 4-byte instruction with 2-byte delay slot.
2404 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2405 pc + 6))
2406 return false;
2407
2408 return true;
2409 }
2410
Emulate_BAL(llvm::MCInst & insn)2411 bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst &insn) {
2412 bool success = false;
2413 int32_t offset, pc, target;
2414
2415 /*
2416 * BAL offset
2417 * offset = sign_ext (offset << 2)
2418 * RA = PC + 8
2419 * PC = PC + offset
2420 */
2421 offset = insn.getOperand(0).getImm();
2422
2423 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2424 if (!success)
2425 return false;
2426
2427 target = pc + offset;
2428
2429 Context context;
2430
2431 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2432 target))
2433 return false;
2434
2435 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2436 pc + 8))
2437 return false;
2438
2439 return true;
2440 }
2441
Emulate_BALC(llvm::MCInst & insn)2442 bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) {
2443 bool success = false;
2444 int32_t offset, pc, target;
2445
2446 /*
2447 * BALC offset
2448 * offset = sign_ext (offset << 2)
2449 * RA = PC + 4
2450 * PC = PC + 4 + offset
2451 */
2452 offset = insn.getOperand(0).getImm();
2453
2454 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2455 if (!success)
2456 return false;
2457
2458 target = pc + offset;
2459
2460 Context context;
2461
2462 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2463 target))
2464 return false;
2465
2466 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2467 pc + 4))
2468 return false;
2469
2470 return true;
2471 }
2472
Emulate_BC(llvm::MCInst & insn)2473 bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) {
2474 bool success = false;
2475 int32_t offset, pc, target;
2476
2477 /*
2478 * BC offset
2479 * offset = sign_ext (offset << 2)
2480 * PC = PC + 4 + offset
2481 */
2482 offset = insn.getOperand(0).getImm();
2483
2484 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2485 if (!success)
2486 return false;
2487
2488 target = pc + offset;
2489
2490 Context context;
2491
2492 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2493 target);
2494 }
2495
Emulate_J(llvm::MCInst & insn)2496 bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) {
2497 bool success = false;
2498 uint32_t offset, pc;
2499
2500 /*
2501 * J offset
2502 * offset = sign_ext (offset << 2)
2503 * PC = PC[63-28] | offset
2504 */
2505 offset = insn.getOperand(0).getImm();
2506
2507 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2508 if (!success)
2509 return false;
2510
2511 /* This is a PC-region branch and not PC-relative */
2512 pc = (pc & 0xF0000000UL) | offset;
2513
2514 Context context;
2515
2516 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc);
2517 }
2518
Emulate_JAL(llvm::MCInst & insn)2519 bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) {
2520 bool success = false;
2521 uint32_t offset, target, pc;
2522
2523 /*
2524 * JAL offset
2525 * offset = sign_ext (offset << 2)
2526 * PC = PC[63-28] | offset
2527 */
2528 offset = insn.getOperand(0).getImm();
2529
2530 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2531 if (!success)
2532 return false;
2533
2534 /* This is a PC-region branch and not PC-relative */
2535 target = (pc & 0xF0000000UL) | offset;
2536
2537 Context context;
2538
2539 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2540 target))
2541 return false;
2542
2543 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2544 pc + 8))
2545 return false;
2546
2547 return true;
2548 }
2549
Emulate_JALR(llvm::MCInst & insn)2550 bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) {
2551 bool success = false;
2552 uint32_t rs, rt;
2553 uint32_t pc, rs_val;
2554
2555 /*
2556 * JALR rt, rs
2557 * GPR[rt] = PC + 8
2558 * PC = GPR[rs]
2559 */
2560 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2561 rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2562
2563 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2564 if (!success)
2565 return false;
2566
2567 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2568 &success);
2569 if (!success)
2570 return false;
2571
2572 Context context;
2573
2574 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2575 rs_val))
2576 return false;
2577
2578 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2579 pc + 8))
2580 return false;
2581
2582 return true;
2583 }
2584
Emulate_JIALC(llvm::MCInst & insn)2585 bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) {
2586 bool success = false;
2587 uint32_t rt;
2588 int32_t target, offset, pc, rt_val;
2589
2590 /*
2591 * JIALC rt, offset
2592 * offset = sign_ext (offset)
2593 * PC = GPR[rt] + offset
2594 * RA = PC + 4
2595 */
2596 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2597 offset = insn.getOperand(1).getImm();
2598
2599 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2600 if (!success)
2601 return false;
2602
2603 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2604 dwarf_zero_mips + rt, 0, &success);
2605 if (!success)
2606 return false;
2607
2608 target = rt_val + offset;
2609
2610 Context context;
2611
2612 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2613 target))
2614 return false;
2615
2616 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2617 pc + 4))
2618 return false;
2619
2620 return true;
2621 }
2622
Emulate_JIC(llvm::MCInst & insn)2623 bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) {
2624 bool success = false;
2625 uint32_t rt;
2626 int32_t target, offset, rt_val;
2627
2628 /*
2629 * JIC rt, offset
2630 * offset = sign_ext (offset)
2631 * PC = GPR[rt] + offset
2632 */
2633 rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2634 offset = insn.getOperand(1).getImm();
2635
2636 rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2637 dwarf_zero_mips + rt, 0, &success);
2638 if (!success)
2639 return false;
2640
2641 target = rt_val + offset;
2642
2643 Context context;
2644
2645 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2646 target);
2647 }
2648
Emulate_JR(llvm::MCInst & insn)2649 bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) {
2650 bool success = false;
2651 uint32_t rs;
2652 uint32_t rs_val;
2653
2654 /*
2655 * JR rs
2656 * PC = GPR[rs]
2657 */
2658 rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2659
2660 rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2661 &success);
2662 if (!success)
2663 return false;
2664
2665 Context context;
2666
2667 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2668 rs_val);
2669 }
2670
2671 /*
2672 Emulate Branch on FP True/False
2673 BC1F, BC1FL : Branch on FP False (L stands for branch likely)
2674 BC1T, BC1TL : Branch on FP True (L stands for branch likely)
2675 */
Emulate_FP_branch(llvm::MCInst & insn)2676 bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) {
2677 bool success = false;
2678 uint32_t cc, fcsr;
2679 int32_t pc, offset, target = 0;
2680 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2681
2682 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2683 offset = insn.getOperand(1).getImm();
2684
2685 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2686 if (!success)
2687 return false;
2688
2689 fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
2690 if (!success)
2691 return false;
2692
2693 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2694 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2695
2696 if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
2697 if ((fcsr & (1 << cc)) == 0)
2698 target = pc + offset;
2699 else
2700 target = pc + 8;
2701 } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
2702 if ((fcsr & (1 << cc)) != 0)
2703 target = pc + offset;
2704 else
2705 target = pc + 8;
2706 }
2707 Context context;
2708
2709 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2710 target);
2711 }
2712
Emulate_BC1EQZ(llvm::MCInst & insn)2713 bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) {
2714 bool success = false;
2715 uint32_t ft;
2716 uint32_t ft_val;
2717 int32_t target, pc, offset;
2718
2719 /*
2720 * BC1EQZ ft, offset
2721 * condition <- (FPR[ft].bit0 == 0)
2722 * if condition then
2723 * offset = sign_ext (offset)
2724 * PC = PC + 4 + offset
2725 */
2726 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2727 offset = insn.getOperand(1).getImm();
2728
2729 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2730 if (!success)
2731 return false;
2732
2733 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2734 &success);
2735 if (!success)
2736 return false;
2737
2738 if ((ft_val & 1) == 0)
2739 target = pc + 4 + offset;
2740 else
2741 target = pc + 8;
2742
2743 Context context;
2744
2745 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2746 target);
2747 }
2748
Emulate_BC1NEZ(llvm::MCInst & insn)2749 bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) {
2750 bool success = false;
2751 uint32_t ft;
2752 uint32_t ft_val;
2753 int32_t target, pc, offset;
2754
2755 /*
2756 * BC1NEZ ft, offset
2757 * condition <- (FPR[ft].bit0 != 0)
2758 * if condition then
2759 * offset = sign_ext (offset)
2760 * PC = PC + 4 + offset
2761 */
2762 ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2763 offset = insn.getOperand(1).getImm();
2764
2765 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2766 if (!success)
2767 return false;
2768
2769 ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2770 &success);
2771 if (!success)
2772 return false;
2773
2774 if ((ft_val & 1) != 0)
2775 target = pc + 4 + offset;
2776 else
2777 target = pc + 8;
2778
2779 Context context;
2780
2781 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2782 target);
2783 }
2784
2785 /*
2786 Emulate MIPS-3D Branch instructions
2787 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
2788 False/True
2789 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
2790 False/True
2791 */
Emulate_3D_branch(llvm::MCInst & insn)2792 bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) {
2793 bool success = false;
2794 uint32_t cc, fcsr;
2795 int32_t pc, offset, target = 0;
2796 const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2797
2798 cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2799 offset = insn.getOperand(1).getImm();
2800
2801 pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2802 if (!success)
2803 return false;
2804
2805 fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0,
2806 &success);
2807 if (!success)
2808 return false;
2809
2810 /* fcsr[23], fcsr[25-31] are vaild condition bits */
2811 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2812
2813 if (!strcasecmp(op_name, "BC1ANY2F")) {
2814 /* if any one bit is 0 */
2815 if (((fcsr >> cc) & 3) != 3)
2816 target = pc + offset;
2817 else
2818 target = pc + 8;
2819 } else if (!strcasecmp(op_name, "BC1ANY2T")) {
2820 /* if any one bit is 1 */
2821 if (((fcsr >> cc) & 3) != 0)
2822 target = pc + offset;
2823 else
2824 target = pc + 8;
2825 } else if (!strcasecmp(op_name, "BC1ANY4F")) {
2826 /* if any one bit is 0 */
2827 if (((fcsr >> cc) & 0xf) != 0xf)
2828 target = pc + offset;
2829 else
2830 target = pc + 8;
2831 } else if (!strcasecmp(op_name, "BC1ANY4T")) {
2832 /* if any one bit is 1 */
2833 if (((fcsr >> cc) & 0xf) != 0)
2834 target = pc + offset;
2835 else
2836 target = pc + 8;
2837 }
2838 Context context;
2839
2840 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2841 target);
2842 }
2843
Emulate_BNZB(llvm::MCInst & insn)2844 bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) {
2845 return Emulate_MSA_Branch_DF(insn, 1, true);
2846 }
2847
Emulate_BNZH(llvm::MCInst & insn)2848 bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) {
2849 return Emulate_MSA_Branch_DF(insn, 2, true);
2850 }
2851
Emulate_BNZW(llvm::MCInst & insn)2852 bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) {
2853 return Emulate_MSA_Branch_DF(insn, 4, true);
2854 }
2855
Emulate_BNZD(llvm::MCInst & insn)2856 bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) {
2857 return Emulate_MSA_Branch_DF(insn, 8, true);
2858 }
2859
Emulate_BZB(llvm::MCInst & insn)2860 bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) {
2861 return Emulate_MSA_Branch_DF(insn, 1, false);
2862 }
2863
Emulate_BZH(llvm::MCInst & insn)2864 bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) {
2865 return Emulate_MSA_Branch_DF(insn, 2, false);
2866 }
2867
Emulate_BZW(llvm::MCInst & insn)2868 bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) {
2869 return Emulate_MSA_Branch_DF(insn, 4, false);
2870 }
2871
Emulate_BZD(llvm::MCInst & insn)2872 bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) {
2873 return Emulate_MSA_Branch_DF(insn, 8, false);
2874 }
2875
Emulate_MSA_Branch_DF(llvm::MCInst & insn,int element_byte_size,bool bnz)2876 bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
2877 int element_byte_size,
2878 bool bnz) {
2879 bool success = false, branch_hit = true;
2880 int32_t target = 0;
2881 RegisterValue reg_value;
2882 const uint8_t *ptr = nullptr;
2883
2884 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2885 int32_t offset = insn.getOperand(1).getImm();
2886
2887 int32_t pc =
2888 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2889 if (!success)
2890 return false;
2891
2892 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2893 ptr = (const uint8_t *)reg_value.GetBytes();
2894 else
2895 return false;
2896
2897 for (int i = 0; i < 16 / element_byte_size; i++) {
2898 switch (element_byte_size) {
2899 case 1:
2900 if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2901 branch_hit = false;
2902 break;
2903 case 2:
2904 if ((*(const uint16_t *)ptr == 0 && bnz) ||
2905 (*(const uint16_t *)ptr != 0 && !bnz))
2906 branch_hit = false;
2907 break;
2908 case 4:
2909 if ((*(const uint32_t *)ptr == 0 && bnz) ||
2910 (*(const uint32_t *)ptr != 0 && !bnz))
2911 branch_hit = false;
2912 break;
2913 case 8:
2914 if ((*(const uint64_t *)ptr == 0 && bnz) ||
2915 (*(const uint64_t *)ptr != 0 && !bnz))
2916 branch_hit = false;
2917 break;
2918 }
2919 if (!branch_hit)
2920 break;
2921 ptr = ptr + element_byte_size;
2922 }
2923
2924 if (branch_hit)
2925 target = pc + offset;
2926 else
2927 target = pc + 8;
2928
2929 Context context;
2930 context.type = eContextRelativeBranchImmediate;
2931
2932 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2933 target);
2934 }
2935
Emulate_BNZV(llvm::MCInst & insn)2936 bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) {
2937 return Emulate_MSA_Branch_V(insn, true);
2938 }
2939
Emulate_BZV(llvm::MCInst & insn)2940 bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) {
2941 return Emulate_MSA_Branch_V(insn, false);
2942 }
2943
Emulate_MSA_Branch_V(llvm::MCInst & insn,bool bnz)2944 bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn,
2945 bool bnz) {
2946 bool success = false;
2947 int32_t target = 0;
2948 llvm::APInt wr_val = llvm::APInt::getNullValue(128);
2949 llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
2950 llvm::APInt zero_value = llvm::APInt::getNullValue(128);
2951 RegisterValue reg_value;
2952
2953 uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2954 int32_t offset = insn.getOperand(1).getImm();
2955
2956 int32_t pc =
2957 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2958 if (!success)
2959 return false;
2960
2961 if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2962 wr_val = reg_value.GetAsUInt128(fail_value);
2963 else
2964 return false;
2965
2966 if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
2967 (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
2968 target = pc + offset;
2969 else
2970 target = pc + 8;
2971
2972 Context context;
2973 context.type = eContextRelativeBranchImmediate;
2974
2975 return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2976 target);
2977 }
2978
Emulate_LDST_Imm(llvm::MCInst & insn)2979 bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) {
2980 bool success = false;
2981 uint32_t base;
2982 int32_t imm, address;
2983 Context bad_vaddr_context;
2984
2985 uint32_t num_operands = insn.getNumOperands();
2986 base =
2987 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
2988 imm = insn.getOperand(num_operands - 1).getImm();
2989
2990 RegisterInfo reg_info_base;
2991 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
2992 reg_info_base))
2993 return false;
2994
2995 /* read base register */
2996 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2997 dwarf_zero_mips + base, 0, &success);
2998 if (!success)
2999 return false;
3000
3001 /* destination address */
3002 address = address + imm;
3003
3004 /* Set the bad_vaddr register with base address used in the instruction */
3005 bad_vaddr_context.type = eContextInvalid;
3006 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
3007 address);
3008
3009 return true;
3010 }
3011
Emulate_LDST_Reg(llvm::MCInst & insn)3012 bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) {
3013 bool success = false;
3014 uint32_t base, index;
3015 int32_t address, index_address;
3016 Context bad_vaddr_context;
3017
3018 uint32_t num_operands = insn.getNumOperands();
3019 base =
3020 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3021 index =
3022 m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
3023
3024 RegisterInfo reg_info_base, reg_info_index;
3025 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
3026 reg_info_base))
3027 return false;
3028
3029 if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
3030 reg_info_index))
3031 return false;
3032
3033 /* read base register */
3034 address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
3035 dwarf_zero_mips + base, 0, &success);
3036 if (!success)
3037 return false;
3038
3039 /* read index register */
3040 index_address = (int32_t)ReadRegisterUnsigned(
3041 eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
3042 if (!success)
3043 return false;
3044
3045 /* destination address */
3046 address = address + index_address;
3047
3048 /* Set the bad_vaddr register with base address used in the instruction */
3049 bad_vaddr_context.type = eContextInvalid;
3050 WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
3051 address);
3052
3053 return true;
3054 }
3055