void Jit64::ps_sign(UGeckoInstruction inst)
{
	INSTRUCTION_START
	JITDISABLE(bJITPairedOff);
	FALLBACK_IF(inst.Rc);

	int d = inst.FD;
	int b = inst.FB;

	fpr.Lock(d, b);
	if (d != b)
	{
		fpr.BindToRegister(d, false);
		MOVAPD(fpr.RX(d), fpr.R(b));
	}
	else
	{
		fpr.BindToRegister(d, true);
	}

	switch (inst.SUBOP10)
	{
	case 40: //neg
		PXOR(fpr.RX(d), M((void*)&psSignBits));
		break;
	case 136: //nabs
		POR(fpr.RX(d), M((void*)&psSignBits));
		break;
	case 264: //abs
		PAND(fpr.RX(d), M((void*)&psAbsMask));
		break;
	}

	fpr.UnlockAll();
}
void Jit64::ps_sel(UGeckoInstruction inst)
{
	// we can't use (V)BLENDVPD here because it just looks at the sign bit
	// but we need -0 = +0

	INSTRUCTION_START
	JITDISABLE(bJITPairedOff);
	FALLBACK_IF(inst.Rc);

	int d = inst.FD;
	int a = inst.FA;
	int b = inst.FB;
	int c = inst.FC;

	fpr.Lock(a, b, c, d);
	MOVAPD(XMM0, fpr.R(a));
	PXOR(XMM1, R(XMM1));
	// XMM0 = XMM0 < 0 ? all 1s : all 0s
	CMPPD(XMM0, R(XMM1), LT);
	MOVAPD(XMM1, R(XMM0));
	PAND(XMM0, fpr.R(b));
	PANDN(XMM1, fpr.R(c));
	POR(XMM0, R(XMM1));
	fpr.BindToRegister(d, false);
	MOVAPD(fpr.RX(d), R(XMM0));
	fpr.UnlockAll();
}
void Jit64::fsign(UGeckoInstruction inst)
{
	INSTRUCTION_START
	JITDISABLE(bJITFloatingPointOff);
	FALLBACK_IF(inst.Rc);

	int d = inst.FD;
	int b = inst.FB;
	fpr.Lock(b, d);
	fpr.BindToRegister(d, true, true);
	MOVSD(XMM0, fpr.R(b));
	switch (inst.SUBOP10) {
	case 40:  // fnegx
		PXOR(XMM0, M((void*)&psSignBits2));
		break;
	case 264: // fabsx
		PAND(XMM0, M((void*)&psAbsMask2));
		break;
	case 136: // fnabs
		POR(XMM0, M((void*)&psSignBits2));
		break;
	default:
		PanicAlert("fsign bleh");
		break;
	}
	MOVSD(fpr.R(d), XMM0);
	fpr.UnlockAll();
}
Exemple #4
0
bool SamplerJitCache::Jit_Decode4444() {
	MOVD_xmm(fpScratchReg1, R(resultReg));
	PUNPCKLBW(fpScratchReg1, R(fpScratchReg1));
	if (RipAccessible(color4444mask)) {
		PAND(fpScratchReg1, M(color4444mask));  // rip accessible
	} else {
		Crash();
	}
	MOVSS(fpScratchReg2, R(fpScratchReg1));
	MOVSS(fpScratchReg3, R(fpScratchReg1));
	PSRLW(fpScratchReg2, 4);
	PSLLW(fpScratchReg3, 4);
	POR(fpScratchReg1, R(fpScratchReg2));
	POR(fpScratchReg1, R(fpScratchReg3));
	MOVD_xmm(R(resultReg), fpScratchReg1);
	return true;
}
Exemple #5
0
void Jit::CompFPComp(int lhs, int rhs, u8 compare, bool allowNaN) {
	gpr.MapReg(MIPS_REG_FPCOND, false, true);

	// This means that NaN also means true, e.g. !<> or !>, etc.
	if (allowNaN) {
		CopyFPReg(XMM0, fpr.R(lhs));
		CopyFPReg(XMM1, fpr.R(lhs));
		CMPSS(XMM0, fpr.R(rhs), compare);
		CMPUNORDSS(XMM1, fpr.R(rhs));

		POR(XMM0, R(XMM1));
	} else {
		CopyFPReg(XMM0, fpr.R(lhs));
		CMPSS(XMM0, fpr.R(rhs), compare);
	}

	MOVD_xmm(gpr.R(MIPS_REG_FPCOND), XMM0);
}