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