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