Merge pull request #4693 from lioncash/interp-naming

Interpreter: Amend parameter naming
This commit is contained in:
Matthew Parlane 2017-01-21 12:31:51 +13:00 committed by GitHub
commit 2f9bf297f1
10 changed files with 1163 additions and 1161 deletions

View File

@ -40,25 +40,25 @@ std::array<Interpreter::Instruction, 1024> Interpreter::m_op_table31;
std::array<Interpreter::Instruction, 32> Interpreter::m_op_table59; std::array<Interpreter::Instruction, 32> Interpreter::m_op_table59;
std::array<Interpreter::Instruction, 1024> Interpreter::m_op_table63; std::array<Interpreter::Instruction, 1024> Interpreter::m_op_table63;
void Interpreter::RunTable4(UGeckoInstruction _inst) void Interpreter::RunTable4(UGeckoInstruction inst)
{ {
m_op_table4[_inst.SUBOP10](_inst); m_op_table4[inst.SUBOP10](inst);
} }
void Interpreter::RunTable19(UGeckoInstruction _inst) void Interpreter::RunTable19(UGeckoInstruction inst)
{ {
m_op_table19[_inst.SUBOP10](_inst); m_op_table19[inst.SUBOP10](inst);
} }
void Interpreter::RunTable31(UGeckoInstruction _inst) void Interpreter::RunTable31(UGeckoInstruction inst)
{ {
m_op_table31[_inst.SUBOP10](_inst); m_op_table31[inst.SUBOP10](inst);
} }
void Interpreter::RunTable59(UGeckoInstruction _inst) void Interpreter::RunTable59(UGeckoInstruction inst)
{ {
m_op_table59[_inst.SUBOP5](_inst); m_op_table59[inst.SUBOP5](inst);
} }
void Interpreter::RunTable63(UGeckoInstruction _inst) void Interpreter::RunTable63(UGeckoInstruction inst)
{ {
m_op_table63[_inst.SUBOP10](_inst); m_op_table63[inst.SUBOP10](inst);
} }
void Interpreter::Init() void Interpreter::Init()
@ -73,7 +73,7 @@ void Interpreter::Shutdown()
static int startTrace = 0; static int startTrace = 0;
static void Trace(UGeckoInstruction& instCode) static void Trace(UGeckoInstruction& inst)
{ {
std::string regs = ""; std::string regs = "";
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
@ -88,11 +88,11 @@ static void Trace(UGeckoInstruction& instCode)
PowerPC::ppcState.ps[i][1]); PowerPC::ppcState.ps[i][1]);
} }
std::string ppc_inst = GekkoDisassembler::Disassemble(instCode.hex, PC); std::string ppc_inst = GekkoDisassembler::Disassemble(inst.hex, PC);
DEBUG_LOG(POWERPC, "INTER PC: %08x SRR0: %08x SRR1: %08x CRval: %016lx FPSCR: %08x MSR: %08x LR: " DEBUG_LOG(POWERPC, "INTER PC: %08x SRR0: %08x SRR1: %08x CRval: %016lx FPSCR: %08x MSR: %08x LR: "
"%08x %s %08x %s", "%08x %s %08x %s",
PC, SRR0, SRR1, (unsigned long)PowerPC::ppcState.cr_val[0], PowerPC::ppcState.fpscr, PC, SRR0, SRR1, (unsigned long)PowerPC::ppcState.cr_val[0], PowerPC::ppcState.fpscr,
PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), instCode.hex, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), inst.hex,
ppc_inst.c_str()); ppc_inst.c_str());
} }
@ -306,20 +306,20 @@ void Interpreter::Run()
} }
} }
void Interpreter::unknown_instruction(UGeckoInstruction _inst) void Interpreter::unknown_instruction(UGeckoInstruction inst)
{ {
std::string disasm = GekkoDisassembler::Disassemble(PowerPC::HostRead_U32(last_pc), last_pc); std::string disasm = GekkoDisassembler::Disassemble(PowerPC::HostRead_U32(last_pc), last_pc);
NOTICE_LOG(POWERPC, "Last PC = %08x : %s", last_pc, disasm.c_str()); NOTICE_LOG(POWERPC, "Last PC = %08x : %s", last_pc, disasm.c_str());
Dolphin_Debugger::PrintCallstack(); Dolphin_Debugger::PrintCallstack();
NOTICE_LOG(POWERPC, NOTICE_LOG(POWERPC,
"\nIntCPU: Unknown instruction %08x at PC = %08x last_PC = %08x LR = %08x\n", "\nIntCPU: Unknown instruction %08x at PC = %08x last_PC = %08x LR = %08x\n",
_inst.hex, PC, last_pc, LR); inst.hex, PC, last_pc, LR);
for (int i = 0; i < 32; i += 4) for (int i = 0; i < 32; i += 4)
NOTICE_LOG(POWERPC, "r%d: 0x%08x r%d: 0x%08x r%d:0x%08x r%d: 0x%08x", i, rGPR[i], i + 1, NOTICE_LOG(POWERPC, "r%d: 0x%08x r%d: 0x%08x r%d:0x%08x r%d: 0x%08x", i, rGPR[i], i + 1,
rGPR[i + 1], i + 2, rGPR[i + 2], i + 3, rGPR[i + 3]); rGPR[i + 1], i + 2, rGPR[i + 2], i + 3, rGPR[i + 3]);
_assert_msg_(POWERPC, 0, _assert_msg_(POWERPC, 0,
"\nIntCPU: Unknown instruction %08x at PC = %08x last_PC = %08x LR = %08x\n", "\nIntCPU: Unknown instruction %08x at PC = %08x last_PC = %08x LR = %08x\n",
_inst.hex, PC, last_pc, LR); inst.hex, PC, last_pc, LR);
} }
void Interpreter::ClearCache() void Interpreter::ClearCache()

View File

@ -22,247 +22,247 @@ public:
void ClearCache() override; void ClearCache() override;
const char* GetName() override; const char* GetName() override;
static void unknown_instruction(UGeckoInstruction _inst); static void unknown_instruction(UGeckoInstruction inst);
// Branch Instructions // Branch Instructions
static void bx(UGeckoInstruction _inst); static void bx(UGeckoInstruction inst);
static void bcx(UGeckoInstruction _inst); static void bcx(UGeckoInstruction inst);
static void bcctrx(UGeckoInstruction _inst); static void bcctrx(UGeckoInstruction inst);
static void bclrx(UGeckoInstruction _inst); static void bclrx(UGeckoInstruction inst);
static void HLEFunction(UGeckoInstruction _inst); static void HLEFunction(UGeckoInstruction inst);
// Syscall Instruction // Syscall Instruction
static void sc(UGeckoInstruction _inst); static void sc(UGeckoInstruction inst);
// Floating Point Instructions // Floating Point Instructions
static void faddsx(UGeckoInstruction _inst); static void faddsx(UGeckoInstruction inst);
static void fdivsx(UGeckoInstruction _inst); static void fdivsx(UGeckoInstruction inst);
static void fmaddsx(UGeckoInstruction _inst); static void fmaddsx(UGeckoInstruction inst);
static void fmsubsx(UGeckoInstruction _inst); static void fmsubsx(UGeckoInstruction inst);
static void fmulsx(UGeckoInstruction _inst); static void fmulsx(UGeckoInstruction inst);
static void fnmaddsx(UGeckoInstruction _inst); static void fnmaddsx(UGeckoInstruction inst);
static void fnmsubsx(UGeckoInstruction _inst); static void fnmsubsx(UGeckoInstruction inst);
static void fresx(UGeckoInstruction _inst); static void fresx(UGeckoInstruction inst);
static void fsubsx(UGeckoInstruction _inst); static void fsubsx(UGeckoInstruction inst);
static void fabsx(UGeckoInstruction _inst); static void fabsx(UGeckoInstruction inst);
static void fcmpo(UGeckoInstruction _inst); static void fcmpo(UGeckoInstruction inst);
static void fcmpu(UGeckoInstruction _inst); static void fcmpu(UGeckoInstruction inst);
static void fctiwx(UGeckoInstruction _inst); static void fctiwx(UGeckoInstruction inst);
static void fctiwzx(UGeckoInstruction _inst); static void fctiwzx(UGeckoInstruction inst);
static void fmrx(UGeckoInstruction _inst); static void fmrx(UGeckoInstruction inst);
static void fnabsx(UGeckoInstruction _inst); static void fnabsx(UGeckoInstruction inst);
static void fnegx(UGeckoInstruction _inst); static void fnegx(UGeckoInstruction inst);
static void frspx(UGeckoInstruction _inst); static void frspx(UGeckoInstruction inst);
static void faddx(UGeckoInstruction _inst); static void faddx(UGeckoInstruction inst);
static void fdivx(UGeckoInstruction _inst); static void fdivx(UGeckoInstruction inst);
static void fmaddx(UGeckoInstruction _inst); static void fmaddx(UGeckoInstruction inst);
static void fmsubx(UGeckoInstruction _inst); static void fmsubx(UGeckoInstruction inst);
static void fmulx(UGeckoInstruction _inst); static void fmulx(UGeckoInstruction inst);
static void fnmaddx(UGeckoInstruction _inst); static void fnmaddx(UGeckoInstruction inst);
static void fnmsubx(UGeckoInstruction _inst); static void fnmsubx(UGeckoInstruction inst);
static void frsqrtex(UGeckoInstruction _inst); static void frsqrtex(UGeckoInstruction inst);
static void fselx(UGeckoInstruction _inst); static void fselx(UGeckoInstruction inst);
static void fsubx(UGeckoInstruction _inst); static void fsubx(UGeckoInstruction inst);
// Integer Instructions // Integer Instructions
static void addi(UGeckoInstruction _inst); static void addi(UGeckoInstruction inst);
static void addic(UGeckoInstruction _inst); static void addic(UGeckoInstruction inst);
static void addic_rc(UGeckoInstruction _inst); static void addic_rc(UGeckoInstruction inst);
static void addis(UGeckoInstruction _inst); static void addis(UGeckoInstruction inst);
static void andi_rc(UGeckoInstruction _inst); static void andi_rc(UGeckoInstruction inst);
static void andis_rc(UGeckoInstruction _inst); static void andis_rc(UGeckoInstruction inst);
static void cmpi(UGeckoInstruction _inst); static void cmpi(UGeckoInstruction inst);
static void cmpli(UGeckoInstruction _inst); static void cmpli(UGeckoInstruction inst);
static void mulli(UGeckoInstruction _inst); static void mulli(UGeckoInstruction inst);
static void ori(UGeckoInstruction _inst); static void ori(UGeckoInstruction inst);
static void oris(UGeckoInstruction _inst); static void oris(UGeckoInstruction inst);
static void subfic(UGeckoInstruction _inst); static void subfic(UGeckoInstruction inst);
static void twi(UGeckoInstruction _inst); static void twi(UGeckoInstruction inst);
static void xori(UGeckoInstruction _inst); static void xori(UGeckoInstruction inst);
static void xoris(UGeckoInstruction _inst); static void xoris(UGeckoInstruction inst);
static void rlwimix(UGeckoInstruction _inst); static void rlwimix(UGeckoInstruction inst);
static void rlwinmx(UGeckoInstruction _inst); static void rlwinmx(UGeckoInstruction inst);
static void rlwnmx(UGeckoInstruction _inst); static void rlwnmx(UGeckoInstruction inst);
static void andx(UGeckoInstruction _inst); static void andx(UGeckoInstruction inst);
static void andcx(UGeckoInstruction _inst); static void andcx(UGeckoInstruction inst);
static void cmp(UGeckoInstruction _inst); static void cmp(UGeckoInstruction inst);
static void cmpl(UGeckoInstruction _inst); static void cmpl(UGeckoInstruction inst);
static void cntlzwx(UGeckoInstruction _inst); static void cntlzwx(UGeckoInstruction inst);
static void eqvx(UGeckoInstruction _inst); static void eqvx(UGeckoInstruction inst);
static void extsbx(UGeckoInstruction _inst); static void extsbx(UGeckoInstruction inst);
static void extshx(UGeckoInstruction _inst); static void extshx(UGeckoInstruction inst);
static void nandx(UGeckoInstruction _inst); static void nandx(UGeckoInstruction inst);
static void norx(UGeckoInstruction _inst); static void norx(UGeckoInstruction inst);
static void orx(UGeckoInstruction _inst); static void orx(UGeckoInstruction inst);
static void orcx(UGeckoInstruction _inst); static void orcx(UGeckoInstruction inst);
static void slwx(UGeckoInstruction _inst); static void slwx(UGeckoInstruction inst);
static void srawx(UGeckoInstruction _inst); static void srawx(UGeckoInstruction inst);
static void srawix(UGeckoInstruction _inst); static void srawix(UGeckoInstruction inst);
static void srwx(UGeckoInstruction _inst); static void srwx(UGeckoInstruction inst);
static void tw(UGeckoInstruction _inst); static void tw(UGeckoInstruction inst);
static void xorx(UGeckoInstruction _inst); static void xorx(UGeckoInstruction inst);
static void addx(UGeckoInstruction _inst); static void addx(UGeckoInstruction inst);
static void addcx(UGeckoInstruction _inst); static void addcx(UGeckoInstruction inst);
static void addex(UGeckoInstruction _inst); static void addex(UGeckoInstruction inst);
static void addmex(UGeckoInstruction _inst); static void addmex(UGeckoInstruction inst);
static void addzex(UGeckoInstruction _inst); static void addzex(UGeckoInstruction inst);
static void divwx(UGeckoInstruction _inst); static void divwx(UGeckoInstruction inst);
static void divwux(UGeckoInstruction _inst); static void divwux(UGeckoInstruction inst);
static void mulhwx(UGeckoInstruction _inst); static void mulhwx(UGeckoInstruction inst);
static void mulhwux(UGeckoInstruction _inst); static void mulhwux(UGeckoInstruction inst);
static void mullwx(UGeckoInstruction _inst); static void mullwx(UGeckoInstruction inst);
static void negx(UGeckoInstruction _inst); static void negx(UGeckoInstruction inst);
static void subfx(UGeckoInstruction _inst); static void subfx(UGeckoInstruction inst);
static void subfcx(UGeckoInstruction _inst); static void subfcx(UGeckoInstruction inst);
static void subfex(UGeckoInstruction _inst); static void subfex(UGeckoInstruction inst);
static void subfmex(UGeckoInstruction _inst); static void subfmex(UGeckoInstruction inst);
static void subfzex(UGeckoInstruction _inst); static void subfzex(UGeckoInstruction inst);
// Load/Store Instructions // Load/Store Instructions
static void lbz(UGeckoInstruction _inst); static void lbz(UGeckoInstruction inst);
static void lbzu(UGeckoInstruction _inst); static void lbzu(UGeckoInstruction inst);
static void lfd(UGeckoInstruction _inst); static void lfd(UGeckoInstruction inst);
static void lfdu(UGeckoInstruction _inst); static void lfdu(UGeckoInstruction inst);
static void lfs(UGeckoInstruction _inst); static void lfs(UGeckoInstruction inst);
static void lfsu(UGeckoInstruction _inst); static void lfsu(UGeckoInstruction inst);
static void lha(UGeckoInstruction _inst); static void lha(UGeckoInstruction inst);
static void lhau(UGeckoInstruction _inst); static void lhau(UGeckoInstruction inst);
static void lhz(UGeckoInstruction _inst); static void lhz(UGeckoInstruction inst);
static void lhzu(UGeckoInstruction _inst); static void lhzu(UGeckoInstruction inst);
static void lmw(UGeckoInstruction _inst); static void lmw(UGeckoInstruction inst);
static void lwz(UGeckoInstruction _inst); static void lwz(UGeckoInstruction inst);
static void lwzu(UGeckoInstruction _inst); static void lwzu(UGeckoInstruction inst);
static void stb(UGeckoInstruction _inst); static void stb(UGeckoInstruction inst);
static void stbu(UGeckoInstruction _inst); static void stbu(UGeckoInstruction inst);
static void stfd(UGeckoInstruction _inst); static void stfd(UGeckoInstruction inst);
static void stfdu(UGeckoInstruction _inst); static void stfdu(UGeckoInstruction inst);
static void stfs(UGeckoInstruction _inst); static void stfs(UGeckoInstruction inst);
static void stfsu(UGeckoInstruction _inst); static void stfsu(UGeckoInstruction inst);
static void sth(UGeckoInstruction _inst); static void sth(UGeckoInstruction inst);
static void sthu(UGeckoInstruction _inst); static void sthu(UGeckoInstruction inst);
static void stmw(UGeckoInstruction _inst); static void stmw(UGeckoInstruction inst);
static void stw(UGeckoInstruction _inst); static void stw(UGeckoInstruction inst);
static void stwu(UGeckoInstruction _inst); static void stwu(UGeckoInstruction inst);
static void dcba(UGeckoInstruction _inst); static void dcba(UGeckoInstruction inst);
static void dcbf(UGeckoInstruction _inst); static void dcbf(UGeckoInstruction inst);
static void dcbi(UGeckoInstruction _inst); static void dcbi(UGeckoInstruction inst);
static void dcbst(UGeckoInstruction _inst); static void dcbst(UGeckoInstruction inst);
static void dcbt(UGeckoInstruction _inst); static void dcbt(UGeckoInstruction inst);
static void dcbtst(UGeckoInstruction _inst); static void dcbtst(UGeckoInstruction inst);
static void dcbz(UGeckoInstruction _inst); static void dcbz(UGeckoInstruction inst);
static void eciwx(UGeckoInstruction _inst); static void eciwx(UGeckoInstruction inst);
static void ecowx(UGeckoInstruction _inst); static void ecowx(UGeckoInstruction inst);
static void eieio(UGeckoInstruction _inst); static void eieio(UGeckoInstruction inst);
static void icbi(UGeckoInstruction _inst); static void icbi(UGeckoInstruction inst);
static void lbzux(UGeckoInstruction _inst); static void lbzux(UGeckoInstruction inst);
static void lbzx(UGeckoInstruction _inst); static void lbzx(UGeckoInstruction inst);
static void lfdux(UGeckoInstruction _inst); static void lfdux(UGeckoInstruction inst);
static void lfdx(UGeckoInstruction _inst); static void lfdx(UGeckoInstruction inst);
static void lfsux(UGeckoInstruction _inst); static void lfsux(UGeckoInstruction inst);
static void lfsx(UGeckoInstruction _inst); static void lfsx(UGeckoInstruction inst);
static void lhaux(UGeckoInstruction _inst); static void lhaux(UGeckoInstruction inst);
static void lhax(UGeckoInstruction _inst); static void lhax(UGeckoInstruction inst);
static void lhbrx(UGeckoInstruction _inst); static void lhbrx(UGeckoInstruction inst);
static void lhzux(UGeckoInstruction _inst); static void lhzux(UGeckoInstruction inst);
static void lhzx(UGeckoInstruction _inst); static void lhzx(UGeckoInstruction inst);
static void lswi(UGeckoInstruction _inst); static void lswi(UGeckoInstruction inst);
static void lswx(UGeckoInstruction _inst); static void lswx(UGeckoInstruction inst);
static void lwarx(UGeckoInstruction _inst); static void lwarx(UGeckoInstruction inst);
static void lwbrx(UGeckoInstruction _inst); static void lwbrx(UGeckoInstruction inst);
static void lwzux(UGeckoInstruction _inst); static void lwzux(UGeckoInstruction inst);
static void lwzx(UGeckoInstruction _inst); static void lwzx(UGeckoInstruction inst);
static void stbux(UGeckoInstruction _inst); static void stbux(UGeckoInstruction inst);
static void stbx(UGeckoInstruction _inst); static void stbx(UGeckoInstruction inst);
static void stfdux(UGeckoInstruction _inst); static void stfdux(UGeckoInstruction inst);
static void stfdx(UGeckoInstruction _inst); static void stfdx(UGeckoInstruction inst);
static void stfiwx(UGeckoInstruction _inst); static void stfiwx(UGeckoInstruction inst);
static void stfsux(UGeckoInstruction _inst); static void stfsux(UGeckoInstruction inst);
static void stfsx(UGeckoInstruction _inst); static void stfsx(UGeckoInstruction inst);
static void sthbrx(UGeckoInstruction _inst); static void sthbrx(UGeckoInstruction inst);
static void sthux(UGeckoInstruction _inst); static void sthux(UGeckoInstruction inst);
static void sthx(UGeckoInstruction _inst); static void sthx(UGeckoInstruction inst);
static void stswi(UGeckoInstruction _inst); static void stswi(UGeckoInstruction inst);
static void stswx(UGeckoInstruction _inst); static void stswx(UGeckoInstruction inst);
static void stwbrx(UGeckoInstruction _inst); static void stwbrx(UGeckoInstruction inst);
static void stwcxd(UGeckoInstruction _inst); static void stwcxd(UGeckoInstruction inst);
static void stwux(UGeckoInstruction _inst); static void stwux(UGeckoInstruction inst);
static void stwx(UGeckoInstruction _inst); static void stwx(UGeckoInstruction inst);
static void tlbie(UGeckoInstruction _inst); static void tlbie(UGeckoInstruction inst);
static void tlbsync(UGeckoInstruction _inst); static void tlbsync(UGeckoInstruction inst);
// Paired Instructions // Paired Instructions
static void psq_l(UGeckoInstruction _inst); static void psq_l(UGeckoInstruction inst);
static void psq_lu(UGeckoInstruction _inst); static void psq_lu(UGeckoInstruction inst);
static void psq_st(UGeckoInstruction _inst); static void psq_st(UGeckoInstruction inst);
static void psq_stu(UGeckoInstruction _inst); static void psq_stu(UGeckoInstruction inst);
static void psq_lx(UGeckoInstruction _inst); static void psq_lx(UGeckoInstruction inst);
static void psq_stx(UGeckoInstruction _inst); static void psq_stx(UGeckoInstruction inst);
static void psq_lux(UGeckoInstruction _inst); static void psq_lux(UGeckoInstruction inst);
static void psq_stux(UGeckoInstruction _inst); static void psq_stux(UGeckoInstruction inst);
static void ps_div(UGeckoInstruction _inst); static void ps_div(UGeckoInstruction inst);
static void ps_sub(UGeckoInstruction _inst); static void ps_sub(UGeckoInstruction inst);
static void ps_add(UGeckoInstruction _inst); static void ps_add(UGeckoInstruction inst);
static void ps_sel(UGeckoInstruction _inst); static void ps_sel(UGeckoInstruction inst);
static void ps_res(UGeckoInstruction _inst); static void ps_res(UGeckoInstruction inst);
static void ps_mul(UGeckoInstruction _inst); static void ps_mul(UGeckoInstruction inst);
static void ps_rsqrte(UGeckoInstruction _inst); static void ps_rsqrte(UGeckoInstruction inst);
static void ps_msub(UGeckoInstruction _inst); static void ps_msub(UGeckoInstruction inst);
static void ps_madd(UGeckoInstruction _inst); static void ps_madd(UGeckoInstruction inst);
static void ps_nmsub(UGeckoInstruction _inst); static void ps_nmsub(UGeckoInstruction inst);
static void ps_nmadd(UGeckoInstruction _inst); static void ps_nmadd(UGeckoInstruction inst);
static void ps_neg(UGeckoInstruction _inst); static void ps_neg(UGeckoInstruction inst);
static void ps_mr(UGeckoInstruction _inst); static void ps_mr(UGeckoInstruction inst);
static void ps_nabs(UGeckoInstruction _inst); static void ps_nabs(UGeckoInstruction inst);
static void ps_abs(UGeckoInstruction _inst); static void ps_abs(UGeckoInstruction inst);
static void ps_sum0(UGeckoInstruction _inst); static void ps_sum0(UGeckoInstruction inst);
static void ps_sum1(UGeckoInstruction _inst); static void ps_sum1(UGeckoInstruction inst);
static void ps_muls0(UGeckoInstruction _inst); static void ps_muls0(UGeckoInstruction inst);
static void ps_muls1(UGeckoInstruction _inst); static void ps_muls1(UGeckoInstruction inst);
static void ps_madds0(UGeckoInstruction _inst); static void ps_madds0(UGeckoInstruction inst);
static void ps_madds1(UGeckoInstruction _inst); static void ps_madds1(UGeckoInstruction inst);
static void ps_cmpu0(UGeckoInstruction _inst); static void ps_cmpu0(UGeckoInstruction inst);
static void ps_cmpo0(UGeckoInstruction _inst); static void ps_cmpo0(UGeckoInstruction inst);
static void ps_cmpu1(UGeckoInstruction _inst); static void ps_cmpu1(UGeckoInstruction inst);
static void ps_cmpo1(UGeckoInstruction _inst); static void ps_cmpo1(UGeckoInstruction inst);
static void ps_merge00(UGeckoInstruction _inst); static void ps_merge00(UGeckoInstruction inst);
static void ps_merge01(UGeckoInstruction _inst); static void ps_merge01(UGeckoInstruction inst);
static void ps_merge10(UGeckoInstruction _inst); static void ps_merge10(UGeckoInstruction inst);
static void ps_merge11(UGeckoInstruction _inst); static void ps_merge11(UGeckoInstruction inst);
static void dcbz_l(UGeckoInstruction _inst); static void dcbz_l(UGeckoInstruction inst);
// System Registers Instructions // System Registers Instructions
static void mcrfs(UGeckoInstruction _inst); static void mcrfs(UGeckoInstruction inst);
static void mffsx(UGeckoInstruction _inst); static void mffsx(UGeckoInstruction inst);
static void mtfsb0x(UGeckoInstruction _inst); static void mtfsb0x(UGeckoInstruction inst);
static void mtfsb1x(UGeckoInstruction _inst); static void mtfsb1x(UGeckoInstruction inst);
static void mtfsfix(UGeckoInstruction _inst); static void mtfsfix(UGeckoInstruction inst);
static void mtfsfx(UGeckoInstruction _inst); static void mtfsfx(UGeckoInstruction inst);
static void mcrxr(UGeckoInstruction _inst); static void mcrxr(UGeckoInstruction inst);
static void mfcr(UGeckoInstruction _inst); static void mfcr(UGeckoInstruction inst);
static void mfmsr(UGeckoInstruction _inst); static void mfmsr(UGeckoInstruction inst);
static void mfsr(UGeckoInstruction _inst); static void mfsr(UGeckoInstruction inst);
static void mfsrin(UGeckoInstruction _inst); static void mfsrin(UGeckoInstruction inst);
static void mtmsr(UGeckoInstruction _inst); static void mtmsr(UGeckoInstruction inst);
static void mtsr(UGeckoInstruction _inst); static void mtsr(UGeckoInstruction inst);
static void mtsrin(UGeckoInstruction _inst); static void mtsrin(UGeckoInstruction inst);
static void mfspr(UGeckoInstruction _inst); static void mfspr(UGeckoInstruction inst);
static void mftb(UGeckoInstruction _inst); static void mftb(UGeckoInstruction inst);
static void mtcrf(UGeckoInstruction _inst); static void mtcrf(UGeckoInstruction inst);
static void mtspr(UGeckoInstruction _inst); static void mtspr(UGeckoInstruction inst);
static void crand(UGeckoInstruction _inst); static void crand(UGeckoInstruction inst);
static void crandc(UGeckoInstruction _inst); static void crandc(UGeckoInstruction inst);
static void creqv(UGeckoInstruction _inst); static void creqv(UGeckoInstruction inst);
static void crnand(UGeckoInstruction _inst); static void crnand(UGeckoInstruction inst);
static void crnor(UGeckoInstruction _inst); static void crnor(UGeckoInstruction inst);
static void cror(UGeckoInstruction _inst); static void cror(UGeckoInstruction inst);
static void crorc(UGeckoInstruction _inst); static void crorc(UGeckoInstruction inst);
static void crxor(UGeckoInstruction _inst); static void crxor(UGeckoInstruction inst);
static void mcrf(UGeckoInstruction _inst); static void mcrf(UGeckoInstruction inst);
static void rfi(UGeckoInstruction _inst); static void rfi(UGeckoInstruction inst);
static void sync(UGeckoInstruction _inst); static void sync(UGeckoInstruction inst);
static void isync(UGeckoInstruction _inst); static void isync(UGeckoInstruction inst);
using Instruction = void (*)(UGeckoInstruction instCode); using Instruction = void (*)(UGeckoInstruction inst);
static std::array<Instruction, 64> m_op_table; static std::array<Instruction, 64> m_op_table;
static std::array<Instruction, 1024> m_op_table4; static std::array<Instruction, 1024> m_op_table4;
static std::array<Instruction, 1024> m_op_table19; static std::array<Instruction, 1024> m_op_table19;
@ -273,25 +273,25 @@ public:
// singleton // singleton
static Interpreter* getInstance(); static Interpreter* getInstance();
static void RunTable4(UGeckoInstruction _instCode); static void RunTable4(UGeckoInstruction inst);
static void RunTable19(UGeckoInstruction _instCode); static void RunTable19(UGeckoInstruction inst);
static void RunTable31(UGeckoInstruction _instCode); static void RunTable31(UGeckoInstruction inst);
static void RunTable59(UGeckoInstruction _instCode); static void RunTable59(UGeckoInstruction inst);
static void RunTable63(UGeckoInstruction _instCode); static void RunTable63(UGeckoInstruction inst);
static u32 Helper_Carry(u32 _uValue1, u32 _uValue2); static u32 Helper_Carry(u32 value1, u32 value2);
private: private:
// flag helper // flag helper
static void Helper_UpdateCR0(u32 _uValue); static void Helper_UpdateCR0(u32 value);
static void Helper_UpdateCR1(); static void Helper_UpdateCR1();
static void Helper_UpdateCRx(int _x, u32 _uValue); static void Helper_UpdateCRx(int x, u32 value);
// address helper // address helper
static u32 Helper_Get_EA(const UGeckoInstruction _inst); static u32 Helper_Get_EA(const UGeckoInstruction inst);
static u32 Helper_Get_EA_U(const UGeckoInstruction _inst); static u32 Helper_Get_EA_U(const UGeckoInstruction inst);
static u32 Helper_Get_EA_X(const UGeckoInstruction _inst); static u32 Helper_Get_EA_X(const UGeckoInstruction inst);
static u32 Helper_Get_EA_UX(const UGeckoInstruction _inst); static u32 Helper_Get_EA_UX(const UGeckoInstruction inst);
// paired helper // paired helper
static void Helper_Dequantize(u32 addr, u32 instI, u32 instRD, u32 instW); static void Helper_Dequantize(u32 addr, u32 instI, u32 instRD, u32 instW);
@ -300,8 +300,8 @@ private:
// other helper // other helper
static u32 Helper_Mask(int mb, int me); static u32 Helper_Mask(int mb, int me);
static void Helper_FloatCompareOrdered(UGeckoInstruction _inst, double a, double b); static void Helper_FloatCompareOrdered(UGeckoInstruction inst, double a, double b);
static void Helper_FloatCompareUnordered(UGeckoInstruction _inst, double a, double b); static void Helper_FloatCompareUnordered(UGeckoInstruction inst, double a, double b);
static bool m_end_block; static bool m_end_block;

