1 //===-- EmulateInstructionMIPS.cpp ----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "EmulateInstructionMIPS.h"
10 
11 #include <cstdlib>
12 #include <optional>
13 
14 #include "lldb/Core/Address.h"
15 #include "lldb/Core/Opcode.h"
16 #include "lldb/Core/PluginManager.h"
17 #include "lldb/Symbol/UnwindPlan.h"
18 #include "lldb/Target/Target.h"
19 #include "lldb/Utility/ArchSpec.h"
20 #include "lldb/Utility/ConstString.h"
21 #include "lldb/Utility/DataExtractor.h"
22 #include "lldb/Utility/RegisterValue.h"
23 #include "lldb/Utility/Stream.h"
24 #include "llvm-c/Disassembler.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
28 #include "llvm/MC/MCInst.h"
29 #include "llvm/MC/MCInstrInfo.h"
30 #include "llvm/MC/MCRegisterInfo.h"
31 #include "llvm/MC/MCSubtargetInfo.h"
32 #include "llvm/MC/MCTargetOptions.h"
33 #include "llvm/MC/TargetRegistry.h"
34 #include "llvm/Support/TargetSelect.h"
35 
36 #include "llvm/ADT/STLExtras.h"
37 
38 #include "Plugins/Process/Utility/InstructionUtils.h"
39 #include "Plugins/Process/Utility/RegisterContext_mips.h"
40 
41 using namespace lldb;
42 using namespace lldb_private;
43 
LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionMIPS,InstructionMIPS)44 LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionMIPS, InstructionMIPS)
45 
46 #define UInt(x) ((uint64_t)x)
47 #define integer int64_t
48 
49 //
50 // EmulateInstructionMIPS implementation
51 //
52 
53 #ifdef __mips__
54 extern "C" {
55 void LLVMInitializeMipsTargetInfo();
56 void LLVMInitializeMipsTarget();
57 void LLVMInitializeMipsAsmPrinter();
58 void LLVMInitializeMipsTargetMC();
59 void LLVMInitializeMipsDisassembler();
60 }
61 #endif
62 
EmulateInstructionMIPS(const lldb_private::ArchSpec & arch)63 EmulateInstructionMIPS::EmulateInstructionMIPS(
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()) {
96   case ArchSpec::eCore_mips32:
97   case ArchSpec::eCore_mips32el:
98     cpu = "mips32";
99     break;
100   case ArchSpec::eCore_mips32r2:
101   case ArchSpec::eCore_mips32r2el:
102     cpu = "mips32r2";
103     break;
104   case ArchSpec::eCore_mips32r3:
105   case ArchSpec::eCore_mips32r3el:
106     cpu = "mips32r3";
107     break;
108   case ArchSpec::eCore_mips32r5:
109   case ArchSpec::eCore_mips32r5el:
110     cpu = "mips32r5";
111     break;
112   case ArchSpec::eCore_mips32r6:
113   case ArchSpec::eCore_mips32r6el:
114     cpu = "mips32r6";
115     break;
116   case ArchSpec::eCore_mips64:
117   case ArchSpec::eCore_mips64el:
118     cpu = "mips64";
119     break;
120   case ArchSpec::eCore_mips64r2:
121   case ArchSpec::eCore_mips64r2el:
122     cpu = "mips64r2";
123     break;
124   case ArchSpec::eCore_mips64r3:
125   case ArchSpec::eCore_mips64r3el:
126     cpu = "mips64r3";
127     break;
128   case ArchSpec::eCore_mips64r5:
129   case ArchSpec::eCore_mips64r5el:
130     cpu = "mips64r5";
131     break;
132   case ArchSpec::eCore_mips64r6:
133   case ArchSpec::eCore_mips64r6el:
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 
184   m_next_inst_size = 0;
185   m_use_alt_disaasm = false;
186 }
187 
Initialize()188 void EmulateInstructionMIPS::Initialize() {
189   PluginManager::RegisterPlugin(GetPluginNameStatic(),
190                                 GetPluginDescriptionStatic(), CreateInstance);
191 }
192 
Terminate()193 void EmulateInstructionMIPS::Terminate() {
194   PluginManager::UnregisterPlugin(CreateInstance);
195 }
196 
GetPluginDescriptionStatic()197 llvm::StringRef EmulateInstructionMIPS::GetPluginDescriptionStatic() {
198   return "Emulate instructions for the MIPS32 architecture.";
199 }
200 
201 EmulateInstruction *
CreateInstance(const ArchSpec & arch,InstructionType inst_type)202 EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch,
203                                        InstructionType inst_type) {
204   if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic(
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 
SetTargetTriple(const ArchSpec & arch)215 bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) {
216   return arch.GetTriple().getArch() == llvm::Triple::mips ||
217          arch.GetTriple().getArch() == llvm::Triple::mipsel;
218 }
219 
GetRegisterName(unsigned reg_num,bool alternate_name)220 const 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";
362     case dwarf_config5_mips:
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";
583   case dwarf_config5_mips:
584     return "config5";
585   }
586   return nullptr;
587 }
588 
589 std::optional<RegisterInfo>
GetRegisterInfo(RegisterKind reg_kind,uint32_t reg_num)590 EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind,
591                                         uint32_t reg_num) {
592   if (reg_kind == eRegisterKindGeneric) {
593     switch (reg_num) {
594     case LLDB_REGNUM_GENERIC_PC:
595       reg_kind = eRegisterKindDWARF;
596       reg_num = dwarf_pc_mips;
597       break;
598     case LLDB_REGNUM_GENERIC_SP:
599       reg_kind = eRegisterKindDWARF;
600       reg_num = dwarf_sp_mips;
601       break;
602     case LLDB_REGNUM_GENERIC_FP:
603       reg_kind = eRegisterKindDWARF;
604       reg_num = dwarf_r30_mips;
605       break;
606     case LLDB_REGNUM_GENERIC_RA:
607       reg_kind = eRegisterKindDWARF;
608       reg_num = dwarf_ra_mips;
609       break;
610     case LLDB_REGNUM_GENERIC_FLAGS:
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:
650       reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
651       break;
652     case dwarf_ra_mips:
653       reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
654       break;
655     case dwarf_sp_mips:
656       reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
657       break;
658     case dwarf_pc_mips:
659       reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
660       break;
661     case dwarf_sr_mips:
662       reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
663       break;
664     default:
665       break;
666     }
667     return reg_info;
668   }
669   return {};
670 }
671 
672 EmulateInstructionMIPS::MipsOpcode *
GetOpcodeForInstruction(llvm::StringRef name)673 EmulateInstructionMIPS::GetOpcodeForInstruction(llvm::StringRef name) {
674   static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = {
675       // Prologue/Epilogue instructions
676       {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu,
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
685       {"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP,
686        "ADDIU immediate"},
687       {"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5,
688        "ADDIUS5 rd,immediate"},
689       {"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)"},
690       {"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
691        "SWM16 reglist,offset(sp)"},
692       {"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
693        "SWM32 reglist,offset(base)"},
694       {"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
695        "SWP rs1,offset(base)"},
696       {"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)"},
697       {"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
698        "LWM16 reglist,offset(sp)"},
699       {"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
700        "LWM32 reglist,offset(base)"},
701       {"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
702        "LWP rd,offset(base)"},
703       {"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP,
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 
714       {"LB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
715        "LB    rt, offset(base)"},
716       {"LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
717        "LBE   rt, offset(base)"},
718       {"LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
719        "LBU   rt, offset(base)"},
720       {"LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
721        "LBUE  rt, offset(base)"},
722       {"LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
723        "LDC1  ft, offset(base)"},
724       {"LD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
725        "LD    rt, offset(base)"},
726       {"LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
727        "LDL   rt, offset(base)"},
728       {"LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
729        "LDR   rt, offset(base)"},
730       {"LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
731        "LLD   rt, offset(base)"},
732       {"LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
733        "LDC2  rt, offset(base)"},
734       {"LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
735        "LDXC1 fd, index (base)"},
736       {"LH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
737        "LH    rt, offset(base)"},
738       {"LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
739        "LHE   rt, offset(base)"},
740       {"LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
741        "LHU   rt, offset(base)"},
742       {"LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
743        "LHUE  rt, offset(base)"},
744       {"LL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
745        "LL    rt, offset(base)"},
746       {"LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
747        "LLE   rt, offset(base)"},
748       {"LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
749        "LUXC1 fd, index (base)"},
750       {"LW", &EmulateInstructionMIPS::Emulate_LDST_Imm,
751        "LW    rt, offset(base)"},
752       {"LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
753        "LWC1  ft, offset(base)"},
754       {"LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
755        "LWC2  rt, offset(base)"},
756       {"LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
757        "LWE   rt, offset(base)"},
758       {"LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
759        "LWL   rt, offset(base)"},
760       {"LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
761        "LWLE  rt, offset(base)"},
762       {"LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
763        "LWR   rt, offset(base)"},
764       {"LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
765        "LWRE  rt, offset(base)"},
766       {"LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
767        "LWXC1 fd, index (base)"},
768       {"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
769        "LLX   rt, offset(base)"},
770       {"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
771        "LLXE  rt, offset(base)"},
772       {"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
773        "LLDX  rt, offset(base)"},
774 
775       {"SB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
776        "SB    rt, offset(base)"},
777       {"SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
778        "SBE   rt, offset(base)"},
779       {"SC", &EmulateInstructionMIPS::Emulate_LDST_Imm,
780        "SC    rt, offset(base)"},
781       {"SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
782        "SCE   rt, offset(base)"},
783       {"SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
784        "SCD   rt, offset(base)"},
785       {"SD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
786        "SD    rt, offset(base)"},
787       {"SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
788        "SDL   rt, offset(base)"},
789       {"SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
790        "SDR   rt, offset(base)"},
791       {"SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
792        "SDC1  ft, offset(base)"},
793       {"SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
794        "SDC2  rt, offset(base)"},
795       {"SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
796        "SDXC1 fs, index(base)"},
797       {"SH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
798        "SH    rt, offset(base)"},
799       {"SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
800        "SHE   rt, offset(base)"},
801       {"SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
802        "SUXC1 fs, index (base)"},
803       {"SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
804        "SWC1  ft, offset(base)"},
805       {"SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
806        "SWC2  rt, offset(base)"},
807       {"SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
808        "SWE   rt, offset(base)"},
809       {"SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
810        "SWL   rt, offset(base)"},
811       {"SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
812        "SWLE  rt, offset(base)"},
813       {"SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
814        "SWR   rt, offset(base)"},
815       {"SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
816        "SWRE  rt, offset(base)"},
817       {"SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
818        "SWXC1 fs, index (base)"},
819       {"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
820        "SCX   rt, offset(base)"},
821       {"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
822        "SCXE  rt, offset(base)"},
823       {"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
824        "SCDX  rt, offset(base)"},
825 
826       // MicroMIPS Load/Store instructions
827       {"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
828        "LBU16 rt, decoded_offset(base)"},
829       {"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
830        "LHU16 rt, left_shifted_offset(base)"},
831       {"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
832        "LW16  rt, left_shifted_offset(base)"},
833       {"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
834        "LWGP  rt, left_shifted_offset(gp)"},
835       {"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
836        "SH16  rt, left_shifted_offset(base)"},
837       {"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
838        "SW16  rt, left_shifted_offset(base)"},
839       {"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
840        "SWSP  rt, left_shifted_offset(base)"},
841       {"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
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"},
849       {"BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
850        "BGEZALL rt,offset"},
851       {"BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset"},
852       {"BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
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"},
857       {"BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
858        "BLEZALC rs,offset"},
859       {"BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
860        "BGEZALC rs,offset"},
861       {"BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
862        "BLTZALC rs,offset"},
863       {"BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
864        "BGTZALC rs,offset"},
865       {"BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
866        "BEQZALC rs,offset"},
867       {"BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
868        "BNEZALC rs,offset"},
869       {"BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
870        "BEQC rs,rt,offset"},
871       {"BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
872        "BNEC rs,rt,offset"},
873       {"BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
874        "BLTC rs,rt,offset"},
875       {"BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
876        "BGEC rs,rt,offset"},
877       {"BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
878        "BLTUC rs,rt,offset"},
879       {"BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
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"},
893       {"BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
894        "BLTZAL rt,offset"},
895       {"BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
896        "BLTZALL rt,offset"},
897       {"BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset"},
898       {"BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
899        "BOVC rs,rt,offset"},
900       {"BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
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"},
917       {"BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch,
918        "BC1ANY2F cc, offset"},
919       {"BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch,
920        "BC1ANY2T cc, offset"},
921       {"BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch,
922        "BC1ANY4F cc, offset"},
923       {"BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch,
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"},
938       {"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
939        "BEQZ16 rs, offset"},
940       {"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
941        "BNEZ16 rs, offset"},
942       {"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
943        "BEQZC rs, offset"},
944       {"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
945        "BNEZC rs, offset"},
946       {"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
947        "BGEZALS rs, offset"},
948       {"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
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 
966 uint32_t
GetSizeOfInstruction(lldb_private::DataExtractor & data,uint64_t inst_addr)967 EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor &data,
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 
974   if (m_use_alt_disaasm)
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 
SetInstruction(const Opcode & insn_opcode,const Address & inst_addr,Target * target)987 bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
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) {
994       Status error;
995       lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
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(),
1018                          GetAddressByteSize());
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 
ReadInstruction()1034 bool EmulateInstructionMIPS::ReadInstruction() {
1035   bool success = false;
1036   m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
1037                                 LLDB_INVALID_ADDRESS, &success);
1038   if (success) {
1039     Context read_inst_context;
1040     read_inst_context.type = eContextReadOpcode;
1041     read_inst_context.SetNoArgs();
1042     m_opcode.SetOpcode32(
1043         ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
1044         GetByteOrder());
1045   }
1046   if (!success)
1047     m_addr = LLDB_INVALID_ADDRESS;
1048   return success;
1049 }
1050 
EvaluateInstruction(uint32_t evaluate_options)1051 bool 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());
1062     if (m_use_alt_disaasm)
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 =
1097         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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 =
1109         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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;
1117       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1118                                  new_pc))
1119         return false;
1120     }
1121   }
1122 
1123   return true;
1124 }
1125 
CreateFunctionEntryUnwind(UnwindPlan & unwind_plan)1126 bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
1127     UnwindPlan &unwind_plan) {
1128   unwind_plan.Clear();
1129   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1130 
1131   UnwindPlan::RowSP row(new UnwindPlan::Row);
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");
1144   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1145   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1146   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1147   unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
1148 
1149   return true;
1150 }
1151 
nonvolatile_reg_p(uint32_t regnum)1152 bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) {
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 
Emulate_ADDiu(llvm::MCInst & insn)1173 bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) {
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 =
1202           GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips);
1203       if (reg_info_sp)
1204         context.SetRegisterPlusOffset(*reg_info_sp, imm);
1205 
1206       /* We are allocating bytes on stack */
1207       context.type = eContextAdjustStackPointer;
1208 
1209       WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1210       return true;
1211     }
1212 
1213     imm += src_opd_val;
1214     context.SetImmediateSigned(imm);
1215     context.type = eContextImmediate;
1216 
1217     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1218                                dwarf_zero_mips + dst, imm))
1219       return false;
1220   }
1221 
1222   return true;
1223 }
1224 
Emulate_SW(llvm::MCInst & insn)1225 bool 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 =
1237       GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + 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;
1252   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
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 =
1258         GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src);
1259     if (!reg_info_src)
1260       return false;
1261 
1262     Context context;
1263     context.type = eContextPushRegisterOnStack;
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 
Emulate_LW(llvm::MCInst & insn)1287 bool 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 
1297   if (GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base))
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;
1311   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1312                         address);
1313 
1314   if (nonvolatile_reg_p(src)) {
1315     RegisterValue data_src;
1316     std::optional<RegisterInfo> reg_info_src =
1317         GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src);
1318     if (!reg_info_src)
1319       return false;
1320 
1321     Context context;
1322     context.type = eContextPopRegisterOffStack;
1323     context.SetAddress(address);
1324 
1325     return WriteRegister(context, *reg_info_src, data_src);
1326   }
1327 
1328   return false;
1329 }
1330 
Emulate_SUBU_ADDU(llvm::MCInst & insn)1331 bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) {
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 =
1367         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips);
1368     if (reg_info_sp)
1369       context.SetRegisterPlusOffset(*reg_info_sp, rt_opd_val);
1370 
1371     /* We are allocating bytes on stack */
1372     context.type = eContextAdjustStackPointer;
1373 
1374     WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
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 
1402     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1403                                dwarf_zero_mips + dst, result))
1404       return false;
1405   }
1406 
1407   return true;
1408 }
1409 
Emulate_LUI(llvm::MCInst & insn)1410 bool 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 
1423   return WriteRegisterUnsigned(context, eRegisterKindDWARF,
1424                                dwarf_zero_mips + rt, imm);
1425 }
1426 
Emulate_ADDIUSP(llvm::MCInst & insn)1427 bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) {
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 =
1435       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1436   if (!success)
1437     return false;
1438 
1439   result = src_opd_val + imm9;
1440 
1441   Context context;
1442   std::optional<RegisterInfo> reg_info_sp =
1443       GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips);
1444   if (reg_info_sp)
1445     context.SetRegisterPlusOffset(*reg_info_sp, imm9);
1446 
1447   // We are adjusting the stack.
1448   context.type = eContextAdjustStackPointer;
1449 
1450   WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1451   return true;
1452 }
1453 
Emulate_ADDIUS5(llvm::MCInst & insn)1454 bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) {
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 =
1475         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips);
1476     if (reg_info_sp)
1477       context.SetRegisterPlusOffset(*reg_info_sp, imm4);
1478 
1479     // We are adjusting the stack.
1480     context.type = eContextAdjustStackPointer;
1481 
1482     WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1483   }
1484 
1485   return true;
1486 }
1487 
Emulate_SWSP(llvm::MCInst & insn)1488 bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) {
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 =
1499       GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base);
1500   if (!reg_info_base)
1501     return false;
1502 
1503   // read base register
1504   address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
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;
1516   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
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;
1523     context.type = eContextPushRegisterOnStack;
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 */
Emulate_SWM16_32(llvm::MCInst & insn)1553 bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) {
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 =
1572       GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + 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 =
1601         GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src);
1602     if (!reg_info_src)
1603       return false;
1604 
1605     Context context;
1606     context.type = eContextPushRegisterOnStack;
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 
Emulate_LWSP(llvm::MCInst & insn)1631 bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) {
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 
1638   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base))
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;
1653   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
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 =
1659         GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src);
1660     if (!reg_info_src)
1661       return false;
1662 
1663     Context context;
1664     context.type = eContextPopRegisterOffStack;
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 */
Emulate_LWM16_32(llvm::MCInst & insn)1679 bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) {
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 =
1721         GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst);
1722     if (!reg_info_dst)
1723       return false;
1724 
1725     Context context;
1726     context.type = eContextPopRegisterOffStack;
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 
Emulate_JRADDIUSP(llvm::MCInst & insn)1736 bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) {
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 =
1748       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1749   if (!success)
1750     return false;
1751 
1752   int32_t ra_val =
1753       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
1754   if (!success)
1755     return false;
1756 
1757   int32_t result = src_opd_val + imm5;
1758 
1759   Context context;
1760 
1761   // Update the PC
1762   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1763                              ra_val))
1764     return false;
1765 
1766   std::optional<RegisterInfo> reg_info_sp =
1767       GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips);
1768   if (reg_info_sp)
1769     context.SetRegisterPlusOffset(*reg_info_sp, imm5);
1770 
1771   // We are adjusting stack
1772   context.type = eContextAdjustStackPointer;
1773 
1774   // update SP
1775   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips,
1776                                result);
1777 }
1778 
IsAdd64bitOverflow(int32_t a,int32_t b)1779 static 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 */
Emulate_BXX_3ops(llvm::MCInst & insn)1789 bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) {
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 
1799   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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;
1827   context.type = eContextRelativeBranchImmediate;
1828   context.SetImmediate(offset);
1829 
1830   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
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 */
Emulate_BXX_3ops_C(llvm::MCInst & insn)1839 bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
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 
1850   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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;
1907   context.type = eContextRelativeBranchImmediate;
1908   context.SetImmediate(current_inst_size + offset);
1909 
1910   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1911                                target);
1912 }
1913 
1914 /*
1915     Emulate below MIPS conditional branch and link instructions.
1916     BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1917 */
Emulate_Bcond_Link_C(llvm::MCInst & insn)1918 bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
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 
1928   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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 
1971   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1972                              target))
1973     return false;
1974 
1975   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
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 */
Emulate_Bcond_Link(llvm::MCInst & insn)1987 bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) {
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 
1997   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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 
2022   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2023                              target))
2024     return false;
2025 
2026   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
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 */
Emulate_BXX_2ops(llvm::MCInst & insn)2038 bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) {
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 
2048   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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;
2084   context.type = eContextRelativeBranchImmediate;
2085   context.SetImmediate(offset);
2086 
2087   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2088                                target);
2089 }
2090 
2091 /*
2092     Emulate below MIPS branch instructions.
2093     BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
2094 */
Emulate_BXX_2ops_C(llvm::MCInst & insn)2095 bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
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 
2106   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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;
2148   context.type = eContextRelativeBranchImmediate;
2149   context.SetImmediate(current_inst_size + offset);
2150 
2151   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2152                                target);
2153 }
2154 
Emulate_B16_MM(llvm::MCInst & insn)2155 bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) {
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 
2162   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2163   if (!success)
2164     return false;
2165 
2166   // unconditional branch
2167   target = pc + offset;
2168 
2169   Context context;
2170   context.type = eContextRelativeBranchImmediate;
2171   context.SetImmediate(current_inst_size + offset);
2172 
2173   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
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 */
Emulate_Branch_MM(llvm::MCInst & insn)2182 bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) {
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 =
2211       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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;
2265   context.type = eContextRelativeBranchImmediate;
2266   context.SetImmediate(current_inst_size + offset);
2267 
2268   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2269                              target))
2270     return false;
2271 
2272   if (update_ra) {
2273     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2274                                pc + ra_offset))
2275       return false;
2276   }
2277   return true;
2278 }
2279 
2280 /* Emulate micromips jump instructions.
2281    JALR16,JALRS16
2282 */
Emulate_JALRx16_MM(llvm::MCInst & insn)2283 bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) {
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 =
2291       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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 
2307   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2308                              rs_val))
2309     return false;
2310 
2311   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
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 */
Emulate_JALx(llvm::MCInst & insn)2322 bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) {
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 
2339   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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 
2356   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2357                              target))
2358     return false;
2359 
2360   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2361                              pc + ra_offset))
2362     return false;
2363 
2364   return true;
2365 }
2366 
Emulate_JALRS(llvm::MCInst & insn)2367 bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) {
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 
2386   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2387   if (!success)
2388     return false;
2389 
2390   Context context;
2391 
2392   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2393                              rs_val))
2394     return false;
2395 
2396   // This is 4-byte instruction with 2-byte delay slot.
2397   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2398                              pc + 6))
2399     return false;
2400 
2401   return true;
2402 }
2403 
Emulate_BAL(llvm::MCInst & insn)2404 bool 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 
2416   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2417   if (!success)
2418     return false;
2419 
2420   target = pc + offset;
2421 
2422   Context context;
2423 
2424   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2425                              target))
2426     return false;
2427 
2428   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2429                              pc + 8))
2430     return false;
2431 
2432   return true;
2433 }
2434 
Emulate_BALC(llvm::MCInst & insn)2435 bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) {
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 
2447   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2448   if (!success)
2449     return false;
2450 
2451   target = pc + offset;
2452 
2453   Context context;
2454 
2455   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2456                              target))
2457     return false;
2458 
2459   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2460                              pc + 4))
2461     return false;
2462 
2463   return true;
2464 }
2465 
Emulate_BC(llvm::MCInst & insn)2466 bool 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 
2477   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2478   if (!success)
2479     return false;
2480 
2481   target = pc + offset;
2482 
2483   Context context;
2484 
2485   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2486                                target);
2487 }
2488 
Emulate_J(llvm::MCInst & insn)2489 bool 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 
2500   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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 
2509   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc);
2510 }
2511 
Emulate_JAL(llvm::MCInst & insn)2512 bool 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 
2523   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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 
2532   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2533                              target))
2534     return false;
2535 
2536   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2537                              pc + 8))
2538     return false;
2539 
2540   return true;
2541 }
2542 
Emulate_JALR(llvm::MCInst & insn)2543 bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) {
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 
2556   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2557   if (!success)
2558     return false;
2559 
2560   rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2561                                 &success);
2562   if (!success)
2563     return false;
2564 
2565   Context context;
2566 
2567   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2568                              rs_val))
2569     return false;
2570 
2571   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2572                              pc + 8))
2573     return false;
2574 
2575   return true;
2576 }
2577 
Emulate_JIALC(llvm::MCInst & insn)2578 bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) {
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 
2592   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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 
2605   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2606                              target))
2607     return false;
2608 
2609   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2610                              pc + 4))
2611     return false;
2612 
2613   return true;
2614 }
2615 
Emulate_JIC(llvm::MCInst & insn)2616 bool 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 
2638   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2639                                target);
2640 }
2641 
Emulate_JR(llvm::MCInst & insn)2642 bool 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 
2653   rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2654                                 &success);
2655   if (!success)
2656     return false;
2657 
2658   Context context;
2659 
2660   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
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 */
Emulate_FP_branch(llvm::MCInst & insn)2669 bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) {
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 
2678   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2679   if (!success)
2680     return false;
2681 
2682   fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
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 
2704   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2705                                target);
2706 }
2707 
Emulate_BC1EQZ(llvm::MCInst & insn)2708 bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) {
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 
2724   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2725   if (!success)
2726     return false;
2727 
2728   ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
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 
2740   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2741                                target);
2742 }
2743 
Emulate_BC1NEZ(llvm::MCInst & insn)2744 bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) {
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 
2760   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2761   if (!success)
2762     return false;
2763 
2764   ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
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 
2776   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
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 */
Emulate_3D_branch(llvm::MCInst & insn)2787 bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) {
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 
2796   pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2797   if (!success)
2798     return false;
2799 
2800   fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0,
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 
2835   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2836                                target);
2837 }
2838 
Emulate_BNZB(llvm::MCInst & insn)2839 bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) {
2840   return Emulate_MSA_Branch_DF(insn, 1, true);
2841 }
2842 
Emulate_BNZH(llvm::MCInst & insn)2843 bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) {
2844   return Emulate_MSA_Branch_DF(insn, 2, true);
2845 }
2846 
Emulate_BNZW(llvm::MCInst & insn)2847 bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) {
2848   return Emulate_MSA_Branch_DF(insn, 4, true);
2849 }
2850 
Emulate_BNZD(llvm::MCInst & insn)2851 bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) {
2852   return Emulate_MSA_Branch_DF(insn, 8, true);
2853 }
2854 
Emulate_BZB(llvm::MCInst & insn)2855 bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) {
2856   return Emulate_MSA_Branch_DF(insn, 1, false);
2857 }
2858 
Emulate_BZH(llvm::MCInst & insn)2859 bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) {
2860   return Emulate_MSA_Branch_DF(insn, 2, false);
2861 }
2862 
Emulate_BZW(llvm::MCInst & insn)2863 bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) {
2864   return Emulate_MSA_Branch_DF(insn, 4, false);
2865 }
2866 
Emulate_BZD(llvm::MCInst & insn)2867 bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) {
2868   return Emulate_MSA_Branch_DF(insn, 8, false);
2869 }
2870 
Emulate_MSA_Branch_DF(llvm::MCInst & insn,int element_byte_size,bool bnz)2871 bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
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 =
2883       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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;
2925   context.type = eContextRelativeBranchImmediate;
2926 
2927   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2928                                target);
2929 }
2930 
Emulate_BNZV(llvm::MCInst & insn)2931 bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) {
2932   return Emulate_MSA_Branch_V(insn, true);
2933 }
2934 
Emulate_BZV(llvm::MCInst & insn)2935 bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) {
2936   return Emulate_MSA_Branch_V(insn, false);
2937 }
2938 
Emulate_MSA_Branch_V(llvm::MCInst & insn,bool bnz)2939 bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn,
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 =
2952       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
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;
2968   context.type = eContextRelativeBranchImmediate;
2969 
2970   return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2971                                target);
2972 }
2973 
Emulate_LDST_Imm(llvm::MCInst & insn)2974 bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) {
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 
2985   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base))
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;
2999   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
3000                         address);
3001 
3002   return true;
3003 }
3004 
Emulate_LDST_Reg(llvm::MCInst & insn)3005 bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) {
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 
3017   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base))
3018     return false;
3019 
3020   if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index))
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;
3040   WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
3041                         address);
3042 
3043   return true;
3044 }
3045