brintos

brintos / llvm-project-archived public Read only

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