View File

@ -10,15 +10,15 @@
#include "Core/HLE/HLE.h" #include "Core/HLE/HLE.h"
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
void Interpreter::bx(UGeckoInstruction _inst) void Interpreter::bx(UGeckoInstruction inst)
{ {
if (_inst.LK) if (inst.LK)
LR = PC + 4; LR = PC + 4;
if (_inst.AA) if (inst.AA)
NPC = SignExt26(_inst.LI << 2); NPC = SignExt26(inst.LI << 2);
else else
NPC = PC + SignExt26(_inst.LI << 2); NPC = PC + SignExt26(inst.LI << 2);
m_end_block = true; m_end_block = true;
@ -29,27 +29,27 @@ void Interpreter::bx(UGeckoInstruction _inst)
} }
// bcx - ugly, straight from PPC manual equations :) // bcx - ugly, straight from PPC manual equations :)
void Interpreter::bcx(UGeckoInstruction _inst) void Interpreter::bcx(UGeckoInstruction inst)
{ {
if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0) if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
CTR--; CTR--;
const bool true_false = ((_inst.BO >> 3) & 1); const bool true_false = ((inst.BO >> 3) & 1);
const bool only_counter_check = ((_inst.BO >> 4) & 1); const bool only_counter_check = ((inst.BO >> 4) & 1);
const bool only_condition_check = ((_inst.BO >> 2) & 1); const bool only_condition_check = ((inst.BO >> 2) & 1);
int ctr_check = ((CTR != 0) ^ (_inst.BO >> 1)) & 1; int ctr_check = ((CTR != 0) ^ (inst.BO >> 1)) & 1;
bool counter = only_condition_check || ctr_check; bool counter = only_condition_check || ctr_check;
bool condition = only_counter_check || (GetCRBit(_inst.BI) == u32(true_false)); bool condition = only_counter_check || (GetCRBit(inst.BI) == u32(true_false));
if (counter && condition) if (counter && condition)
{ {
if (_inst.LK) if (inst.LK)
LR = PC + 4; LR = PC + 4;
if (_inst.AA) if (inst.AA)
NPC = SignExt16(_inst.BD << 2); NPC = SignExt16(inst.BD << 2);
else else
NPC = PC + SignExt16(_inst.BD << 2); NPC = PC + SignExt16(inst.BD << 2);
} }
m_end_block = true; m_end_block = true;
@ -58,7 +58,7 @@ void Interpreter::bcx(UGeckoInstruction _inst)
// lwz r0, XXXX(r13) // lwz r0, XXXX(r13)
// cmpXwi r0,0 // cmpXwi r0,0
// beq -8 // beq -8
if (NPC == PC - 8 && _inst.hex == 0x4182fff8 /* beq */) if (NPC == PC - 8 && inst.hex == 0x4182fff8 /* beq */)
{ {
if (PowerPC::HostRead_U32(PC - 8) >> 16 == 0x800D /* lwz */) if (PowerPC::HostRead_U32(PC - 8) >> 16 == 0x800D /* lwz */)
{ {
@ -73,48 +73,48 @@ void Interpreter::bcx(UGeckoInstruction _inst)
} }
} }
void Interpreter::bcctrx(UGeckoInstruction _inst) void Interpreter::bcctrx(UGeckoInstruction inst)
{ {
_dbg_assert_msg_(POWERPC, _inst.BO_2 & BO_DONT_DECREMENT_FLAG, _dbg_assert_msg_(POWERPC, inst.BO_2 & BO_DONT_DECREMENT_FLAG,
"bcctrx with decrement and test CTR option is invalid!"); "bcctrx with decrement and test CTR option is invalid!");
int condition = ((_inst.BO_2 >> 4) | (GetCRBit(_inst.BI_2) == ((_inst.BO_2 >> 3) & 1))) & 1; int condition = ((inst.BO_2 >> 4) | (GetCRBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
if (condition) if (condition)
{ {
NPC = CTR & (~3); NPC = CTR & (~3);
if (_inst.LK_3) if (inst.LK_3)
LR = PC + 4; LR = PC + 4;
} }
m_end_block = true; m_end_block = true;
} }
void Interpreter::bclrx(UGeckoInstruction _inst) void Interpreter::bclrx(UGeckoInstruction inst)
{ {
if ((_inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0) if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0)
CTR--; CTR--;
int counter = ((_inst.BO_2 >> 2) | ((CTR != 0) ^ (_inst.BO_2 >> 1))) & 1; int counter = ((inst.BO_2 >> 2) | ((CTR != 0) ^ (inst.BO_2 >> 1))) & 1;
int condition = ((_inst.BO_2 >> 4) | (GetCRBit(_inst.BI_2) == ((_inst.BO_2 >> 3) & 1))) & 1; int condition = ((inst.BO_2 >> 4) | (GetCRBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
if (counter & condition) if (counter & condition)
{ {
NPC = LR & (~3); NPC = LR & (~3);
if (_inst.LK_3) if (inst.LK_3)
LR = PC + 4; LR = PC + 4;
} }
m_end_block = true; m_end_block = true;
} }
void Interpreter::HLEFunction(UGeckoInstruction _inst) void Interpreter::HLEFunction(UGeckoInstruction inst)
{ {
m_end_block = true; m_end_block = true;
HLE::Execute(PC, _inst.hex); HLE::Execute(PC, inst.hex);
} }
void Interpreter::rfi(UGeckoInstruction _inst) void Interpreter::rfi(UGeckoInstruction inst)
{ {
// Restore saved bits from SRR1 to MSR. // Restore saved bits from SRR1 to MSR.
// Gecko/Broadway can save more bits than explicitly defined in ppc spec // Gecko/Broadway can save more bits than explicitly defined in ppc spec
@ -135,7 +135,7 @@ void Interpreter::rfi(UGeckoInstruction _inst)
// sc isn't really used for anything important in GameCube games (just for a write barrier) so we // sc isn't really used for anything important in GameCube games (just for a write barrier) so we
// really don't have to emulate it. // really don't have to emulate it.
// We do it anyway, though :P // We do it anyway, though :P
void Interpreter::sc(UGeckoInstruction _inst) void Interpreter::sc(UGeckoInstruction inst)
{ {
PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL; PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL;
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();

View File

@ -49,10 +49,10 @@ inline void UpdateFPSCR()
FPSCR.FEX = 0; // we assume that "?E" bits are always 0 FPSCR.FEX = 0; // we assume that "?E" bits are always 0
} }
inline double ForceSingle(double _x) inline double ForceSingle(double value)
{ {
// convert to float... // convert to float...
float x = (float)_x; float x = (float)value;
if (!cpu_info.bFlushToZero && FPSCR.NI) if (!cpu_info.bFlushToZero && FPSCR.NI)
{ {
x = MathUtil::FlushToZero(x); x = MathUtil::FlushToZero(x);
@ -247,14 +247,14 @@ inline u32 ConvertToSingleFTZ(u64 x)
} }
} }
inline u64 ConvertToDouble(u32 _x) inline u64 ConvertToDouble(u32 value)
{ {
// This is a little-endian re-implementation of the algorithm described in // This is a little-endian re-implementation of the algorithm described in
// the PowerPC Programming Environments Manual for loading single // the PowerPC Programming Environments Manual for loading single
// precision floating point numbers. // precision floating point numbers.
// See page 566 of http://www.freescale.com/files/product/doc/MPCFPE32B.pdf // See page 566 of http://www.freescale.com/files/product/doc/MPCFPE32B.pdf
u64 x = _x; u64 x = value;
u64 exp = (x >> 23) & 0xff; u64 exp = (x >> 23) & 0xff;
u64 frac = x & 0x007fffff; u64 frac = x & 0x007fffff;

View File

@ -20,7 +20,7 @@ void Interpreter::Helper_UpdateCR1()
SetCRField(1, (FPSCR.FX << 3) | (FPSCR.FEX << 2) | (FPSCR.VX << 1) | FPSCR.OX); SetCRField(1, (FPSCR.FX << 3) | (FPSCR.FEX << 2) | (FPSCR.VX << 1) | FPSCR.OX);
} }
void Interpreter::Helper_FloatCompareOrdered(UGeckoInstruction _inst, double fa, double fb) void Interpreter::Helper_FloatCompareOrdered(UGeckoInstruction inst, double fa, double fb)
{ {
int compareResult; int compareResult;
@ -56,10 +56,10 @@ void Interpreter::Helper_FloatCompareOrdered(UGeckoInstruction _inst, double fa,
// Clear and set the FPCC bits accordingly. // Clear and set the FPCC bits accordingly.
FPSCR.FPRF = (FPSCR.FPRF & ~0xF) | compareResult; FPSCR.FPRF = (FPSCR.FPRF & ~0xF) | compareResult;
SetCRField(_inst.CRFD, compareResult); SetCRField(inst.CRFD, compareResult);
} }
void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction _inst, double fa, double fb) void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction inst, double fa, double fb)
{ {
int compareResult; int compareResult;
@ -88,23 +88,23 @@ void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction _inst, double f
// Clear and set the FPCC bits accordingly. // Clear and set the FPCC bits accordingly.
FPSCR.FPRF = (FPSCR.FPRF & ~0xF) | compareResult; FPSCR.FPRF = (FPSCR.FPRF & ~0xF) | compareResult;
SetCRField(_inst.CRFD, compareResult); SetCRField(inst.CRFD, compareResult);
} }
void Interpreter::fcmpo(UGeckoInstruction _inst) void Interpreter::fcmpo(UGeckoInstruction inst)
{ {
Helper_FloatCompareOrdered(_inst, rPS0(_inst.FA), rPS0(_inst.FB)); Helper_FloatCompareOrdered(inst, rPS0(inst.FA), rPS0(inst.FB));
} }
void Interpreter::fcmpu(UGeckoInstruction _inst) void Interpreter::fcmpu(UGeckoInstruction inst)
{ {
Helper_FloatCompareUnordered(_inst, rPS0(_inst.FA), rPS0(_inst.FB)); Helper_FloatCompareUnordered(inst, rPS0(inst.FA), rPS0(inst.FB));
} }
// Apply current rounding mode // Apply current rounding mode
void Interpreter::fctiwx(UGeckoInstruction _inst) void Interpreter::fctiwx(UGeckoInstruction inst)
{ {
const double b = rPS0(_inst.FB); const double b = rPS0(inst.FB);
u32 value; u32 value;
if (b > (double)0x7fffffff) if (b > (double)0x7fffffff)
@ -171,17 +171,17 @@ void Interpreter::fctiwx(UGeckoInstruction _inst)
// based on HW tests // based on HW tests
// FPRF is not affected // FPRF is not affected
riPS0(_inst.FD) = 0xfff8000000000000ull | value; riPS0(inst.FD) = 0xfff8000000000000ull | value;
if (value == 0 && std::signbit(b)) if (value == 0 && std::signbit(b))
riPS0(_inst.FD) |= 0x100000000ull; riPS0(inst.FD) |= 0x100000000ull;
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
// Always round toward zero // Always round toward zero
void Interpreter::fctiwzx(UGeckoInstruction _inst) void Interpreter::fctiwzx(UGeckoInstruction inst)
{ {
const double b = rPS0(_inst.FB); const double b = rPS0(inst.FB);
u32 value; u32 value;
if (b > (double)0x7fffffff) if (b > (double)0x7fffffff)
@ -217,55 +217,55 @@ void Interpreter::fctiwzx(UGeckoInstruction _inst)
// based on HW tests // based on HW tests
// FPRF is not affected // FPRF is not affected
riPS0(_inst.FD) = 0xfff8000000000000ull | value; riPS0(inst.FD) = 0xfff8000000000000ull | value;
if (value == 0 && std::signbit(b)) if (value == 0 && std::signbit(b))
riPS0(_inst.FD) |= 0x100000000ull; riPS0(inst.FD) |= 0x100000000ull;
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fmrx(UGeckoInstruction _inst) void Interpreter::fmrx(UGeckoInstruction inst)
{ {
riPS0(_inst.FD) = riPS0(_inst.FB); riPS0(inst.FD) = riPS0(inst.FB);
// This is a binary instruction. Does not alter FPSCR // This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fabsx(UGeckoInstruction _inst) void Interpreter::fabsx(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = fabs(rPS0(_inst.FB)); rPS0(inst.FD) = fabs(rPS0(inst.FB));
// This is a binary instruction. Does not alter FPSCR // This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fnabsx(UGeckoInstruction _inst) void Interpreter::fnabsx(UGeckoInstruction inst)
{ {
riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63); riPS0(inst.FD) = riPS0(inst.FB) | (1ULL << 63);
// This is a binary instruction. Does not alter FPSCR // This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fnegx(UGeckoInstruction _inst) void Interpreter::fnegx(UGeckoInstruction inst)
{ {
riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63); riPS0(inst.FD) = riPS0(inst.FB) ^ (1ULL << 63);
// This is a binary instruction. Does not alter FPSCR // This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fselx(UGeckoInstruction _inst) void Interpreter::fselx(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = (rPS0(_inst.FA) >= -0.0) ? rPS0(_inst.FC) : rPS0(_inst.FB); rPS0(inst.FD) = (rPS0(inst.FA) >= -0.0) ? rPS0(inst.FC) : rPS0(inst.FB);
// This is a binary instruction. Does not alter FPSCR // This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
@ -285,108 +285,108 @@ void Interpreter::frspx(UGeckoInstruction inst) // round to single
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fmulx(UGeckoInstruction _inst) void Interpreter::fmulx(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = ForceDouble(NI_mul(rPS0(_inst.FA), rPS0(_inst.FC))); rPS0(inst.FD) = ForceDouble(NI_mul(rPS0(inst.FA), rPS0(inst.FC)));
FPSCR.FI = 0; // are these flags important? FPSCR.FI = 0; // are these flags important?
FPSCR.FR = 0; FPSCR.FR = 0;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fmulsx(UGeckoInstruction _inst) void Interpreter::fmulsx(UGeckoInstruction inst)
{ {
double c_value = Force25Bit(rPS0(_inst.FC)); double c_value = Force25Bit(rPS0(inst.FC));
double d_value = NI_mul(rPS0(_inst.FA), c_value); double d_value = NI_mul(rPS0(inst.FA), c_value);
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(d_value); rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(d_value);
// FPSCR.FI = d_value != rPS0(_inst.FD); // FPSCR.FI = d_value != rPS0(_inst.FD);
FPSCR.FI = 0; FPSCR.FI = 0;
FPSCR.FR = 0; FPSCR.FR = 0;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fmaddx(UGeckoInstruction _inst) void Interpreter::fmaddx(UGeckoInstruction inst)
{ {
double result = ForceDouble(NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); double result = ForceDouble(NI_madd(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB)));
rPS0(_inst.FD) = result; rPS0(inst.FD) = result;
UpdateFPRF(result); UpdateFPRF(result);
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fmaddsx(UGeckoInstruction _inst) void Interpreter::fmaddsx(UGeckoInstruction inst)
{ {
double c_value = Force25Bit(rPS0(_inst.FC)); double c_value = Force25Bit(rPS0(inst.FC));
double d_value = NI_madd(rPS0(_inst.FA), c_value, rPS0(_inst.FB)); double d_value = NI_madd(rPS0(inst.FA), c_value, rPS0(inst.FB));
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(d_value); rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(d_value);
FPSCR.FI = d_value != rPS0(_inst.FD); FPSCR.FI = d_value != rPS0(inst.FD);
FPSCR.FR = 0; FPSCR.FR = 0;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::faddx(UGeckoInstruction _inst) void Interpreter::faddx(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = ForceDouble(NI_add(rPS0(_inst.FA), rPS0(_inst.FB))); rPS0(inst.FD) = ForceDouble(NI_add(rPS0(inst.FA), rPS0(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::faddsx(UGeckoInstruction _inst) void Interpreter::faddsx(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB))); rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(NI_add(rPS0(inst.FA), rPS0(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fdivx(UGeckoInstruction _inst) void Interpreter::fdivx(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = ForceDouble(NI_div(rPS0(_inst.FA), rPS0(_inst.FB))); rPS0(inst.FD) = ForceDouble(NI_div(rPS0(inst.FA), rPS0(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
// FR,FI,OX,UX??? // FR,FI,OX,UX???
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fdivsx(UGeckoInstruction _inst) void Interpreter::fdivsx(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_div(rPS0(_inst.FA), rPS0(_inst.FB))); rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(NI_div(rPS0(inst.FA), rPS0(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
// Single precision only. // Single precision only.
void Interpreter::fresx(UGeckoInstruction _inst) void Interpreter::fresx(UGeckoInstruction inst)
{ {
double b = rPS0(_inst.FB); double b = rPS0(inst.FB);
rPS0(_inst.FD) = rPS1(_inst.FD) = ApproximateReciprocal(b); rPS0(inst.FD) = rPS1(inst.FD) = ApproximateReciprocal(b);
if (b == 0.0) if (b == 0.0)
{ {
SetFPException(FPSCR_ZX); SetFPException(FPSCR_ZX);
} }
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::frsqrtex(UGeckoInstruction _inst) void Interpreter::frsqrtex(UGeckoInstruction inst)
{ {
double b = rPS0(_inst.FB); double b = rPS0(inst.FB);
if (b < 0.0) if (b < 0.0)
{ {
@ -397,10 +397,10 @@ void Interpreter::frsqrtex(UGeckoInstruction _inst)
SetFPException(FPSCR_ZX); SetFPException(FPSCR_ZX);
} }
rPS0(_inst.FD) = ApproximateReciprocalSquareRoot(b); rPS0(inst.FD) = ApproximateReciprocalSquareRoot(b);
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
@ -413,72 +413,72 @@ void Interpreter::fmsubx(UGeckoInstruction _inst)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fmsubsx(UGeckoInstruction _inst) void Interpreter::fmsubsx(UGeckoInstruction inst)
{ {
double c_value = Force25Bit(rPS0(_inst.FC)); double c_value = Force25Bit(rPS0(inst.FC));
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_msub(rPS0(_inst.FA), c_value, rPS0(_inst.FB))); rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(NI_msub(rPS0(inst.FA), c_value, rPS0(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fnmaddx(UGeckoInstruction _inst) void Interpreter::fnmaddx(UGeckoInstruction inst)
{ {
double result = ForceDouble(NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); double result = ForceDouble(NI_madd(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB)));
rPS0(_inst.FD) = std::isnan(result) ? result : -result; rPS0(inst.FD) = std::isnan(result) ? result : -result;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fnmaddsx(UGeckoInstruction _inst) void Interpreter::fnmaddsx(UGeckoInstruction inst)
{ {
double c_value = Force25Bit(rPS0(_inst.FC)); double c_value = Force25Bit(rPS0(inst.FC));
double result = ForceSingle(NI_madd(rPS0(_inst.FA), c_value, rPS0(_inst.FB))); double result = ForceSingle(NI_madd(rPS0(inst.FA), c_value, rPS0(inst.FB)));
rPS0(_inst.FD) = rPS1(_inst.FD) = std::isnan(result) ? result : -result; rPS0(inst.FD) = rPS1(inst.FD) = std::isnan(result) ? result : -result;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fnmsubx(UGeckoInstruction _inst) void Interpreter::fnmsubx(UGeckoInstruction inst)
{ {
double result = ForceDouble(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); double result = ForceDouble(NI_msub(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB)));
rPS0(_inst.FD) = std::isnan(result) ? result : -result; rPS0(inst.FD) = std::isnan(result) ? result : -result;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fnmsubsx(UGeckoInstruction _inst) void Interpreter::fnmsubsx(UGeckoInstruction inst)
{ {
double c_value = Force25Bit(rPS0(_inst.FC)); double c_value = Force25Bit(rPS0(inst.FC));
double result = ForceSingle(NI_msub(rPS0(_inst.FA), c_value, rPS0(_inst.FB))); double result = ForceSingle(NI_msub(rPS0(inst.FA), c_value, rPS0(inst.FB)));
rPS0(_inst.FD) = rPS1(_inst.FD) = std::isnan(result) ? result : -result; rPS0(inst.FD) = rPS1(inst.FD) = std::isnan(result) ? result : -result;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fsubx(UGeckoInstruction _inst) void Interpreter::fsubx(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = ForceDouble(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB))); rPS0(inst.FD) = ForceDouble(NI_sub(rPS0(inst.FA), rPS0(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::fsubsx(UGeckoInstruction _inst) void Interpreter::fsubsx(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB))); rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(NI_sub(rPS0(inst.FA), rPS0(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }

View File

@ -23,9 +23,9 @@ void Interpreter::Helper_UpdateCRx(int idx, u32 value)
PowerPC::ppcState.cr_val[idx] = cr_val; PowerPC::ppcState.cr_val[idx] = cr_val;
} }
u32 Interpreter::Helper_Carry(u32 _uValue1, u32 _uValue2) u32 Interpreter::Helper_Carry(u32 value1, u32 value2)
{ {
return _uValue2 > (~_uValue1); return value2 > (~value1);
} }
u32 Interpreter::Helper_Mask(int mb, int me) u32 Interpreter::Helper_Mask(int mb, int me)
@ -43,58 +43,58 @@ u32 Interpreter::Helper_Mask(int mb, int me)
return mask; return mask;
} }
void Interpreter::addi(UGeckoInstruction _inst) void Interpreter::addi(UGeckoInstruction inst)
{ {
if (_inst.RA) if (inst.RA)
rGPR[_inst.RD] = rGPR[_inst.RA] + _inst.SIMM_16; rGPR[inst.RD] = rGPR[inst.RA] + inst.SIMM_16;
else else
rGPR[_inst.RD] = _inst.SIMM_16; rGPR[inst.RD] = inst.SIMM_16;
} }
void Interpreter::addic(UGeckoInstruction _inst) void Interpreter::addic(UGeckoInstruction inst)
{ {
u32 a = rGPR[_inst.RA]; u32 a = rGPR[inst.RA];
u32 imm = (u32)(s32)_inst.SIMM_16; u32 imm = (u32)(s32)inst.SIMM_16;
// TODO(ector): verify this thing // TODO(ector): verify this thing
rGPR[_inst.RD] = a + imm; rGPR[inst.RD] = a + imm;
SetCarry(Helper_Carry(a, imm)); SetCarry(Helper_Carry(a, imm));
} }
void Interpreter::addic_rc(UGeckoInstruction _inst) void Interpreter::addic_rc(UGeckoInstruction inst)
{ {
addic(_inst); addic(inst);
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::addis(UGeckoInstruction _inst) void Interpreter::addis(UGeckoInstruction inst)
{ {
if (_inst.RA) if (inst.RA)
rGPR[_inst.RD] = rGPR[_inst.RA] + (_inst.SIMM_16 << 16); rGPR[inst.RD] = rGPR[inst.RA] + (inst.SIMM_16 << 16);
else else
rGPR[_inst.RD] = (_inst.SIMM_16 << 16); rGPR[inst.RD] = (inst.SIMM_16 << 16);
} }
void Interpreter::andi_rc(UGeckoInstruction _inst) void Interpreter::andi_rc(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = rGPR[_inst.RS] & _inst.UIMM; rGPR[inst.RA] = rGPR[inst.RS] & inst.UIMM;
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::andis_rc(UGeckoInstruction _inst) void Interpreter::andis_rc(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = rGPR[_inst.RS] & ((u32)_inst.UIMM << 16); rGPR[inst.RA] = rGPR[inst.RS] & ((u32)inst.UIMM << 16);
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::cmpi(UGeckoInstruction _inst) void Interpreter::cmpi(UGeckoInstruction inst)
{ {
Helper_UpdateCRx(_inst.CRFD, rGPR[_inst.RA] - _inst.SIMM_16); Helper_UpdateCRx(inst.CRFD, rGPR[inst.RA] - inst.SIMM_16);
} }
void Interpreter::cmpli(UGeckoInstruction _inst) void Interpreter::cmpli(UGeckoInstruction inst)
{ {
u32 a = rGPR[_inst.RA]; u32 a = rGPR[inst.RA];
u32 b = _inst.UIMM; u32 b = inst.UIMM;
int f; int f;
if (a < b) if (a < b)
@ -107,28 +107,28 @@ void Interpreter::cmpli(UGeckoInstruction _inst)
if (GetXER_SO()) if (GetXER_SO())
f |= 0x1; f |= 0x1;
SetCRField(_inst.CRFD, f); SetCRField(inst.CRFD, f);
} }
void Interpreter::mulli(UGeckoInstruction _inst) void Interpreter::mulli(UGeckoInstruction inst)
{ {
rGPR[_inst.RD] = (s32)rGPR[_inst.RA] * _inst.SIMM_16; rGPR[inst.RD] = (s32)rGPR[inst.RA] * inst.SIMM_16;
} }
void Interpreter::ori(UGeckoInstruction _inst) void Interpreter::ori(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = rGPR[_inst.RS] | _inst.UIMM; rGPR[inst.RA] = rGPR[inst.RS] | inst.UIMM;
} }
void Interpreter::oris(UGeckoInstruction _inst) void Interpreter::oris(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = rGPR[_inst.RS] | (_inst.UIMM << 16); rGPR[inst.RA] = rGPR[inst.RS] | (inst.UIMM << 16);
} }
void Interpreter::subfic(UGeckoInstruction _inst) void Interpreter::subfic(UGeckoInstruction inst)
{ {
/* u32 rra = ~rGPR[_inst.RA]; /* u32 rra = ~rGPR[inst.RA];
s32 immediate = (s16)_inst.SIMM_16 + 1; s32 immediate = (s16)inst.SIMM_16 + 1;
// #define CALC_XER_CA(X,Y) (((X) + (Y) < X) ? SET_XER_CA : CLEAR_XER_CA) // #define CALC_XER_CA(X,Y) (((X) + (Y) < X) ? SET_XER_CA : CLEAR_XER_CA)
if ((rra + immediate) < rra) if ((rra + immediate) < rra)
@ -136,19 +136,19 @@ void Interpreter::subfic(UGeckoInstruction _inst)
else else
SetCarry(0); SetCarry(0);
rGPR[_inst.RD] = rra - immediate; rGPR[inst.RD] = rra - immediate;
*/ */
s32 immediate = _inst.SIMM_16; s32 immediate = inst.SIMM_16;
rGPR[_inst.RD] = immediate - (int)rGPR[_inst.RA]; rGPR[inst.RD] = immediate - (int)rGPR[inst.RA];
SetCarry((rGPR[_inst.RA] == 0) || (Helper_Carry(0 - rGPR[_inst.RA], immediate))); SetCarry((rGPR[inst.RA] == 0) || (Helper_Carry(0 - rGPR[inst.RA], immediate)));
} }
void Interpreter::twi(UGeckoInstruction _inst) void Interpreter::twi(UGeckoInstruction inst)
{ {
s32 a = rGPR[_inst.RA]; s32 a = rGPR[inst.RA];
s32 b = _inst.SIMM_16; s32 b = inst.SIMM_16;
s32 TO = _inst.TO; s32 TO = inst.TO;
DEBUG_LOG(POWERPC, "twi rA %x SIMM %x TO %0x", a, b, TO); DEBUG_LOG(POWERPC, "twi rA %x SIMM %x TO %0x", a, b, TO);
@ -161,63 +161,63 @@ void Interpreter::twi(UGeckoInstruction _inst)
} }
} }
void Interpreter::xori(UGeckoInstruction _inst) void Interpreter::xori(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = rGPR[_inst.RS] ^ _inst.UIMM; rGPR[inst.RA] = rGPR[inst.RS] ^ inst.UIMM;
} }
void Interpreter::xoris(UGeckoInstruction _inst) void Interpreter::xoris(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = rGPR[_inst.RS] ^ (_inst.UIMM << 16); rGPR[inst.RA] = rGPR[inst.RS] ^ (inst.UIMM << 16);
} }
void Interpreter::rlwimix(UGeckoInstruction _inst) void Interpreter::rlwimix(UGeckoInstruction inst)
{ {
u32 mask = Helper_Mask(_inst.MB, _inst.ME); u32 mask = Helper_Mask(inst.MB, inst.ME);
rGPR[_inst.RA] = (rGPR[_inst.RA] & ~mask) | (_rotl(rGPR[_inst.RS], _inst.SH) & mask); rGPR[inst.RA] = (rGPR[inst.RA] & ~mask) | (_rotl(rGPR[inst.RS], inst.SH) & mask);
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::rlwinmx(UGeckoInstruction _inst) void Interpreter::rlwinmx(UGeckoInstruction inst)
{ {
u32 mask = Helper_Mask(_inst.MB, _inst.ME); u32 mask = Helper_Mask(inst.MB, inst.ME);
rGPR[_inst.RA] = _rotl(rGPR[_inst.RS], _inst.SH) & mask; rGPR[inst.RA] = _rotl(rGPR[inst.RS], inst.SH) & mask;
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::rlwnmx(UGeckoInstruction _inst) void Interpreter::rlwnmx(UGeckoInstruction inst)
{ {
u32 mask = Helper_Mask(_inst.MB, _inst.ME); u32 mask = Helper_Mask(inst.MB, inst.ME);
rGPR[_inst.RA] = _rotl(rGPR[_inst.RS], rGPR[_inst.RB] & 0x1F) & mask; rGPR[inst.RA] = _rotl(rGPR[inst.RS], rGPR[inst.RB] & 0x1F) & mask;
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::andx(UGeckoInstruction _inst) void Interpreter::andx(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = rGPR[_inst.RS] & rGPR[_inst.RB]; rGPR[inst.RA] = rGPR[inst.RS] & rGPR[inst.RB];
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::andcx(UGeckoInstruction _inst) void Interpreter::andcx(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = rGPR[_inst.RS] & ~rGPR[_inst.RB]; rGPR[inst.RA] = rGPR[inst.RS] & ~rGPR[inst.RB];
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::cmp(UGeckoInstruction _inst) void Interpreter::cmp(UGeckoInstruction inst)
{ {
s32 a = (s32)rGPR[_inst.RA]; s32 a = (s32)rGPR[inst.RA];
s32 b = (s32)rGPR[_inst.RB]; s32 b = (s32)rGPR[inst.RB];
int fTemp; int fTemp;
if (a < b) if (a < b)
@ -230,13 +230,13 @@ void Interpreter::cmp(UGeckoInstruction _inst)
if (GetXER_SO()) if (GetXER_SO())
fTemp |= 0x1; fTemp |= 0x1;
SetCRField(_inst.CRFD, fTemp); SetCRField(inst.CRFD, fTemp);
} }
void Interpreter::cmpl(UGeckoInstruction _inst) void Interpreter::cmpl(UGeckoInstruction inst)
{ {
u32 a = rGPR[_inst.RA]; u32 a = rGPR[inst.RA];
u32 b = rGPR[_inst.RB]; u32 b = rGPR[inst.RB];
u32 fTemp; u32 fTemp;
if (a < b) if (a < b)
@ -249,12 +249,12 @@ void Interpreter::cmpl(UGeckoInstruction _inst)
if (GetXER_SO()) if (GetXER_SO())
fTemp |= 0x1; fTemp |= 0x1;
SetCRField(_inst.CRFD, fTemp); SetCRField(inst.CRFD, fTemp);
} }
void Interpreter::cntlzwx(UGeckoInstruction _inst) void Interpreter::cntlzwx(UGeckoInstruction inst)
{ {
u32 val = rGPR[_inst.RS]; u32 val = rGPR[inst.RS];
u32 mask = 0x80000000; u32 mask = 0x80000000;
int i = 0; int i = 0;
@ -264,34 +264,34 @@ void Interpreter::cntlzwx(UGeckoInstruction _inst)
break; break;
} }
rGPR[_inst.RA] = i; rGPR[inst.RA] = i;
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::eqvx(UGeckoInstruction _inst) void Interpreter::eqvx(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = ~(rGPR[_inst.RS] ^ rGPR[_inst.RB]); rGPR[inst.RA] = ~(rGPR[inst.RS] ^ rGPR[inst.RB]);
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::extsbx(UGeckoInstruction _inst) void Interpreter::extsbx(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = (u32)(s32)(s8)rGPR[_inst.RS]; rGPR[inst.RA] = (u32)(s32)(s8)rGPR[inst.RS];
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::extshx(UGeckoInstruction _inst) void Interpreter::extshx(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = (u32)(s32)(s16)rGPR[_inst.RS]; rGPR[inst.RA] = (u32)(s32)(s16)rGPR[inst.RS];
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::nandx(UGeckoInstruction _inst) void Interpreter::nandx(UGeckoInstruction _inst)
@ -302,53 +302,53 @@ void Interpreter::nandx(UGeckoInstruction _inst)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[_inst.RA]);
} }
void Interpreter::norx(UGeckoInstruction _inst) void Interpreter::norx(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = ~(rGPR[_inst.RS] | rGPR[_inst.RB]); rGPR[inst.RA] = ~(rGPR[inst.RS] | rGPR[inst.RB]);
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::orx(UGeckoInstruction _inst) void Interpreter::orx(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = rGPR[_inst.RS] | rGPR[_inst.RB]; rGPR[inst.RA] = rGPR[inst.RS] | rGPR[inst.RB];
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::orcx(UGeckoInstruction _inst) void Interpreter::orcx(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = rGPR[_inst.RS] | (~rGPR[_inst.RB]); rGPR[inst.RA] = rGPR[inst.RS] | (~rGPR[inst.RB]);
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::slwx(UGeckoInstruction _inst) void Interpreter::slwx(UGeckoInstruction inst)
{ {
u32 amount = rGPR[_inst.RB]; u32 amount = rGPR[inst.RB];
rGPR[_inst.RA] = (amount & 0x20) ? 0 : rGPR[_inst.RS] << (amount & 0x1f); rGPR[inst.RA] = (amount & 0x20) ? 0 : rGPR[inst.RS] << (amount & 0x1f);
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::srawx(UGeckoInstruction _inst) void Interpreter::srawx(UGeckoInstruction inst)
{ {
int rb = rGPR[_inst.RB]; int rb = rGPR[inst.RB];
if (rb & 0x20) if (rb & 0x20)
{ {
if (rGPR[_inst.RS] & 0x80000000) if (rGPR[inst.RS] & 0x80000000)
{ {
rGPR[_inst.RA] = 0xFFFFFFFF; rGPR[inst.RA] = 0xFFFFFFFF;
SetCarry(1); SetCarry(1);
} }
else else
{ {
rGPR[_inst.RA] = 0x00000000; rGPR[inst.RA] = 0x00000000;
SetCarry(0); SetCarry(0);
} }
} }
@ -357,13 +357,13 @@ void Interpreter::srawx(UGeckoInstruction _inst)
int amount = rb & 0x1f; int amount = rb & 0x1f;
if (amount == 0) if (amount == 0)
{ {
rGPR[_inst.RA] = rGPR[_inst.RS]; rGPR[inst.RA] = rGPR[inst.RS];
SetCarry(0); SetCarry(0);
} }
else else
{ {
s32 rrs = rGPR[_inst.RS]; s32 rrs = rGPR[inst.RS];
rGPR[_inst.RA] = rrs >> amount; rGPR[inst.RA] = rrs >> amount;
if ((rrs < 0) && (rrs << (32 - amount))) if ((rrs < 0) && (rrs << (32 - amount)))
SetCarry(1); SetCarry(1);
@ -372,18 +372,18 @@ void Interpreter::srawx(UGeckoInstruction _inst)
} }
} }
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::srawix(UGeckoInstruction _inst) void Interpreter::srawix(UGeckoInstruction inst)
{ {
int amount = _inst.SH; int amount = inst.SH;
if (amount != 0) if (amount != 0)
{ {
s32 rrs = rGPR[_inst.RS]; s32 rrs = rGPR[inst.RS];
rGPR[_inst.RA] = rrs >> amount; rGPR[inst.RA] = rrs >> amount;
if ((rrs < 0) && (rrs << (32 - amount))) if ((rrs < 0) && (rrs << (32 - amount)))
SetCarry(1); SetCarry(1);
@ -393,27 +393,27 @@ void Interpreter::srawix(UGeckoInstruction _inst)
else else
{ {
SetCarry(0); SetCarry(0);
rGPR[_inst.RA] = rGPR[_inst.RS]; rGPR[inst.RA] = rGPR[inst.RS];
} }
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::srwx(UGeckoInstruction _inst) void Interpreter::srwx(UGeckoInstruction inst)
{ {
u32 amount = rGPR[_inst.RB]; u32 amount = rGPR[inst.RB];
rGPR[_inst.RA] = (amount & 0x20) ? 0 : (rGPR[_inst.RS] >> (amount & 0x1f)); rGPR[inst.RA] = (amount & 0x20) ? 0 : (rGPR[inst.RS] >> (amount & 0x1f));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::tw(UGeckoInstruction _inst) void Interpreter::tw(UGeckoInstruction inst)
{ {
s32 a = rGPR[_inst.RA]; s32 a = rGPR[inst.RA];
s32 b = rGPR[_inst.RB]; s32 b = rGPR[inst.RB];
s32 TO = _inst.TO; s32 TO = inst.TO;
DEBUG_LOG(POWERPC, "tw rA %0x rB %0x TO %0x", a, b, TO); DEBUG_LOG(POWERPC, "tw rA %0x rB %0x TO %0x", a, b, TO);
@ -426,250 +426,252 @@ void Interpreter::tw(UGeckoInstruction _inst)
} }
} }
void Interpreter::xorx(UGeckoInstruction _inst) void Interpreter::xorx(UGeckoInstruction inst)
{ {
rGPR[_inst.RA] = rGPR[_inst.RS] ^ rGPR[_inst.RB]; rGPR[inst.RA] = rGPR[inst.RS] ^ rGPR[inst.RB];
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RA]); Helper_UpdateCR0(rGPR[inst.RA]);
} }
void Interpreter::addx(UGeckoInstruction _inst) void Interpreter::addx(UGeckoInstruction inst)
{ {
rGPR[_inst.RD] = rGPR[_inst.RA] + rGPR[_inst.RB]; rGPR[inst.RD] = rGPR[inst.RA] + rGPR[inst.RB];
if (_inst.OE) if (inst.OE)
PanicAlert("OE: addx"); PanicAlert("OE: addx");
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::addcx(UGeckoInstruction _inst) void Interpreter::addcx(UGeckoInstruction inst)
{ {
u32 a = rGPR[_inst.RA]; u32 a = rGPR[inst.RA];
u32 b = rGPR[_inst.RB]; u32 b = rGPR[inst.RB];
rGPR[_inst.RD] = a + b; rGPR[inst.RD] = a + b;
SetCarry(Helper_Carry(a, b)); SetCarry(Helper_Carry(a, b));
if (_inst.OE) if (inst.OE)
PanicAlert("OE: addcx"); PanicAlert("OE: addcx");
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::addex(UGeckoInstruction _inst) void Interpreter::addex(UGeckoInstruction inst)
{ {
int carry = GetCarry(); int carry = GetCarry();
int a = rGPR[_inst.RA]; int a = rGPR[inst.RA];
int b = rGPR[_inst.RB]; int b = rGPR[inst.RB];
rGPR[_inst.RD] = a + b + carry; rGPR[inst.RD] = a + b + carry;
SetCarry(Helper_Carry(a, b) || (carry != 0 && Helper_Carry(a + b, carry))); SetCarry(Helper_Carry(a, b) || (carry != 0 && Helper_Carry(a + b, carry)));
if (_inst.OE) if (inst.OE)
PanicAlert("OE: addex"); PanicAlert("OE: addex");
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::addmex(UGeckoInstruction _inst) void Interpreter::addmex(UGeckoInstruction inst)
{ {
int carry = GetCarry(); int carry = GetCarry();
int a = rGPR[_inst.RA]; int a = rGPR[inst.RA];
rGPR[_inst.RD] = a + carry - 1; rGPR[inst.RD] = a + carry - 1;
SetCarry(Helper_Carry(a, carry - 1)); SetCarry(Helper_Carry(a, carry - 1));
if (_inst.OE) if (inst.OE)
PanicAlert("OE: addmex"); PanicAlert("OE: addmex");
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::addzex(UGeckoInstruction _inst) void Interpreter::addzex(UGeckoInstruction inst)
{ {
int carry = GetCarry(); int carry = GetCarry();
int a = rGPR[_inst.RA]; int a = rGPR[inst.RA];
rGPR[_inst.RD] = a + carry; rGPR[inst.RD] = a + carry;
SetCarry(Helper_Carry(a, carry)); SetCarry(Helper_Carry(a, carry));
if (_inst.OE) if (inst.OE)
PanicAlert("OE: addzex"); PanicAlert("OE: addzex");
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::divwx(UGeckoInstruction _inst) void Interpreter::divwx(UGeckoInstruction inst)
{ {
s32 a = rGPR[_inst.RA]; s32 a = rGPR[inst.RA];
s32 b = rGPR[_inst.RB]; s32 b = rGPR[inst.RB];
if (b == 0 || ((u32)a == 0x80000000 && b == -1)) if (b == 0 || ((u32)a == 0x80000000 && b == -1))
{ {
if (_inst.OE) if (inst.OE)
{ {
// should set OV // should set OV
PanicAlert("OE: divwx"); PanicAlert("OE: divwx");
} }
if (((u32)a & 0x80000000) && b == 0) if (((u32)a & 0x80000000) && b == 0)
rGPR[_inst.RD] = -1; rGPR[inst.RD] = -1;
else else
rGPR[_inst.RD] = 0; rGPR[inst.RD] = 0;
} }
else else
{ {
rGPR[_inst.RD] = (u32)(a / b); rGPR[inst.RD] = (u32)(a / b);
} }
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::divwux(UGeckoInstruction _inst) void Interpreter::divwux(UGeckoInstruction inst)
{ {
u32 a = rGPR[_inst.RA]; u32 a = rGPR[inst.RA];
u32 b = rGPR[_inst.RB]; u32 b = rGPR[inst.RB];
if (b == 0) if (b == 0)
{ {
if (_inst.OE) if (inst.OE)
{ {
// should set OV // should set OV
PanicAlert("OE: divwux"); PanicAlert("OE: divwux");
} }
rGPR[_inst.RD] = 0; rGPR[inst.RD] = 0;
} }
else else
{ {
rGPR[_inst.RD] = a / b; rGPR[inst.RD] = a / b;
} }
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::mulhwx(UGeckoInstruction _inst) void Interpreter::mulhwx(UGeckoInstruction inst)
{ {
u32 a = rGPR[_inst.RA]; u32 a = rGPR[inst.RA];
u32 b = rGPR[_inst.RB]; u32 b = rGPR[inst.RB];
u32 d = (u32)((u64)(((s64)(s32)a * (s64)(s32)b)) >>
32); // This can be done better. Not in plain C/C++ though.
rGPR[_inst.RD] = d;
if (_inst.Rc) // This can be done better. Not in plain C/C++ though.
Helper_UpdateCR0(rGPR[_inst.RD]); u32 d = (u32)((u64)(((s64)(s32)a * (s64)(s32)b)) >> 32);
rGPR[inst.RD] = d;
if (inst.Rc)
Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::mulhwux(UGeckoInstruction _inst) void Interpreter::mulhwux(UGeckoInstruction inst)
{ {
u32 a = rGPR[_inst.RA]; u32 a = rGPR[inst.RA];
u32 b = rGPR[_inst.RB]; u32 b = rGPR[inst.RB];
u32 d = (u32)(((u64)a * (u64)b) >> 32); u32 d = (u32)(((u64)a * (u64)b) >> 32);
rGPR[_inst.RD] = d; rGPR[inst.RD] = d;
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::mullwx(UGeckoInstruction _inst) void Interpreter::mullwx(UGeckoInstruction inst)
{ {
u32 a = rGPR[_inst.RA]; u32 a = rGPR[inst.RA];
u32 b = rGPR[_inst.RB]; u32 b = rGPR[inst.RB];
u32 d = (u32)((s32)a * (s32)b); u32 d = (u32)((s32)a * (s32)b);
rGPR[_inst.RD] = d; rGPR[inst.RD] = d;
if (_inst.OE) if (inst.OE)
PanicAlert("OE: mullwx"); PanicAlert("OE: mullwx");
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::negx(UGeckoInstruction _inst) void Interpreter::negx(UGeckoInstruction inst)
{ {
rGPR[_inst.RD] = (~rGPR[_inst.RA]) + 1; rGPR[inst.RD] = (~rGPR[inst.RA]) + 1;
if (rGPR[_inst.RD] == 0x80000000) if (rGPR[inst.RD] == 0x80000000)
{ {
if (_inst.OE) if (inst.OE)
PanicAlert("OE: negx"); PanicAlert("OE: negx");
} }
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::subfx(UGeckoInstruction _inst) void Interpreter::subfx(UGeckoInstruction inst)
{ {
rGPR[_inst.RD] = rGPR[_inst.RB] - rGPR[_inst.RA]; rGPR[inst.RD] = rGPR[inst.RB] - rGPR[inst.RA];
if (_inst.OE) if (inst.OE)
PanicAlert("OE: subfx"); PanicAlert("OE: subfx");
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::subfcx(UGeckoInstruction _inst) void Interpreter::subfcx(UGeckoInstruction inst)
{ {
u32 a = rGPR[_inst.RA]; u32 a = rGPR[inst.RA];
u32 b = rGPR[_inst.RB]; u32 b = rGPR[inst.RB];
rGPR[_inst.RD] = b - a; rGPR[inst.RD] = b - a;
SetCarry(a == 0 || Helper_Carry(b, 0 - a)); SetCarry(a == 0 || Helper_Carry(b, 0 - a));
if (_inst.OE) if (inst.OE)
PanicAlert("OE: subfcx"); PanicAlert("OE: subfcx");
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::subfex(UGeckoInstruction _inst) void Interpreter::subfex(UGeckoInstruction inst)
{ {
u32 a = rGPR[_inst.RA]; u32 a = rGPR[inst.RA];
u32 b = rGPR[_inst.RB]; u32 b = rGPR[inst.RB];
int carry = GetCarry(); int carry = GetCarry();
rGPR[_inst.RD] = (~a) + b + carry; rGPR[inst.RD] = (~a) + b + carry;
SetCarry(Helper_Carry(~a, b) || Helper_Carry((~a) + b, carry)); SetCarry(Helper_Carry(~a, b) || Helper_Carry((~a) + b, carry));
if (_inst.OE) if (inst.OE)
PanicAlert("OE: subfex"); PanicAlert("OE: subfex");
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
// sub from minus one // sub from minus one
void Interpreter::subfmex(UGeckoInstruction _inst) void Interpreter::subfmex(UGeckoInstruction inst)
{ {
u32 a = rGPR[_inst.RA]; u32 a = rGPR[inst.RA];
int carry = GetCarry(); int carry = GetCarry();
rGPR[_inst.RD] = (~a) + carry - 1; rGPR[inst.RD] = (~a) + carry - 1;
SetCarry(Helper_Carry(~a, carry - 1)); SetCarry(Helper_Carry(~a, carry - 1));
if (_inst.OE) if (inst.OE)
PanicAlert("OE: subfmex"); PanicAlert("OE: subfmex");
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
// sub from zero // sub from zero
void Interpreter::subfzex(UGeckoInstruction _inst) void Interpreter::subfzex(UGeckoInstruction inst)
{ {
u32 a = rGPR[_inst.RA]; u32 a = rGPR[inst.RA];
int carry = GetCarry(); int carry = GetCarry();
rGPR[_inst.RD] = (~a) + carry; rGPR[inst.RD] = (~a) + carry;
SetCarry(Helper_Carry(~a, carry)); SetCarry(Helper_Carry(~a, carry));
if (_inst.OE) if (inst.OE)
PanicAlert("OE: subfzex"); PanicAlert("OE: subfzex");
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[_inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }

View File

@ -15,173 +15,173 @@
bool Interpreter::m_reserve; bool Interpreter::m_reserve;
u32 Interpreter::m_reserve_address; u32 Interpreter::m_reserve_address;
u32 Interpreter::Helper_Get_EA(const UGeckoInstruction _inst) u32 Interpreter::Helper_Get_EA(const UGeckoInstruction inst)
{ {
return _inst.RA ? (rGPR[_inst.RA] + _inst.SIMM_16) : (u32)_inst.SIMM_16; return inst.RA ? (rGPR[inst.RA] + inst.SIMM_16) : (u32)inst.SIMM_16;
} }
u32 Interpreter::Helper_Get_EA_U(const UGeckoInstruction _inst) u32 Interpreter::Helper_Get_EA_U(const UGeckoInstruction inst)
{ {
return (rGPR[_inst.RA] + _inst.SIMM_16); return (rGPR[inst.RA] + inst.SIMM_16);
} }
u32 Interpreter::Helper_Get_EA_X(const UGeckoInstruction _inst) u32 Interpreter::Helper_Get_EA_X(const UGeckoInstruction inst)
{ {
return _inst.RA ? (rGPR[_inst.RA] + rGPR[_inst.RB]) : rGPR[_inst.RB]; return inst.RA ? (rGPR[inst.RA] + rGPR[inst.RB]) : rGPR[inst.RB];
} }
u32 Interpreter::Helper_Get_EA_UX(const UGeckoInstruction _inst) u32 Interpreter::Helper_Get_EA_UX(const UGeckoInstruction inst)
{ {
return (rGPR[_inst.RA] + rGPR[_inst.RB]); return (rGPR[inst.RA] + rGPR[inst.RB]);
} }
void Interpreter::lbz(UGeckoInstruction _inst) void Interpreter::lbz(UGeckoInstruction inst)
{ {
u32 temp = (u32)PowerPC::Read_U8(Helper_Get_EA(_inst)); u32 temp = (u32)PowerPC::Read_U8(Helper_Get_EA(inst));
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
} }
void Interpreter::lbzu(UGeckoInstruction _inst) void Interpreter::lbzu(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(inst);
u32 temp = (u32)PowerPC::Read_U8(uAddress); u32 temp = (u32)PowerPC::Read_U8(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::lfd(UGeckoInstruction _inst) void Interpreter::lfd(UGeckoInstruction inst)
{ {
u64 temp = PowerPC::Read_U64(Helper_Get_EA(_inst)); u64 temp = PowerPC::Read_U64(Helper_Get_EA(inst));
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
riPS0(_inst.FD) = temp; riPS0(inst.FD) = temp;
} }
void Interpreter::lfdu(UGeckoInstruction _inst) void Interpreter::lfdu(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(inst);
u64 temp = PowerPC::Read_U64(uAddress); u64 temp = PowerPC::Read_U64(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
riPS0(_inst.FD) = temp; riPS0(inst.FD) = temp;
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::lfdux(UGeckoInstruction _inst) void Interpreter::lfdux(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(inst);
u64 temp = PowerPC::Read_U64(uAddress); u64 temp = PowerPC::Read_U64(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
riPS0(_inst.FD) = temp; riPS0(inst.FD) = temp;
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::lfdx(UGeckoInstruction _inst) void Interpreter::lfdx(UGeckoInstruction inst)
{ {
u64 temp = PowerPC::Read_U64(Helper_Get_EA_X(_inst)); u64 temp = PowerPC::Read_U64(Helper_Get_EA_X(inst));
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
riPS0(_inst.FD) = temp; riPS0(inst.FD) = temp;
} }
void Interpreter::lfs(UGeckoInstruction _inst) void Interpreter::lfs(UGeckoInstruction inst)
{ {
u32 uTemp = PowerPC::Read_U32(Helper_Get_EA(_inst)); u32 uTemp = PowerPC::Read_U32(Helper_Get_EA(inst));
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
u64 value = ConvertToDouble(uTemp); u64 value = ConvertToDouble(uTemp);
riPS0(_inst.FD) = value; riPS0(inst.FD) = value;
riPS1(_inst.FD) = value; riPS1(inst.FD) = value;
} }
} }
void Interpreter::lfsu(UGeckoInstruction _inst) void Interpreter::lfsu(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(inst);
u32 uTemp = PowerPC::Read_U32(uAddress); u32 uTemp = PowerPC::Read_U32(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
u64 value = ConvertToDouble(uTemp); u64 value = ConvertToDouble(uTemp);
riPS0(_inst.FD) = value; riPS0(inst.FD) = value;
riPS1(_inst.FD) = value; riPS1(inst.FD) = value;
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::lfsux(UGeckoInstruction _inst) void Interpreter::lfsux(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(inst);
u32 uTemp = PowerPC::Read_U32(uAddress); u32 uTemp = PowerPC::Read_U32(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
u64 value = ConvertToDouble(uTemp); u64 value = ConvertToDouble(uTemp);
riPS0(_inst.FD) = value; riPS0(inst.FD) = value;
riPS1(_inst.FD) = value; riPS1(inst.FD) = value;
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::lfsx(UGeckoInstruction _inst) void Interpreter::lfsx(UGeckoInstruction inst)
{ {
u32 uTemp = PowerPC::Read_U32(Helper_Get_EA_X(_inst)); u32 uTemp = PowerPC::Read_U32(Helper_Get_EA_X(inst));
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
u64 value = ConvertToDouble(uTemp); u64 value = ConvertToDouble(uTemp);
riPS0(_inst.FD) = value; riPS0(inst.FD) = value;
riPS1(_inst.FD) = value; riPS1(inst.FD) = value;
} }
} }
void Interpreter::lha(UGeckoInstruction _inst) void Interpreter::lha(UGeckoInstruction inst)
{ {
u32 temp = (u32)(s32)(s16)PowerPC::Read_U16(Helper_Get_EA(_inst)); u32 temp = (u32)(s32)(s16)PowerPC::Read_U16(Helper_Get_EA(inst));
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
} }
} }
void Interpreter::lhau(UGeckoInstruction _inst) void Interpreter::lhau(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(inst);
u32 temp = (u32)(s32)(s16)PowerPC::Read_U16(uAddress); u32 temp = (u32)(s32)(s16)PowerPC::Read_U16(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::lhz(UGeckoInstruction _inst) void Interpreter::lhz(UGeckoInstruction inst)
{ {
u32 temp = (u32)(u16)PowerPC::Read_U16(Helper_Get_EA(_inst)); u32 temp = (u32)(u16)PowerPC::Read_U16(Helper_Get_EA(inst));
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
} }
} }
void Interpreter::lhzu(UGeckoInstruction _inst) void Interpreter::lhzu(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(inst);
u32 temp = (u32)(u16)PowerPC::Read_U16(uAddress); u32 temp = (u32)(u16)PowerPC::Read_U16(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
// FIXME: lmw should do a total rollback if a DSI occurs // FIXME: lmw should do a total rollback if a DSI occurs
void Interpreter::lmw(UGeckoInstruction _inst) void Interpreter::lmw(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA(_inst); u32 uAddress = Helper_Get_EA(inst);
for (int iReg = _inst.RD; iReg <= 31; iReg++, uAddress += 4) for (int iReg = inst.RD; iReg <= 31; iReg++, uAddress += 4)
{ {
u32 TempReg = PowerPC::Read_U32(uAddress); u32 TempReg = PowerPC::Read_U32(uAddress);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
@ -198,10 +198,10 @@ void Interpreter::lmw(UGeckoInstruction _inst)
} }
// FIXME: stmw should do a total rollback if a DSI occurs // FIXME: stmw should do a total rollback if a DSI occurs
void Interpreter::stmw(UGeckoInstruction _inst) void Interpreter::stmw(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA(_inst); u32 uAddress = Helper_Get_EA(inst);
for (int iReg = _inst.RS; iReg <= 31; iReg++, uAddress += 4) for (int iReg = inst.RS; iReg <= 31; iReg++, uAddress += 4)
{ {
PowerPC::Write_U32(rGPR[iReg], uAddress); PowerPC::Write_U32(rGPR[iReg], uAddress);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
@ -213,108 +213,108 @@ void Interpreter::stmw(UGeckoInstruction _inst)
} }
} }
void Interpreter::lwz(UGeckoInstruction _inst) void Interpreter::lwz(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA(_inst); u32 uAddress = Helper_Get_EA(inst);
u32 temp = PowerPC::Read_U32(uAddress); u32 temp = PowerPC::Read_U32(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
} }
} }
void Interpreter::lwzu(UGeckoInstruction _inst) void Interpreter::lwzu(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(inst);
u32 temp = PowerPC::Read_U32(uAddress); u32 temp = PowerPC::Read_U32(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::stb(UGeckoInstruction _inst) void Interpreter::stb(UGeckoInstruction inst)
{ {
PowerPC::Write_U8((u8)rGPR[_inst.RS], Helper_Get_EA(_inst)); PowerPC::Write_U8((u8)rGPR[inst.RS], Helper_Get_EA(inst));
} }
void Interpreter::stbu(UGeckoInstruction _inst) void Interpreter::stbu(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(inst);
PowerPC::Write_U8((u8)rGPR[_inst.RS], uAddress); PowerPC::Write_U8((u8)rGPR[inst.RS], uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::stfd(UGeckoInstruction _inst) void Interpreter::stfd(UGeckoInstruction inst)
{ {
PowerPC::Write_U64(riPS0(_inst.FS), Helper_Get_EA(_inst)); PowerPC::Write_U64(riPS0(inst.FS), Helper_Get_EA(inst));
} }
void Interpreter::stfdu(UGeckoInstruction _inst) void Interpreter::stfdu(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(inst);
PowerPC::Write_U64(riPS0(_inst.FS), uAddress); PowerPC::Write_U64(riPS0(inst.FS), uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::stfs(UGeckoInstruction _inst) void Interpreter::stfs(UGeckoInstruction inst)
{ {
PowerPC::Write_U32(ConvertToSingle(riPS0(_inst.FS)), Helper_Get_EA(_inst)); PowerPC::Write_U32(ConvertToSingle(riPS0(inst.FS)), Helper_Get_EA(inst));
} }
void Interpreter::stfsu(UGeckoInstruction _inst) void Interpreter::stfsu(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(inst);
PowerPC::Write_U32(ConvertToSingle(riPS0(_inst.FS)), uAddress); PowerPC::Write_U32(ConvertToSingle(riPS0(inst.FS)), uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::sth(UGeckoInstruction _inst) void Interpreter::sth(UGeckoInstruction inst)
{ {
PowerPC::Write_U16((u16)rGPR[_inst.RS], Helper_Get_EA(_inst)); PowerPC::Write_U16((u16)rGPR[inst.RS], Helper_Get_EA(inst));
} }
void Interpreter::sthu(UGeckoInstruction _inst) void Interpreter::sthu(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(inst);
PowerPC::Write_U16((u16)rGPR[_inst.RS], uAddress); PowerPC::Write_U16((u16)rGPR[inst.RS], uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::stw(UGeckoInstruction _inst) void Interpreter::stw(UGeckoInstruction inst)
{ {
PowerPC::Write_U32(rGPR[_inst.RS], Helper_Get_EA(_inst)); PowerPC::Write_U32(rGPR[inst.RS], Helper_Get_EA(inst));
} }
void Interpreter::stwu(UGeckoInstruction _inst) void Interpreter::stwu(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(inst);
PowerPC::Write_U32(rGPR[_inst.RS], uAddress); PowerPC::Write_U32(rGPR[inst.RS], uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::dcba(UGeckoInstruction _inst) void Interpreter::dcba(UGeckoInstruction inst)
{ {
_assert_msg_(POWERPC, 0, "dcba - Not implemented - not a Gekko instruction"); _assert_msg_(POWERPC, 0, "dcba - Not implemented - not a Gekko instruction");
} }
void Interpreter::dcbf(UGeckoInstruction _inst) void Interpreter::dcbf(UGeckoInstruction inst)
{ {
// TODO: Implement some sort of L2 emulation. // TODO: Implement some sort of L2 emulation.
// TODO: Raise DSI if translation fails (except for direct-store segments). // TODO: Raise DSI if translation fails (except for direct-store segments).
@ -322,11 +322,11 @@ void Interpreter::dcbf(UGeckoInstruction _inst)
// Invalidate the JIT cache here as a heuristic to compensate for // Invalidate the JIT cache here as a heuristic to compensate for
// the lack of precise L1 icache emulation in the JIT. (Portable software // the lack of precise L1 icache emulation in the JIT. (Portable software
// should use icbi consistently, but games aren't portable.) // should use icbi consistently, but games aren't portable.)
u32 address = Helper_Get_EA_X(_inst); u32 address = Helper_Get_EA_X(inst);
JitInterface::InvalidateICache(address & ~0x1f, 32, false); JitInterface::InvalidateICache(address & ~0x1f, 32, false);
} }
void Interpreter::dcbi(UGeckoInstruction _inst) void Interpreter::dcbi(UGeckoInstruction inst)
{ {
// TODO: Implement some sort of L2 emulation. // TODO: Implement some sort of L2 emulation.
// TODO: Raise DSI if translation fails (except for direct-store segments). // TODO: Raise DSI if translation fails (except for direct-store segments).
@ -334,11 +334,11 @@ void Interpreter::dcbi(UGeckoInstruction _inst)
// Invalidate the JIT cache here as a heuristic to compensate for // Invalidate the JIT cache here as a heuristic to compensate for
// the lack of precise L1 icache emulation in the JIT. (Portable software // the lack of precise L1 icache emulation in the JIT. (Portable software
// should use icbi consistently, but games aren't portable.) // should use icbi consistently, but games aren't portable.)
u32 address = Helper_Get_EA_X(_inst); u32 address = Helper_Get_EA_X(inst);
JitInterface::InvalidateICache(address & ~0x1f, 32, false); JitInterface::InvalidateICache(address & ~0x1f, 32, false);
} }
void Interpreter::dcbst(UGeckoInstruction _inst) void Interpreter::dcbst(UGeckoInstruction inst)
{ {
// TODO: Implement some sort of L2 emulation. // TODO: Implement some sort of L2 emulation.
// TODO: Raise DSI if translation fails (except for direct-store segments). // TODO: Raise DSI if translation fails (except for direct-store segments).
@ -346,34 +346,34 @@ void Interpreter::dcbst(UGeckoInstruction _inst)
// Invalidate the JIT cache here as a heuristic to compensate for // Invalidate the JIT cache here as a heuristic to compensate for
// the lack of precise L1 icache emulation in the JIT. (Portable software // the lack of precise L1 icache emulation in the JIT. (Portable software
// should use icbi consistently, but games aren't portable.) // should use icbi consistently, but games aren't portable.)
u32 address = Helper_Get_EA_X(_inst); u32 address = Helper_Get_EA_X(inst);
JitInterface::InvalidateICache(address & ~0x1f, 32, false); JitInterface::InvalidateICache(address & ~0x1f, 32, false);
} }
void Interpreter::dcbt(UGeckoInstruction _inst) void Interpreter::dcbt(UGeckoInstruction inst)
{ {
// TODO: Implement some sort of L2 emulation. // TODO: Implement some sort of L2 emulation.
} }
void Interpreter::dcbtst(UGeckoInstruction _inst) void Interpreter::dcbtst(UGeckoInstruction inst)
{ {
// TODO: Implement some sort of L2 emulation. // TODO: Implement some sort of L2 emulation.
} }
void Interpreter::dcbz(UGeckoInstruction _inst) void Interpreter::dcbz(UGeckoInstruction inst)
{ {
// TODO: Implement some sort of L2 emulation. // TODO: Implement some sort of L2 emulation.
// DCBZOFF is a hack to fix certain games which would otherwise require // DCBZOFF is a hack to fix certain games which would otherwise require
// accurate L2 emulation. // accurate L2 emulation.
if (!SConfig::GetInstance().bDCBZOFF) if (!SConfig::GetInstance().bDCBZOFF)
PowerPC::ClearCacheLine(Helper_Get_EA_X(_inst) & (~31)); PowerPC::ClearCacheLine(Helper_Get_EA_X(inst) & (~31));
} }
// eciwx/ecowx technically should access the specified device // eciwx/ecowx technically should access the specified device
// We just do it instantly from ppc...and hey, it works! :D // We just do it instantly from ppc...and hey, it works! :D
void Interpreter::eciwx(UGeckoInstruction _inst) void Interpreter::eciwx(UGeckoInstruction inst)
{ {
u32 EA = Helper_Get_EA_X(_inst); u32 EA = Helper_Get_EA_X(inst);
if (!(PowerPC::ppcState.spr[SPR_EAR] & 0x80000000)) if (!(PowerPC::ppcState.spr[SPR_EAR] & 0x80000000))
{ {
@ -383,14 +383,14 @@ void Interpreter::eciwx(UGeckoInstruction _inst)
PowerPC::ppcState.Exceptions |= EXCEPTION_ALIGNMENT; PowerPC::ppcState.Exceptions |= EXCEPTION_ALIGNMENT;
// _assert_msg_(POWERPC,0,"eciwx - fill r%i with word @ %08x from device %02x", // _assert_msg_(POWERPC,0,"eciwx - fill r%i with word @ %08x from device %02x",
// _inst.RS, EA, PowerPC::ppcState.spr[SPR_EAR] & 0x1f); // inst.RS, EA, PowerPC::ppcState.spr[SPR_EAR] & 0x1f);
rGPR[_inst.RD] = PowerPC::Read_U32(EA); rGPR[inst.RD] = PowerPC::Read_U32(EA);
} }
void Interpreter::ecowx(UGeckoInstruction _inst) void Interpreter::ecowx(UGeckoInstruction inst)
{ {
u32 EA = Helper_Get_EA_X(_inst); u32 EA = Helper_Get_EA_X(inst);
if (!(PowerPC::ppcState.spr[SPR_EAR] & 0x80000000)) if (!(PowerPC::ppcState.spr[SPR_EAR] & 0x80000000))
{ {
@ -402,10 +402,10 @@ void Interpreter::ecowx(UGeckoInstruction _inst)
// _assert_msg_(POWERPC,0,"ecowx - send stw request (%08x@%08x) to device %02x", // _assert_msg_(POWERPC,0,"ecowx - send stw request (%08x@%08x) to device %02x",
// rGPR[_inst.RS], EA, PowerPC::ppcState.spr[SPR_EAR] & 0x1f); // rGPR[_inst.RS], EA, PowerPC::ppcState.spr[SPR_EAR] & 0x1f);
PowerPC::Write_U32(rGPR[_inst.RS], EA); PowerPC::Write_U32(rGPR[inst.RS], EA);
} }
void Interpreter::eieio(UGeckoInstruction _inst) void Interpreter::eieio(UGeckoInstruction inst)
{ {
// Basically ensures that loads/stores before this instruction // Basically ensures that loads/stores before this instruction
// have completed (in order) before executing the next op. // have completed (in order) before executing the next op.
@ -413,91 +413,91 @@ void Interpreter::eieio(UGeckoInstruction _inst)
// But (at least in interpreter) we do everything realtime anyways. // But (at least in interpreter) we do everything realtime anyways.
} }
void Interpreter::icbi(UGeckoInstruction _inst) void Interpreter::icbi(UGeckoInstruction inst)
{ {
// TODO: Raise DSI if translation fails (except for direct-store segments). // TODO: Raise DSI if translation fails (except for direct-store segments).
u32 address = Helper_Get_EA_X(_inst); u32 address = Helper_Get_EA_X(inst);
PowerPC::ppcState.iCache.Invalidate(address); PowerPC::ppcState.iCache.Invalidate(address);
} }
void Interpreter::lbzux(UGeckoInstruction _inst) void Interpreter::lbzux(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(inst);
u32 temp = (u32)PowerPC::Read_U8(uAddress); u32 temp = (u32)PowerPC::Read_U8(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::lbzx(UGeckoInstruction _inst) void Interpreter::lbzx(UGeckoInstruction inst)
{ {
u32 temp = (u32)PowerPC::Read_U8(Helper_Get_EA_X(_inst)); u32 temp = (u32)PowerPC::Read_U8(Helper_Get_EA_X(inst));
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
} }
} }
void Interpreter::lhaux(UGeckoInstruction _inst) void Interpreter::lhaux(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(inst);
s32 temp = (s32)(s16)PowerPC::Read_U16(uAddress); s32 temp = (s32)(s16)PowerPC::Read_U16(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::lhax(UGeckoInstruction _inst) void Interpreter::lhax(UGeckoInstruction inst)
{ {
s32 temp = (s32)(s16)PowerPC::Read_U16(Helper_Get_EA_X(_inst)); s32 temp = (s32)(s16)PowerPC::Read_U16(Helper_Get_EA_X(inst));
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
} }
} }
void Interpreter::lhbrx(UGeckoInstruction _inst) void Interpreter::lhbrx(UGeckoInstruction inst)
{ {
u32 temp = (u32)Common::swap16(PowerPC::Read_U16(Helper_Get_EA_X(_inst))); u32 temp = (u32)Common::swap16(PowerPC::Read_U16(Helper_Get_EA_X(inst)));
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
} }
} }
void Interpreter::lhzux(UGeckoInstruction _inst) void Interpreter::lhzux(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(inst);
u32 temp = (u32)PowerPC::Read_U16(uAddress); u32 temp = (u32)PowerPC::Read_U16(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::lhzx(UGeckoInstruction _inst) void Interpreter::lhzx(UGeckoInstruction inst)
{ {
u32 temp = (u32)PowerPC::Read_U16(Helper_Get_EA_X(_inst)); u32 temp = (u32)PowerPC::Read_U16(Helper_Get_EA_X(inst));
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
} }
} }
// FIXME: Should rollback if a DSI occurs // FIXME: Should rollback if a DSI occurs
void Interpreter::lswx(UGeckoInstruction _inst) void Interpreter::lswx(UGeckoInstruction inst)
{ {
u32 EA = Helper_Get_EA_X(_inst); u32 EA = Helper_Get_EA_X(inst);
// Confirmed by hardware test that the zero case doesn't zero rGPR[r] // Confirmed by hardware test that the zero case doesn't zero rGPR[r]
for (u32 n = 0; n < static_cast<u8>(PowerPC::ppcState.xer_stringctrl); n++) for (u32 n = 0; n < static_cast<u8>(PowerPC::ppcState.xer_stringctrl); n++)
{ {
int reg = (_inst.RD + (n >> 2)) & 0x1f; int reg = (inst.RD + (n >> 2)) & 0x1f;
int offset = (n & 3) << 3; int offset = (n & 3) << 3;
if ((n & 3) == 0) if ((n & 3) == 0)
rGPR[reg] = 0; rGPR[reg] = 0;
@ -515,127 +515,127 @@ void Interpreter::lswx(UGeckoInstruction _inst)
} }
} }
void Interpreter::lwbrx(UGeckoInstruction _inst) void Interpreter::lwbrx(UGeckoInstruction inst)
{ {
u32 temp = Common::swap32(PowerPC::Read_U32(Helper_Get_EA_X(_inst))); u32 temp = Common::swap32(PowerPC::Read_U32(Helper_Get_EA_X(inst)));
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
} }
} }
void Interpreter::lwzux(UGeckoInstruction _inst) void Interpreter::lwzux(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(inst);
u32 temp = PowerPC::Read_U32(uAddress); u32 temp = PowerPC::Read_U32(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::lwzx(UGeckoInstruction _inst) void Interpreter::lwzx(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_X(_inst); u32 uAddress = Helper_Get_EA_X(inst);
u32 temp = PowerPC::Read_U32(uAddress); u32 temp = PowerPC::Read_U32(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
} }
} }
void Interpreter::stbux(UGeckoInstruction _inst) void Interpreter::stbux(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(inst);
PowerPC::Write_U8((u8)rGPR[_inst.RS], uAddress); PowerPC::Write_U8((u8)rGPR[inst.RS], uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::stbx(UGeckoInstruction _inst) void Interpreter::stbx(UGeckoInstruction inst)
{ {
PowerPC::Write_U8((u8)rGPR[_inst.RS], Helper_Get_EA_X(_inst)); PowerPC::Write_U8((u8)rGPR[inst.RS], Helper_Get_EA_X(inst));
} }
void Interpreter::stfdux(UGeckoInstruction _inst) void Interpreter::stfdux(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(inst);
PowerPC::Write_U64(riPS0(_inst.FS), uAddress); PowerPC::Write_U64(riPS0(inst.FS), uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::stfdx(UGeckoInstruction _inst) void Interpreter::stfdx(UGeckoInstruction inst)
{ {
PowerPC::Write_U64(riPS0(_inst.FS), Helper_Get_EA_X(_inst)); PowerPC::Write_U64(riPS0(inst.FS), Helper_Get_EA_X(inst));
} }
// Stores Floating points into Integers indeXed // Stores Floating points into Integers indeXed
void Interpreter::stfiwx(UGeckoInstruction _inst) void Interpreter::stfiwx(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_X(_inst); u32 uAddress = Helper_Get_EA_X(inst);
PowerPC::Write_U32((u32)riPS0(_inst.FS), uAddress); PowerPC::Write_U32((u32)riPS0(inst.FS), uAddress);
} }
void Interpreter::stfsux(UGeckoInstruction _inst) void Interpreter::stfsux(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(inst);
PowerPC::Write_U32(ConvertToSingle(riPS0(_inst.FS)), uAddress); PowerPC::Write_U32(ConvertToSingle(riPS0(inst.FS)), uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::stfsx(UGeckoInstruction _inst) void Interpreter::stfsx(UGeckoInstruction inst)
{ {
PowerPC::Write_U32(ConvertToSingle(riPS0(_inst.FS)), Helper_Get_EA_X(_inst)); PowerPC::Write_U32(ConvertToSingle(riPS0(inst.FS)), Helper_Get_EA_X(inst));
} }
void Interpreter::sthbrx(UGeckoInstruction _inst) void Interpreter::sthbrx(UGeckoInstruction inst)
{ {
PowerPC::Write_U16(Common::swap16((u16)rGPR[_inst.RS]), Helper_Get_EA_X(_inst)); PowerPC::Write_U16(Common::swap16((u16)rGPR[inst.RS]), Helper_Get_EA_X(inst));
} }
void Interpreter::sthux(UGeckoInstruction _inst) void Interpreter::sthux(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(inst);
PowerPC::Write_U16((u16)rGPR[_inst.RS], uAddress); PowerPC::Write_U16((u16)rGPR[inst.RS], uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::sthx(UGeckoInstruction _inst) void Interpreter::sthx(UGeckoInstruction inst)
{ {
PowerPC::Write_U16((u16)rGPR[_inst.RS], Helper_Get_EA_X(_inst)); PowerPC::Write_U16((u16)rGPR[inst.RS], Helper_Get_EA_X(inst));
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// lswi - bizarro string instruction // lswi - bizarro string instruction
// FIXME: Should rollback if a DSI occurs // FIXME: Should rollback if a DSI occurs
void Interpreter::lswi(UGeckoInstruction _inst) void Interpreter::lswi(UGeckoInstruction inst)
{ {
u32 EA; u32 EA;
if (_inst.RA == 0) if (inst.RA == 0)
EA = 0; EA = 0;
else else
EA = rGPR[_inst.RA]; EA = rGPR[inst.RA];
u32 n; u32 n;
if (_inst.NB == 0) if (inst.NB == 0)
n = 32; n = 32;
else else
n = _inst.NB; n = inst.NB;
int r = _inst.RD - 1; int r = inst.RD - 1;
int i = 0; int i = 0;
while (n > 0) while (n > 0)
{ {
@ -667,21 +667,21 @@ void Interpreter::lswi(UGeckoInstruction _inst)
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// stswi - bizarro string instruction // stswi - bizarro string instruction
// FIXME: Should rollback if a DSI occurs // FIXME: Should rollback if a DSI occurs
void Interpreter::stswi(UGeckoInstruction _inst) void Interpreter::stswi(UGeckoInstruction inst)
{ {
u32 EA; u32 EA;
if (_inst.RA == 0) if (inst.RA == 0)
EA = 0; EA = 0;
else else
EA = rGPR[_inst.RA]; EA = rGPR[inst.RA];
u32 n; u32 n;
if (_inst.NB == 0) if (inst.NB == 0)
n = 32; n = 32;
else else
n = _inst.NB; n = inst.NB;
int r = _inst.RS - 1; int r = inst.RS - 1;
int i = 0; int i = 0;
while (n > 0) while (n > 0)
{ {
@ -705,11 +705,11 @@ void Interpreter::stswi(UGeckoInstruction _inst)
} }
// TODO: is this right? is it DSI interruptible? // TODO: is this right? is it DSI interruptible?
void Interpreter::stswx(UGeckoInstruction _inst) void Interpreter::stswx(UGeckoInstruction inst)
{ {
u32 EA = Helper_Get_EA_X(_inst); u32 EA = Helper_Get_EA_X(inst);
u32 n = (u8)PowerPC::ppcState.xer_stringctrl; u32 n = (u8)PowerPC::ppcState.xer_stringctrl;
int r = _inst.RS; int r = inst.RS;
int i = 0; int i = 0;
while (n > 0) while (n > 0)
@ -727,38 +727,38 @@ void Interpreter::stswx(UGeckoInstruction _inst)
} }
} }
void Interpreter::stwbrx(UGeckoInstruction _inst) void Interpreter::stwbrx(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_X(_inst); u32 uAddress = Helper_Get_EA_X(inst);
PowerPC::Write_U32(Common::swap32(rGPR[_inst.RS]), uAddress); PowerPC::Write_U32(Common::swap32(rGPR[inst.RS]), uAddress);
} }
// The following two instructions are for SMP communications. On a single // The following two instructions are for SMP communications. On a single
// CPU, they cannot fail unless an interrupt happens in between. // CPU, they cannot fail unless an interrupt happens in between.
void Interpreter::lwarx(UGeckoInstruction _inst) void Interpreter::lwarx(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_X(_inst); u32 uAddress = Helper_Get_EA_X(inst);
u32 temp = PowerPC::Read_U32(uAddress); u32 temp = PowerPC::Read_U32(uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RD] = temp; rGPR[inst.RD] = temp;
m_reserve = true; m_reserve = true;
m_reserve_address = uAddress; m_reserve_address = uAddress;
} }
} }
void Interpreter::stwcxd(UGeckoInstruction _inst) void Interpreter::stwcxd(UGeckoInstruction inst)
{ {
// Stores Word Conditional indeXed // Stores Word Conditional indeXed
u32 uAddress; u32 uAddress;
if (m_reserve) if (m_reserve)
{ {
uAddress = Helper_Get_EA_X(_inst); uAddress = Helper_Get_EA_X(inst);
if (uAddress == m_reserve_address) if (uAddress == m_reserve_address)
{ {
PowerPC::Write_U32(rGPR[_inst.RS], uAddress); PowerPC::Write_U32(rGPR[inst.RS], uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
m_reserve = false; m_reserve = false;
@ -771,35 +771,35 @@ void Interpreter::stwcxd(UGeckoInstruction _inst)
SetCRField(0, GetXER_SO()); SetCRField(0, GetXER_SO());
} }
void Interpreter::stwux(UGeckoInstruction _inst) void Interpreter::stwux(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(inst);
PowerPC::Write_U32(rGPR[_inst.RS], uAddress); PowerPC::Write_U32(rGPR[inst.RS], uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{ {
rGPR[_inst.RA] = uAddress; rGPR[inst.RA] = uAddress;
} }
} }
void Interpreter::stwx(UGeckoInstruction _inst) void Interpreter::stwx(UGeckoInstruction inst)
{ {
u32 uAddress = Helper_Get_EA_X(_inst); u32 uAddress = Helper_Get_EA_X(inst);
PowerPC::Write_U32(rGPR[_inst.RS], uAddress); PowerPC::Write_U32(rGPR[inst.RS], uAddress);
} }
void Interpreter::sync(UGeckoInstruction _inst) void Interpreter::sync(UGeckoInstruction inst)
{ {
// ignored // ignored
} }
void Interpreter::tlbie(UGeckoInstruction _inst) void Interpreter::tlbie(UGeckoInstruction inst)
{ {
// Invalidate TLB entry // Invalidate TLB entry
u32 _Address = rGPR[_inst.RB]; u32 _Address = rGPR[inst.RB];
PowerPC::InvalidateTLBEntry(_Address); PowerPC::InvalidateTLBEntry(_Address);
} }
void Interpreter::tlbsync(UGeckoInstruction _inst) void Interpreter::tlbsync(UGeckoInstruction inst)
{ {
// MessageBox(0,"TLBsync","TLBsyncE",0); // MessageBox(0,"TLBsync","TLBsyncE",0);
} }

View File

@ -295,74 +295,74 @@ void Interpreter::Helper_Dequantize(u32 addr, u32 instI, u32 instRD, u32 instW)
rPS1(instRD) = ps1; rPS1(instRD) = ps1;
} }
void Interpreter::psq_l(UGeckoInstruction _inst) void Interpreter::psq_l(UGeckoInstruction inst)
{ {
const u32 EA = _inst.RA ? (rGPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12; const u32 EA = inst.RA ? (rGPR[inst.RA] + inst.SIMM_12) : (u32)inst.SIMM_12;
Helper_Dequantize(EA, _inst.I, _inst.RD, _inst.W); Helper_Dequantize(EA, inst.I, inst.RD, inst.W);
} }
void Interpreter::psq_lu(UGeckoInstruction _inst) void Interpreter::psq_lu(UGeckoInstruction inst)
{ {
const u32 EA = rGPR[_inst.RA] + _inst.SIMM_12; const u32 EA = rGPR[inst.RA] + inst.SIMM_12;
Helper_Dequantize(EA, _inst.I, _inst.RD, _inst.W); Helper_Dequantize(EA, inst.I, inst.RD, inst.W);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{ {
return; return;
} }
rGPR[_inst.RA] = EA; rGPR[inst.RA] = EA;
} }
void Interpreter::psq_st(UGeckoInstruction _inst) void Interpreter::psq_st(UGeckoInstruction inst)
{ {
const u32 EA = _inst.RA ? (rGPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12; const u32 EA = inst.RA ? (rGPR[inst.RA] + inst.SIMM_12) : (u32)inst.SIMM_12;
Helper_Quantize(EA, _inst.I, _inst.RS, _inst.W); Helper_Quantize(EA, inst.I, inst.RS, inst.W);
} }
void Interpreter::psq_stu(UGeckoInstruction _inst) void Interpreter::psq_stu(UGeckoInstruction inst)
{ {
const u32 EA = rGPR[_inst.RA] + _inst.SIMM_12; const u32 EA = rGPR[inst.RA] + inst.SIMM_12;
Helper_Quantize(EA, _inst.I, _inst.RS, _inst.W); Helper_Quantize(EA, inst.I, inst.RS, inst.W);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{ {
return; return;
} }
rGPR[_inst.RA] = EA; rGPR[inst.RA] = EA;
} }
void Interpreter::psq_lx(UGeckoInstruction _inst) void Interpreter::psq_lx(UGeckoInstruction inst)
{ {
const u32 EA = _inst.RA ? (rGPR[_inst.RA] + rGPR[_inst.RB]) : rGPR[_inst.RB]; const u32 EA = inst.RA ? (rGPR[inst.RA] + rGPR[inst.RB]) : rGPR[inst.RB];
Helper_Dequantize(EA, _inst.Ix, _inst.RD, _inst.Wx); Helper_Dequantize(EA, inst.Ix, inst.RD, inst.Wx);
} }
void Interpreter::psq_stx(UGeckoInstruction _inst) void Interpreter::psq_stx(UGeckoInstruction inst)
{ {
const u32 EA = _inst.RA ? (rGPR[_inst.RA] + rGPR[_inst.RB]) : rGPR[_inst.RB]; const u32 EA = inst.RA ? (rGPR[inst.RA] + rGPR[inst.RB]) : rGPR[inst.RB];
Helper_Quantize(EA, _inst.Ix, _inst.RS, _inst.Wx); Helper_Quantize(EA, inst.Ix, inst.RS, inst.Wx);
} }
void Interpreter::psq_lux(UGeckoInstruction _inst) void Interpreter::psq_lux(UGeckoInstruction inst)
{ {
const u32 EA = rGPR[_inst.RA] + rGPR[_inst.RB]; const u32 EA = rGPR[inst.RA] + rGPR[inst.RB];
Helper_Dequantize(EA, _inst.Ix, _inst.RD, _inst.Wx); Helper_Dequantize(EA, inst.Ix, inst.RD, inst.Wx);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{ {
return; return;
} }
rGPR[_inst.RA] = EA; rGPR[inst.RA] = EA;
} }
void Interpreter::psq_stux(UGeckoInstruction _inst) void Interpreter::psq_stux(UGeckoInstruction inst)
{ {
const u32 EA = rGPR[_inst.RA] + rGPR[_inst.RB]; const u32 EA = rGPR[inst.RA] + rGPR[inst.RB];
Helper_Quantize(EA, _inst.Ix, _inst.RS, _inst.Wx); Helper_Quantize(EA, inst.Ix, inst.RS, inst.Wx);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{ {
return; return;
} }
rGPR[_inst.RA] = EA; rGPR[inst.RA] = EA;
} }

View File

@ -13,332 +13,332 @@
using namespace MathUtil; using namespace MathUtil;
// These "binary instructions" do not alter FPSCR. // These "binary instructions" do not alter FPSCR.
void Interpreter::ps_sel(UGeckoInstruction _inst) void Interpreter::ps_sel(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = rPS0(_inst.FA) >= -0.0 ? rPS0(_inst.FC) : rPS0(_inst.FB); rPS0(inst.FD) = rPS0(inst.FA) >= -0.0 ? rPS0(inst.FC) : rPS0(inst.FB);
rPS1(_inst.FD) = rPS1(_inst.FA) >= -0.0 ? rPS1(_inst.FC) : rPS1(_inst.FB); rPS1(inst.FD) = rPS1(inst.FA) >= -0.0 ? rPS1(inst.FC) : rPS1(inst.FB);
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_neg(UGeckoInstruction _inst) void Interpreter::ps_neg(UGeckoInstruction inst)
{ {
riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63); riPS0(inst.FD) = riPS0(inst.FB) ^ (1ULL << 63);
riPS1(_inst.FD) = riPS1(_inst.FB) ^ (1ULL << 63); riPS1(inst.FD) = riPS1(inst.FB) ^ (1ULL << 63);
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_mr(UGeckoInstruction _inst) void Interpreter::ps_mr(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = rPS0(_inst.FB); rPS0(inst.FD) = rPS0(inst.FB);
rPS1(_inst.FD) = rPS1(_inst.FB); rPS1(inst.FD) = rPS1(inst.FB);
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_nabs(UGeckoInstruction _inst) void Interpreter::ps_nabs(UGeckoInstruction inst)
{ {
riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63); riPS0(inst.FD) = riPS0(inst.FB) | (1ULL << 63);
riPS1(_inst.FD) = riPS1(_inst.FB) | (1ULL << 63); riPS1(inst.FD) = riPS1(inst.FB) | (1ULL << 63);
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_abs(UGeckoInstruction _inst) void Interpreter::ps_abs(UGeckoInstruction inst)
{ {
riPS0(_inst.FD) = riPS0(_inst.FB) & ~(1ULL << 63); riPS0(inst.FD) = riPS0(inst.FB) & ~(1ULL << 63);
riPS1(_inst.FD) = riPS1(_inst.FB) & ~(1ULL << 63); riPS1(inst.FD) = riPS1(inst.FB) & ~(1ULL << 63);
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
// These are just moves, double is OK. // These are just moves, double is OK.
void Interpreter::ps_merge00(UGeckoInstruction _inst) void Interpreter::ps_merge00(UGeckoInstruction inst)
{ {
double p0 = rPS0(_inst.FA); double p0 = rPS0(inst.FA);
double p1 = rPS0(_inst.FB); double p1 = rPS0(inst.FB);
rPS0(_inst.FD) = p0; rPS0(inst.FD) = p0;
rPS1(_inst.FD) = p1; rPS1(inst.FD) = p1;
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_merge01(UGeckoInstruction _inst) void Interpreter::ps_merge01(UGeckoInstruction inst)
{ {
double p0 = rPS0(_inst.FA); double p0 = rPS0(inst.FA);
double p1 = rPS1(_inst.FB); double p1 = rPS1(inst.FB);
rPS0(_inst.FD) = p0; rPS0(inst.FD) = p0;
rPS1(_inst.FD) = p1; rPS1(inst.FD) = p1;
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_merge10(UGeckoInstruction _inst) void Interpreter::ps_merge10(UGeckoInstruction inst)
{ {
double p0 = rPS1(_inst.FA); double p0 = rPS1(inst.FA);
double p1 = rPS0(_inst.FB); double p1 = rPS0(inst.FB);
rPS0(_inst.FD) = p0; rPS0(inst.FD) = p0;
rPS1(_inst.FD) = p1; rPS1(inst.FD) = p1;
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_merge11(UGeckoInstruction _inst) void Interpreter::ps_merge11(UGeckoInstruction inst)
{ {
double p0 = rPS1(_inst.FA); double p0 = rPS1(inst.FA);
double p1 = rPS1(_inst.FB); double p1 = rPS1(inst.FB);
rPS0(_inst.FD) = p0; rPS0(inst.FD) = p0;
rPS1(_inst.FD) = p1; rPS1(inst.FD) = p1;
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
// From here on, the real deal. // From here on, the real deal.
void Interpreter::ps_div(UGeckoInstruction _inst) void Interpreter::ps_div(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = ForceSingle(NI_div(rPS0(_inst.FA), rPS0(_inst.FB))); rPS0(inst.FD) = ForceSingle(NI_div(rPS0(inst.FA), rPS0(inst.FB)));
rPS1(_inst.FD) = ForceSingle(NI_div(rPS1(_inst.FA), rPS1(_inst.FB))); rPS1(inst.FD) = ForceSingle(NI_div(rPS1(inst.FA), rPS1(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_res(UGeckoInstruction _inst) void Interpreter::ps_res(UGeckoInstruction inst)
{ {
// this code is based on the real hardware tests // this code is based on the real hardware tests
double a = rPS0(_inst.FB); double a = rPS0(inst.FB);
double b = rPS1(_inst.FB); double b = rPS1(inst.FB);
if (a == 0.0 || b == 0.0) if (a == 0.0 || b == 0.0)
{ {
SetFPException(FPSCR_ZX); SetFPException(FPSCR_ZX);
} }
rPS0(_inst.FD) = ApproximateReciprocal(a); rPS0(inst.FD) = ApproximateReciprocal(a);
rPS1(_inst.FD) = ApproximateReciprocal(b); rPS1(inst.FD) = ApproximateReciprocal(b);
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_rsqrte(UGeckoInstruction _inst) void Interpreter::ps_rsqrte(UGeckoInstruction inst)
{ {
if (rPS0(_inst.FB) == 0.0 || rPS1(_inst.FB) == 0.0) if (rPS0(inst.FB) == 0.0 || rPS1(inst.FB) == 0.0)
{ {
SetFPException(FPSCR_ZX); SetFPException(FPSCR_ZX);
} }
if (rPS0(_inst.FB) < 0.0 || rPS1(_inst.FB) < 0.0) if (rPS0(inst.FB) < 0.0 || rPS1(inst.FB) < 0.0)
{ {
SetFPException(FPSCR_VXSQRT); SetFPException(FPSCR_VXSQRT);
} }
rPS0(_inst.FD) = ForceSingle(ApproximateReciprocalSquareRoot(rPS0(_inst.FB))); rPS0(inst.FD) = ForceSingle(ApproximateReciprocalSquareRoot(rPS0(inst.FB)));
rPS1(_inst.FD) = ForceSingle(ApproximateReciprocalSquareRoot(rPS1(_inst.FB))); rPS1(inst.FD) = ForceSingle(ApproximateReciprocalSquareRoot(rPS1(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_sub(UGeckoInstruction _inst) void Interpreter::ps_sub(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB))); rPS0(inst.FD) = ForceSingle(NI_sub(rPS0(inst.FA), rPS0(inst.FB)));
rPS1(_inst.FD) = ForceSingle(NI_sub(rPS1(_inst.FA), rPS1(_inst.FB))); rPS1(inst.FD) = ForceSingle(NI_sub(rPS1(inst.FA), rPS1(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_add(UGeckoInstruction _inst) void Interpreter::ps_add(UGeckoInstruction inst)
{ {
rPS0(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB))); rPS0(inst.FD) = ForceSingle(NI_add(rPS0(inst.FA), rPS0(inst.FB)));
rPS1(_inst.FD) = ForceSingle(NI_add(rPS1(_inst.FA), rPS1(_inst.FB))); rPS1(inst.FD) = ForceSingle(NI_add(rPS1(inst.FA), rPS1(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_mul(UGeckoInstruction _inst) void Interpreter::ps_mul(UGeckoInstruction inst)
{ {
double c0 = Force25Bit(rPS0(_inst.FC)); double c0 = Force25Bit(rPS0(inst.FC));
double c1 = Force25Bit(rPS1(_inst.FC)); double c1 = Force25Bit(rPS1(inst.FC));
rPS0(_inst.FD) = ForceSingle(NI_mul(rPS0(_inst.FA), c0)); rPS0(inst.FD) = ForceSingle(NI_mul(rPS0(inst.FA), c0));
rPS1(_inst.FD) = ForceSingle(NI_mul(rPS1(_inst.FA), c1)); rPS1(inst.FD) = ForceSingle(NI_mul(rPS1(inst.FA), c1));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_msub(UGeckoInstruction _inst) void Interpreter::ps_msub(UGeckoInstruction inst)
{ {
double c0 = Force25Bit(rPS0(_inst.FC)); double c0 = Force25Bit(rPS0(inst.FC));
double c1 = Force25Bit(rPS1(_inst.FC)); double c1 = Force25Bit(rPS1(inst.FC));
rPS0(_inst.FD) = ForceSingle(NI_msub(rPS0(_inst.FA), c0, rPS0(_inst.FB))); rPS0(inst.FD) = ForceSingle(NI_msub(rPS0(inst.FA), c0, rPS0(inst.FB)));
rPS1(_inst.FD) = ForceSingle(NI_msub(rPS1(_inst.FA), c1, rPS1(_inst.FB))); rPS1(inst.FD) = ForceSingle(NI_msub(rPS1(inst.FA), c1, rPS1(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_madd(UGeckoInstruction _inst) void Interpreter::ps_madd(UGeckoInstruction inst)
{ {
double c0 = Force25Bit(rPS0(_inst.FC)); double c0 = Force25Bit(rPS0(inst.FC));
double c1 = Force25Bit(rPS1(_inst.FC)); double c1 = Force25Bit(rPS1(inst.FC));
rPS0(_inst.FD) = ForceSingle(NI_madd(rPS0(_inst.FA), c0, rPS0(_inst.FB))); rPS0(inst.FD) = ForceSingle(NI_madd(rPS0(inst.FA), c0, rPS0(inst.FB)));
rPS1(_inst.FD) = ForceSingle(NI_madd(rPS1(_inst.FA), c1, rPS1(_inst.FB))); rPS1(inst.FD) = ForceSingle(NI_madd(rPS1(inst.FA), c1, rPS1(inst.FB)));
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_nmsub(UGeckoInstruction _inst) void Interpreter::ps_nmsub(UGeckoInstruction inst)
{ {
double c0 = Force25Bit(rPS0(_inst.FC)); double c0 = Force25Bit(rPS0(inst.FC));
double c1 = Force25Bit(rPS1(_inst.FC)); double c1 = Force25Bit(rPS1(inst.FC));
double result0 = ForceSingle(NI_msub(rPS0(_inst.FA), c0, rPS0(_inst.FB))); double result0 = ForceSingle(NI_msub(rPS0(inst.FA), c0, rPS0(inst.FB)));
double result1 = ForceSingle(NI_msub(rPS1(_inst.FA), c1, rPS1(_inst.FB))); double result1 = ForceSingle(NI_msub(rPS1(inst.FA), c1, rPS1(inst.FB)));
rPS0(_inst.FD) = std::isnan(result0) ? result0 : -result0; rPS0(inst.FD) = std::isnan(result0) ? result0 : -result0;
rPS1(_inst.FD) = std::isnan(result1) ? result1 : -result1; rPS1(inst.FD) = std::isnan(result1) ? result1 : -result1;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_nmadd(UGeckoInstruction _inst) void Interpreter::ps_nmadd(UGeckoInstruction inst)
{ {
double c0 = Force25Bit(rPS0(_inst.FC)); double c0 = Force25Bit(rPS0(inst.FC));
double c1 = Force25Bit(rPS1(_inst.FC)); double c1 = Force25Bit(rPS1(inst.FC));
double result0 = ForceSingle(NI_madd(rPS0(_inst.FA), c0, rPS0(_inst.FB))); double result0 = ForceSingle(NI_madd(rPS0(inst.FA), c0, rPS0(inst.FB)));
double result1 = ForceSingle(NI_madd(rPS1(_inst.FA), c1, rPS1(_inst.FB))); double result1 = ForceSingle(NI_madd(rPS1(inst.FA), c1, rPS1(inst.FB)));
rPS0(_inst.FD) = std::isnan(result0) ? result0 : -result0; rPS0(inst.FD) = std::isnan(result0) ? result0 : -result0;
rPS1(_inst.FD) = std::isnan(result1) ? result1 : -result1; rPS1(inst.FD) = std::isnan(result1) ? result1 : -result1;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_sum0(UGeckoInstruction _inst) void Interpreter::ps_sum0(UGeckoInstruction inst)
{ {
double p0 = ForceSingle(NI_add(rPS0(_inst.FA), rPS1(_inst.FB))); double p0 = ForceSingle(NI_add(rPS0(inst.FA), rPS1(inst.FB)));
double p1 = ForceSingle(rPS1(_inst.FC)); double p1 = ForceSingle(rPS1(inst.FC));
rPS0(_inst.FD) = p0; rPS0(inst.FD) = p0;
rPS1(_inst.FD) = p1; rPS1(inst.FD) = p1;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_sum1(UGeckoInstruction _inst) void Interpreter::ps_sum1(UGeckoInstruction inst)
{ {
double p0 = ForceSingle(rPS0(_inst.FC)); double p0 = ForceSingle(rPS0(inst.FC));
double p1 = ForceSingle(NI_add(rPS0(_inst.FA), rPS1(_inst.FB))); double p1 = ForceSingle(NI_add(rPS0(inst.FA), rPS1(inst.FB)));
rPS0(_inst.FD) = p0; rPS0(inst.FD) = p0;
rPS1(_inst.FD) = p1; rPS1(inst.FD) = p1;
UpdateFPRF(rPS1(_inst.FD)); UpdateFPRF(rPS1(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_muls0(UGeckoInstruction _inst) void Interpreter::ps_muls0(UGeckoInstruction inst)
{ {
double c0 = Force25Bit(rPS0(_inst.FC)); double c0 = Force25Bit(rPS0(inst.FC));
double p0 = ForceSingle(NI_mul(rPS0(_inst.FA), c0)); double p0 = ForceSingle(NI_mul(rPS0(inst.FA), c0));
double p1 = ForceSingle(NI_mul(rPS1(_inst.FA), c0)); double p1 = ForceSingle(NI_mul(rPS1(inst.FA), c0));
rPS0(_inst.FD) = p0; rPS0(inst.FD) = p0;
rPS1(_inst.FD) = p1; rPS1(inst.FD) = p1;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_muls1(UGeckoInstruction _inst) void Interpreter::ps_muls1(UGeckoInstruction inst)
{ {
double c1 = Force25Bit(rPS1(_inst.FC)); double c1 = Force25Bit(rPS1(inst.FC));
double p0 = ForceSingle(NI_mul(rPS0(_inst.FA), c1)); double p0 = ForceSingle(NI_mul(rPS0(inst.FA), c1));
double p1 = ForceSingle(NI_mul(rPS1(_inst.FA), c1)); double p1 = ForceSingle(NI_mul(rPS1(inst.FA), c1));
rPS0(_inst.FD) = p0; rPS0(inst.FD) = p0;
rPS1(_inst.FD) = p1; rPS1(inst.FD) = p1;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_madds0(UGeckoInstruction _inst) void Interpreter::ps_madds0(UGeckoInstruction inst)
{ {
double c0 = Force25Bit(rPS0(_inst.FC)); double c0 = Force25Bit(rPS0(inst.FC));
double p0 = ForceSingle(NI_madd(rPS0(_inst.FA), c0, rPS0(_inst.FB))); double p0 = ForceSingle(NI_madd(rPS0(inst.FA), c0, rPS0(inst.FB)));
double p1 = ForceSingle(NI_madd(rPS1(_inst.FA), c0, rPS1(_inst.FB))); double p1 = ForceSingle(NI_madd(rPS1(inst.FA), c0, rPS1(inst.FB)));
rPS0(_inst.FD) = p0; rPS0(inst.FD) = p0;
rPS1(_inst.FD) = p1; rPS1(inst.FD) = p1;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_madds1(UGeckoInstruction _inst) void Interpreter::ps_madds1(UGeckoInstruction inst)
{ {
double c1 = Force25Bit(rPS1(_inst.FC)); double c1 = Force25Bit(rPS1(inst.FC));
double p0 = ForceSingle(NI_madd(rPS0(_inst.FA), c1, rPS0(_inst.FB))); double p0 = ForceSingle(NI_madd(rPS0(inst.FA), c1, rPS0(inst.FB)));
double p1 = ForceSingle(NI_madd(rPS1(_inst.FA), c1, rPS1(_inst.FB))); double p1 = ForceSingle(NI_madd(rPS1(inst.FA), c1, rPS1(inst.FB)));
rPS0(_inst.FD) = p0; rPS0(inst.FD) = p0;
rPS1(_inst.FD) = p1; rPS1(inst.FD) = p1;
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(inst.FD));
if (_inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }
void Interpreter::ps_cmpu0(UGeckoInstruction _inst) void Interpreter::ps_cmpu0(UGeckoInstruction inst)
{ {
Helper_FloatCompareUnordered(_inst, rPS0(_inst.FA), rPS0(_inst.FB)); Helper_FloatCompareUnordered(inst, rPS0(inst.FA), rPS0(inst.FB));
} }
void Interpreter::ps_cmpo0(UGeckoInstruction _inst) void Interpreter::ps_cmpo0(UGeckoInstruction inst)
{ {
Helper_FloatCompareOrdered(_inst, rPS0(_inst.FA), rPS0(_inst.FB)); Helper_FloatCompareOrdered(inst, rPS0(inst.FA), rPS0(inst.FB));
} }
void Interpreter::ps_cmpu1(UGeckoInstruction _inst) void Interpreter::ps_cmpu1(UGeckoInstruction inst)
{ {
Helper_FloatCompareUnordered(_inst, rPS1(_inst.FA), rPS1(_inst.FB)); Helper_FloatCompareUnordered(inst, rPS1(inst.FA), rPS1(inst.FB));
} }
void Interpreter::ps_cmpo1(UGeckoInstruction _inst) void Interpreter::ps_cmpo1(UGeckoInstruction inst)
{ {
Helper_FloatCompareOrdered(_inst, rPS1(_inst.FA), rPS1(_inst.FB)); Helper_FloatCompareOrdered(inst, rPS1(inst.FA), rPS1(inst.FB));
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// dcbz_l // dcbz_l
// TODO(ector) check docs // TODO(ector) check docs
void Interpreter::dcbz_l(UGeckoInstruction _inst) void Interpreter::dcbz_l(UGeckoInstruction inst)
{ {
// FAKE: clear memory instead of clearing the cache block // FAKE: clear memory instead of clearing the cache block
PowerPC::ClearCacheLine(Helper_Get_EA_X(_inst) & (~31)); PowerPC::ClearCacheLine(Helper_Get_EA_X(inst) & (~31));
} }

View File

@ -45,54 +45,54 @@ static void FPSCRtoFPUSettings(UReg_FPSCR fp)
FPURoundMode::SetSIMDMode(fp.RN, fp.NI); FPURoundMode::SetSIMDMode(fp.RN, fp.NI);
} }
void Interpreter::mtfsb0x(UGeckoInstruction _inst) void Interpreter::mtfsb0x(UGeckoInstruction inst)
{ {
u32 b = 0x80000000 >> _inst.CRBD; u32 b = 0x80000000 >> inst.CRBD;
/*if (b & 0x9ff80700) /*if (b & 0x9ff80700)
PanicAlert("mtfsb0 clears bit %d, PC=%x", _inst.CRBD, PC);*/ PanicAlert("mtfsb0 clears bit %d, PC=%x", inst.CRBD, PC);*/
FPSCR.Hex &= ~b; FPSCR.Hex &= ~b;
FPSCRtoFPUSettings(FPSCR); FPSCRtoFPUSettings(FPSCR);
if (_inst.Rc) if (inst.Rc)
PanicAlert("mtfsb0x: inst_.Rc"); PanicAlert("mtfsb0x: inst.Rc");
} }
void Interpreter::mtfsb1x(UGeckoInstruction _inst) void Interpreter::mtfsb1x(UGeckoInstruction inst)
{ {
// this instruction can affect FX // this instruction can affect FX
u32 b = 0x80000000 >> _inst.CRBD; u32 b = 0x80000000 >> inst.CRBD;
if (b & FPSCR_ANY_X) if (b & FPSCR_ANY_X)
SetFPException(b); SetFPException(b);
else else
FPSCR.Hex |= b; FPSCR.Hex |= b;
FPSCRtoFPUSettings(FPSCR); FPSCRtoFPUSettings(FPSCR);
if (_inst.Rc) if (inst.Rc)
PanicAlert("mtfsb1x: inst_.Rc"); PanicAlert("mtfsb1x: inst.Rc");
} }
void Interpreter::mtfsfix(UGeckoInstruction _inst) void Interpreter::mtfsfix(UGeckoInstruction inst)
{ {
u32 mask = (0xF0000000 >> (4 * _inst.CRFD)); u32 mask = (0xF0000000 >> (4 * inst.CRFD));
u32 imm = (_inst.hex << 16) & 0xF0000000; u32 imm = (inst.hex << 16) & 0xF0000000;
/*u32 cleared = ~(imm >> (4 * _inst.CRFD)) & FPSCR.Hex & mask; /*u32 cleared = ~(imm >> (4 * _inst.CRFD)) & FPSCR.Hex & mask;
if (cleared & 0x9ff80700) if (cleared & 0x9ff80700)
PanicAlert("mtfsfi clears %08x, PC=%x", cleared, PC);*/ PanicAlert("mtfsfi clears %08x, PC=%x", cleared, PC);*/
FPSCR.Hex = (FPSCR.Hex & ~mask) | (imm >> (4 * _inst.CRFD)); FPSCR.Hex = (FPSCR.Hex & ~mask) | (imm >> (4 * inst.CRFD));
FPSCRtoFPUSettings(FPSCR); FPSCRtoFPUSettings(FPSCR);
if (_inst.Rc) if (inst.Rc)
PanicAlert("mtfsfix: inst_.Rc"); PanicAlert("mtfsfix: inst.Rc");
} }
void Interpreter::mtfsfx(UGeckoInstruction _inst) void Interpreter::mtfsfx(UGeckoInstruction inst)
{ {
u32 fm = _inst.FM; u32 fm = inst.FM;
u32 m = 0; u32 m = 0;
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
@ -104,31 +104,31 @@ void Interpreter::mtfsfx(UGeckoInstruction _inst)
if (cleared & 0x9ff80700) if (cleared & 0x9ff80700)
PanicAlert("mtfsf clears %08x, PC=%x", cleared, PC);*/ PanicAlert("mtfsf clears %08x, PC=%x", cleared, PC);*/
FPSCR.Hex = (FPSCR.Hex & ~m) | ((u32)(riPS0(_inst.FB)) & m); FPSCR.Hex = (FPSCR.Hex & ~m) | ((u32)(riPS0(inst.FB)) & m);
FPSCRtoFPUSettings(FPSCR); FPSCRtoFPUSettings(FPSCR);
if (_inst.Rc) if (inst.Rc)
PanicAlert("mtfsfx: inst_.Rc"); PanicAlert("mtfsfx: inst.Rc");
} }
void Interpreter::mcrxr(UGeckoInstruction _inst) void Interpreter::mcrxr(UGeckoInstruction inst)
{ {
SetCRField(_inst.CRFD, GetXER().Hex >> 28); SetCRField(inst.CRFD, GetXER().Hex >> 28);
PowerPC::ppcState.xer_ca = 0; PowerPC::ppcState.xer_ca = 0;
PowerPC::ppcState.xer_so_ov = 0; PowerPC::ppcState.xer_so_ov = 0;
} }
void Interpreter::mfcr(UGeckoInstruction _inst) void Interpreter::mfcr(UGeckoInstruction inst)
{ {
rGPR[_inst.RD] = GetCR(); rGPR[inst.RD] = GetCR();
} }
void Interpreter::mtcrf(UGeckoInstruction _inst) void Interpreter::mtcrf(UGeckoInstruction inst)
{ {
u32 crm = _inst.CRM; u32 crm = inst.CRM;
if (crm == 0xFF) if (crm == 0xFF)
{ {
SetCR(rGPR[_inst.RS]); SetCR(rGPR[inst.RS]);
} }
else else
{ {
@ -140,31 +140,31 @@ void Interpreter::mtcrf(UGeckoInstruction _inst)
mask |= 0xF << (i * 4); mask |= 0xF << (i * 4);
} }
SetCR((GetCR() & ~mask) | (rGPR[_inst.RS] & mask)); SetCR((GetCR() & ~mask) | (rGPR[inst.RS] & mask));
} }
} }
void Interpreter::mfmsr(UGeckoInstruction _inst) void Interpreter::mfmsr(UGeckoInstruction inst)
{ {
// Privileged? // Privileged?
rGPR[_inst.RD] = MSR; rGPR[inst.RD] = MSR;
} }
void Interpreter::mfsr(UGeckoInstruction _inst) void Interpreter::mfsr(UGeckoInstruction inst)
{ {
rGPR[_inst.RD] = PowerPC::ppcState.sr[_inst.SR]; rGPR[inst.RD] = PowerPC::ppcState.sr[inst.SR];
} }
void Interpreter::mfsrin(UGeckoInstruction _inst) void Interpreter::mfsrin(UGeckoInstruction inst)
{ {
int index = (rGPR[_inst.RB] >> 28) & 0xF; int index = (rGPR[inst.RB] >> 28) & 0xF;
rGPR[_inst.RD] = PowerPC::ppcState.sr[index]; rGPR[inst.RD] = PowerPC::ppcState.sr[index];
} }
void Interpreter::mtmsr(UGeckoInstruction _inst) void Interpreter::mtmsr(UGeckoInstruction inst)
{ {
// Privileged? // Privileged?
MSR = rGPR[_inst.RS]; MSR = rGPR[inst.RS];
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();
m_end_block = true; m_end_block = true;
} }
@ -178,31 +178,31 @@ static void SetSR(int index, u32 value)
PowerPC::ppcState.sr[index] = value; PowerPC::ppcState.sr[index] = value;
} }
void Interpreter::mtsr(UGeckoInstruction _inst) void Interpreter::mtsr(UGeckoInstruction inst)
{ {
int index = _inst.SR; int index = inst.SR;
u32 value = rGPR[_inst.RS]; u32 value = rGPR[inst.RS];
SetSR(index, value); SetSR(index, value);
} }
void Interpreter::mtsrin(UGeckoInstruction _inst) void Interpreter::mtsrin(UGeckoInstruction inst)
{ {
int index = (rGPR[_inst.RB] >> 28) & 0xF; int index = (rGPR[inst.RB] >> 28) & 0xF;
u32 value = rGPR[_inst.RS]; u32 value = rGPR[inst.RS];
SetSR(index, value); SetSR(index, value);
} }
void Interpreter::mftb(UGeckoInstruction _inst) void Interpreter::mftb(UGeckoInstruction inst)
{ {
int iIndex = (_inst.TBR >> 5) | ((_inst.TBR & 0x1F) << 5); int iIndex = (inst.TBR >> 5) | ((inst.TBR & 0x1F) << 5);
_dbg_assert_msg_(POWERPC, (iIndex == SPR_TL) || (iIndex == SPR_TU), "Invalid mftb"); _dbg_assert_msg_(POWERPC, (iIndex == SPR_TL) || (iIndex == SPR_TU), "Invalid mftb");
(void)iIndex; (void)iIndex;
mfspr(_inst); mfspr(inst);
} }
void Interpreter::mfspr(UGeckoInstruction _inst) void Interpreter::mfspr(UGeckoInstruction inst)
{ {
u32 iIndex = ((_inst.SPR & 0x1F) << 5) + ((_inst.SPR >> 5) & 0x1F); u32 iIndex = ((inst.SPR & 0x1F) << 5) + ((inst.SPR >> 5) & 0x1F);
// TODO - check processor privilege level - many of these require privilege // TODO - check processor privilege level - many of these require privilege
// XER LR CTR are the only ones available in user mode, time base can be read too. // XER LR CTR are the only ones available in user mode, time base can be read too.
@ -241,14 +241,14 @@ void Interpreter::mfspr(UGeckoInstruction _inst)
rSPR(iIndex) = GetXER().Hex; rSPR(iIndex) = GetXER().Hex;
break; break;
} }
rGPR[_inst.RD] = rSPR(iIndex); rGPR[inst.RD] = rSPR(iIndex);
} }
void Interpreter::mtspr(UGeckoInstruction _inst) void Interpreter::mtspr(UGeckoInstruction inst)
{ {
u32 iIndex = (_inst.SPRU << 5) | (_inst.SPRL & 0x1F); u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F);
u32 oldValue = rSPR(iIndex); u32 oldValue = rSPR(iIndex);
rSPR(iIndex) = rGPR[_inst.RD]; rSPR(iIndex) = rGPR[inst.RD];
// TODO - check processor privilege level - many of these require privilege // TODO - check processor privilege level - many of these require privilege
// XER LR CTR are the only ones available in user mode, time base can be read too. // XER LR CTR are the only ones available in user mode, time base can be read too.
@ -265,12 +265,12 @@ void Interpreter::mtspr(UGeckoInstruction _inst)
break; break;
case SPR_TL_W: case SPR_TL_W:
TL = rGPR[_inst.RD]; TL = rGPR[inst.RD];
SystemTimers::TimeBaseSet(); SystemTimers::TimeBaseSet();
break; break;
case SPR_TU_W: case SPR_TU_W:
TU = rGPR[_inst.RD]; TU = rGPR[inst.RD];
SystemTimers::TimeBaseSet(); SystemTimers::TimeBaseSet();
break; break;
@ -313,7 +313,7 @@ void Interpreter::mtspr(UGeckoInstruction _inst)
break; break;
case SPR_WPAR: case SPR_WPAR:
_assert_msg_(POWERPC, rGPR[_inst.RD] == 0x0C008000, "Gather pipe @ %08x", PC); _assert_msg_(POWERPC, rGPR[inst.RD] == 0x0C008000, "Gather pipe @ %08x", PC);
GPFifo::ResetGatherPipe(); GPFifo::ResetGatherPipe();
break; break;
@ -353,7 +353,7 @@ void Interpreter::mtspr(UGeckoInstruction _inst)
break; break;
case SPR_DEC: case SPR_DEC:
if (!(oldValue >> 31) && (rGPR[_inst.RD] >> 31)) // top bit from 0 to 1 if (!(oldValue >> 31) && (rGPR[inst.RD] >> 31)) // top bit from 0 to 1
{ {
PanicAlert("Interesting - Software triggered Decrementer exception"); PanicAlert("Interesting - Software triggered Decrementer exception");
PowerPC::ppcState.Exceptions |= EXCEPTION_DECREMENTER; PowerPC::ppcState.Exceptions |= EXCEPTION_DECREMENTER;
@ -418,67 +418,67 @@ void Interpreter::mtspr(UGeckoInstruction _inst)
} }
} }
void Interpreter::crand(UGeckoInstruction _inst) void Interpreter::crand(UGeckoInstruction inst)
{ {
SetCRBit(_inst.CRBD, GetCRBit(_inst.CRBA) & GetCRBit(_inst.CRBB)); SetCRBit(inst.CRBD, GetCRBit(inst.CRBA) & GetCRBit(inst.CRBB));
} }
void Interpreter::crandc(UGeckoInstruction _inst) void Interpreter::crandc(UGeckoInstruction inst)
{ {
SetCRBit(_inst.CRBD, GetCRBit(_inst.CRBA) & (1 ^ GetCRBit(_inst.CRBB))); SetCRBit(inst.CRBD, GetCRBit(inst.CRBA) & (1 ^ GetCRBit(inst.CRBB)));
} }
void Interpreter::creqv(UGeckoInstruction _inst) void Interpreter::creqv(UGeckoInstruction inst)
{ {
SetCRBit(_inst.CRBD, 1 ^ (GetCRBit(_inst.CRBA) ^ GetCRBit(_inst.CRBB))); SetCRBit(inst.CRBD, 1 ^ (GetCRBit(inst.CRBA) ^ GetCRBit(inst.CRBB)));
} }
void Interpreter::crnand(UGeckoInstruction _inst) void Interpreter::crnand(UGeckoInstruction inst)
{ {
SetCRBit(_inst.CRBD, 1 ^ (GetCRBit(_inst.CRBA) & GetCRBit(_inst.CRBB))); SetCRBit(inst.CRBD, 1 ^ (GetCRBit(inst.CRBA) & GetCRBit(inst.CRBB)));
} }
void Interpreter::crnor(UGeckoInstruction _inst) void Interpreter::crnor(UGeckoInstruction inst)
{ {
SetCRBit(_inst.CRBD, 1 ^ (GetCRBit(_inst.CRBA) | GetCRBit(_inst.CRBB))); SetCRBit(inst.CRBD, 1 ^ (GetCRBit(inst.CRBA) | GetCRBit(inst.CRBB)));
} }
void Interpreter::cror(UGeckoInstruction _inst) void Interpreter::cror(UGeckoInstruction inst)
{ {
SetCRBit(_inst.CRBD, (GetCRBit(_inst.CRBA) | GetCRBit(_inst.CRBB))); SetCRBit(inst.CRBD, (GetCRBit(inst.CRBA) | GetCRBit(inst.CRBB)));
} }
void Interpreter::crorc(UGeckoInstruction _inst) void Interpreter::crorc(UGeckoInstruction inst)
{ {
SetCRBit(_inst.CRBD, (GetCRBit(_inst.CRBA) | (1 ^ GetCRBit(_inst.CRBB)))); SetCRBit(inst.CRBD, (GetCRBit(inst.CRBA) | (1 ^ GetCRBit(inst.CRBB))));
} }
void Interpreter::crxor(UGeckoInstruction _inst) void Interpreter::crxor(UGeckoInstruction inst)
{ {
SetCRBit(_inst.CRBD, (GetCRBit(_inst.CRBA) ^ GetCRBit(_inst.CRBB))); SetCRBit(inst.CRBD, (GetCRBit(inst.CRBA) ^ GetCRBit(inst.CRBB)));
} }
void Interpreter::mcrf(UGeckoInstruction _inst) void Interpreter::mcrf(UGeckoInstruction inst)
{ {
int cr_f = GetCRField(_inst.CRFS); int cr_f = GetCRField(inst.CRFS);
SetCRField(_inst.CRFD, cr_f); SetCRField(inst.CRFD, cr_f);
} }
void Interpreter::isync(UGeckoInstruction _inst) void Interpreter::isync(UGeckoInstruction inst)
{ {
// shouldn't do anything // shouldn't do anything
} }
// the following commands read from FPSCR // the following commands read from FPSCR
void Interpreter::mcrfs(UGeckoInstruction _inst) void Interpreter::mcrfs(UGeckoInstruction inst)
{ {
// if (_inst.CRFS != 3 && _inst.CRFS != 4) // if (_inst.CRFS != 3 && _inst.CRFS != 4)
// PanicAlert("msrfs at %x, CRFS = %d, CRFD = %d", PC, (int)_inst.CRFS, (int)_inst.CRFD); // PanicAlert("msrfs at %x, CRFS = %d, CRFD = %d", PC, (int)_inst.CRFS, (int)_inst.CRFD);
UpdateFPSCR(); UpdateFPSCR();
u32 fpflags = ((FPSCR.Hex >> (4 * (7 - _inst.CRFS))) & 0xF); u32 fpflags = ((FPSCR.Hex >> (4 * (7 - inst.CRFS))) & 0xF);
switch (_inst.CRFS) switch (inst.CRFS)
{ {
case 0: case 0:
FPSCR.FX = 0; FPSCR.FX = 0;
@ -505,17 +505,17 @@ void Interpreter::mcrfs(UGeckoInstruction _inst)
FPSCR.VXCVI = 0; FPSCR.VXCVI = 0;
break; break;
} }
SetCRField(_inst.CRFD, fpflags); SetCRField(inst.CRFD, fpflags);
} }
void Interpreter::mffsx(UGeckoInstruction _inst) void Interpreter::mffsx(UGeckoInstruction inst)
{ {
// load from FPSCR // load from FPSCR
// TODO(ector): grab all overflow flags etc and set them in FPSCR // TODO(ector): grab all overflow flags etc and set them in FPSCR
UpdateFPSCR(); UpdateFPSCR();
riPS0(_inst.FD) = 0xFFF8000000000000 | FPSCR.Hex; riPS0(inst.FD) = 0xFFF8000000000000 | FPSCR.Hex;
if (_inst.Rc) if (inst.Rc)
PanicAlert("mffsx: inst_.Rc"); PanicAlert("mffsx: inst_.Rc");
} }