More linux prep

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@121 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-08-01 09:30:04 +00:00
parent 73a8bb9b2f
commit 814af6c7b9
4 changed files with 82 additions and 65 deletions

View File

@ -29,6 +29,14 @@ void ABI_CallFunctionR(void *func, X64Reg reg1) {
ADD(32, R(ESP), Imm8(4)); ADD(32, R(ESP), Imm8(4));
} }
void ABI_CallFunctionRR(void *func, Gen::X64Reg reg1, Gen::X64Reg reg2)
{
PUSH(32, R(reg2));
PUSH(32, R(reg1));
CALL(func);
ADD(32, R(ESP), Imm8(8));
}
void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2) void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2)
{ {
PUSH(32, arg1); PUSH(32, arg1);
@ -74,6 +82,15 @@ void ABI_CallFunctionR(void *func, X64Reg reg1) {
CALL(func); CALL(func);
} }
// Pass a register as a paremeter.
void ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2) {
if (reg1 != ABI_PARAM1)
MOV(32, R(ABI_PARAM1), R(reg1));
if (reg2 != ABI_PARAM2)
MOV(32, R(ABI_PARAM2), R(reg2));
CALL(func);
}
void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2) void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2)
{ {
if (!arg1.IsSimpleReg(ABI_PARAM1)) if (!arg1.IsSimpleReg(ABI_PARAM1))

View File

@ -48,6 +48,11 @@
#ifdef _M_IX86 #ifdef _M_IX86
// 32 bit calling convention, shared by all // 32 bit calling convention, shared by all
// 32-bit don't pass parameters in regs, but these are convenient to have anyway when we have to
// choose regs to put stuff in.
#define ABI_PARAM1 RCX
#define ABI_PARAM2 RDX
// There are no ABI_PARAM* here, since args are pushed. // There are no ABI_PARAM* here, since args are pushed.
// === 32-bit bog standard cdecl, shared between linux and windows ============================ // === 32-bit bog standard cdecl, shared between linux and windows ============================
@ -85,6 +90,7 @@ void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2);
// Pass a register as a paremeter. // Pass a register as a paremeter.
void ABI_CallFunctionR(void *func, Gen::X64Reg reg1); void ABI_CallFunctionR(void *func, Gen::X64Reg reg1);
void ABI_CallFunctionRR(void *func, Gen::X64Reg reg1, Gen::X64Reg reg2);
void ABI_PushAllCalleeSavedRegsAndAdjustStack(); void ABI_PushAllCalleeSavedRegsAndAdjustStack();
void ABI_PopAllCalleeSavedRegsAndAdjustStack(); void ABI_PopAllCalleeSavedRegsAndAdjustStack();

View File

@ -87,10 +87,10 @@ namespace Jit64
gpr.LoadToX64(d, true, true); gpr.LoadToX64(d, true, true);
else else
gpr.LoadToX64(d, false, true); gpr.LoadToX64(d, false, true);
MOV(32, R(ECX), gpr.R(b)); MOV(32, R(ABI_PARAM1), gpr.R(b));
if (a) if (a)
ADD(32, R(ECX), gpr.R(a)); ADD(32, R(ABI_PARAM1), gpr.R(a));
SafeLoadRegToEAX(ECX, 8, 0); SafeLoadRegToEAX(ABI_PARAM1, 8, 0);
MOV(32, gpr.R(d), R(EAX)); MOV(32, gpr.R(d), R(EAX));
gpr.UnlockAll(); gpr.UnlockAll();
} }
@ -143,8 +143,8 @@ namespace Jit64
// Safe and boring // Safe and boring
gpr.Flush(FLUSH_VOLATILE); gpr.Flush(FLUSH_VOLATILE);
gpr.Lock(d, a); gpr.Lock(d, a);
MOV(32, R(ECX), gpr.R(a)); MOV(32, R(ABI_PARAM1), gpr.R(a));
SafeLoadRegToEAX(ECX, accessSize, offset); SafeLoadRegToEAX(ABI_PARAM1, accessSize, offset);
gpr.LoadToX64(d, false, true); gpr.LoadToX64(d, false, true);
MOV(32, gpr.R(d), R(EAX)); MOV(32, gpr.R(d), R(EAX));
gpr.UnlockAll(); gpr.UnlockAll();
@ -184,7 +184,7 @@ namespace Jit64
gpr.Flush(FLUSH_VOLATILE); gpr.Flush(FLUSH_VOLATILE);
gpr.Lock(d, a); gpr.Lock(d, a);
MOV(32,R(ECX), gpr.R(a)); MOV(32, R(ABI_PARAM1), gpr.R(a));
#ifdef _M_X64 #ifdef _M_X64
if (!jo.noAssumeFPLoadFromMem) if (!jo.noAssumeFPLoadFromMem)
{ {
@ -197,7 +197,7 @@ namespace Jit64
else else
#endif #endif
{ {
SafeLoadRegToEAX(ECX, 32, offset); SafeLoadRegToEAX(ABI_PARAM1, 32, offset);
} }
MOV(32, M(&temp32), R(EAX)); MOV(32, M(&temp32), R(EAX));
@ -271,21 +271,21 @@ namespace Jit64
gpr.Flush(FLUSH_VOLATILE); gpr.Flush(FLUSH_VOLATILE);
gpr.Lock(a); gpr.Lock(a);
fpr.Lock(s); fpr.Lock(s);
MOV(32,R(EDX),gpr.R(a)); MOV(32, R(ABI_PARAM2), gpr.R(a));
if (offset) if (offset)
ADD(32,R(EDX),Imm32((u32)offset)); ADD(32, R(ABI_PARAM2), Imm32((u32)offset));
if (update && offset) if (update && offset)
{ {
MOV(32,gpr.R(a),R(EDX)); MOV(32, gpr.R(a), R(ABI_PARAM2));
} }
CVTSD2SS(XMM0,fpr.R(s)); CVTSD2SS(XMM0, fpr.R(s));
MOVSS(M(&temp32),XMM0); MOVSS(M(&temp32), XMM0);
MOV(32,R(ECX),M(&temp32)); MOV(32, R(ABI_PARAM1), M(&temp32));
TEST(32,R(EDX),Imm32(0x0C000000)); TEST(32, R(ABI_PARAM2), Imm32(0x0C000000));
FixupBranch argh = J_CC(CC_NZ); FixupBranch argh = J_CC(CC_NZ);
BSWAP(32,ECX); BSWAP(32, ABI_PARAM1);
MOV(32, MComplex(RBX, EDX, SCALE_1, 0), R(ECX)); MOV(32, MComplex(RBX, ABI_PARAM2, SCALE_1, 0), R(ABI_PARAM1));
FixupBranch arg2 = J(); FixupBranch arg2 = J();
SetJumpTarget(argh); SetJumpTarget(argh);
CALL((void *)&Memory::Write_U32); CALL((void *)&Memory::Write_U32);
@ -358,7 +358,7 @@ namespace Jit64
case 38: accessSize = 8; break; //stb case 38: accessSize = 8; break; //stb
default: _assert_msg_(DYNA_REC, 0, "AWETKLJASDLKF"); return; default: _assert_msg_(DYNA_REC, 0, "AWETKLJASDLKF"); return;
} }
/*
if (gpr.R(a).IsImm() && !update) if (gpr.R(a).IsImm() && !update)
{ {
u32 addr = (u32)gpr.R(a).offset; u32 addr = (u32)gpr.R(a).offset;
@ -424,48 +424,41 @@ namespace Jit64
ADD(32, gpr.R(a), Imm32(offset)); ADD(32, gpr.R(a), Imm32(offset));
return; return;
} }
*/
//Still here? Do regular path. //Still here? Do regular path.
gpr.Lock(s, a); gpr.Lock(s, a);
MOV(32, R(EDX), gpr.R(a)); MOV(32, R(ABI_PARAM2), gpr.R(a));
MOV(32, R(ECX), gpr.R(s)); MOV(32, R(ABI_PARAM1), gpr.R(s));
if (offset) if (offset)
ADD(32, R(EDX), Imm32((u32)offset)); ADD(32, R(ABI_PARAM2), Imm32((u32)offset));
if (update && offset) if (update && offset)
{ {
MOV(32, gpr.R(a), R(EDX)); MOV(32, gpr.R(a), R(ABI_PARAM2));
} }
TEST(32, R(EDX), Imm32(0x0C000000)); TEST(32, R(ABI_PARAM2), Imm32(0x0C000000));
FixupBranch argh = J_CC(CC_NZ); FixupBranch argh = J_CC(CC_NZ);
if (accessSize == 32) if (accessSize == 32)
BSWAP(32, ECX); BSWAP(32, ABI_PARAM1);
else if (accessSize == 16) else if (accessSize == 16)
{ {
// TODO(ector): xchg ch, cl? // TODO(ector): xchg ch, cl?
BSWAP(32, ECX); BSWAP(32, ABI_PARAM1);
SHR(32, R(ECX), Imm8(16)); SHR(32, R(ABI_PARAM1), Imm8(16));
} }
#ifdef _M_X64 #ifdef _M_X64
MOV(accessSize, MComplex(RBX, EDX, SCALE_1, 0), R(ECX)); MOV(accessSize, MComplex(RBX, ABI_PARAM2, SCALE_1, 0), R(ABI_PARAM1));
#else #else
AND(32, R(EDX), Imm32(Memory::MEMVIEW32_MASK)); AND(32, R(ABI_PARAM2), Imm32(Memory::MEMVIEW32_MASK));
MOV(accessSize, MDisp(EDX, (u32)Memory::base), R(ECX)); MOV(accessSize, MDisp(ABI_PARAM2, (u32)Memory::base), R(ABI_PARAM1));
#endif #endif
FixupBranch arg2 = J(); FixupBranch arg2 = J();
SetJumpTarget(argh); SetJumpTarget(argh);
#ifdef _M_IX86
PUSH(EDX);
PUSH(ECX);
#endif
switch (accessSize) switch (accessSize)
{ {
case 32: CALL((void *)&Memory::Write_U32); break; case 32: ABI_CallFunctionRR((void *)&Memory::Write_U32, ABI_PARAM1, ABI_PARAM2); break;
case 16: CALL((void *)&Memory::Write_U16); break; case 16: ABI_CallFunctionRR((void *)&Memory::Write_U16, ABI_PARAM1, ABI_PARAM2); break;
case 8: CALL((void *)&Memory::Write_U8); break; case 8: ABI_CallFunctionRR((void *)&Memory::Write_U8, ABI_PARAM1, ABI_PARAM2); break;
} }
#ifdef _M_IX86
ADD(32, R(ESP), Imm8(8));
#endif
SetJumpTarget(arg2); SetJumpTarget(arg2);
gpr.UnlockAll(); gpr.UnlockAll();
} }

