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