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