| 365 | } |
| 366 | |
| 367 | MipsOpcodeInfo GetOpcodeInfo(DebugInterface* cpu, u32 address) { |
| 368 | MipsOpcodeInfo info; |
| 369 | memset(&info, 0, sizeof(info)); |
| 370 | |
| 371 | if (!cpu->isValidAddress(address)) |
| 372 | return info; |
| 373 | |
| 374 | info.cpu = cpu; |
| 375 | info.opcodeAddress = address; |
| 376 | info.encodedOpcode = cpu->Read32(address); |
| 377 | u32 op = info.encodedOpcode; |
| 378 | const R5900::OPCODE& opcode = R5900::GetInstruction(op); |
| 379 | |
| 380 | // extract all the branch related information |
| 381 | info.isBranch = (opcode.flags & IS_BRANCH) != 0; |
| 382 | if (info.isBranch) |
| 383 | { |
| 384 | info.isLinkedBranch = (opcode.flags & IS_LINKED) != 0; |
| 385 | info.isLikelyBranch = (opcode.flags & IS_LIKELY) != 0; |
| 386 | |
| 387 | s64 rs,rt; |
| 388 | u32 value; |
| 389 | switch (opcode.flags & BRANCHTYPE_MASK) |
| 390 | { |
| 391 | case BRANCHTYPE_JUMP: |
| 392 | info.isConditional = false; |
| 393 | info.branchTarget = (info.opcodeAddress & 0xF0000000) | ((op&0x03FFFFFF) << 2); |
| 394 | break; |
| 395 | case BRANCHTYPE_BRANCH: |
| 396 | info.isConditional = true; |
| 397 | info.branchTarget = info.opcodeAddress + 4 + ((s16)(op&0xFFFF)<<2); |
| 398 | |
| 399 | // Sign extend from 32bit for IOP regs |
| 400 | if (info.cpu->getRegisterSize(0) == 32) { |
| 401 | rs = (s32)info.cpu->getRegister(0,MIPS_GET_RS(op))._u32[0]; |
| 402 | rt = (s32)info.cpu->getRegister(0,MIPS_GET_RT(op))._u32[0]; |
| 403 | } else { |
| 404 | rs = (s64)info.cpu->getRegister(0,MIPS_GET_RS(op))._u64[0]; |
| 405 | rt = (s64)info.cpu->getRegister(0,MIPS_GET_RT(op))._u64[0]; |
| 406 | } |
| 407 | |
| 408 | switch (opcode.flags & CONDTYPE_MASK) |
| 409 | { |
| 410 | case CONDTYPE_EQ: |
| 411 | info.conditionMet = (rt == rs); |
| 412 | if (MIPS_GET_RT(op) == MIPS_GET_RS(op)) // always true |
| 413 | info.isConditional = false; |
| 414 | break; |
| 415 | case CONDTYPE_NE: |
| 416 | info.conditionMet = (rt != rs); |
| 417 | if (MIPS_GET_RT(op) == MIPS_GET_RS(op)) // always false |
| 418 | info.isConditional = false; |
| 419 | break; |
| 420 | case CONDTYPE_LEZ: |
| 421 | info.conditionMet = (rs <= 0); |
| 422 | break; |
| 423 | case CONDTYPE_GTZ: |
| 424 | info.conditionMet = (rs > 0); |
no test coverage detected