Skip to content

Commit

Permalink
x86/iR5900: Fix quadword stores on Linux
Browse files Browse the repository at this point in the history
Linux counts vector and GPR registers separately for which register
they get passed in when calling functions.

Windows uses the argument position.
  • Loading branch information
stenzek authored and lightningterror committed Oct 16, 2022
1 parent 8981572 commit 48926a7
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
37 changes: 36 additions & 1 deletion common/emitter/x86types.h
Expand Up @@ -442,6 +442,11 @@ namespace x86Emitter

static const inline xRegisterSSE& GetInstance(uint id);
static const inline xRegisterSSE& GetYMMInstance(uint id);

/// Returns the register to use when calling a C function.
/// arg_number is the argument position from the left, starting with 0.
/// sse_number is the argument position relative to the number of vector registers.
static const inline xRegisterSSE& GetArgRegister(uint arg_number, uint sse_number, bool ymm = false);
};

class xRegisterCL : public xRegister8
Expand Down Expand Up @@ -483,14 +488,18 @@ namespace x86Emitter
// Returns true if the register is the stack pointer: ESP.
bool IsStackPointer() const { return Id == 4; }

/// Returns the register to use when calling a C function.
/// arg_number is the argument position from the left, starting with 0.
/// sse_number is the argument position relative to the number of vector registers.
static const inline xAddressReg& GetArgRegister(uint arg_number, uint gpr_number);

xAddressVoid operator+(const xAddressReg& right) const;
xAddressVoid operator+(sptr right) const;
xAddressVoid operator+(const void* right) const;
xAddressVoid operator-(sptr right) const;
xAddressVoid operator-(const void* right) const;
xAddressVoid operator*(int factor) const;
xAddressVoid operator<<(u32 shift) const;
xAddressReg& operator=(const xAddressReg&) = default;
};

// --------------------------------------------------------------------------------------
Expand Down Expand Up @@ -653,6 +662,32 @@ extern const xRegister32
return *m_tbl_ymmRegs[id];
}

const xRegisterSSE& xRegisterSSE::GetArgRegister(uint arg_number, uint sse_number, bool ymm)
{
#ifdef _WIN32
// Windows passes arguments according to their position from the left.
return ymm ? GetYMMInstance(arg_number) : GetInstance(arg_number);
#else
// Linux counts the number of vector parameters.
return ymm ? GetYMMInstance(sse_number) : GetInstance(sse_number);
#endif
}

const xAddressReg& xAddressReg::GetArgRegister(uint arg_number, uint gpr_number)
{
#ifdef _WIN32
// Windows passes arguments according to their position from the left.
static constexpr const xAddressReg* regs[] = {&rcx, &rdx, &r8, &r9};
pxAssert(arg_number < std::size(regs));
return *regs[arg_number];
#else
// Linux counts the number of GPR parameters.
static constexpr const xAddressReg* regs[] = {&rdi, &rsi, &rdx, &rcx};
pxAssert(gpr_number < std::size(regs));
return *regs[gpr_number];
#endif
}

// --------------------------------------------------------------------------------------
// xAddressVoid
// --------------------------------------------------------------------------------------
Expand Down
13 changes: 7 additions & 6 deletions pcsx2/x86/ix86-32/iR5900LoadStore.cpp
Expand Up @@ -200,9 +200,10 @@ static void recStore(u32 bits)
else
{
_flushEEreg(_Rt_); // flush register to mem
int rpreg = _allocTempXMMreg(XMMT_INT, 1);
xMOVAPS(xRegisterSSE(rpreg), ptr128[&cpuRegs.GPR.r[_Rt_].UL[0]]);
_freeXMMreg(rpreg);

const xRegisterSSE& dreg = xRegisterSSE::GetArgRegister(1, 0);
_freeXMMreg(dreg.GetId());
xMOVAPS(dreg, ptr128[&cpuRegs.GPR.r[_Rt_].UL[0]]);
}

// Load ECX with the destination address, or issue a direct optimized write
Expand Down Expand Up @@ -981,9 +982,9 @@ void recSQC2()
skip.SetTarget();
skipvuidle.SetTarget();

int rpreg = _allocTempXMMreg(XMMT_INT, 1);
xMOVAPS(xRegisterSSE(rpreg), ptr128[&VU0.VF[_Ft_].UD[0]]);
_freeXMMreg(rpreg);
const xRegisterSSE& dreg = xRegisterSSE::GetArgRegister(1, 0);
_freeXMMreg(dreg.GetId());
xMOVAPS(dreg, ptr128[&VU0.VF[_Ft_].UD[0]]);

if (GPR_IS_CONST1(_Rs_))
{
Expand Down
6 changes: 3 additions & 3 deletions pcsx2/x86/ix86-32/recVTLB.cpp
Expand Up @@ -161,7 +161,7 @@ namespace vtlb_private
break;

case 128:
xMOVAPS(ptr[arg1reg], xmm1);
xMOVAPS(ptr[arg1reg], xRegisterSSE::GetArgRegister(1, 0));
break;
}
}
Expand Down Expand Up @@ -514,7 +514,7 @@ void vtlb_DynGenWrite_Const(u32 bits, u32 addr_const)
break;

case 128:
xMOVAPS(ptr128[(void*)ppf], xmm1);
xMOVAPS(ptr128[(void*)ppf], xRegisterSSE::GetArgRegister(1, 0));
break;
}
}
Expand All @@ -534,7 +534,7 @@ void vtlb_DynGenWrite_Const(u32 bits, u32 addr_const)
}

iFlushCall(FLUSH_FULLVTLB);
xFastCall(vmv.assumeHandlerGetRaw(szidx, true), paddr, arg2reg);
xFastCall(vmv.assumeHandlerGetRaw(szidx, true), paddr);
}
}

Expand Down

0 comments on commit 48926a7

Please sign in to comment.