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 //---------------------------------------------------------------------- 501 // MicroMIPS Prologue/Epilogue instructions 502 //---------------------------------------------------------------------- 503 { "ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP, "ADDIU immediate" }, 504 { "ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5, "ADDIUS5 rd,immediate" }, 505 { "SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)" }, 506 { "SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, "SWM16 reglist,offset(sp)" }, 507 { "SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, "SWM32 reglist,offset(base)" }, 508 { "SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, "SWP rs1,offset(base)" }, 509 { "LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)" }, 510 { "LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, "LWM16 reglist,offset(sp)" }, 511 { "LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, "LWM32 reglist,offset(base)" }, 512 { "LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, "LWP rd,offset(base)" }, 513 { "JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP, "JRADDIUSP immediate" }, 514 //---------------------------------------------------------------------- 515 516 // Load/Store instructions 517 //---------------------------------------------------------------------- 518 /* Following list of emulated instructions are required by implementation of hardware watchpoint 519 for MIPS in lldb. As we just need the address accessed by instructions, we have generalised 520 all these instructions in 2 functions depending on their addressing modes */ 521 522 { "LB", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LB rt, offset(base)" }, 523 { "LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBE rt, offset(base)" }, 524 { "LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBU rt, offset(base)" }, 525 { "LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBUE rt, offset(base)" }, 526 { "LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDC1 ft, offset(base)" }, 527 { "LD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LD rt, offset(base)" }, 528 { "LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDL rt, offset(base)" }, 529 { "LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDR rt, offset(base)" }, 530 { "LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLD rt, offset(base)" }, 531 { "LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDC2 rt, offset(base)" }, 532 { "LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "LDXC1 fd, index (base)" }, 533 { "LH", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LH rt, offset(base)" }, 534 { "LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHE rt, offset(base)" }, 535 { "LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHU rt, offset(base)" }, 536 { "LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHUE rt, offset(base)" }, 537 { "LL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LL rt, offset(base)" }, 538 { "LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLE rt, offset(base)" }, 539 { "LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "LUXC1 fd, index (base)" }, 540 { "LW", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LW rt, offset(base)" }, 541 { "LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWC1 ft, offset(base)" }, 542 { "LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWC2 rt, offset(base)" }, 543 { "LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWE rt, offset(base)" }, 544 { "LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWL rt, offset(base)" }, 545 { "LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWLE rt, offset(base)" }, 546 { "LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWR rt, offset(base)" }, 547 { "LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWRE rt, offset(base)" }, 548 { "LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "LWXC1 fd, index (base)" }, 549 { "LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLX rt, offset(base)" }, 550 { "LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLXE rt, offset(base)" }, 551 { "LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLDX rt, offset(base)" }, 552 553 { "SB", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SB rt, offset(base)" }, 554 { "SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SBE rt, offset(base)" }, 555 { "SC", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SC rt, offset(base)" }, 556 { "SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCE rt, offset(base)" }, 557 { "SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCD rt, offset(base)" }, 558 { "SD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SD rt, offset(base)" }, 559 { "SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDL rt, offset(base)" }, 560 { "SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDR rt, offset(base)" }, 561 { "SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDC1 ft, offset(base)" }, 562 { "SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDC2 rt, offset(base)" }, 563 { "SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "SDXC1 fs, index(base)" }, 564 { "SH", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SH rt, offset(base)" }, 565 { "SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SHE rt, offset(base)" }, 566 { "SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "SUXC1 fs, index (base)" }, 567 { "SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWC1 ft, offset(base)" }, 568 { "SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWC2 rt, offset(base)" }, 569 { "SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWE rt, offset(base)" }, 570 { "SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWL rt, offset(base)" }, 571 { "SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWLE rt, offset(base)" }, 572 { "SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWR rt, offset(base)" }, 573 { "SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWRE rt, offset(base)" }, 574 { "SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "SWXC1 fs, index (base)" }, 575 { "SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCX rt, offset(base)" }, 576 { "SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCXE rt, offset(base)" }, 577 { "SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCDX rt, offset(base)" }, 578 579 //---------------------------------------------------------------------- 580 // MicroMIPS Load/Store instructions 581 //---------------------------------------------------------------------- 582 { "LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBU16 rt, decoded_offset(base)" }, 583 { "LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHU16 rt, left_shifted_offset(base)" }, 584 { "LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LW16 rt, left_shifted_offset(base)" }, 585 { "LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWGP rt, left_shifted_offset(gp)" }, 586 { "SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SH16 rt, left_shifted_offset(base)" }, 587 { "SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SW16 rt, left_shifted_offset(base)" }, 588 { "SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWSP rt, left_shifted_offset(base)" }, 589 { "SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SB16 rt, offset(base)" }, 590 591 //---------------------------------------------------------------------- 592 // Branch instructions 593 //---------------------------------------------------------------------- 594 { "BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset" }, 595 { "BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset" }, 596 { "BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset" }, 597 { "BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset" }, 598 { "BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BGEZALL rt,offset" }, 599 { "BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset" }, 600 { "BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BGEZAL rs,offset" }, 601 { "BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset" }, 602 { "BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset" }, 603 { "BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset" }, 604 { "BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BLEZALC rs,offset" }, 605 { "BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BGEZALC rs,offset" }, 606 { "BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BLTZALC rs,offset" }, 607 { "BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BGTZALC rs,offset" }, 608 { "BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BEQZALC rs,offset" }, 609 { "BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BNEZALC rs,offset" }, 610 { "BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BEQC rs,rt,offset" }, 611 { "BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BNEC rs,rt,offset" }, 612 { "BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BLTC rs,rt,offset" }, 613 { "BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BGEC rs,rt,offset" }, 614 { "BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BLTUC rs,rt,offset" }, 615 { "BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BGEUC rs,rt,offset" }, 616 { "BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset" }, 617 { "BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset" }, 618 { "BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset" }, 619 { "BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset" }, 620 { "BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset" }, 621 { "BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset" }, 622 { "BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset" }, 623 { "BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset" }, 624 { "BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset" }, 625 { "BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset" }, 626 { "BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset" }, 627 { "BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset" }, 628 { "BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BLTZAL rt,offset" }, 629 { "BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BLTZALL rt,offset" }, 630 { "BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset" }, 631 { "BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BOVC rs,rt,offset" }, 632 { "BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BNVC rs,rt,offset" }, 633 { "J", &EmulateInstructionMIPS::Emulate_J, "J target" }, 634 { "JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target" }, 635 { "JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target" }, 636 { "JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target" }, 637 { "JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target" }, 638 { "JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset" }, 639 { "JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset" }, 640 { "JR", &EmulateInstructionMIPS::Emulate_JR, "JR target" }, 641 { "JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target" }, 642 { "BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset" }, 643 { "BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset" }, 644 { "BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset" }, 645 { "BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset" }, 646 { "BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset" }, 647 { "BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset" }, 648 { "BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY2F cc, offset" }, 649 { "BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY2T cc, offset" }, 650 { "BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY4F cc, offset" }, 651 { "BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY4T cc, offset" }, 652 { "BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16" }, 653 { "BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16" }, 654 { "BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16" }, 655 { "BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16" }, 656 { "BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16" }, 657 { "BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16" }, 658 { "BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16" }, 659 { "BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16" }, 660 { "BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16" }, 661 { "BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16" }, 662 663 //---------------------------------------------------------------------- 664 // MicroMIPS Branch instructions 665 //---------------------------------------------------------------------- 666 { "B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset" }, 667 { "BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BEQZ16 rs, offset" }, 668 { "BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BNEZ16 rs, offset" }, 669 { "BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BEQZC rs, offset" }, 670 { "BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BNEZC rs, offset" }, 671 { "BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BGEZALS rs, offset" }, 672 { "BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BLTZALS rs, offset" }, 673 { "JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs" }, 674 { "JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs" }, 675 { "JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs" }, 676 { "JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs" }, 677 { "JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target" }, 678 { "JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target" }, 679 { "JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs" }, 680 }; 681 682 static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes); 683 684 for (size_t i = 0; i < k_num_mips_opcodes; ++i) 685 { 686 if (! strcasecmp (g_opcodes[i].op_name, op_name)) 687 return &g_opcodes[i]; 688 } 689 690 return NULL; 691 } 692 693 uint32_t 694 EmulateInstructionMIPS::GetSizeOfInstruction (lldb_private::DataExtractor& data, uint64_t inst_addr) 695 { 696 uint64_t next_inst_size = 0; 697 llvm::MCInst mc_insn; 698 llvm::MCDisassembler::DecodeStatus decode_status; 699 llvm::ArrayRef<uint8_t> raw_insn (data.GetDataStart(), data.GetByteSize()); 700 701 if (m_use_alt_disaasm) 702 decode_status = m_alt_disasm->getInstruction (mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls(), llvm::nulls()); 703 else 704 decode_status = m_disasm->getInstruction (mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls(), llvm::nulls()); 705 706 if (decode_status != llvm::MCDisassembler::Success) 707 return false; 708 709 return m_insn_info->get(mc_insn.getOpcode()).getSize(); 710 } 711 712 bool 713 EmulateInstructionMIPS::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 714 { 715 m_use_alt_disaasm = false; 716 717 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 718 { 719 if (inst_addr.GetAddressClass() == eAddressClassCodeAlternateISA) 720 { 721 Error error; 722 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 723 724 /* 725 * The address belongs to microMIPS function. To find the size of 726 * next instruction use microMIPS disassembler. 727 */ 728 m_use_alt_disaasm = true; 729 730 uint32_t current_inst_size = insn_opcode.GetByteSize(); 731 uint8_t buf[sizeof(uint32_t)]; 732 uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size; 733 Address next_addr (next_inst_addr); 734 735 const size_t bytes_read = target->ReadMemory (next_addr, /* Address of next instruction */ 736 true, /* prefer_file_cache */ 737 buf, 738 sizeof(uint32_t), 739 error, 740 &load_addr); 741 742 if (bytes_read == 0) 743 return true; 744 745 DataExtractor data (buf, sizeof(uint32_t), GetByteOrder(), GetAddressByteSize()); 746 m_next_inst_size = GetSizeOfInstruction (data, next_inst_addr); 747 return true; 748 } 749 else 750 { 751 /* 752 * If the address class is not eAddressClassCodeAlternateISA then 753 * the function is not microMIPS. In this case instruction size is 754 * always 4 bytes. 755 */ 756 m_next_inst_size = 4; 757 return true; 758 } 759 } 760 return false; 761 } 762 763 bool 764 EmulateInstructionMIPS::ReadInstruction () 765 { 766 bool success = false; 767 m_addr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 768 if (success) 769 { 770 Context read_inst_context; 771 read_inst_context.type = eContextReadOpcode; 772 read_inst_context.SetNoArgs (); 773 m_opcode.SetOpcode32 (ReadMemoryUnsigned (read_inst_context, m_addr, 4, 0, &success), GetByteOrder()); 774 } 775 if (!success) 776 m_addr = LLDB_INVALID_ADDRESS; 777 return success; 778 } 779 780 bool 781 EmulateInstructionMIPS::EvaluateInstruction (uint32_t evaluate_options) 782 { 783 bool success = false; 784 llvm::MCInst mc_insn; 785 uint64_t insn_size; 786 DataExtractor data; 787 788 /* Keep the complexity of the decode logic with the llvm::MCDisassembler class. */ 789 if (m_opcode.GetData (data)) 790 { 791 llvm::MCDisassembler::DecodeStatus decode_status; 792 llvm::ArrayRef<uint8_t> raw_insn (data.GetDataStart(), data.GetByteSize()); 793 if (m_use_alt_disaasm) 794 decode_status = m_alt_disasm->getInstruction (mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls()); 795 else 796 decode_status = m_disasm->getInstruction (mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls()); 797 798 if (decode_status != llvm::MCDisassembler::Success) 799 return false; 800 } 801 802 /* 803 * mc_insn.getOpcode() returns decoded opcode. However to make use 804 * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc". 805 */ 806 const char *op_name = m_insn_info->getName (mc_insn.getOpcode ()); 807 808 if (op_name == NULL) 809 return false; 810 811 /* 812 * Decoding has been done already. Just get the call-back function 813 * and emulate the instruction. 814 */ 815 MipsOpcode *opcode_data = GetOpcodeForInstruction (op_name); 816 817 if (opcode_data == NULL) 818 return false; 819 820 uint64_t old_pc = 0, new_pc = 0; 821 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 822 823 if (auto_advance_pc) 824 { 825 old_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 826 if (!success) 827 return false; 828 } 829 830 /* emulate instruction */ 831 success = (this->*opcode_data->callback) (mc_insn); 832 if (!success) 833 return false; 834 835 if (auto_advance_pc) 836 { 837 new_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 838 if (!success) 839 return false; 840 841 /* If we haven't changed the PC, change it here */ 842 if (old_pc == new_pc) 843 { 844 new_pc += 4; 845 Context context; 846 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, new_pc)) 847 return false; 848 } 849 } 850 851 return true; 852 } 853 854 bool 855 EmulateInstructionMIPS::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 856 { 857 unwind_plan.Clear(); 858 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 859 860 UnwindPlan::RowSP row(new UnwindPlan::Row); 861 const bool can_replace = false; 862 863 // Our previous Call Frame Address is the stack pointer 864 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0); 865 866 // Our previous PC is in the RA 867 row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace); 868 869 unwind_plan.AppendRow (row); 870 871 // All other registers are the same. 872 unwind_plan.SetSourceName ("EmulateInstructionMIPS"); 873 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 874 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 875 unwind_plan.SetReturnAddressRegister (dwarf_ra_mips); 876 877 return true; 878 } 879 880 bool 881 EmulateInstructionMIPS::nonvolatile_reg_p (uint32_t regnum) 882 { 883 switch (regnum) 884 { 885 case dwarf_r16_mips: 886 case dwarf_r17_mips: 887 case dwarf_r18_mips: 888 case dwarf_r19_mips: 889 case dwarf_r20_mips: 890 case dwarf_r21_mips: 891 case dwarf_r22_mips: 892 case dwarf_r23_mips: 893 case dwarf_gp_mips: 894 case dwarf_sp_mips: 895 case dwarf_r30_mips: 896 case dwarf_ra_mips: 897 return true; 898 default: 899 return false; 900 } 901 return false; 902 } 903 904 bool 905 EmulateInstructionMIPS::Emulate_ADDiu (llvm::MCInst& insn) 906 { 907 bool success = false; 908 const uint32_t imm16 = insn.getOperand(2).getImm(); 909 uint32_t imm = SignedBits(imm16, 15, 0); 910 uint64_t result; 911 uint32_t src, dst; 912 913 dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 914 src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); 915 916 /* Check if this is addiu sp,<src>,imm16 */ 917 if (dst == dwarf_sp_mips) 918 { 919 /* read <src> register */ 920 uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); 921 if (!success) 922 return false; 923 924 result = src_opd_val + imm; 925 926 Context context; 927 RegisterInfo reg_info_sp; 928 if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 929 context.SetRegisterPlusOffset (reg_info_sp, imm); 930 931 /* We are allocating bytes on stack */ 932 context.type = eContextAdjustStackPointer; 933 934 WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result); 935 } 936 937 return true; 938 } 939 940 bool 941 EmulateInstructionMIPS::Emulate_SW (llvm::MCInst& insn) 942 { 943 bool success = false; 944 uint32_t imm16 = insn.getOperand(2).getImm(); 945 uint32_t imm = SignedBits(imm16, 15, 0); 946 uint32_t src, base; 947 int32_t address; 948 Context bad_vaddr_context; 949 950 RegisterInfo reg_info_base; 951 952 src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 953 base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); 954 955 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base)) 956 return false; 957 958 /* read base register */ 959 address = (int32_t)ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 960 if (!success) 961 return false; 962 963 /* destination address */ 964 address = address + imm; 965 966 /* Set the bad_vaddr register with base address used in the instruction */ 967 bad_vaddr_context.type = eContextInvalid; 968 WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address); 969 970 /* We look for sp based non-volatile register stores */ 971 if (base == dwarf_sp_mips && nonvolatile_reg_p (src)) 972 { 973 974 RegisterInfo reg_info_src; 975 976 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src)) 977 return false; 978 979 Context context; 980 RegisterValue data_src; 981 context.type = eContextPushRegisterOnStack; 982 context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0); 983 984 uint8_t buffer [RegisterValue::kMaxRegisterByteSize]; 985 Error error; 986 987 if (!ReadRegister (®_info_base, data_src)) 988 return false; 989 990 if (data_src.GetAsMemoryData (®_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0) 991 return false; 992 993 if (!WriteMemory (context, address, buffer, reg_info_src.byte_size)) 994 return false; 995 996 return true; 997 } 998 999 return false; 1000 } 1001 1002 bool 1003 EmulateInstructionMIPS::Emulate_LW (llvm::MCInst& insn) 1004 { 1005 bool success =false; 1006 uint32_t src, base; 1007 int32_t imm, address; 1008 Context bad_vaddr_context; 1009 1010 src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 1011 base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); 1012 imm = insn.getOperand(2).getImm(); 1013 1014 RegisterInfo reg_info_base; 1015 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base)) 1016 return false; 1017 1018 /* read base register */ 1019 address = (int32_t)ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1020 if (!success) 1021 return false; 1022 1023 /* destination address */ 1024 address = address + imm; 1025 1026 /* Set the bad_vaddr register with base address used in the instruction */ 1027 bad_vaddr_context.type = eContextInvalid; 1028 WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address); 1029 1030 if (base == dwarf_sp_mips && nonvolatile_reg_p (src)) 1031 { 1032 RegisterValue data_src; 1033 RegisterInfo reg_info_src; 1034 1035 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src)) 1036 return false; 1037 1038 Context context; 1039 context.type = eContextPopRegisterOffStack; 1040 context.SetAddress (address); 1041 1042 if (!WriteRegister (context, ®_info_src, data_src)) 1043 return false; 1044 1045 return true; 1046 } 1047 1048 return false; 1049 } 1050 1051 bool 1052 EmulateInstructionMIPS::Emulate_ADDIUSP (llvm::MCInst& insn) 1053 { 1054 bool success = false; 1055 const uint32_t imm9 = insn.getOperand(0).getImm(); 1056 uint64_t result; 1057 1058 // This instruction operates implicitly on stack pointer, so read <sp> register. 1059 uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_sp_mips, 0, &success); 1060 if (!success) 1061 return false; 1062 1063 result = src_opd_val + imm9; 1064 1065 Context context; 1066 RegisterInfo reg_info_sp; 1067 if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1068 context.SetRegisterPlusOffset (reg_info_sp, imm9); 1069 1070 // We are adjusting the stack. 1071 context.type = eContextAdjustStackPointer; 1072 1073 WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result); 1074 return true; 1075 } 1076 1077 bool 1078 EmulateInstructionMIPS::Emulate_ADDIUS5 (llvm::MCInst& insn) 1079 { 1080 bool success = false; 1081 uint32_t base; 1082 const uint32_t imm4 = insn.getOperand(2).getImm(); 1083 uint64_t result; 1084 1085 // The source and destination register is same for this instruction. 1086 base = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 1087 1088 // We are looking for stack adjustment only 1089 if (base == dwarf_sp_mips) 1090 { 1091 // Read stack pointer register 1092 uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1093 if (!success) 1094 return false; 1095 1096 result = src_opd_val + imm4; 1097 1098 Context context; 1099 RegisterInfo reg_info_sp; 1100 if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1101 context.SetRegisterPlusOffset (reg_info_sp, imm4); 1102 1103 // We are adjusting the stack. 1104 context.type = eContextAdjustStackPointer; 1105 1106 WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result); 1107 } 1108 1109 return true; 1110 } 1111 1112 bool 1113 EmulateInstructionMIPS::Emulate_SWSP (llvm::MCInst& insn) 1114 { 1115 bool success = false; 1116 uint32_t imm5 = insn.getOperand(2).getImm(); 1117 uint32_t src, base; 1118 Context bad_vaddr_context; 1119 uint32_t address; 1120 1121 src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 1122 base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); 1123 1124 RegisterInfo reg_info_base; 1125 1126 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base)) 1127 return false; 1128 1129 // read base register 1130 address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1131 if (!success) 1132 return false; 1133 1134 // destination address 1135 address = address + imm5; 1136 1137 // We use bad_vaddr_context to store base address which is used by H/W watchpoint 1138 // Set the bad_vaddr register with base address used in the instruction 1139 bad_vaddr_context.type = eContextInvalid; 1140 WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address); 1141 1142 // We look for sp based non-volatile register stores. 1143 if (base == dwarf_sp_mips && nonvolatile_reg_p (src)) 1144 { 1145 RegisterInfo reg_info_src = {}; 1146 Context context; 1147 RegisterValue data_src; 1148 context.type = eContextPushRegisterOnStack; 1149 context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0); 1150 1151 uint8_t buffer [RegisterValue::kMaxRegisterByteSize]; 1152 Error error; 1153 1154 if (!ReadRegister (®_info_base, data_src)) 1155 return false; 1156 1157 if (data_src.GetAsMemoryData (®_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0) 1158 return false; 1159 1160 if (!WriteMemory (context, address, buffer, reg_info_src.byte_size)) 1161 return false; 1162 1163 return true; 1164 } 1165 1166 return false; 1167 } 1168 1169 /* Emulate SWM16,SWM32 and SWP instruction. 1170 1171 SWM16 always has stack pointer as a base register (but it is still available in MCInst as an operand). 1172 SWM32 and SWP can have base register other than stack pointer. 1173 */ 1174 bool 1175 EmulateInstructionMIPS::Emulate_SWM16_32 (llvm::MCInst& insn) 1176 { 1177 bool success = false; 1178 uint32_t src, base; 1179 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on no of regs to store. 1180 1181 // Base register is second last operand of the instruction. 1182 base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg()); 1183 1184 // We are looking for sp based stores so if base is not a stack pointer then don't proceed. 1185 if (base != dwarf_sp_mips) 1186 return false; 1187 1188 // offset is always the last operand. 1189 uint32_t offset = insn.getOperand(num_operands-1).getImm(); 1190 1191 RegisterInfo reg_info_base; 1192 RegisterInfo reg_info_src; 1193 1194 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base)) 1195 return false; 1196 1197 // read SP 1198 uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1199 if (!success) 1200 return false; 1201 1202 // Resulting base addrss 1203 base_address = base_address + offset; 1204 1205 // Total no of registers to be stored are num_operands-2. 1206 for (uint32_t i = 0; i < num_operands - 2; i++) 1207 { 1208 // Get the register number to be stored. 1209 src = m_reg_info->getEncodingValue (insn.getOperand(i).getReg()); 1210 1211 /* 1212 Record only non-volatile stores. 1213 This check is required for SWP instruction because source operand could be any register. 1214 SWM16 and SWM32 instruction always has saved registers as source operands. 1215 */ 1216 if (!nonvolatile_reg_p (src)) 1217 return false; 1218 1219 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src)) 1220 return false; 1221 1222 Context context; 1223 RegisterValue data_src; 1224 context.type = eContextPushRegisterOnStack; 1225 context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0); 1226 1227 uint8_t buffer [RegisterValue::kMaxRegisterByteSize]; 1228 Error error; 1229 1230 if (!ReadRegister (®_info_base, data_src)) 1231 return false; 1232 1233 if (data_src.GetAsMemoryData (®_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0) 1234 return false; 1235 1236 if (!WriteMemory (context, base_address, buffer, reg_info_src.byte_size)) 1237 return false; 1238 1239 // Stack address for next register 1240 base_address = base_address + reg_info_src.byte_size; 1241 } 1242 return true; 1243 } 1244 1245 bool 1246 EmulateInstructionMIPS::Emulate_LWSP (llvm::MCInst& insn) 1247 { 1248 bool success = false; 1249 uint32_t src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 1250 uint32_t base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); 1251 uint32_t imm5 = insn.getOperand(2).getImm(); 1252 Context bad_vaddr_context; 1253 1254 RegisterInfo reg_info_base; 1255 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base)) 1256 return false; 1257 1258 // read base register 1259 uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1260 if (!success) 1261 return false; 1262 1263 base_address = base_address + imm5; 1264 1265 // We use bad_vaddr_context to store base address which is used by H/W watchpoint 1266 // Set the bad_vaddr register with base address used in the instruction 1267 bad_vaddr_context.type = eContextInvalid; 1268 WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, base_address); 1269 1270 if (base == dwarf_sp_mips && nonvolatile_reg_p (src)) 1271 { 1272 RegisterValue data_src; 1273 RegisterInfo reg_info_src; 1274 1275 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src)) 1276 return false; 1277 1278 Context context; 1279 context.type = eContextPopRegisterOffStack; 1280 context.SetAddress (base_address); 1281 1282 if (!WriteRegister (context, ®_info_src, data_src)) 1283 return false; 1284 1285 return true; 1286 } 1287 1288 return false; 1289 } 1290 1291 /* Emulate LWM16, LWM32 and LWP instructions. 1292 1293 LWM16 always has stack pointer as a base register (but it is still available in MCInst as an operand). 1294 LWM32 and LWP can have base register other than stack pointer. 1295 */ 1296 bool 1297 EmulateInstructionMIPS::Emulate_LWM16_32 (llvm::MCInst& insn) 1298 { 1299 bool success = false; 1300 uint32_t dst, base; 1301 uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on no of regs to store. 1302 uint32_t imm = insn.getOperand(num_operands-1).getImm(); // imm is the last operand in the instruction. 1303 1304 // Base register is second last operand of the instruction. 1305 base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg()); 1306 1307 // We are looking for sp based loads so if base is not a stack pointer then don't proceed. 1308 if (base != dwarf_sp_mips) 1309 return false; 1310 1311 uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 1312 if (!success) 1313 return false; 1314 1315 base_address = base_address + imm; 1316 1317 RegisterValue data_dst; 1318 RegisterInfo reg_info_dst; 1319 1320 // Total no of registers to be re-stored are num_operands-2. 1321 for (uint32_t i = 0; i < num_operands - 2; i++) 1322 { 1323 // Get the register number to be re-stored. 1324 dst = m_reg_info->getEncodingValue (insn.getOperand(i).getReg()); 1325 1326 /* 1327 Record only non-volatile loads. 1328 This check is required for LWP instruction because destination operand could be any register. 1329 LWM16 and LWM32 instruction always has saved registers as destination operands. 1330 */ 1331 if (!nonvolatile_reg_p (dst)) 1332 return false; 1333 1334 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + dst, reg_info_dst)) 1335 return false; 1336 1337 Context context; 1338 context.type = eContextPopRegisterOffStack; 1339 context.SetAddress (base_address + (i*4)); 1340 1341 if (!WriteRegister (context, ®_info_dst, data_dst)) 1342 return false; 1343 } 1344 1345 return true; 1346 } 1347 1348 bool 1349 EmulateInstructionMIPS::Emulate_JRADDIUSP (llvm::MCInst& insn) 1350 { 1351 bool success = false; 1352 int32_t imm5 = insn.getOperand(0).getImm(); 1353 1354 /* JRADDIUSP immediate 1355 * PC <- RA 1356 * SP <- SP + zero_extend(Immediate << 2) 1357 */ 1358 1359 // This instruction operates implicitly on stack pointer, so read <sp> register. 1360 int32_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_sp_mips, 0, &success); 1361 if (!success) 1362 return false; 1363 1364 int32_t ra_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_ra_mips, 0, &success); 1365 if (!success) 1366 return false; 1367 1368 int32_t result = src_opd_val + imm5; 1369 1370 Context context; 1371 1372 // Update the PC 1373 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, ra_val)) 1374 return false; 1375 1376 RegisterInfo reg_info_sp; 1377 if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) 1378 context.SetRegisterPlusOffset (reg_info_sp, imm5); 1379 1380 // We are adjusting stack 1381 context.type = eContextAdjustStackPointer; 1382 1383 // update SP 1384 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result)) 1385 return false; 1386 1387 return true; 1388 } 1389 1390 static int 1391 IsAdd64bitOverflow (int32_t a, int32_t b) 1392 { 1393 int32_t r = (uint32_t) a + (uint32_t) b; 1394 return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0); 1395 } 1396 1397 /* 1398 Emulate below MIPS branch instructions. 1399 BEQ, BNE : Branch on condition 1400 BEQL, BNEL : Branch likely 1401 */ 1402 bool 1403 EmulateInstructionMIPS::Emulate_BXX_3ops (llvm::MCInst& insn) 1404 { 1405 bool success = false; 1406 uint32_t rs, rt; 1407 int32_t offset, pc, target = 0, rs_val, rt_val; 1408 const char *op_name = m_insn_info->getName (insn.getOpcode ()); 1409 1410 rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 1411 rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); 1412 offset = insn.getOperand(2).getImm(); 1413 1414 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1415 if (!success) 1416 return false; 1417 1418 rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 1419 if (!success) 1420 return false; 1421 1422 rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); 1423 if (!success) 1424 return false; 1425 1426 if (!strcasecmp (op_name, "BEQ") || 1427 !strcasecmp (op_name, "BEQL")) 1428 { 1429 if (rs_val == rt_val) 1430 target = pc + offset; 1431 else 1432 target = pc + 8; 1433 } 1434 else if (!strcasecmp (op_name, "BNE") || 1435 !strcasecmp (op_name, "BNEL")) 1436 { 1437 if (rs_val != rt_val) 1438 target = pc + offset; 1439 else 1440 target = pc + 8; 1441 } 1442 1443 Context context; 1444 context.type = eContextRelativeBranchImmediate; 1445 context.SetImmediate (offset); 1446 1447 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 1448 return false; 1449 1450 return true; 1451 } 1452 1453 /* 1454 Emulate below MIPS branch instructions. 1455 BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch instructions with no delay slot 1456 */ 1457 bool 1458 EmulateInstructionMIPS::Emulate_BXX_3ops_C (llvm::MCInst& insn) 1459 { 1460 bool success = false; 1461 uint32_t rs, rt; 1462 int32_t offset, pc, target = 0, rs_val, rt_val; 1463 const char *op_name = m_insn_info->getName (insn.getOpcode ()); 1464 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 1465 1466 rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 1467 rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); 1468 offset = insn.getOperand(2).getImm(); 1469 1470 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1471 if (!success) 1472 return false; 1473 1474 rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 1475 if (!success) 1476 return false; 1477 1478 rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); 1479 if (!success) 1480 return false; 1481 1482 if (!strcasecmp (op_name, "BEQC")) 1483 { 1484 if (rs_val == rt_val) 1485 target = pc + 4 + offset; 1486 else 1487 target = pc + 4; 1488 } 1489 else if (!strcasecmp (op_name, "BNEC")) 1490 { 1491 if (rs_val != rt_val) 1492 target = pc + 4 + offset; 1493 else 1494 target = pc + 4; 1495 } 1496 else if (!strcasecmp (op_name, "BLTC")) 1497 { 1498 if (rs_val < rt_val) 1499 target = pc + 4 + offset; 1500 else 1501 target = pc + 4; 1502 } 1503 else if (!strcasecmp (op_name, "BGEC")) 1504 { 1505 if (rs_val >= rt_val) 1506 target = pc + 4 + offset; 1507 else 1508 target = pc + 4; 1509 } 1510 else if (!strcasecmp (op_name, "BLTUC")) 1511 { 1512 if (rs_val < rt_val) 1513 target = pc + 4 + offset; 1514 else 1515 target = pc + 4; 1516 } 1517 else if (!strcasecmp (op_name, "BGEUC")) 1518 { 1519 if ((uint32_t)rs_val >= (uint32_t)rt_val) 1520 target = pc + 4 + offset; 1521 else 1522 target = pc + 4; 1523 } 1524 else if (!strcasecmp (op_name, "BOVC")) 1525 { 1526 if (IsAdd64bitOverflow (rs_val, rt_val)) 1527 target = pc + 4 + offset; 1528 else 1529 target = pc + 4; 1530 } 1531 else if (!strcasecmp (op_name, "BNVC")) 1532 { 1533 if (!IsAdd64bitOverflow (rs_val, rt_val)) 1534 target = pc + 4 + offset; 1535 else 1536 target = pc + 4; 1537 } 1538 1539 Context context; 1540 context.type = eContextRelativeBranchImmediate; 1541 context.SetImmediate (current_inst_size + offset); 1542 1543 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 1544 return false; 1545 1546 return true; 1547 } 1548 1549 /* 1550 Emulate below MIPS conditional branch and link instructions. 1551 BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches 1552 */ 1553 bool 1554 EmulateInstructionMIPS::Emulate_Bcond_Link_C (llvm::MCInst& insn) 1555 { 1556 bool success = false; 1557 uint32_t rs; 1558 int32_t offset, pc, target = 0; 1559 int32_t rs_val; 1560 const char *op_name = m_insn_info->getName (insn.getOpcode ()); 1561 1562 rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 1563 offset = insn.getOperand(1).getImm(); 1564 1565 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1566 if (!success) 1567 return false; 1568 1569 rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 1570 if (!success) 1571 return false; 1572 1573 if (!strcasecmp (op_name, "BLEZALC")) 1574 { 1575 if (rs_val <= 0) 1576 target = pc + offset; 1577 else 1578 target = pc + 4; 1579 } 1580 else if (!strcasecmp (op_name, "BGEZALC")) 1581 { 1582 if (rs_val >= 0) 1583 target = pc + offset; 1584 else 1585 target = pc + 4; 1586 } 1587 else if (!strcasecmp (op_name, "BLTZALC")) 1588 { 1589 if (rs_val < 0) 1590 target = pc + offset; 1591 else 1592 target = pc + 4; 1593 } 1594 else if (!strcasecmp (op_name, "BGTZALC")) 1595 { 1596 if (rs_val > 0) 1597 target = pc + offset; 1598 else 1599 target = pc + 4; 1600 } 1601 else if (!strcasecmp (op_name, "BEQZALC")) 1602 { 1603 if (rs_val == 0) 1604 target = pc + offset; 1605 else 1606 target = pc + 4; 1607 } 1608 else if (!strcasecmp (op_name, "BNEZALC")) 1609 { 1610 if (rs_val != 0) 1611 target = pc + offset; 1612 else 1613 target = pc + 4; 1614 } 1615 1616 Context context; 1617 1618 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 1619 return false; 1620 1621 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4)) 1622 return false; 1623 1624 return true; 1625 } 1626 1627 /* 1628 Emulate below MIPS Non-Compact conditional branch and link instructions. 1629 BLTZAL, BGEZAL : 1630 BLTZALL, BGEZALL : Branch likely 1631 */ 1632 bool 1633 EmulateInstructionMIPS::Emulate_Bcond_Link (llvm::MCInst& insn) 1634 { 1635 bool success = false; 1636 uint32_t rs; 1637 int32_t offset, pc, target = 0; 1638 int32_t rs_val; 1639 const char *op_name = m_insn_info->getName (insn.getOpcode ()); 1640 1641 rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 1642 offset = insn.getOperand(1).getImm(); 1643 1644 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1645 if (!success) 1646 return false; 1647 1648 rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 1649 if (!success) 1650 return false; 1651 1652 if (!strcasecmp (op_name, "BLTZAL") || 1653 !strcasecmp (op_name, "BLTZALL")) 1654 { 1655 if ((int32_t) rs_val < 0) 1656 target = pc + offset; 1657 else 1658 target = pc + 8; 1659 } 1660 else if (!strcasecmp (op_name, "BGEZAL") || 1661 !strcasecmp (op_name, "BGEZALL")) 1662 { 1663 if ((int32_t) rs_val >= 0) 1664 target = pc + offset; 1665 else 1666 target = pc + 8; 1667 } 1668 1669 Context context; 1670 1671 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 1672 return false; 1673 1674 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8)) 1675 return false; 1676 1677 return true; 1678 } 1679 1680 /* 1681 Emulate below MIPS branch instructions. 1682 BLTZL, BGEZL, BGTZL, BLEZL : Branch likely 1683 BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches 1684 */ 1685 bool 1686 EmulateInstructionMIPS::Emulate_BXX_2ops (llvm::MCInst& insn) 1687 { 1688 bool success = false; 1689 uint32_t rs; 1690 int32_t offset, pc, target = 0; 1691 int32_t rs_val; 1692 const char *op_name = m_insn_info->getName (insn.getOpcode ()); 1693 1694 rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 1695 offset = insn.getOperand(1).getImm(); 1696 1697 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1698 if (!success) 1699 return false; 1700 1701 rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 1702 if (!success) 1703 return false; 1704 1705 if (!strcasecmp (op_name, "BLTZL") || 1706 !strcasecmp (op_name, "BLTZ")) 1707 { 1708 if (rs_val < 0) 1709 target = pc + offset; 1710 else 1711 target = pc + 8; 1712 } 1713 else if (!strcasecmp (op_name, "BGEZL") || 1714 !strcasecmp (op_name, "BGEZ")) 1715 { 1716 if (rs_val >= 0) 1717 target = pc + offset; 1718 else 1719 target = pc + 8; 1720 } 1721 else if (!strcasecmp (op_name, "BGTZL") || 1722 !strcasecmp (op_name, "BGTZ")) 1723 { 1724 if (rs_val > 0) 1725 target = pc + offset; 1726 else 1727 target = pc + 8; 1728 } 1729 else if (!strcasecmp (op_name, "BLEZL") || 1730 !strcasecmp (op_name, "BLEZ")) 1731 { 1732 if (rs_val <= 0) 1733 target = pc + offset; 1734 else 1735 target = pc + 8; 1736 } 1737 1738 Context context; 1739 context.type = eContextRelativeBranchImmediate; 1740 context.SetImmediate (offset); 1741 1742 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 1743 return false; 1744 1745 return true; 1746 } 1747 1748 /* 1749 Emulate below MIPS branch instructions. 1750 BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches 1751 */ 1752 bool 1753 EmulateInstructionMIPS::Emulate_BXX_2ops_C (llvm::MCInst& insn) 1754 { 1755 bool success = false; 1756 uint32_t rs; 1757 int32_t offset, pc, target = 0; 1758 int32_t rs_val; 1759 const char *op_name = m_insn_info->getName (insn.getOpcode ()); 1760 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 1761 1762 rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 1763 offset = insn.getOperand(1).getImm(); 1764 1765 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1766 if (!success) 1767 return false; 1768 1769 rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 1770 if (!success) 1771 return false; 1772 1773 if (!strcasecmp (op_name, "BLTZC")) 1774 { 1775 if (rs_val < 0) 1776 target = pc + 4 + offset; 1777 else 1778 target = pc + 4; 1779 } 1780 else if (!strcasecmp (op_name, "BLEZC")) 1781 { 1782 if (rs_val <= 0) 1783 target = pc + 4 + offset; 1784 else 1785 target = pc + 4; 1786 } 1787 else if (!strcasecmp (op_name, "BGEZC")) 1788 { 1789 if (rs_val >= 0) 1790 target = pc + 4 + offset; 1791 else 1792 target = pc + 4; 1793 } 1794 else if (!strcasecmp (op_name, "BGTZC")) 1795 { 1796 if (rs_val > 0) 1797 target = pc + 4 + offset; 1798 else 1799 target = pc + 4; 1800 } 1801 else if (!strcasecmp (op_name, "BEQZC")) 1802 { 1803 if (rs_val == 0) 1804 target = pc + 4 + offset; 1805 else 1806 target = pc + 4; 1807 } 1808 else if (!strcasecmp (op_name, "BNEZC")) 1809 { 1810 if (rs_val != 0) 1811 target = pc + 4 + offset; 1812 else 1813 target = pc + 4; 1814 } 1815 1816 Context context; 1817 context.type = eContextRelativeBranchImmediate; 1818 context.SetImmediate (current_inst_size + offset); 1819 1820 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 1821 return false; 1822 1823 return true; 1824 } 1825 1826 bool 1827 EmulateInstructionMIPS::Emulate_B16_MM (llvm::MCInst& insn) 1828 { 1829 bool success = false; 1830 int32_t offset, pc, target; 1831 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 1832 1833 offset = insn.getOperand(0).getImm(); 1834 1835 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1836 if (!success) 1837 return false; 1838 1839 // unconditional branch 1840 target = pc + offset; 1841 1842 Context context; 1843 context.type = eContextRelativeBranchImmediate; 1844 context.SetImmediate (current_inst_size + offset); 1845 1846 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 1847 return false; 1848 1849 return true; 1850 } 1851 1852 /* 1853 BEQZC, BNEZC are 32 bit compact instructions without a delay slot. 1854 BEQZ16, BNEZ16 are 16 bit instructions with delay slot. 1855 BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot. 1856 */ 1857 bool 1858 EmulateInstructionMIPS::Emulate_Branch_MM (llvm::MCInst& insn) 1859 { 1860 bool success = false; 1861 int32_t target = 0; 1862 uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); 1863 const char *op_name = m_insn_info->getName (insn.getOpcode ()); 1864 bool update_ra = false; 1865 uint32_t ra_offset = 0; 1866 1867 /* 1868 * BEQZ16 rs, offset 1869 * condition <- (GPR[rs] = 0) 1870 * if condition then 1871 * PC = PC + sign_ext (offset || 0) 1872 * 1873 * BNEZ16 rs, offset 1874 * condition <- (GPR[rs] != 0) 1875 * if condition then 1876 * PC = PC + sign_ext (offset || 0) 1877 * 1878 * BEQZC rs, offset (compact instruction: No delay slot) 1879 * condition <- (GPR[rs] == 0) 1880 * if condition then 1881 * PC = PC + 4 + sign_ext (offset || 0) 1882 */ 1883 1884 uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 1885 int32_t offset = insn.getOperand(1).getImm(); 1886 1887 int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1888 if (!success) 1889 return false; 1890 1891 int32_t rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 1892 if (!success) 1893 return false; 1894 1895 if (!strcasecmp (op_name, "BEQZ16_MM")) 1896 { 1897 if (rs_val == 0) 1898 target = pc + offset; 1899 else 1900 target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction. 1901 } 1902 else if (!strcasecmp (op_name, "BNEZ16_MM")) 1903 { 1904 if (rs_val != 0) 1905 target = pc + offset; 1906 else 1907 target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction. 1908 } 1909 else if (!strcasecmp (op_name, "BEQZC_MM")) 1910 { 1911 if (rs_val == 0) 1912 target = pc + 4 + offset; 1913 else 1914 target = pc + 4; // 32 bit instruction and does not have delay slot instruction. 1915 } 1916 else if (!strcasecmp (op_name, "BNEZC_MM")) 1917 { 1918 if (rs_val != 0) 1919 target = pc + 4 + offset; 1920 else 1921 target = pc + 4; // 32 bit instruction and does not have delay slot instruction. 1922 } 1923 else if (!strcasecmp (op_name, "BGEZALS_MM")) 1924 { 1925 if (rs_val >= 0) 1926 target = pc + offset; 1927 else 1928 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot 1929 1930 update_ra = true; 1931 ra_offset = 6; 1932 } 1933 else if (!strcasecmp (op_name, "BLTZALS_MM")) 1934 { 1935 if (rs_val >= 0) 1936 target = pc + offset; 1937 else 1938 target = pc + 6; // 32 bit instruction with short (2-byte) delay slot 1939 1940 update_ra = true; 1941 ra_offset = 6; 1942 } 1943 1944 Context context; 1945 context.type = eContextRelativeBranchImmediate; 1946 context.SetImmediate (current_inst_size + offset); 1947 1948 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 1949 return false; 1950 1951 if (update_ra) 1952 { 1953 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset)) 1954 return false; 1955 } 1956 return true; 1957 } 1958 1959 /* Emulate micromips jump instructions. 1960 JALR16,JALRS16 1961 */ 1962 bool 1963 EmulateInstructionMIPS::Emulate_JALRx16_MM (llvm::MCInst& insn) 1964 { 1965 bool success = false; 1966 uint32_t ra_offset = 0; 1967 const char *op_name = m_insn_info->getName (insn.getOpcode ()); 1968 1969 uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 1970 1971 uint32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 1972 if (!success) 1973 return false; 1974 1975 uint32_t rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 1976 if (!success) 1977 return false; 1978 1979 if (!strcasecmp (op_name, "JALR16_MM")) 1980 ra_offset = 6; // 2-byte instruction with 4-byte delay slot. 1981 else if (!strcasecmp (op_name, "JALRS16_MM")) 1982 ra_offset = 4; // 2-byte instruction with 2-byte delay slot. 1983 1984 Context context; 1985 1986 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val)) 1987 return false; 1988 1989 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset)) 1990 return false; 1991 1992 return true; 1993 } 1994 1995 /* Emulate JALS and JALX instructions. 1996 JALS 32 bit instruction with short (2-byte) delay slot. 1997 JALX 32 bit instruction with 4-byte delay slot. 1998 */ 1999 bool 2000 EmulateInstructionMIPS::Emulate_JALx (llvm::MCInst& insn) 2001 { 2002 bool success = false; 2003 uint32_t offset=0, target=0, pc=0, ra_offset=0; 2004 const char *op_name = m_insn_info->getName (insn.getOpcode ()); 2005 2006 /* 2007 * JALS target 2008 * RA = PC + 6 2009 * offset = sign_ext (offset << 1) 2010 * PC = PC[31-27] | offset 2011 * JALX target 2012 * RA = PC + 8 2013 * offset = sign_ext (offset << 2) 2014 * PC = PC[31-28] | offset 2015 */ 2016 offset = insn.getOperand(0).getImm(); 2017 2018 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2019 if (!success) 2020 return false; 2021 2022 // These are PC-region branches and not PC-relative. 2023 if (!strcasecmp (op_name, "JALS_MM")) 2024 { 2025 // target address is in the “current” 128 MB-aligned region 2026 target = (pc & 0xF8000000UL) | offset; 2027 ra_offset = 6; 2028 } 2029 else if (!strcasecmp (op_name, "JALX_MM")) 2030 { 2031 // target address is in the “current” 256 MB-aligned region 2032 target = (pc & 0xF0000000UL) | offset; 2033 ra_offset = 8; 2034 } 2035 2036 Context context; 2037 2038 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2039 return false; 2040 2041 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset)) 2042 return false; 2043 2044 return true; 2045 } 2046 2047 bool 2048 EmulateInstructionMIPS::Emulate_JALRS (llvm::MCInst& insn) 2049 { 2050 bool success = false; 2051 uint32_t rs=0, rt=0; 2052 int32_t pc=0, rs_val=0; 2053 2054 /* 2055 JALRS rt, rs 2056 GPR[rt] <- PC + 6 2057 PC <- GPR[rs] 2058 */ 2059 2060 rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 2061 rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); 2062 2063 rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 2064 if (!success) 2065 return false; 2066 2067 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2068 if (!success) 2069 return false; 2070 2071 Context context; 2072 2073 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val)) 2074 return false; 2075 2076 // This is 4-byte instruction with 2-byte delay slot. 2077 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, pc + 6)) 2078 return false; 2079 2080 return true; 2081 } 2082 2083 bool 2084 EmulateInstructionMIPS::Emulate_BAL (llvm::MCInst& insn) 2085 { 2086 bool success = false; 2087 int32_t offset, pc, target; 2088 2089 /* 2090 * BAL offset 2091 * offset = sign_ext (offset << 2) 2092 * RA = PC + 8 2093 * PC = PC + offset 2094 */ 2095 offset = insn.getOperand(0).getImm(); 2096 2097 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2098 if (!success) 2099 return false; 2100 2101 target = pc + offset; 2102 2103 Context context; 2104 2105 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2106 return false; 2107 2108 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8)) 2109 return false; 2110 2111 return true; 2112 } 2113 2114 bool 2115 EmulateInstructionMIPS::Emulate_BALC (llvm::MCInst& insn) 2116 { 2117 bool success = false; 2118 int32_t offset, pc, target; 2119 2120 /* 2121 * BALC offset 2122 * offset = sign_ext (offset << 2) 2123 * RA = PC + 4 2124 * PC = PC + 4 + offset 2125 */ 2126 offset = insn.getOperand(0).getImm(); 2127 2128 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2129 if (!success) 2130 return false; 2131 2132 target = pc + 4 + offset; 2133 2134 Context context; 2135 2136 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2137 return false; 2138 2139 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4)) 2140 return false; 2141 2142 return true; 2143 } 2144 2145 bool 2146 EmulateInstructionMIPS::Emulate_BC (llvm::MCInst& insn) 2147 { 2148 bool success = false; 2149 int32_t offset, pc, target; 2150 2151 /* 2152 * BC offset 2153 * offset = sign_ext (offset << 2) 2154 * PC = PC + 4 + offset 2155 */ 2156 offset = insn.getOperand(0).getImm(); 2157 2158 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2159 if (!success) 2160 return false; 2161 2162 target = pc + 4 + offset; 2163 2164 Context context; 2165 2166 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2167 return false; 2168 2169 return true; 2170 } 2171 2172 bool 2173 EmulateInstructionMIPS::Emulate_J (llvm::MCInst& insn) 2174 { 2175 bool success = false; 2176 uint32_t offset, pc; 2177 2178 /* 2179 * J offset 2180 * offset = sign_ext (offset << 2) 2181 * PC = PC[63-28] | offset 2182 */ 2183 offset = insn.getOperand(0).getImm(); 2184 2185 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2186 if (!success) 2187 return false; 2188 2189 /* This is a PC-region branch and not PC-relative */ 2190 pc = (pc & 0xF0000000UL) | offset; 2191 2192 Context context; 2193 2194 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, pc)) 2195 return false; 2196 2197 return true; 2198 } 2199 2200 bool 2201 EmulateInstructionMIPS::Emulate_JAL (llvm::MCInst& insn) 2202 { 2203 bool success = false; 2204 uint32_t offset, target, pc; 2205 2206 /* 2207 * JAL offset 2208 * offset = sign_ext (offset << 2) 2209 * PC = PC[63-28] | offset 2210 */ 2211 offset = insn.getOperand(0).getImm(); 2212 2213 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2214 if (!success) 2215 return false; 2216 2217 /* This is a PC-region branch and not PC-relative */ 2218 target = (pc & 0xF0000000UL) | offset; 2219 2220 Context context; 2221 2222 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2223 return false; 2224 2225 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8)) 2226 return false; 2227 2228 return true; 2229 } 2230 2231 bool 2232 EmulateInstructionMIPS::Emulate_JALR (llvm::MCInst& insn) 2233 { 2234 bool success = false; 2235 uint32_t rs, rt; 2236 uint32_t pc, rs_val; 2237 2238 /* 2239 * JALR rt, rs 2240 * GPR[rt] = PC + 8 2241 * PC = GPR[rs] 2242 */ 2243 rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 2244 rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); 2245 2246 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2247 if (!success) 2248 return false; 2249 2250 rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 2251 if (!success) 2252 return false; 2253 2254 Context context; 2255 2256 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val)) 2257 return false; 2258 2259 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, pc + 8)) 2260 return false; 2261 2262 return true; 2263 } 2264 2265 bool 2266 EmulateInstructionMIPS::Emulate_JIALC (llvm::MCInst& insn) 2267 { 2268 bool success = false; 2269 uint32_t rt; 2270 int32_t target, offset, pc, rt_val; 2271 2272 /* 2273 * JIALC rt, offset 2274 * offset = sign_ext (offset) 2275 * PC = GPR[rt] + offset 2276 * RA = PC + 4 2277 */ 2278 rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 2279 offset = insn.getOperand(1).getImm(); 2280 2281 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2282 if (!success) 2283 return false; 2284 2285 rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); 2286 if (!success) 2287 return false; 2288 2289 target = rt_val + offset; 2290 2291 Context context; 2292 2293 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2294 return false; 2295 2296 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4)) 2297 return false; 2298 2299 return true; 2300 } 2301 2302 bool 2303 EmulateInstructionMIPS::Emulate_JIC (llvm::MCInst& insn) 2304 { 2305 bool success = false; 2306 uint32_t rt; 2307 int32_t target, offset, rt_val; 2308 2309 /* 2310 * JIC rt, offset 2311 * offset = sign_ext (offset) 2312 * PC = GPR[rt] + offset 2313 */ 2314 rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 2315 offset = insn.getOperand(1).getImm(); 2316 2317 rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); 2318 if (!success) 2319 return false; 2320 2321 target = rt_val + offset; 2322 2323 Context context; 2324 2325 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2326 return false; 2327 2328 return true; 2329 } 2330 2331 bool 2332 EmulateInstructionMIPS::Emulate_JR (llvm::MCInst& insn) 2333 { 2334 bool success = false; 2335 uint32_t rs; 2336 uint32_t rs_val; 2337 2338 /* 2339 * JR rs 2340 * PC = GPR[rs] 2341 */ 2342 rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 2343 2344 rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); 2345 if (!success) 2346 return false; 2347 2348 Context context; 2349 2350 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val)) 2351 return false; 2352 2353 return true; 2354 } 2355 2356 /* 2357 Emulate Branch on FP True/False 2358 BC1F, BC1FL : Branch on FP False (L stands for branch likely) 2359 BC1T, BC1TL : Branch on FP True (L stands for branch likely) 2360 */ 2361 bool 2362 EmulateInstructionMIPS::Emulate_FP_branch (llvm::MCInst& insn) 2363 { 2364 bool success = false; 2365 uint32_t cc, fcsr; 2366 int32_t pc, offset, target = 0; 2367 const char *op_name = m_insn_info->getName (insn.getOpcode ()); 2368 2369 cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 2370 offset = insn.getOperand(1).getImm(); 2371 2372 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2373 if (!success) 2374 return false; 2375 2376 fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success); 2377 if (!success) 2378 return false; 2379 2380 /* fcsr[23], fcsr[25-31] are vaild condition bits */ 2381 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); 2382 2383 if (!strcasecmp (op_name, "BC1F") || 2384 !strcasecmp (op_name, "BC1FL")) 2385 { 2386 if ((fcsr & (1 << cc)) == 0) 2387 target = pc + offset; 2388 else 2389 target = pc + 8; 2390 } 2391 else if (!strcasecmp (op_name, "BC1T") || 2392 !strcasecmp (op_name, "BC1TL")) 2393 { 2394 if ((fcsr & (1 << cc)) != 0) 2395 target = pc + offset; 2396 else 2397 target = pc + 8; 2398 } 2399 Context context; 2400 2401 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2402 return false; 2403 2404 return true; 2405 } 2406 2407 bool 2408 EmulateInstructionMIPS::Emulate_BC1EQZ (llvm::MCInst& insn) 2409 { 2410 bool success = false; 2411 uint32_t ft; 2412 uint32_t ft_val; 2413 int32_t target, pc, offset; 2414 2415 /* 2416 * BC1EQZ ft, offset 2417 * condition <- (FPR[ft].bit0 == 0) 2418 * if condition then 2419 * offset = sign_ext (offset) 2420 * PC = PC + 4 + offset 2421 */ 2422 ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 2423 offset = insn.getOperand(1).getImm(); 2424 2425 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2426 if (!success) 2427 return false; 2428 2429 ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + ft, 0, &success); 2430 if (!success) 2431 return false; 2432 2433 if ((ft_val & 1) == 0) 2434 target = pc + 4 + offset; 2435 else 2436 target = pc + 8; 2437 2438 Context context; 2439 2440 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2441 return false; 2442 2443 return true; 2444 } 2445 2446 bool 2447 EmulateInstructionMIPS::Emulate_BC1NEZ (llvm::MCInst& insn) 2448 { 2449 bool success = false; 2450 uint32_t ft; 2451 uint32_t ft_val; 2452 int32_t target, pc, offset; 2453 2454 /* 2455 * BC1NEZ ft, offset 2456 * condition <- (FPR[ft].bit0 != 0) 2457 * if condition then 2458 * offset = sign_ext (offset) 2459 * PC = PC + 4 + offset 2460 */ 2461 ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 2462 offset = insn.getOperand(1).getImm(); 2463 2464 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2465 if (!success) 2466 return false; 2467 2468 ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + ft, 0, &success); 2469 if (!success) 2470 return false; 2471 2472 if ((ft_val & 1) != 0) 2473 target = pc + 4 + offset; 2474 else 2475 target = pc + 8; 2476 2477 Context context; 2478 2479 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2480 return false; 2481 2482 return true; 2483 } 2484 2485 /* 2486 Emulate MIPS-3D Branch instructions 2487 BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes False/True 2488 BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes False/True 2489 */ 2490 bool 2491 EmulateInstructionMIPS::Emulate_3D_branch (llvm::MCInst& insn) 2492 { 2493 bool success = false; 2494 uint32_t cc, fcsr; 2495 int32_t pc, offset, target = 0; 2496 const char *op_name = m_insn_info->getName (insn.getOpcode ()); 2497 2498 cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 2499 offset = insn.getOperand(1).getImm(); 2500 2501 pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2502 if (!success) 2503 return false; 2504 2505 fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success); 2506 if (!success) 2507 return false; 2508 2509 /* fcsr[23], fcsr[25-31] are vaild condition bits */ 2510 fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); 2511 2512 if (!strcasecmp (op_name, "BC1ANY2F")) 2513 { 2514 /* if any one bit is 0 */ 2515 if (((fcsr >> cc) & 3) != 3) 2516 target = pc + offset; 2517 else 2518 target = pc + 8; 2519 } 2520 else if (!strcasecmp (op_name, "BC1ANY2T")) 2521 { 2522 /* if any one bit is 1 */ 2523 if (((fcsr >> cc) & 3) != 0) 2524 target = pc + offset; 2525 else 2526 target = pc + 8; 2527 } 2528 else if (!strcasecmp (op_name, "BC1ANY4F")) 2529 { 2530 /* if any one bit is 0 */ 2531 if (((fcsr >> cc) & 0xf) != 0xf) 2532 target = pc + offset; 2533 else 2534 target = pc + 8; 2535 } 2536 else if (!strcasecmp (op_name, "BC1ANY4T")) 2537 { 2538 /* if any one bit is 1 */ 2539 if (((fcsr >> cc) & 0xf) != 0) 2540 target = pc + offset; 2541 else 2542 target = pc + 8; 2543 } 2544 Context context; 2545 2546 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2547 return false; 2548 2549 return true; 2550 } 2551 2552 bool 2553 EmulateInstructionMIPS::Emulate_BNZB (llvm::MCInst& insn) 2554 { 2555 return Emulate_MSA_Branch_DF(insn, 1, true); 2556 } 2557 2558 bool 2559 EmulateInstructionMIPS::Emulate_BNZH (llvm::MCInst& insn) 2560 { 2561 return Emulate_MSA_Branch_DF(insn, 2, true); 2562 } 2563 2564 bool 2565 EmulateInstructionMIPS::Emulate_BNZW (llvm::MCInst& insn) 2566 { 2567 return Emulate_MSA_Branch_DF(insn, 4, true); 2568 } 2569 2570 bool 2571 EmulateInstructionMIPS::Emulate_BNZD (llvm::MCInst& insn) 2572 { 2573 return Emulate_MSA_Branch_DF(insn, 8, true); 2574 } 2575 2576 bool 2577 EmulateInstructionMIPS::Emulate_BZB (llvm::MCInst& insn) 2578 { 2579 return Emulate_MSA_Branch_DF(insn, 1, false); 2580 } 2581 2582 bool 2583 EmulateInstructionMIPS::Emulate_BZH (llvm::MCInst& insn) 2584 { 2585 return Emulate_MSA_Branch_DF(insn, 2, false); 2586 } 2587 2588 bool 2589 EmulateInstructionMIPS::Emulate_BZW (llvm::MCInst& insn) 2590 { 2591 return Emulate_MSA_Branch_DF(insn, 4, false); 2592 } 2593 2594 bool 2595 EmulateInstructionMIPS::Emulate_BZD (llvm::MCInst& insn) 2596 { 2597 return Emulate_MSA_Branch_DF(insn, 8, false); 2598 } 2599 2600 bool 2601 EmulateInstructionMIPS::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_byte_size, bool bnz) 2602 { 2603 bool success = false, branch_hit = true; 2604 int32_t target = 0; 2605 RegisterValue reg_value; 2606 uint8_t * ptr = NULL; 2607 2608 uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 2609 int32_t offset = insn.getOperand(1).getImm(); 2610 2611 int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2612 if (!success) 2613 return false; 2614 2615 if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value)) 2616 ptr = (uint8_t *)reg_value.GetBytes(); 2617 else 2618 return false; 2619 2620 for(int i = 0; i < 16 / element_byte_size; i++) 2621 { 2622 switch(element_byte_size) 2623 { 2624 case 1: 2625 if((*ptr == 0 && bnz) || (*ptr != 0 && !bnz) ) 2626 branch_hit = false; 2627 break; 2628 case 2: 2629 if((*(uint16_t *)ptr == 0 && bnz) || (*(uint16_t *)ptr != 0 && !bnz)) 2630 branch_hit = false; 2631 break; 2632 case 4: 2633 if((*(uint32_t *)ptr == 0 && bnz) || (*(uint32_t *)ptr != 0 && !bnz)) 2634 branch_hit = false; 2635 break; 2636 case 8: 2637 if((*(uint64_t *)ptr == 0 && bnz) || (*(uint64_t *)ptr != 0 && !bnz)) 2638 branch_hit = false; 2639 break; 2640 } 2641 if(!branch_hit) 2642 break; 2643 ptr = ptr + element_byte_size; 2644 } 2645 2646 if(branch_hit) 2647 target = pc + offset; 2648 else 2649 target = pc + 8; 2650 2651 Context context; 2652 context.type = eContextRelativeBranchImmediate; 2653 2654 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2655 return false; 2656 2657 return true; 2658 } 2659 2660 bool 2661 EmulateInstructionMIPS::Emulate_BNZV (llvm::MCInst& insn) 2662 { 2663 return Emulate_MSA_Branch_V (insn, true); 2664 } 2665 2666 bool 2667 EmulateInstructionMIPS::Emulate_BZV (llvm::MCInst& insn) 2668 { 2669 return Emulate_MSA_Branch_V (insn, false); 2670 } 2671 2672 bool 2673 EmulateInstructionMIPS::Emulate_MSA_Branch_V (llvm::MCInst& insn, bool bnz) 2674 { 2675 bool success = false; 2676 int32_t target = 0; 2677 llvm::APInt wr_val = llvm::APInt::getNullValue(128); 2678 llvm::APInt fail_value = llvm::APInt::getMaxValue(128); 2679 llvm::APInt zero_value = llvm::APInt::getNullValue(128); 2680 RegisterValue reg_value; 2681 2682 uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); 2683 int32_t offset = insn.getOperand(1).getImm(); 2684 2685 int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); 2686 if (!success) 2687 return false; 2688 2689 if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value)) 2690 wr_val = reg_value.GetAsUInt128(fail_value); 2691 else 2692 return false; 2693 2694 if((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz)) 2695 target = pc + offset; 2696 else 2697 target = pc + 8; 2698 2699 Context context; 2700 context.type = eContextRelativeBranchImmediate; 2701 2702 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) 2703 return false; 2704 2705 return true; 2706 } 2707 2708 bool 2709 EmulateInstructionMIPS::Emulate_LDST_Imm (llvm::MCInst& insn) 2710 { 2711 bool success = false; 2712 uint32_t base; 2713 int32_t imm, address; 2714 Context bad_vaddr_context; 2715 2716 uint32_t num_operands = insn.getNumOperands(); 2717 base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg()); 2718 imm = insn.getOperand(num_operands-1).getImm(); 2719 2720 RegisterInfo reg_info_base; 2721 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base)) 2722 return false; 2723 2724 /* read base register */ 2725 address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 2726 if (!success) 2727 return false; 2728 2729 /* destination address */ 2730 address = address + imm; 2731 2732 /* Set the bad_vaddr register with base address used in the instruction */ 2733 bad_vaddr_context.type = eContextInvalid; 2734 WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address); 2735 2736 return true; 2737 } 2738 2739 bool 2740 EmulateInstructionMIPS::Emulate_LDST_Reg (llvm::MCInst& insn) 2741 { 2742 bool success = false; 2743 uint32_t base, index; 2744 int32_t address, index_address; 2745 Context bad_vaddr_context; 2746 2747 uint32_t num_operands = insn.getNumOperands(); 2748 base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg()); 2749 index = m_reg_info->getEncodingValue (insn.getOperand(num_operands-1).getReg()); 2750 2751 RegisterInfo reg_info_base, reg_info_index; 2752 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base)) 2753 return false; 2754 2755 if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + index, reg_info_index)) 2756 return false; 2757 2758 /* read base register */ 2759 address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); 2760 if (!success) 2761 return false; 2762 2763 /* read index register */ 2764 index_address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success); 2765 if (!success) 2766 return false; 2767 2768 /* destination address */ 2769 address = address + index_address; 2770 2771 /* Set the bad_vaddr register with base address used in the instruction */ 2772 bad_vaddr_context.type = eContextInvalid; 2773 WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address); 2774 2775 return true; 2776 } 2777