EmulateInstructionMIPS.cpp revision 341825
1//===-- EmulateInstructionMIPS.cpp -------------------------------*- C++-*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "EmulateInstructionMIPS.h"
11
12#include <stdlib.h>
13
14#include "lldb/Core/Address.h"
15#include "lldb/Core/Opcode.h"
16#include "lldb/Core/PluginManager.h"
17#include "lldb/Core/RegisterValue.h"
18#include "lldb/Symbol/UnwindPlan.h"
19#include "lldb/Target/Target.h"
20#include "lldb/Utility/ArchSpec.h"
21#include "lldb/Utility/ConstString.h"
22#include "lldb/Utility/DataExtractor.h"
23#include "lldb/Utility/Stream.h"
24#include "llvm-c/Disassembler.h"
25#include "llvm/MC/MCAsmInfo.h"
26#include "llvm/MC/MCContext.h"
27#include "llvm/MC/MCDisassembler/MCDisassembler.h"
28#include "llvm/MC/MCInst.h"
29#include "llvm/MC/MCInstrInfo.h"
30#include "llvm/MC/MCRegisterInfo.h"
31#include "llvm/MC/MCSubtargetInfo.h"
32#include "llvm/Support/TargetRegistry.h"
33#include "llvm/Support/TargetSelect.h"
34
35#include "llvm/ADT/STLExtras.h"
36
37#include "Plugins/Process/Utility/InstructionUtils.h"
38#include "Plugins/Process/Utility/RegisterContext_mips.h" //mips32 has same registers nos as mips64
39
40using namespace lldb;
41using namespace lldb_private;
42
43#define UInt(x) ((uint64_t)x)
44#define integer int64_t
45
46//----------------------------------------------------------------------
47//
48// EmulateInstructionMIPS implementation
49//
50//----------------------------------------------------------------------
51
52#ifdef __mips__
53extern "C" {
54void LLVMInitializeMipsTargetInfo();
55void LLVMInitializeMipsTarget();
56void LLVMInitializeMipsAsmPrinter();
57void LLVMInitializeMipsTargetMC();
58void LLVMInitializeMipsDisassembler();
59}
60#endif
61
62EmulateInstructionMIPS::EmulateInstructionMIPS(
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  m_asm_info.reset(target->createMCAsmInfo(*m_reg_info, triple.getTriple()));
156  m_subtype_info.reset(
157      target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
158  assert(m_asm_info.get() && m_subtype_info.get());
159
160  m_context.reset(
161      new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr));
162  assert(m_context.get());
163
164  m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
165  assert(m_disasm.get());
166
167  /* Create alternate disassembler for microMIPS */
168  if (arch_flags & ArchSpec::eMIPSAse_mips16)
169    features += "+mips16,";
170  else if (arch_flags & ArchSpec::eMIPSAse_micromips)
171    features += "+micromips,";
172
173  m_alt_subtype_info.reset(
174      target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
175  assert(m_alt_subtype_info.get());
176
177  m_alt_disasm.reset(
178      target->createMCDisassembler(*m_alt_subtype_info, *m_context));
179  assert(m_alt_disasm.get());
180
181  m_next_inst_size = 0;
182  m_use_alt_disaasm = false;
183}
184
185void EmulateInstructionMIPS::Initialize() {
186  PluginManager::RegisterPlugin(GetPluginNameStatic(),
187                                GetPluginDescriptionStatic(), CreateInstance);
188}
189
190void EmulateInstructionMIPS::Terminate() {
191  PluginManager::UnregisterPlugin(CreateInstance);
192}
193
194ConstString EmulateInstructionMIPS::GetPluginNameStatic() {
195  ConstString g_plugin_name("lldb.emulate-instruction.mips32");
196  return g_plugin_name;
197}
198
199lldb_private::ConstString EmulateInstructionMIPS::GetPluginName() {
200  static ConstString g_plugin_name("EmulateInstructionMIPS");
201  return g_plugin_name;
202}
203
204const char *EmulateInstructionMIPS::GetPluginDescriptionStatic() {
205  return "Emulate instructions for the MIPS32 architecture.";
206}
207
208EmulateInstruction *
209EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch,
210                                       InstructionType inst_type) {
211  if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic(
212          inst_type)) {
213    if (arch.GetTriple().getArch() == llvm::Triple::mips ||
214        arch.GetTriple().getArch() == llvm::Triple::mipsel) {
215      return new EmulateInstructionMIPS(arch);
216    }
217  }
218
219  return NULL;
220}
221
222bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) {
223  if (arch.GetTriple().getArch() == llvm::Triple::mips ||
224      arch.GetTriple().getArch() == llvm::Triple::mipsel)
225    return true;
226  return false;
227}
228
229const 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
598bool EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind,
599                                             uint32_t reg_num,
600                                             RegisterInfo &reg_info) {
601  if (reg_kind == eRegisterKindGeneric) {
602    switch (reg_num) {
603    case LLDB_REGNUM_GENERIC_PC:
604      reg_kind = eRegisterKindDWARF;
605      reg_num = dwarf_pc_mips;
606      break;
607    case LLDB_REGNUM_GENERIC_SP:
608      reg_kind = eRegisterKindDWARF;
609      reg_num = dwarf_sp_mips;
610      break;
611    case LLDB_REGNUM_GENERIC_FP:
612      reg_kind = eRegisterKindDWARF;
613      reg_num = dwarf_r30_mips;
614      break;
615    case LLDB_REGNUM_GENERIC_RA:
616      reg_kind = eRegisterKindDWARF;
617      reg_num = dwarf_ra_mips;
618      break;
619    case LLDB_REGNUM_GENERIC_FLAGS:
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:
658      reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
659      break;
660    case dwarf_ra_mips:
661      reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
662      break;
663    case dwarf_sp_mips:
664      reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
665      break;
666    case dwarf_pc_mips:
667      reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
668      break;
669    case dwarf_sr_mips:
670      reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
671      break;
672    default:
673      break;
674    }
675    return true;
676  }
677  return false;
678}
679
680EmulateInstructionMIPS::MipsOpcode *
681EmulateInstructionMIPS::GetOpcodeForInstruction(const char *op_name) {
682  static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = {
683      //----------------------------------------------------------------------
684      // Prologue/Epilogue instructions
685      //----------------------------------------------------------------------
686      {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu,
687       "ADDIU rt, rs, immediate"},
688      {"SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)"},
689      {"LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)"},
690      {"SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt"},
691      {"ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt"},
692      {"LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate"},
693
694      //----------------------------------------------------------------------
695      // MicroMIPS Prologue/Epilogue instructions
696      //----------------------------------------------------------------------
697      {"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP,
698       "ADDIU immediate"},
699      {"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5,
700       "ADDIUS5 rd,immediate"},
701      {"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)"},
702      {"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
703       "SWM16 reglist,offset(sp)"},
704      {"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
705       "SWM32 reglist,offset(base)"},
706      {"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
707       "SWP rs1,offset(base)"},
708      {"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)"},
709      {"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
710       "LWM16 reglist,offset(sp)"},
711      {"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
712       "LWM32 reglist,offset(base)"},
713      {"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
714       "LWP rd,offset(base)"},
715      {"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP,
716       "JRADDIUSP immediate"},
717      //----------------------------------------------------------------------
718
719      // Load/Store  instructions
720      //----------------------------------------------------------------------
721      /* Following list of emulated instructions are required by implementation
722         of hardware watchpoint
723         for MIPS in lldb. As we just need the address accessed by instructions,
724         we have generalised
725         all these instructions in 2 functions depending on their addressing
726         modes */
727
728      {"LB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
729       "LB    rt, offset(base)"},
730      {"LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
731       "LBE   rt, offset(base)"},
732      {"LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
733       "LBU   rt, offset(base)"},
734      {"LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
735       "LBUE  rt, offset(base)"},
736      {"LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
737       "LDC1  ft, offset(base)"},
738      {"LD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
739       "LD    rt, offset(base)"},
740      {"LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
741       "LDL   rt, offset(base)"},
742      {"LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
743       "LDR   rt, offset(base)"},
744      {"LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
745       "LLD   rt, offset(base)"},
746      {"LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
747       "LDC2  rt, offset(base)"},
748      {"LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
749       "LDXC1 fd, index (base)"},
750      {"LH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
751       "LH    rt, offset(base)"},
752      {"LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
753       "LHE   rt, offset(base)"},
754      {"LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
755       "LHU   rt, offset(base)"},
756      {"LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
757       "LHUE  rt, offset(base)"},
758      {"LL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
759       "LL    rt, offset(base)"},
760      {"LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
761       "LLE   rt, offset(base)"},
762      {"LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
763       "LUXC1 fd, index (base)"},
764      {"LW", &EmulateInstructionMIPS::Emulate_LDST_Imm,
765       "LW    rt, offset(base)"},
766      {"LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
767       "LWC1  ft, offset(base)"},
768      {"LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
769       "LWC2  rt, offset(base)"},
770      {"LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
771       "LWE   rt, offset(base)"},
772      {"LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
773       "LWL   rt, offset(base)"},
774      {"LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
775       "LWLE  rt, offset(base)"},
776      {"LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
777       "LWR   rt, offset(base)"},
778      {"LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
779       "LWRE  rt, offset(base)"},
780      {"LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
781       "LWXC1 fd, index (base)"},
782      {"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
783       "LLX   rt, offset(base)"},
784      {"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
785       "LLXE  rt, offset(base)"},
786      {"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
787       "LLDX  rt, offset(base)"},
788
789      {"SB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
790       "SB    rt, offset(base)"},
791      {"SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
792       "SBE   rt, offset(base)"},
793      {"SC", &EmulateInstructionMIPS::Emulate_LDST_Imm,
794       "SC    rt, offset(base)"},
795      {"SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
796       "SCE   rt, offset(base)"},
797      {"SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
798       "SCD   rt, offset(base)"},
799      {"SD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
800       "SD    rt, offset(base)"},
801      {"SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
802       "SDL   rt, offset(base)"},
803      {"SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
804       "SDR   rt, offset(base)"},
805      {"SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
806       "SDC1  ft, offset(base)"},
807      {"SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
808       "SDC2  rt, offset(base)"},
809      {"SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
810       "SDXC1 fs, index(base)"},
811      {"SH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
812       "SH    rt, offset(base)"},
813      {"SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
814       "SHE   rt, offset(base)"},
815      {"SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
816       "SUXC1 fs, index (base)"},
817      {"SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
818       "SWC1  ft, offset(base)"},
819      {"SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
820       "SWC2  rt, offset(base)"},
821      {"SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
822       "SWE   rt, offset(base)"},
823      {"SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
824       "SWL   rt, offset(base)"},
825      {"SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
826       "SWLE  rt, offset(base)"},
827      {"SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
828       "SWR   rt, offset(base)"},
829      {"SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
830       "SWRE  rt, offset(base)"},
831      {"SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
832       "SWXC1 fs, index (base)"},
833      {"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
834       "SCX   rt, offset(base)"},
835      {"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
836       "SCXE  rt, offset(base)"},
837      {"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
838       "SCDX  rt, offset(base)"},
839
840      //----------------------------------------------------------------------
841      // MicroMIPS Load/Store instructions
842      //----------------------------------------------------------------------
843      {"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
844       "LBU16 rt, decoded_offset(base)"},
845      {"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
846       "LHU16 rt, left_shifted_offset(base)"},
847      {"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
848       "LW16  rt, left_shifted_offset(base)"},
849      {"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
850       "LWGP  rt, left_shifted_offset(gp)"},
851      {"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
852       "SH16  rt, left_shifted_offset(base)"},
853      {"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
854       "SW16  rt, left_shifted_offset(base)"},
855      {"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
856       "SWSP  rt, left_shifted_offset(base)"},
857      {"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
858       "SB16  rt, offset(base)"},
859
860      //----------------------------------------------------------------------
861      // Branch instructions
862      //----------------------------------------------------------------------
863      {"BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
864      {"BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset"},
865      {"BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset"},
866      {"BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset"},
867      {"BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
868       "BGEZALL rt,offset"},
869      {"BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset"},
870      {"BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
871       "BGEZAL rs,offset"},
872      {"BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset"},
873      {"BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset"},
874      {"BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset"},
875      {"BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
876       "BLEZALC rs,offset"},
877      {"BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
878       "BGEZALC rs,offset"},
879      {"BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
880       "BLTZALC rs,offset"},
881      {"BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
882       "BGTZALC rs,offset"},
883      {"BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
884       "BEQZALC rs,offset"},
885      {"BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
886       "BNEZALC rs,offset"},
887      {"BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
888       "BEQC rs,rt,offset"},
889      {"BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
890       "BNEC rs,rt,offset"},
891      {"BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
892       "BLTC rs,rt,offset"},
893      {"BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
894       "BGEC rs,rt,offset"},
895      {"BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
896       "BLTUC rs,rt,offset"},
897      {"BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
898       "BGEUC rs,rt,offset"},
899      {"BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset"},
900      {"BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset"},
901      {"BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset"},
902      {"BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset"},
903      {"BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset"},
904      {"BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset"},
905      {"BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset"},
906      {"BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset"},
907      {"BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset"},
908      {"BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset"},
909      {"BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset"},
910      {"BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset"},
911      {"BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
912       "BLTZAL rt,offset"},
913      {"BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
914       "BLTZALL rt,offset"},
915      {"BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset"},
916      {"BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
917       "BOVC rs,rt,offset"},
918      {"BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
919       "BNVC rs,rt,offset"},
920      {"J", &EmulateInstructionMIPS::Emulate_J, "J target"},
921      {"JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target"},
922      {"JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target"},
923      {"JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target"},
924      {"JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target"},
925      {"JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset"},
926      {"JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset"},
927      {"JR", &EmulateInstructionMIPS::Emulate_JR, "JR target"},
928      {"JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target"},
929      {"BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset"},
930      {"BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset"},
931      {"BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset"},
932      {"BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset"},
933      {"BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset"},
934      {"BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset"},
935      {"BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch,
936       "BC1ANY2F cc, offset"},
937      {"BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch,
938       "BC1ANY2T cc, offset"},
939      {"BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch,
940       "BC1ANY4F cc, offset"},
941      {"BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch,
942       "BC1ANY4T cc, offset"},
943      {"BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16"},
944      {"BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16"},
945      {"BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16"},
946      {"BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16"},
947      {"BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16"},
948      {"BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16"},
949      {"BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16"},
950      {"BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16"},
951      {"BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16"},
952      {"BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16"},
953
954      //----------------------------------------------------------------------
955      // MicroMIPS Branch instructions
956      //----------------------------------------------------------------------
957      {"B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset"},
958      {"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
959       "BEQZ16 rs, offset"},
960      {"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
961       "BNEZ16 rs, offset"},
962      {"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
963       "BEQZC rs, offset"},
964      {"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
965       "BNEZC rs, offset"},
966      {"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
967       "BGEZALS rs, offset"},
968      {"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
969       "BLTZALS rs, offset"},
970      {"JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs"},
971      {"JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs"},
972      {"JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs"},
973      {"JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs"},
974      {"JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target"},
975      {"JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target"},
976      {"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs"},
977  };
978
979  static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
980
981  for (size_t i = 0; i < k_num_mips_opcodes; ++i) {
982    if (!strcasecmp(g_opcodes[i].op_name, op_name))
983      return &g_opcodes[i];
984  }
985
986  return NULL;
987}
988
989uint32_t
990EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor &data,
991                                             uint64_t inst_addr) {
992  uint64_t next_inst_size = 0;
993  llvm::MCInst mc_insn;
994  llvm::MCDisassembler::DecodeStatus decode_status;
995  llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
996
997  if (m_use_alt_disaasm)
998    decode_status =
999        m_alt_disasm->getInstruction(mc_insn, next_inst_size, raw_insn,
1000                                     inst_addr, llvm::nulls(), llvm::nulls());
1001  else
1002    decode_status =
1003        m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn, inst_addr,
1004                                 llvm::nulls(), llvm::nulls());
1005
1006  if (decode_status != llvm::MCDisassembler::Success)
1007    return false;
1008
1009  return m_insn_info->get(mc_insn.getOpcode()).getSize();
1010}
1011
1012bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
1013                                            const Address &inst_addr,
1014                                            Target *target) {
1015  m_use_alt_disaasm = false;
1016
1017  if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
1018    if (inst_addr.GetAddressClass() == AddressClass::eCodeAlternateISA) {
1019      Status error;
1020      lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1021
1022      /*
1023       * The address belongs to microMIPS function. To find the size of
1024       * next instruction use microMIPS disassembler.
1025      */
1026      m_use_alt_disaasm = true;
1027
1028      uint32_t current_inst_size = insn_opcode.GetByteSize();
1029      uint8_t buf[sizeof(uint32_t)];
1030      uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size;
1031      Address next_addr(next_inst_addr);
1032
1033      const size_t bytes_read =
1034          target->ReadMemory(next_addr, /* Address of next instruction */
1035                             true,      /* prefer_file_cache */
1036                             buf, sizeof(uint32_t), error, &load_addr);
1037
1038      if (bytes_read == 0)
1039        return true;
1040
1041      DataExtractor data(buf, sizeof(uint32_t), GetByteOrder(),
1042                         GetAddressByteSize());
1043      m_next_inst_size = GetSizeOfInstruction(data, next_inst_addr);
1044      return true;
1045    } else {
1046      /*
1047       * If the address class is not AddressClass::eCodeAlternateISA then
1048       * the function is not microMIPS. In this case instruction size is
1049       * always 4 bytes.
1050      */
1051      m_next_inst_size = 4;
1052      return true;
1053    }
1054  }
1055  return false;
1056}
1057
1058bool EmulateInstructionMIPS::ReadInstruction() {
1059  bool success = false;
1060  m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
1061                                LLDB_INVALID_ADDRESS, &success);
1062  if (success) {
1063    Context read_inst_context;
1064    read_inst_context.type = eContextReadOpcode;
1065    read_inst_context.SetNoArgs();
1066    m_opcode.SetOpcode32(
1067        ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
1068        GetByteOrder());
1069  }
1070  if (!success)
1071    m_addr = LLDB_INVALID_ADDRESS;
1072  return success;
1073}
1074
1075bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options) {
1076  bool success = false;
1077  llvm::MCInst mc_insn;
1078  uint64_t insn_size;
1079  DataExtractor data;
1080
1081  /* Keep the complexity of the decode logic with the llvm::MCDisassembler
1082   * class. */
1083  if (m_opcode.GetData(data)) {
1084    llvm::MCDisassembler::DecodeStatus decode_status;
1085    llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
1086    if (m_use_alt_disaasm)
1087      decode_status = m_alt_disasm->getInstruction(
1088          mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
1089    else
1090      decode_status = m_disasm->getInstruction(
1091          mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
1092
1093    if (decode_status != llvm::MCDisassembler::Success)
1094      return false;
1095  }
1096
1097  /*
1098   * mc_insn.getOpcode() returns decoded opcode. However to make use
1099   * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
1100  */
1101  const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
1102
1103  if (op_name == NULL)
1104    return false;
1105
1106  /*
1107   * Decoding has been done already. Just get the call-back function
1108   * and emulate the instruction.
1109  */
1110  MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
1111
1112  if (opcode_data == NULL)
1113    return false;
1114
1115  uint64_t old_pc = 0, new_pc = 0;
1116  const bool auto_advance_pc =
1117      evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
1118
1119  if (auto_advance_pc) {
1120    old_pc =
1121        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1122    if (!success)
1123      return false;
1124  }
1125
1126  /* emulate instruction */
1127  success = (this->*opcode_data->callback)(mc_insn);
1128  if (!success)
1129    return false;
1130
1131  if (auto_advance_pc) {
1132    new_pc =
1133        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1134    if (!success)
1135      return false;
1136
1137    /* If we haven't changed the PC, change it here */
1138    if (old_pc == new_pc) {
1139      new_pc += 4;
1140      Context context;
1141      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1142                                 new_pc))
1143        return false;
1144    }
1145  }
1146
1147  return true;
1148}
1149
1150bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
1151    UnwindPlan &unwind_plan) {
1152  unwind_plan.Clear();
1153  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1154
1155  UnwindPlan::RowSP row(new UnwindPlan::Row);
1156  const bool can_replace = false;
1157
1158  // Our previous Call Frame Address is the stack pointer
1159  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0);
1160
1161  // Our previous PC is in the RA
1162  row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace);
1163
1164  unwind_plan.AppendRow(row);
1165
1166  // All other registers are the same.
1167  unwind_plan.SetSourceName("EmulateInstructionMIPS");
1168  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1169  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1170  unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
1171
1172  return true;
1173}
1174
1175bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) {
1176  switch (regnum) {
1177  case dwarf_r16_mips:
1178  case dwarf_r17_mips:
1179  case dwarf_r18_mips:
1180  case dwarf_r19_mips:
1181  case dwarf_r20_mips:
1182  case dwarf_r21_mips:
1183  case dwarf_r22_mips:
1184  case dwarf_r23_mips:
1185  case dwarf_gp_mips:
1186  case dwarf_sp_mips:
1187  case dwarf_r30_mips:
1188  case dwarf_ra_mips:
1189    return true;
1190  default:
1191    return false;
1192  }
1193  return false;
1194}
1195
1196bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) {
1197  // ADDIU rt, rs, immediate
1198  // GPR[rt] <- GPR[rs] + sign_extend(immediate)
1199
1200  uint8_t dst, src;
1201  bool success = false;
1202  const uint32_t imm16 = insn.getOperand(2).getImm();
1203  int64_t imm = SignedBits(imm16, 15, 0);
1204
1205  dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1206  src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1207
1208  // If immediate value is greater then 2^16 - 1 then clang generate LUI,
1209  // ADDIU, SUBU instructions in prolog. Example lui    $1, 0x2 addiu $1, $1,
1210  // -0x5920 subu  $sp, $sp, $1 In this case, ADDIU dst and src will be same
1211  // and not equal to sp
1212  if (dst == src) {
1213    Context context;
1214
1215    /* read <src> register */
1216    const int64_t src_opd_val = ReadRegisterUnsigned(
1217        eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1218    if (!success)
1219      return false;
1220
1221    /* Check if this is daddiu sp, sp, imm16 */
1222    if (dst == dwarf_sp_mips) {
1223      uint64_t result = src_opd_val + imm;
1224      RegisterInfo reg_info_sp;
1225
1226      if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1227        context.SetRegisterPlusOffset(reg_info_sp, imm);
1228
1229      /* We are allocating bytes on stack */
1230      context.type = eContextAdjustStackPointer;
1231
1232      WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1233      return true;
1234    }
1235
1236    imm += src_opd_val;
1237    context.SetImmediateSigned(imm);
1238    context.type = eContextImmediate;
1239
1240    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1241                               dwarf_zero_mips + dst, imm))
1242      return false;
1243  }
1244
1245  return true;
1246}
1247
1248bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) {
1249  bool success = false;
1250  uint32_t imm16 = insn.getOperand(2).getImm();
1251  uint32_t imm = SignedBits(imm16, 15, 0);
1252  uint32_t src, base;
1253  int32_t address;
1254  Context bad_vaddr_context;
1255
1256  RegisterInfo reg_info_base;
1257
1258  src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1259  base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1260
1261  if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1262                       reg_info_base))
1263    return false;
1264
1265  /* read base register */
1266  address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1267                                          dwarf_zero_mips + base, 0, &success);
1268  if (!success)
1269    return false;
1270
1271  /* destination address */
1272  address = address + imm;
1273
1274  /* Set the bad_vaddr register with base address used in the instruction */
1275  bad_vaddr_context.type = eContextInvalid;
1276  WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1277                        address);
1278
1279  /* We look for sp based non-volatile register stores */
1280  if (nonvolatile_reg_p(src)) {
1281
1282    RegisterInfo reg_info_src;
1283
1284    if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1285                         reg_info_src))
1286      return false;
1287
1288    Context context;
1289    RegisterValue data_src;
1290    context.type = eContextPushRegisterOnStack;
1291    context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1292
1293    uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1294    Status error;
1295
1296    if (!ReadRegister(&reg_info_base, data_src))
1297      return false;
1298
1299    if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
1300                                 eByteOrderLittle, error) == 0)
1301      return false;
1302
1303    if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1304      return false;
1305
1306    return true;
1307  }
1308
1309  return false;
1310}
1311
1312bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) {
1313  bool success = false;
1314  uint32_t src, base;
1315  int32_t imm, address;
1316  Context bad_vaddr_context;
1317
1318  src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1319  base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1320  imm = insn.getOperand(2).getImm();
1321
1322  RegisterInfo reg_info_base;
1323  if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1324                       reg_info_base))
1325    return false;
1326
1327  /* read base register */
1328  address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1329                                          dwarf_zero_mips + base, 0, &success);
1330  if (!success)
1331    return false;
1332
1333  /* destination address */
1334  address = address + imm;
1335
1336  /* Set the bad_vaddr register with base address used in the instruction */
1337  bad_vaddr_context.type = eContextInvalid;
1338  WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1339                        address);
1340
1341  if (nonvolatile_reg_p(src)) {
1342    RegisterValue data_src;
1343    RegisterInfo reg_info_src;
1344
1345    if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1346                         reg_info_src))
1347      return false;
1348
1349    Context context;
1350    context.type = eContextPopRegisterOffStack;
1351    context.SetAddress(address);
1352
1353    if (!WriteRegister(context, &reg_info_src, data_src))
1354      return false;
1355
1356    return true;
1357  }
1358
1359  return false;
1360}
1361
1362bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) {
1363  // SUBU sp, <src>, <rt>
1364  // ADDU sp, <src>, <rt>
1365  // ADDU dst, sp, <rt>
1366
1367  bool success = false;
1368  uint64_t result;
1369  uint8_t src, dst, rt;
1370  const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1371
1372  dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1373  src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1374
1375  /* Check if sp is destination register */
1376  if (dst == dwarf_sp_mips) {
1377    rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1378
1379    /* read <src> register */
1380    uint64_t src_opd_val = ReadRegisterUnsigned(
1381        eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1382    if (!success)
1383      return false;
1384
1385    /* read <rt > register */
1386    uint64_t rt_opd_val = ReadRegisterUnsigned(
1387        eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1388    if (!success)
1389      return false;
1390
1391    if (!strcasecmp(op_name, "SUBU"))
1392      result = src_opd_val - rt_opd_val;
1393    else
1394      result = src_opd_val + rt_opd_val;
1395
1396    Context context;
1397    RegisterInfo reg_info_sp;
1398    if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1399      context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
1400
1401    /* We are allocating bytes on stack */
1402    context.type = eContextAdjustStackPointer;
1403
1404    WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1405
1406    return true;
1407  } else if (src == dwarf_sp_mips) {
1408    rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
1409
1410    /* read <src> register */
1411    uint64_t src_opd_val = ReadRegisterUnsigned(
1412        eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
1413    if (!success)
1414      return false;
1415
1416    /* read <rt> register */
1417    uint64_t rt_opd_val = ReadRegisterUnsigned(
1418        eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
1419    if (!success)
1420      return false;
1421
1422    Context context;
1423
1424    if (!strcasecmp(op_name, "SUBU"))
1425      result = src_opd_val - rt_opd_val;
1426    else
1427      result = src_opd_val + rt_opd_val;
1428
1429    context.SetImmediateSigned(result);
1430    context.type = eContextImmediate;
1431
1432    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
1433                               dwarf_zero_mips + dst, result))
1434      return false;
1435  }
1436
1437  return true;
1438}
1439
1440bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) {
1441  // LUI rt, immediate
1442  // GPR[rt] <- sign_extend(immediate << 16)
1443
1444  const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
1445  int64_t imm = SignedBits(imm32, 31, 0);
1446  uint8_t rt;
1447  Context context;
1448
1449  rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1450  context.SetImmediateSigned(imm);
1451  context.type = eContextImmediate;
1452
1453  if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
1454                            imm))
1455    return true;
1456
1457  return false;
1458}
1459
1460bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) {
1461  bool success = false;
1462  const uint32_t imm9 = insn.getOperand(0).getImm();
1463  uint64_t result;
1464
1465  // This instruction operates implicitly on stack pointer, so read <sp>
1466  // register.
1467  uint64_t src_opd_val =
1468      ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1469  if (!success)
1470    return false;
1471
1472  result = src_opd_val + imm9;
1473
1474  Context context;
1475  RegisterInfo reg_info_sp;
1476  if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1477    context.SetRegisterPlusOffset(reg_info_sp, imm9);
1478
1479  // We are adjusting the stack.
1480  context.type = eContextAdjustStackPointer;
1481
1482  WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1483  return true;
1484}
1485
1486bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) {
1487  bool success = false;
1488  uint32_t base;
1489  const uint32_t imm4 = insn.getOperand(2).getImm();
1490  uint64_t result;
1491
1492  // The source and destination register is same for this instruction.
1493  base = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1494
1495  // We are looking for stack adjustment only
1496  if (base == dwarf_sp_mips) {
1497    // Read stack pointer register
1498    uint64_t src_opd_val = ReadRegisterUnsigned(
1499        eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1500    if (!success)
1501      return false;
1502
1503    result = src_opd_val + imm4;
1504
1505    Context context;
1506    RegisterInfo reg_info_sp;
1507    if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1508      context.SetRegisterPlusOffset(reg_info_sp, imm4);
1509
1510    // We are adjusting the stack.
1511    context.type = eContextAdjustStackPointer;
1512
1513    WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
1514  }
1515
1516  return true;
1517}
1518
1519bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) {
1520  bool success = false;
1521  uint32_t imm5 = insn.getOperand(2).getImm();
1522  uint32_t src, base;
1523  Context bad_vaddr_context;
1524  uint32_t address;
1525
1526  src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1527  base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1528
1529  RegisterInfo reg_info_base;
1530
1531  if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1532                       reg_info_base))
1533    return false;
1534
1535  // read base register
1536  address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
1537                                 &success);
1538  if (!success)
1539    return false;
1540
1541  // destination address
1542  address = address + imm5;
1543
1544  // We use bad_vaddr_context to store base address which is used by H/W
1545  // watchpoint Set the bad_vaddr register with base address used in the
1546  // instruction
1547  bad_vaddr_context.type = eContextInvalid;
1548  WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1549                        address);
1550
1551  // We look for sp based non-volatile register stores.
1552  if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1553    RegisterInfo reg_info_src = {};
1554    Context context;
1555    RegisterValue data_src;
1556    context.type = eContextPushRegisterOnStack;
1557    context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1558
1559    uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1560    Status error;
1561
1562    if (!ReadRegister(&reg_info_base, data_src))
1563      return false;
1564
1565    if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
1566                                 eByteOrderLittle, error) == 0)
1567      return false;
1568
1569    if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
1570      return false;
1571
1572    return true;
1573  }
1574
1575  return false;
1576}
1577
1578/* Emulate SWM16,SWM32 and SWP instruction.
1579
1580   SWM16 always has stack pointer as a base register (but it is still available
1581   in MCInst as an operand).
1582   SWM32 and SWP can have base register other than stack pointer.
1583*/
1584bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) {
1585  bool success = false;
1586  uint32_t src, base;
1587  uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1588                                                 // no of regs to store.
1589
1590  // Base register is second last operand of the instruction.
1591  base =
1592      m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1593
1594  // We are looking for sp based stores so if base is not a stack pointer then
1595  // don't proceed.
1596  if (base != dwarf_sp_mips)
1597    return false;
1598
1599  // offset is always the last operand.
1600  uint32_t offset = insn.getOperand(num_operands - 1).getImm();
1601
1602  RegisterInfo reg_info_base;
1603  RegisterInfo reg_info_src;
1604
1605  if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1606                       reg_info_base))
1607    return false;
1608
1609  // read SP
1610  uint32_t base_address = ReadRegisterUnsigned(
1611      eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1612  if (!success)
1613    return false;
1614
1615  // Resulting base addrss
1616  base_address = base_address + offset;
1617
1618  // Total no of registers to be stored are num_operands-2.
1619  for (uint32_t i = 0; i < num_operands - 2; i++) {
1620    // Get the register number to be stored.
1621    src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1622
1623    /*
1624        Record only non-volatile stores.
1625        This check is required for SWP instruction because source operand could
1626       be any register.
1627        SWM16 and SWM32 instruction always has saved registers as source
1628       operands.
1629    */
1630    if (!nonvolatile_reg_p(src))
1631      return false;
1632
1633    if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1634                         reg_info_src))
1635      return false;
1636
1637    Context context;
1638    RegisterValue data_src;
1639    context.type = eContextPushRegisterOnStack;
1640    context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
1641
1642    uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
1643    Status error;
1644
1645    if (!ReadRegister(&reg_info_base, data_src))
1646      return false;
1647
1648    if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
1649                                 eByteOrderLittle, error) == 0)
1650      return false;
1651
1652    if (!WriteMemory(context, base_address, buffer, reg_info_src.byte_size))
1653      return false;
1654
1655    // Stack address for next register
1656    base_address = base_address + reg_info_src.byte_size;
1657  }
1658  return true;
1659}
1660
1661bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) {
1662  bool success = false;
1663  uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1664  uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1665  uint32_t imm5 = insn.getOperand(2).getImm();
1666  Context bad_vaddr_context;
1667
1668  RegisterInfo reg_info_base;
1669  if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
1670                       reg_info_base))
1671    return false;
1672
1673  // read base register
1674  uint32_t base_address = ReadRegisterUnsigned(
1675      eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1676  if (!success)
1677    return false;
1678
1679  base_address = base_address + imm5;
1680
1681  // We use bad_vaddr_context to store base address which is used by H/W
1682  // watchpoint Set the bad_vaddr register with base address used in the
1683  // instruction
1684  bad_vaddr_context.type = eContextInvalid;
1685  WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
1686                        base_address);
1687
1688  if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
1689    RegisterValue data_src;
1690    RegisterInfo reg_info_src;
1691
1692    if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
1693                         reg_info_src))
1694      return false;
1695
1696    Context context;
1697    context.type = eContextPopRegisterOffStack;
1698    context.SetAddress(base_address);
1699
1700    if (!WriteRegister(context, &reg_info_src, data_src))
1701      return false;
1702
1703    return true;
1704  }
1705
1706  return false;
1707}
1708
1709/* Emulate LWM16, LWM32 and LWP instructions.
1710
1711   LWM16 always has stack pointer as a base register (but it is still available
1712   in MCInst as an operand).
1713   LWM32 and LWP can have base register other than stack pointer.
1714*/
1715bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) {
1716  bool success = false;
1717  uint32_t dst, base;
1718  uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
1719                                                 // no of regs to store.
1720  uint32_t imm = insn.getOperand(num_operands - 1)
1721                     .getImm(); // imm is the last operand in the instruction.
1722
1723  // Base register is second last operand of the instruction.
1724  base =
1725      m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
1726
1727  // We are looking for sp based loads so if base is not a stack pointer then
1728  // don't proceed.
1729  if (base != dwarf_sp_mips)
1730    return false;
1731
1732  uint32_t base_address = ReadRegisterUnsigned(
1733      eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
1734  if (!success)
1735    return false;
1736
1737  base_address = base_address + imm;
1738
1739  RegisterValue data_dst;
1740  RegisterInfo reg_info_dst;
1741
1742  // Total no of registers to be re-stored are num_operands-2.
1743  for (uint32_t i = 0; i < num_operands - 2; i++) {
1744    // Get the register number to be re-stored.
1745    dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
1746
1747    /*
1748        Record only non-volatile loads.
1749        This check is required for LWP instruction because destination operand
1750       could be any register.
1751        LWM16 and LWM32 instruction always has saved registers as destination
1752       operands.
1753    */
1754    if (!nonvolatile_reg_p(dst))
1755      return false;
1756
1757    if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst,
1758                         reg_info_dst))
1759      return false;
1760
1761    Context context;
1762    context.type = eContextPopRegisterOffStack;
1763    context.SetAddress(base_address + (i * 4));
1764
1765    if (!WriteRegister(context, &reg_info_dst, data_dst))
1766      return false;
1767  }
1768
1769  return true;
1770}
1771
1772bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) {
1773  bool success = false;
1774  int32_t imm5 = insn.getOperand(0).getImm();
1775
1776  /* JRADDIUSP immediate
1777  *       PC <- RA
1778  *       SP <- SP + zero_extend(Immediate << 2)
1779  */
1780
1781  // This instruction operates implicitly on stack pointer, so read <sp>
1782  // register.
1783  int32_t src_opd_val =
1784      ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
1785  if (!success)
1786    return false;
1787
1788  int32_t ra_val =
1789      ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
1790  if (!success)
1791    return false;
1792
1793  int32_t result = src_opd_val + imm5;
1794
1795  Context context;
1796
1797  // Update the PC
1798  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1799                             ra_val))
1800    return false;
1801
1802  RegisterInfo reg_info_sp;
1803  if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
1804    context.SetRegisterPlusOffset(reg_info_sp, imm5);
1805
1806  // We are adjusting stack
1807  context.type = eContextAdjustStackPointer;
1808
1809  // update SP
1810  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips,
1811                             result))
1812    return false;
1813
1814  return true;
1815}
1816
1817static int IsAdd64bitOverflow(int32_t a, int32_t b) {
1818  int32_t r = (uint32_t)a + (uint32_t)b;
1819  return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
1820}
1821
1822/*
1823    Emulate below MIPS branch instructions.
1824    BEQ, BNE : Branch on condition
1825    BEQL, BNEL : Branch likely
1826*/
1827bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) {
1828  bool success = false;
1829  uint32_t rs, rt;
1830  int32_t offset, pc, target = 0, rs_val, rt_val;
1831  const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1832
1833  rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1834  rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1835  offset = insn.getOperand(2).getImm();
1836
1837  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1838  if (!success)
1839    return false;
1840
1841  rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1842                                         dwarf_zero_mips + rs, 0, &success);
1843  if (!success)
1844    return false;
1845
1846  rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1847                                         dwarf_zero_mips + rt, 0, &success);
1848  if (!success)
1849    return false;
1850
1851  if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) {
1852    if (rs_val == rt_val)
1853      target = pc + offset;
1854    else
1855      target = pc + 8;
1856  } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) {
1857    if (rs_val != rt_val)
1858      target = pc + offset;
1859    else
1860      target = pc + 8;
1861  }
1862
1863  Context context;
1864  context.type = eContextRelativeBranchImmediate;
1865  context.SetImmediate(offset);
1866
1867  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1868                             target))
1869    return false;
1870
1871  return true;
1872}
1873
1874/*
1875    Emulate below MIPS branch instructions.
1876    BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
1877   instructions with no delay slot
1878*/
1879bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
1880  bool success = false;
1881  uint32_t rs, rt;
1882  int32_t offset, pc, target = 0, rs_val, rt_val;
1883  const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1884  uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
1885
1886  rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1887  rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
1888  offset = insn.getOperand(2).getImm();
1889
1890  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1891  if (!success)
1892    return false;
1893
1894  rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1895                                         dwarf_zero_mips + rs, 0, &success);
1896  if (!success)
1897    return false;
1898
1899  rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1900                                         dwarf_zero_mips + rt, 0, &success);
1901  if (!success)
1902    return false;
1903
1904  if (!strcasecmp(op_name, "BEQC")) {
1905    if (rs_val == rt_val)
1906      target = pc + offset;
1907    else
1908      target = pc + 4;
1909  } else if (!strcasecmp(op_name, "BNEC")) {
1910    if (rs_val != rt_val)
1911      target = pc + offset;
1912    else
1913      target = pc + 4;
1914  } else if (!strcasecmp(op_name, "BLTC")) {
1915    if (rs_val < rt_val)
1916      target = pc + offset;
1917    else
1918      target = pc + 4;
1919  } else if (!strcasecmp(op_name, "BGEC")) {
1920    if (rs_val >= rt_val)
1921      target = pc + offset;
1922    else
1923      target = pc + 4;
1924  } else if (!strcasecmp(op_name, "BLTUC")) {
1925    if (rs_val < rt_val)
1926      target = pc + offset;
1927    else
1928      target = pc + 4;
1929  } else if (!strcasecmp(op_name, "BGEUC")) {
1930    if ((uint32_t)rs_val >= (uint32_t)rt_val)
1931      target = pc + offset;
1932    else
1933      target = pc + 4;
1934  } else if (!strcasecmp(op_name, "BOVC")) {
1935    if (IsAdd64bitOverflow(rs_val, rt_val))
1936      target = pc + offset;
1937    else
1938      target = pc + 4;
1939  } else if (!strcasecmp(op_name, "BNVC")) {
1940    if (!IsAdd64bitOverflow(rs_val, rt_val))
1941      target = pc + offset;
1942    else
1943      target = pc + 4;
1944  }
1945
1946  Context context;
1947  context.type = eContextRelativeBranchImmediate;
1948  context.SetImmediate(current_inst_size + offset);
1949
1950  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
1951                             target))
1952    return false;
1953
1954  return true;
1955}
1956
1957/*
1958    Emulate below MIPS conditional branch and link instructions.
1959    BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
1960*/
1961bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
1962  bool success = false;
1963  uint32_t rs;
1964  int32_t offset, pc, target = 0;
1965  int32_t rs_val;
1966  const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
1967
1968  rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
1969  offset = insn.getOperand(1).getImm();
1970
1971  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
1972  if (!success)
1973    return false;
1974
1975  rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
1976                                         dwarf_zero_mips + rs, 0, &success);
1977  if (!success)
1978    return false;
1979
1980  if (!strcasecmp(op_name, "BLEZALC")) {
1981    if (rs_val <= 0)
1982      target = pc + offset;
1983    else
1984      target = pc + 4;
1985  } else if (!strcasecmp(op_name, "BGEZALC")) {
1986    if (rs_val >= 0)
1987      target = pc + offset;
1988    else
1989      target = pc + 4;
1990  } else if (!strcasecmp(op_name, "BLTZALC")) {
1991    if (rs_val < 0)
1992      target = pc + offset;
1993    else
1994      target = pc + 4;
1995  } else if (!strcasecmp(op_name, "BGTZALC")) {
1996    if (rs_val > 0)
1997      target = pc + offset;
1998    else
1999      target = pc + 4;
2000  } else if (!strcasecmp(op_name, "BEQZALC")) {
2001    if (rs_val == 0)
2002      target = pc + offset;
2003    else
2004      target = pc + 4;
2005  } else if (!strcasecmp(op_name, "BNEZALC")) {
2006    if (rs_val != 0)
2007      target = pc + offset;
2008    else
2009      target = pc + 4;
2010  }
2011
2012  Context context;
2013
2014  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2015                             target))
2016    return false;
2017
2018  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2019                             pc + 4))
2020    return false;
2021
2022  return true;
2023}
2024
2025/*
2026    Emulate below MIPS Non-Compact conditional branch and link instructions.
2027    BLTZAL, BGEZAL      :
2028    BLTZALL, BGEZALL    : Branch likely
2029*/
2030bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) {
2031  bool success = false;
2032  uint32_t rs;
2033  int32_t offset, pc, target = 0;
2034  int32_t rs_val;
2035  const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2036
2037  rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2038  offset = insn.getOperand(1).getImm();
2039
2040  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2041  if (!success)
2042    return false;
2043
2044  rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2045                                         dwarf_zero_mips + rs, 0, &success);
2046  if (!success)
2047    return false;
2048
2049  if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
2050    if ((int32_t)rs_val < 0)
2051      target = pc + offset;
2052    else
2053      target = pc + 8;
2054  } else if (!strcasecmp(op_name, "BGEZAL") ||
2055             !strcasecmp(op_name, "BGEZALL")) {
2056    if ((int32_t)rs_val >= 0)
2057      target = pc + offset;
2058    else
2059      target = pc + 8;
2060  }
2061
2062  Context context;
2063
2064  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2065                             target))
2066    return false;
2067
2068  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2069                             pc + 8))
2070    return false;
2071
2072  return true;
2073}
2074
2075/*
2076    Emulate below MIPS branch instructions.
2077    BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
2078    BLTZ, BGEZ, BGTZ, BLEZ     : Non-compact branches
2079*/
2080bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) {
2081  bool success = false;
2082  uint32_t rs;
2083  int32_t offset, pc, target = 0;
2084  int32_t rs_val;
2085  const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2086
2087  rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2088  offset = insn.getOperand(1).getImm();
2089
2090  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2091  if (!success)
2092    return false;
2093
2094  rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2095                                         dwarf_zero_mips + rs, 0, &success);
2096  if (!success)
2097    return false;
2098
2099  if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) {
2100    if (rs_val < 0)
2101      target = pc + offset;
2102    else
2103      target = pc + 8;
2104  } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) {
2105    if (rs_val >= 0)
2106      target = pc + offset;
2107    else
2108      target = pc + 8;
2109  } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) {
2110    if (rs_val > 0)
2111      target = pc + offset;
2112    else
2113      target = pc + 8;
2114  } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) {
2115    if (rs_val <= 0)
2116      target = pc + offset;
2117    else
2118      target = pc + 8;
2119  }
2120
2121  Context context;
2122  context.type = eContextRelativeBranchImmediate;
2123  context.SetImmediate(offset);
2124
2125  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2126                             target))
2127    return false;
2128
2129  return true;
2130}
2131
2132/*
2133    Emulate below MIPS branch instructions.
2134    BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
2135*/
2136bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
2137  bool success = false;
2138  uint32_t rs;
2139  int32_t offset, pc, target = 0;
2140  int32_t rs_val;
2141  const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2142  uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2143
2144  rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2145  offset = insn.getOperand(1).getImm();
2146
2147  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2148  if (!success)
2149    return false;
2150
2151  rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2152                                         dwarf_zero_mips + rs, 0, &success);
2153  if (!success)
2154    return false;
2155
2156  if (!strcasecmp(op_name, "BLTZC")) {
2157    if (rs_val < 0)
2158      target = pc + offset;
2159    else
2160      target = pc + 4;
2161  } else if (!strcasecmp(op_name, "BLEZC")) {
2162    if (rs_val <= 0)
2163      target = pc + offset;
2164    else
2165      target = pc + 4;
2166  } else if (!strcasecmp(op_name, "BGEZC")) {
2167    if (rs_val >= 0)
2168      target = pc + offset;
2169    else
2170      target = pc + 4;
2171  } else if (!strcasecmp(op_name, "BGTZC")) {
2172    if (rs_val > 0)
2173      target = pc + offset;
2174    else
2175      target = pc + 4;
2176  } else if (!strcasecmp(op_name, "BEQZC")) {
2177    if (rs_val == 0)
2178      target = pc + offset;
2179    else
2180      target = pc + 4;
2181  } else if (!strcasecmp(op_name, "BNEZC")) {
2182    if (rs_val != 0)
2183      target = pc + offset;
2184    else
2185      target = pc + 4;
2186  }
2187
2188  Context context;
2189  context.type = eContextRelativeBranchImmediate;
2190  context.SetImmediate(current_inst_size + offset);
2191
2192  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2193                             target))
2194    return false;
2195
2196  return true;
2197}
2198
2199bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) {
2200  bool success = false;
2201  int32_t offset, pc, target;
2202  uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2203
2204  offset = insn.getOperand(0).getImm();
2205
2206  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2207  if (!success)
2208    return false;
2209
2210  // unconditional branch
2211  target = pc + offset;
2212
2213  Context context;
2214  context.type = eContextRelativeBranchImmediate;
2215  context.SetImmediate(current_inst_size + offset);
2216
2217  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2218                             target))
2219    return false;
2220
2221  return true;
2222}
2223
2224/*
2225   BEQZC, BNEZC are 32 bit compact instructions without a delay slot.
2226   BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
2227   BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
2228*/
2229bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) {
2230  bool success = false;
2231  int32_t target = 0;
2232  uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
2233  const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2234  bool update_ra = false;
2235  uint32_t ra_offset = 0;
2236
2237  /*
2238   * BEQZ16 rs, offset
2239   *      condition <- (GPR[rs] = 0)
2240   *      if condition then
2241   *          PC = PC + sign_ext (offset || 0)
2242   *
2243   * BNEZ16 rs, offset
2244   *      condition <- (GPR[rs] != 0)
2245   *      if condition then
2246   *          PC = PC + sign_ext (offset || 0)
2247   *
2248   * BEQZC rs, offset     (compact instruction: No delay slot)
2249   *      condition <- (GPR[rs] == 0)
2250   *      if condition then
2251   *         PC = PC + 4 + sign_ext (offset || 0)
2252  */
2253
2254  uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2255  int32_t offset = insn.getOperand(1).getImm();
2256
2257  int32_t pc =
2258      ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2259  if (!success)
2260    return false;
2261
2262  int32_t rs_val = (int32_t)ReadRegisterUnsigned(
2263      eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
2264  if (!success)
2265    return false;
2266
2267  if (!strcasecmp(op_name, "BEQZ16_MM")) {
2268    if (rs_val == 0)
2269      target = pc + offset;
2270    else
2271      target = pc + current_inst_size +
2272               m_next_inst_size; // Skip delay slot instruction.
2273  } else if (!strcasecmp(op_name, "BNEZ16_MM")) {
2274    if (rs_val != 0)
2275      target = pc + offset;
2276    else
2277      target = pc + current_inst_size +
2278               m_next_inst_size; // Skip delay slot instruction.
2279  } else if (!strcasecmp(op_name, "BEQZC_MM")) {
2280    if (rs_val == 0)
2281      target = pc + 4 + offset;
2282    else
2283      target =
2284          pc +
2285          4; // 32 bit instruction and does not have delay slot instruction.
2286  } else if (!strcasecmp(op_name, "BNEZC_MM")) {
2287    if (rs_val != 0)
2288      target = pc + 4 + offset;
2289    else
2290      target =
2291          pc +
2292          4; // 32 bit instruction and does not have delay slot instruction.
2293  } else if (!strcasecmp(op_name, "BGEZALS_MM")) {
2294    if (rs_val >= 0)
2295      target = pc + offset;
2296    else
2297      target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2298
2299    update_ra = true;
2300    ra_offset = 6;
2301  } else if (!strcasecmp(op_name, "BLTZALS_MM")) {
2302    if (rs_val >= 0)
2303      target = pc + offset;
2304    else
2305      target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
2306
2307    update_ra = true;
2308    ra_offset = 6;
2309  }
2310
2311  Context context;
2312  context.type = eContextRelativeBranchImmediate;
2313  context.SetImmediate(current_inst_size + offset);
2314
2315  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2316                             target))
2317    return false;
2318
2319  if (update_ra) {
2320    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2321                               pc + ra_offset))
2322      return false;
2323  }
2324  return true;
2325}
2326
2327/* Emulate micromips jump instructions.
2328   JALR16,JALRS16
2329*/
2330bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) {
2331  bool success = false;
2332  uint32_t ra_offset = 0;
2333  const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2334
2335  uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2336
2337  uint32_t pc =
2338      ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2339  if (!success)
2340    return false;
2341
2342  uint32_t rs_val = ReadRegisterUnsigned(eRegisterKindDWARF,
2343                                         dwarf_zero_mips + rs, 0, &success);
2344  if (!success)
2345    return false;
2346
2347  if (!strcasecmp(op_name, "JALR16_MM"))
2348    ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
2349  else if (!strcasecmp(op_name, "JALRS16_MM"))
2350    ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
2351
2352  Context context;
2353
2354  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2355                             rs_val))
2356    return false;
2357
2358  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2359                             pc + ra_offset))
2360    return false;
2361
2362  return true;
2363}
2364
2365/* Emulate JALS and JALX instructions.
2366    JALS 32 bit instruction with short (2-byte) delay slot.
2367    JALX 32 bit instruction with 4-byte delay slot.
2368*/
2369bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) {
2370  bool success = false;
2371  uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0;
2372  const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2373
2374  /*
2375   * JALS target
2376   *      RA = PC + 6
2377   *      offset = sign_ext (offset << 1)
2378   *      PC = PC[31-27] | offset
2379   * JALX target
2380   *      RA = PC + 8
2381   *      offset = sign_ext (offset << 2)
2382   *      PC = PC[31-28] | offset
2383  */
2384  offset = insn.getOperand(0).getImm();
2385
2386  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2387  if (!success)
2388    return false;
2389
2390  // These are PC-region branches and not PC-relative.
2391  if (!strcasecmp(op_name, "JALS_MM")) {
2392    // target address is in the ���current��� 128 MB-aligned region
2393    target = (pc & 0xF8000000UL) | offset;
2394    ra_offset = 6;
2395  } else if (!strcasecmp(op_name, "JALX_MM")) {
2396    // target address is in the ���current��� 256 MB-aligned region
2397    target = (pc & 0xF0000000UL) | offset;
2398    ra_offset = 8;
2399  }
2400
2401  Context context;
2402
2403  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2404                             target))
2405    return false;
2406
2407  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2408                             pc + ra_offset))
2409    return false;
2410
2411  return true;
2412}
2413
2414bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) {
2415  bool success = false;
2416  uint32_t rs = 0, rt = 0;
2417  int32_t pc = 0, rs_val = 0;
2418
2419  /*
2420      JALRS rt, rs
2421          GPR[rt] <- PC + 6
2422          PC <- GPR[rs]
2423  */
2424
2425  rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2426  rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2427
2428  rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2429                                         dwarf_zero_mips + rs, 0, &success);
2430  if (!success)
2431    return false;
2432
2433  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2434  if (!success)
2435    return false;
2436
2437  Context context;
2438
2439  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2440                             rs_val))
2441    return false;
2442
2443  // This is 4-byte instruction with 2-byte delay slot.
2444  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2445                             pc + 6))
2446    return false;
2447
2448  return true;
2449}
2450
2451bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst &insn) {
2452  bool success = false;
2453  int32_t offset, pc, target;
2454
2455  /*
2456   * BAL offset
2457   *      offset = sign_ext (offset << 2)
2458   *      RA = PC + 8
2459   *      PC = PC + offset
2460  */
2461  offset = insn.getOperand(0).getImm();
2462
2463  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2464  if (!success)
2465    return false;
2466
2467  target = pc + offset;
2468
2469  Context context;
2470
2471  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2472                             target))
2473    return false;
2474
2475  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2476                             pc + 8))
2477    return false;
2478
2479  return true;
2480}
2481
2482bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) {
2483  bool success = false;
2484  int32_t offset, pc, target;
2485
2486  /*
2487   * BALC offset
2488   *      offset = sign_ext (offset << 2)
2489   *      RA = PC + 4
2490   *      PC = PC + 4 + offset
2491  */
2492  offset = insn.getOperand(0).getImm();
2493
2494  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2495  if (!success)
2496    return false;
2497
2498  target = pc + offset;
2499
2500  Context context;
2501
2502  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2503                             target))
2504    return false;
2505
2506  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2507                             pc + 4))
2508    return false;
2509
2510  return true;
2511}
2512
2513bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) {
2514  bool success = false;
2515  int32_t offset, pc, target;
2516
2517  /*
2518   * BC offset
2519   *      offset = sign_ext (offset << 2)
2520   *      PC = PC + 4 + offset
2521  */
2522  offset = insn.getOperand(0).getImm();
2523
2524  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2525  if (!success)
2526    return false;
2527
2528  target = pc + offset;
2529
2530  Context context;
2531
2532  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2533                             target))
2534    return false;
2535
2536  return true;
2537}
2538
2539bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) {
2540  bool success = false;
2541  uint32_t offset, pc;
2542
2543  /*
2544   * J offset
2545   *      offset = sign_ext (offset << 2)
2546   *      PC = PC[63-28] | offset
2547  */
2548  offset = insn.getOperand(0).getImm();
2549
2550  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2551  if (!success)
2552    return false;
2553
2554  /* This is a PC-region branch and not PC-relative */
2555  pc = (pc & 0xF0000000UL) | offset;
2556
2557  Context context;
2558
2559  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc))
2560    return false;
2561
2562  return true;
2563}
2564
2565bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) {
2566  bool success = false;
2567  uint32_t offset, target, pc;
2568
2569  /*
2570   * JAL offset
2571   *      offset = sign_ext (offset << 2)
2572   *      PC = PC[63-28] | offset
2573  */
2574  offset = insn.getOperand(0).getImm();
2575
2576  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2577  if (!success)
2578    return false;
2579
2580  /* This is a PC-region branch and not PC-relative */
2581  target = (pc & 0xF0000000UL) | offset;
2582
2583  Context context;
2584
2585  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2586                             target))
2587    return false;
2588
2589  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2590                             pc + 8))
2591    return false;
2592
2593  return true;
2594}
2595
2596bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) {
2597  bool success = false;
2598  uint32_t rs, rt;
2599  uint32_t pc, rs_val;
2600
2601  /*
2602   * JALR rt, rs
2603   *      GPR[rt] = PC + 8
2604   *      PC = GPR[rs]
2605  */
2606  rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2607  rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
2608
2609  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2610  if (!success)
2611    return false;
2612
2613  rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2614                                &success);
2615  if (!success)
2616    return false;
2617
2618  Context context;
2619
2620  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2621                             rs_val))
2622    return false;
2623
2624  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
2625                             pc + 8))
2626    return false;
2627
2628  return true;
2629}
2630
2631bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) {
2632  bool success = false;
2633  uint32_t rt;
2634  int32_t target, offset, pc, rt_val;
2635
2636  /*
2637   * JIALC rt, offset
2638   *      offset = sign_ext (offset)
2639   *      PC = GPR[rt] + offset
2640   *      RA = PC + 4
2641  */
2642  rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2643  offset = insn.getOperand(1).getImm();
2644
2645  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2646  if (!success)
2647    return false;
2648
2649  rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2650                                         dwarf_zero_mips + rt, 0, &success);
2651  if (!success)
2652    return false;
2653
2654  target = rt_val + offset;
2655
2656  Context context;
2657
2658  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2659                             target))
2660    return false;
2661
2662  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
2663                             pc + 4))
2664    return false;
2665
2666  return true;
2667}
2668
2669bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) {
2670  bool success = false;
2671  uint32_t rt;
2672  int32_t target, offset, rt_val;
2673
2674  /*
2675   * JIC rt, offset
2676   *      offset = sign_ext (offset)
2677   *      PC = GPR[rt] + offset
2678  */
2679  rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2680  offset = insn.getOperand(1).getImm();
2681
2682  rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
2683                                         dwarf_zero_mips + rt, 0, &success);
2684  if (!success)
2685    return false;
2686
2687  target = rt_val + offset;
2688
2689  Context context;
2690
2691  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2692                             target))
2693    return false;
2694
2695  return true;
2696}
2697
2698bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) {
2699  bool success = false;
2700  uint32_t rs;
2701  uint32_t rs_val;
2702
2703  /*
2704   * JR rs
2705   *      PC = GPR[rs]
2706  */
2707  rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2708
2709  rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
2710                                &success);
2711  if (!success)
2712    return false;
2713
2714  Context context;
2715
2716  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2717                             rs_val))
2718    return false;
2719
2720  return true;
2721}
2722
2723/*
2724    Emulate Branch on FP True/False
2725    BC1F, BC1FL :   Branch on FP False (L stands for branch likely)
2726    BC1T, BC1TL :   Branch on FP True  (L stands for branch likely)
2727*/
2728bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) {
2729  bool success = false;
2730  uint32_t cc, fcsr;
2731  int32_t pc, offset, target = 0;
2732  const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2733
2734  cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2735  offset = insn.getOperand(1).getImm();
2736
2737  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2738  if (!success)
2739    return false;
2740
2741  fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
2742  if (!success)
2743    return false;
2744
2745  /* fcsr[23], fcsr[25-31] are vaild condition bits */
2746  fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2747
2748  if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
2749    if ((fcsr & (1 << cc)) == 0)
2750      target = pc + offset;
2751    else
2752      target = pc + 8;
2753  } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
2754    if ((fcsr & (1 << cc)) != 0)
2755      target = pc + offset;
2756    else
2757      target = pc + 8;
2758  }
2759  Context context;
2760
2761  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2762                             target))
2763    return false;
2764
2765  return true;
2766}
2767
2768bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) {
2769  bool success = false;
2770  uint32_t ft;
2771  uint32_t ft_val;
2772  int32_t target, pc, offset;
2773
2774  /*
2775   * BC1EQZ ft, offset
2776   *  condition <- (FPR[ft].bit0 == 0)
2777   *      if condition then
2778   *          offset = sign_ext (offset)
2779   *          PC = PC + 4 + offset
2780  */
2781  ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2782  offset = insn.getOperand(1).getImm();
2783
2784  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2785  if (!success)
2786    return false;
2787
2788  ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2789                                &success);
2790  if (!success)
2791    return false;
2792
2793  if ((ft_val & 1) == 0)
2794    target = pc + 4 + offset;
2795  else
2796    target = pc + 8;
2797
2798  Context context;
2799
2800  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2801                             target))
2802    return false;
2803
2804  return true;
2805}
2806
2807bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) {
2808  bool success = false;
2809  uint32_t ft;
2810  uint32_t ft_val;
2811  int32_t target, pc, offset;
2812
2813  /*
2814   * BC1NEZ ft, offset
2815   *  condition <- (FPR[ft].bit0 != 0)
2816   *      if condition then
2817   *          offset = sign_ext (offset)
2818   *          PC = PC + 4 + offset
2819  */
2820  ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2821  offset = insn.getOperand(1).getImm();
2822
2823  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2824  if (!success)
2825    return false;
2826
2827  ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
2828                                &success);
2829  if (!success)
2830    return false;
2831
2832  if ((ft_val & 1) != 0)
2833    target = pc + 4 + offset;
2834  else
2835    target = pc + 8;
2836
2837  Context context;
2838
2839  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2840                             target))
2841    return false;
2842
2843  return true;
2844}
2845
2846/*
2847    Emulate MIPS-3D Branch instructions
2848    BC1ANY2F, BC1ANY2T  : Branch on Any of Two Floating Point Condition Codes
2849   False/True
2850    BC1ANY4F, BC1ANY4T  : Branch on Any of Four Floating Point Condition Codes
2851   False/True
2852*/
2853bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) {
2854  bool success = false;
2855  uint32_t cc, fcsr;
2856  int32_t pc, offset, target = 0;
2857  const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
2858
2859  cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2860  offset = insn.getOperand(1).getImm();
2861
2862  pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2863  if (!success)
2864    return false;
2865
2866  fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0,
2867                                        &success);
2868  if (!success)
2869    return false;
2870
2871  /* fcsr[23], fcsr[25-31] are vaild condition bits */
2872  fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
2873
2874  if (!strcasecmp(op_name, "BC1ANY2F")) {
2875    /* if any one bit is 0 */
2876    if (((fcsr >> cc) & 3) != 3)
2877      target = pc + offset;
2878    else
2879      target = pc + 8;
2880  } else if (!strcasecmp(op_name, "BC1ANY2T")) {
2881    /* if any one bit is 1 */
2882    if (((fcsr >> cc) & 3) != 0)
2883      target = pc + offset;
2884    else
2885      target = pc + 8;
2886  } else if (!strcasecmp(op_name, "BC1ANY4F")) {
2887    /* if any one bit is 0 */
2888    if (((fcsr >> cc) & 0xf) != 0xf)
2889      target = pc + offset;
2890    else
2891      target = pc + 8;
2892  } else if (!strcasecmp(op_name, "BC1ANY4T")) {
2893    /* if any one bit is 1 */
2894    if (((fcsr >> cc) & 0xf) != 0)
2895      target = pc + offset;
2896    else
2897      target = pc + 8;
2898  }
2899  Context context;
2900
2901  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2902                             target))
2903    return false;
2904
2905  return true;
2906}
2907
2908bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) {
2909  return Emulate_MSA_Branch_DF(insn, 1, true);
2910}
2911
2912bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) {
2913  return Emulate_MSA_Branch_DF(insn, 2, true);
2914}
2915
2916bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) {
2917  return Emulate_MSA_Branch_DF(insn, 4, true);
2918}
2919
2920bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) {
2921  return Emulate_MSA_Branch_DF(insn, 8, true);
2922}
2923
2924bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) {
2925  return Emulate_MSA_Branch_DF(insn, 1, false);
2926}
2927
2928bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) {
2929  return Emulate_MSA_Branch_DF(insn, 2, false);
2930}
2931
2932bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) {
2933  return Emulate_MSA_Branch_DF(insn, 4, false);
2934}
2935
2936bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) {
2937  return Emulate_MSA_Branch_DF(insn, 8, false);
2938}
2939
2940bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
2941                                                   int element_byte_size,
2942                                                   bool bnz) {
2943  bool success = false, branch_hit = true;
2944  int32_t target = 0;
2945  RegisterValue reg_value;
2946  const uint8_t *ptr = NULL;
2947
2948  uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
2949  int32_t offset = insn.getOperand(1).getImm();
2950
2951  int32_t pc =
2952      ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
2953  if (!success)
2954    return false;
2955
2956  if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
2957    ptr = (const uint8_t *)reg_value.GetBytes();
2958  else
2959    return false;
2960
2961  for (int i = 0; i < 16 / element_byte_size; i++) {
2962    switch (element_byte_size) {
2963    case 1:
2964      if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
2965        branch_hit = false;
2966      break;
2967    case 2:
2968      if ((*(const uint16_t *)ptr == 0 && bnz) ||
2969          (*(const uint16_t *)ptr != 0 && !bnz))
2970        branch_hit = false;
2971      break;
2972    case 4:
2973      if ((*(const uint32_t *)ptr == 0 && bnz) ||
2974          (*(const uint32_t *)ptr != 0 && !bnz))
2975        branch_hit = false;
2976      break;
2977    case 8:
2978      if ((*(const uint64_t *)ptr == 0 && bnz) ||
2979          (*(const uint64_t *)ptr != 0 && !bnz))
2980        branch_hit = false;
2981      break;
2982    }
2983    if (!branch_hit)
2984      break;
2985    ptr = ptr + element_byte_size;
2986  }
2987
2988  if (branch_hit)
2989    target = pc + offset;
2990  else
2991    target = pc + 8;
2992
2993  Context context;
2994  context.type = eContextRelativeBranchImmediate;
2995
2996  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
2997                             target))
2998    return false;
2999
3000  return true;
3001}
3002
3003bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) {
3004  return Emulate_MSA_Branch_V(insn, true);
3005}
3006
3007bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) {
3008  return Emulate_MSA_Branch_V(insn, false);
3009}
3010
3011bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn,
3012                                                  bool bnz) {
3013  bool success = false;
3014  int32_t target = 0;
3015  llvm::APInt wr_val = llvm::APInt::getNullValue(128);
3016  llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
3017  llvm::APInt zero_value = llvm::APInt::getNullValue(128);
3018  RegisterValue reg_value;
3019
3020  uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
3021  int32_t offset = insn.getOperand(1).getImm();
3022
3023  int32_t pc =
3024      ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
3025  if (!success)
3026    return false;
3027
3028  if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
3029    wr_val = reg_value.GetAsUInt128(fail_value);
3030  else
3031    return false;
3032
3033  if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
3034      (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
3035    target = pc + offset;
3036  else
3037    target = pc + 8;
3038
3039  Context context;
3040  context.type = eContextRelativeBranchImmediate;
3041
3042  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
3043                             target))
3044    return false;
3045
3046  return true;
3047}
3048
3049bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) {
3050  bool success = false;
3051  uint32_t base;
3052  int32_t imm, address;
3053  Context bad_vaddr_context;
3054
3055  uint32_t num_operands = insn.getNumOperands();
3056  base =
3057      m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3058  imm = insn.getOperand(num_operands - 1).getImm();
3059
3060  RegisterInfo reg_info_base;
3061  if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
3062                       reg_info_base))
3063    return false;
3064
3065  /* read base register */
3066  address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
3067                                          dwarf_zero_mips + base, 0, &success);
3068  if (!success)
3069    return false;
3070
3071  /* destination address */
3072  address = address + imm;
3073
3074  /* Set the bad_vaddr register with base address used in the instruction */
3075  bad_vaddr_context.type = eContextInvalid;
3076  WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
3077                        address);
3078
3079  return true;
3080}
3081
3082bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) {
3083  bool success = false;
3084  uint32_t base, index;
3085  int32_t address, index_address;
3086  Context bad_vaddr_context;
3087
3088  uint32_t num_operands = insn.getNumOperands();
3089  base =
3090      m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
3091  index =
3092      m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
3093
3094  RegisterInfo reg_info_base, reg_info_index;
3095  if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
3096                       reg_info_base))
3097    return false;
3098
3099  if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
3100                       reg_info_index))
3101    return false;
3102
3103  /* read base register */
3104  address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
3105                                          dwarf_zero_mips + base, 0, &success);
3106  if (!success)
3107    return false;
3108
3109  /* read index register */
3110  index_address = (int32_t)ReadRegisterUnsigned(
3111      eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
3112  if (!success)
3113    return false;
3114
3115  /* destination address */
3116  address = address + index_address;
3117
3118  /* Set the bad_vaddr register with base address used in the instruction */
3119  bad_vaddr_context.type = eContextInvalid;
3120  WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
3121                        address);
3122
3123  return true;
3124}
3125