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));
}
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)
{
PUSH(32, arg1);
@ -74,6 +82,15 @@ void ABI_CallFunctionR(void *func, X64Reg reg1) {
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)
{
if (!arg1.IsSimpleReg(ABI_PARAM1))

View File

@ -48,6 +48,11 @@
#ifdef _M_IX86
// 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.
// === 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.
void ABI_CallFunctionR(void *func, Gen::X64Reg reg1);
void ABI_CallFunctionRR(void *func, Gen::X64Reg reg1, Gen::X64Reg reg2);
void ABI_PushAllCalleeSavedRegsAndAdjustStack();
void ABI_PopAllCalleeSavedRegsAndAdjustStack();

View File

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

View File

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