View File

@ -26,6 +26,7 @@
#include "../../HW/Memmap.h" #include "../../HW/Memmap.h"
#include "../PPCTables.h" #include "../PPCTables.h"
#include "x64Emitter.h" #include "x64Emitter.h"
#include "ABI.h"
#include "Jit.h" #include "Jit.h"
#include "JitCache.h" #include "JitCache.h"
@ -111,7 +112,7 @@ void psq_st(UGeckoInstruction inst)
const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE); const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
int stScale = gqr.ST_SCALE; int stScale = gqr.ST_SCALE;
bool update = inst.OPCD == 61; bool update = inst.OPCD == 61;
if (!inst.RA || inst.W) if (update || !inst.RA || inst.W)
{ {
// PanicAlert(inst.RA ? "W" : "inst"); // PanicAlert(inst.RA ? "W" : "inst");
Default(inst); Default(inst);
@ -129,25 +130,25 @@ void psq_st(UGeckoInstruction inst)
fpr.Lock(s); fpr.Lock(s);
if (update) if (update)
gpr.LoadToX64(a, true, true); gpr.LoadToX64(a, true, true);
MOV(32, R(EDX), gpr.R(a)); MOV(32, R(ABI_PARAM2), gpr.R(a));
if (offset) if (offset)
ADD(32, R(EDX), Imm32((u32)offset)); ADD(32, R(ABI_PARAM2), Imm32((u32)offset));
TEST(32, R(EDX), Imm32(0x0C000000)); TEST(32, R(ABI_PARAM2), Imm32(0x0C000000));
if (update && offset) if (update && offset)
MOV(32, gpr.R(a), R(EDX)); MOV(32, gpr.R(a), R(ABI_PARAM2));
CVTPD2PS(XMM0, fpr.R(s)); CVTPD2PS(XMM0, fpr.R(s));
SHUFPS(XMM0, R(XMM0), 1); SHUFPS(XMM0, R(XMM0), 1);
MOVAPS(M(&temp64), XMM0); MOVAPS(M(&temp64), XMM0);
MOV(64, R(ECX), M(&temp64)); MOV(64, R(ABI_PARAM1), M(&temp64));
FixupBranch argh = J_CC(CC_NZ); FixupBranch argh = J_CC(CC_NZ);
BSWAP(64, ECX); BSWAP(64, ABI_PARAM1);
MOV(64, MComplex(RBX, EDX, SCALE_1, 0), R(ECX)); MOV(64, MComplex(RBX, ABI_PARAM2, SCALE_1, 0), R(ABI_PARAM1));
FixupBranch arg2 = J(); FixupBranch arg2 = J();
SetJumpTarget(argh); SetJumpTarget(argh);
CALL((void *)&WriteDual32); CALL((void *)&WriteDual32);
SetJumpTarget(arg2); SetJumpTarget(arg2);
if (update) if (update)
MOV(32, gpr.R(a), R(EDX)); MOV(32, gpr.R(a), R(ABI_PARAM2));
gpr.UnlockAll(); gpr.UnlockAll();
fpr.UnlockAll(); fpr.UnlockAll();
} }
@ -158,9 +159,9 @@ void psq_st(UGeckoInstruction inst)
fpr.Lock(s); fpr.Lock(s);
if (update) if (update)
gpr.LoadToX64(a, true, update); gpr.LoadToX64(a, true, update);
MOV(32, R(EDX), gpr.R(a)); MOV(32, R(ABI_PARAM2), gpr.R(a));
if (offset) if (offset)
ADD(32,R(EDX),Imm32((u32)offset)); ADD(32, R(ABI_PARAM2), Imm32((u32)offset));
MOVAPS(XMM0, fpr.R(s)); MOVAPS(XMM0, fpr.R(s));
MOVDDUP(XMM1, M((void*)&m_quantizeTableD[stScale])); MOVDDUP(XMM1, M((void*)&m_quantizeTableD[stScale]));
MULPD(XMM0, R(XMM1)); MULPD(XMM0, R(XMM1));
@ -168,16 +169,16 @@ void psq_st(UGeckoInstruction inst)
PACKSSDW(XMM0, R(XMM0)); PACKSSDW(XMM0, R(XMM0));
PACKUSWB(XMM0, R(XMM0)); PACKUSWB(XMM0, R(XMM0));
MOVAPS(M(&temp64), XMM0); MOVAPS(M(&temp64), XMM0);
MOV(16, R(ECX), M(&temp64)); MOV(16, R(ABI_PARAM1), M(&temp64));
#ifdef _M_X64 #ifdef _M_X64
MOV(16, MComplex(RBX, RDX, SCALE_1, 0), R(ECX)); MOV(16, MComplex(RBX, RDX, SCALE_1, 0), R(ABI_PARAM1));
#else #else
BSWAP(32, ECX); BSWAP(32, ABI_PARAM1);
SHR(32, R(ECX), Imm8(16)); SHR(32, R(ABI_PARAM1), Imm8(16));
CALL(&Memory::Write_U16); CALL(&Memory::Write_U16);
#endif #endif
if (update) if (update)
MOV(32, gpr.R(a), R(EDX)); MOV(32, gpr.R(a), R(ABI_PARAM2));
gpr.UnlockAll(); gpr.UnlockAll();
fpr.UnlockAll(); fpr.UnlockAll();
} }
@ -187,9 +188,9 @@ void psq_st(UGeckoInstruction inst)
fpr.Lock(s); fpr.Lock(s);
if (update) if (update)
gpr.LoadToX64(a, true, update); gpr.LoadToX64(a, true, update);
MOV(32, R(EDX), gpr.R(a)); MOV(32, R(ABI_PARAM2), gpr.R(a));
if (offset) if (offset)
ADD(32,R(EDX),Imm32((u32)offset)); ADD(32, R(ABI_PARAM2), Imm32((u32)offset));
MOVAPS(XMM0, fpr.R(s)); MOVAPS(XMM0, fpr.R(s));
MOVDDUP(XMM1, M((void*)&m_quantizeTableD[stScale])); MOVDDUP(XMM1, M((void*)&m_quantizeTableD[stScale]));
MULPD(XMM0, R(XMM1)); MULPD(XMM0, R(XMM1));
@ -197,16 +198,16 @@ void psq_st(UGeckoInstruction inst)
CVTPD2DQ(XMM0, R(XMM0)); CVTPD2DQ(XMM0, R(XMM0));
PACKSSDW(XMM0, R(XMM0)); PACKSSDW(XMM0, R(XMM0));
MOVD_xmm(M(&temp64), XMM0); MOVD_xmm(M(&temp64), XMM0);
MOV(32, R(ECX), M(&temp64)); MOV(32, R(ABI_PARAM1), M(&temp64));
#ifdef _M_X64 #ifdef _M_X64
BSWAP(32, ECX); BSWAP(32, ABI_PARAM1);
MOV(32, MComplex(RBX, RDX, SCALE_1, 0), R(ECX)); MOV(32, MComplex(RBX, RDX, SCALE_1, 0), R(ABI_PARAM1));
#else #else
BSWAP(32, ECX); BSWAP(32, ABI_PARAM1);
CALL(&Memory::Write_U32); CALL(&Memory::Write_U32);
#endif #endif
if (update) if (update)
MOV(32, gpr.R(a), R(EDX)); MOV(32, gpr.R(a), R(ABI_PARAM2));
gpr.UnlockAll(); gpr.UnlockAll();
fpr.UnlockAll(); fpr.UnlockAll();
} }
@ -231,14 +232,14 @@ void psq_l(UGeckoInstruction inst)
const UGQR gqr(rSPR(SPR_GQR0 + inst.I)); const UGQR gqr(rSPR(SPR_GQR0 + inst.I));
const EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE); const EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE);
int ldScale = gqr.LD_SCALE; int ldScale = gqr.LD_SCALE;
if (!inst.RA || inst.W) bool update = inst.OPCD == 57;
if (update || !inst.RA || inst.W)
{ {
// 0 1 during load // 0 1 during load
//PanicAlert("ld:%i %i", ldType, (int)inst.W); //PanicAlert("ld:%i %i", ldType, (int)inst.W);
Default(inst); Default(inst);
return; return;
} }
bool update = inst.OPCD == 57;
int offset = inst.SIMM_12; int offset = inst.SIMM_12;
//INT3(); //INT3();
switch (ldType) { switch (ldType) {
@ -248,7 +249,7 @@ void psq_l(UGeckoInstruction inst)
gpr.LoadToX64(inst.RA); gpr.LoadToX64(inst.RA);
MOV(64, R(RAX), MComplex(RBX, gpr.R(inst.RA).GetSimpleReg(), 1, offset)); MOV(64, R(RAX), MComplex(RBX, gpr.R(inst.RA).GetSimpleReg(), 1, offset));
BSWAP(64, RAX); BSWAP(64, RAX);
MOV(64, M(&psTemp[0]),R(RAX)); MOV(64, M(&psTemp[0]), R(RAX));
fpr.LoadToX64(inst.RS, false); fpr.LoadToX64(inst.RS, false);
X64Reg r = fpr.R(inst.RS).GetSimpleReg(); X64Reg r = fpr.R(inst.RS).GetSimpleReg();
CVTPS2PD(r, M(&psTemp[0])); CVTPS2PD(r, M(&psTemp[0]));