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