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