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