From 96bab6bdd8893d7c07b962141a2951cf682bc3ff Mon Sep 17 00:00:00 2001 From: magumagu9 Date: Mon, 5 Jan 2009 00:32:51 +0000 Subject: [PATCH] Small WIP JIT improvement: implement stfs. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1782 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp | 16 ++++ Source/Core/Core/Src/PowerPC/Jit64IL/IR.h | 4 + .../PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp | 81 ++++--------------- 3 files changed, 35 insertions(+), 66 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp index a06431f8d1..791e7f377c 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp @@ -1103,6 +1103,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { regMarkUse(RI, I, getOp1(I), 1); regMarkMemAddress(RI, I, getOp2(I), 2); break; + case StoreSingle: case StorePaired: regMarkUse(RI, I, getOp1(I), 1); regMarkUse(RI, I, getOp2(I), 2); @@ -1433,6 +1434,21 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { regNormalRegClear(RI, I); break; } + case StoreSingle: { + regSpill(RI, EAX); + if (fregLocForInst(RI, getOp1(I)).IsSimpleReg()) { + Jit->MOVD_xmm(R(EAX), fregLocForInst(RI, getOp1(I)).GetSimpleReg()); + } else { + Jit->MOV(32, R(EAX), fregLocForInst(RI, getOp1(I))); + } + Jit->MOV(32, R(ECX), regLocForInst(RI, getOp2(I))); + RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 0); + if (RI.IInfo[I - RI.FirstI] & 4) + fregClearInst(RI, getOp1(I)); + if (RI.IInfo[I - RI.FirstI] & 8) + regClearInst(RI, getOp2(I)); + break; + } case StorePaired: { regSpill(RI, EAX); regSpill(RI, EDX); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h index 092831ed03..4db1100791 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h @@ -163,6 +163,7 @@ namespace IREmitter { FPNeg, FResult_End, StorePaired, + StoreSingle, StoreFReg, // "Trinary" operators @@ -376,6 +377,9 @@ namespace IREmitter { InstLoc EmitLoadPaired(InstLoc addr, unsigned quantReg) { return FoldUOp(LoadPaired, addr, quantReg); } + InstLoc EmitStoreSingle(InstLoc value, InstLoc addr) { + return FoldBiOp(StoreSingle, value, addr); + } InstLoc EmitStorePaired(InstLoc value, InstLoc addr, unsigned quantReg) { return FoldBiOp(StorePaired, value, addr, quantReg); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp index 9e70c74b4f..fca175b33c 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp @@ -185,78 +185,27 @@ void Jit64::stfd(UGeckoInstruction inst) void Jit64::stfs(UGeckoInstruction inst) { - if (Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff) - {Default(inst); return;} // turn off from debugger - INSTRUCTION_START; - - bool update = inst.OPCD & 1; - int s = inst.RS; - int a = inst.RA; - s32 offset = (s32)(s16)inst.SIMM_16; - if (!a || update) { - Default(inst); - return; - } - - if (gpr.R(a).IsImm()) - { - u32 addr = (u32)(gpr.R(a).offset + offset); - if (Memory::IsRAMAddress(addr)) - { - if (cpu_info.bSSSE3) { - CVTSD2SS(XMM0, fpr.R(s)); - PSHUFB(XMM0, M((void *)bswapShuffle1x4)); - WriteFloatToConstRamAddress(XMM0, addr); - return; - } - } - else if (addr == 0xCC008000) - { - // Float directly to write gather pipe! Fun! - CVTSD2SS(XMM0, fpr.R(s)); - CALL((void*)asm_routines.fifoDirectWriteFloat); - // TODO - js.fifoBytesThisBlock += 4; - return; - } - } - - gpr.FlushLockX(ABI_PARAM1, ABI_PARAM2); - gpr.Lock(a); - fpr.Lock(s); - MOV(32, R(ABI_PARAM2), gpr.R(a)); - ADD(32, R(ABI_PARAM2), Imm32(offset)); - if (update && offset) - { - MOV(32, gpr.R(a), R(ABI_PARAM2)); - } - CVTSD2SS(XMM0, fpr.R(s)); - MOVSS(M(&temp32), XMM0); - MOV(32, R(ABI_PARAM1), M(&temp32)); - SafeWriteRegToReg(ABI_PARAM1, ABI_PARAM2, 32, 0); - gpr.UnlockAll(); - gpr.UnlockAllX(); - fpr.UnlockAll(); + IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16), + val = ibuild.EmitLoadFReg(inst.RS); + if (inst.RA) + addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); + if (inst.OPCD & 1) + ibuild.EmitStoreGReg(addr, inst.RA); + val = ibuild.EmitDoubleToSingle(val); + ibuild.EmitStoreSingle(val, addr); + return; } void Jit64::stfsx(UGeckoInstruction inst) { - if (Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff) - {Default(inst); return;} // turn off from debugger - INSTRUCTION_START; - - // We can take a shortcut here - it's not likely that a hardware access would use this instruction. - gpr.FlushLockX(ABI_PARAM1); - fpr.Lock(inst.RS); - MOV(32, R(ABI_PARAM1), gpr.R(inst.RB)); + IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB), + val = ibuild.EmitLoadFReg(inst.RS); if (inst.RA) - ADD(32, R(ABI_PARAM1), gpr.R(inst.RA)); - CVTSD2SS(XMM0, fpr.R(inst.RS)); - MOVD_xmm(R(EAX), XMM0); - UnsafeWriteRegToReg(EAX, ABI_PARAM1, 32, 0); - gpr.UnlockAllX(); - fpr.UnlockAll(); + addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); + val = ibuild.EmitDoubleToSingle(val); + ibuild.EmitStoreSingle(val, addr); + return; }