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