コード例 #1
0
ファイル: ArmCompFPU.cpp プロジェクト: jack00/ppsspp
void Jit::Comp_FPUComp(u32 op) {
	CONDITIONAL_DISABLE;
	int opc = op & 0xF;
	if (opc >= 8) opc -= 8; // alias
	if (opc == 0)//f, sf (signalling false)
	{
		MOVI2R(R0, 0);
		STR(R0, CTXREG, offsetof(MIPSState, fpcond));
		return;
	}

	int fs = _FS;
	int ft = _FT;
	fpr.MapInIn(fs, ft);
	VCMP(fpr.R(fs), fpr.R(ft));
	VMRS_APSR(); // Move FP flags from FPSCR to APSR (regular flags).
	switch(opc)
	{
	case 1:      // un,  ngle (unordered)
		SetCC(CC_VS);
		MOVI2R(R0, 1);
		SetCC(CC_VC);
		break;
	case 2:      // eq,  seq (equal, ordered)
		SetCC(CC_EQ);
		MOVI2R(R0, 1);
		SetCC(CC_NEQ);
		break;
	case 3:      // ueq, ngl (equal, unordered)
		SetCC(CC_EQ);
		MOVI2R(R0, 1);
		SetCC(CC_NEQ);
		MOVI2R(R0, 0);
		SetCC(CC_VS);
		MOVI2R(R0, 1);
		SetCC(CC_AL);
		STR(R0, CTXREG, offsetof(MIPSState, fpcond));
		return;
	case 4:      // olt, lt (less than, ordered)
		SetCC(CC_LO);
		MOVI2R(R0, 1);
		SetCC(CC_HS);
		break;
	case 5:      // ult, nge (less than, unordered)
		SetCC(CC_LT);
		MOVI2R(R0, 1);
		SetCC(CC_GE);
		break;
	case 6:      // ole, le (less equal, ordered)
		SetCC(CC_LS);
		MOVI2R(R0, 1);
		SetCC(CC_HI);
		break;
	case 7:      // ule, ngt (less equal, unordered)
		SetCC(CC_LE);
		MOVI2R(R0, 1);
		SetCC(CC_GT);
		break;
	default:
		Comp_Generic(op);
		return;
	}
	MOVI2R(R0, 0);
	SetCC(CC_AL);
	STR(R0, CTXREG, offsetof(MIPSState, fpcond));
}
コード例 #2
0
ファイル: ArmCompVFPU.cpp プロジェクト: ravenue/ppsspp
void Jit::ApplyPrefixD(const u8 *vregs, VectorSize sz) {
    _assert_(js.prefixDFlag & ArmJitState::PREFIX_KNOWN);
    if (!js.prefixD) return;

    int n = GetNumVectorElements(sz);
    for (int i = 0; i < n; i++) 	{
        if (js.VfpuWriteMask(i))
            continue;

        // TODO: These clampers are wrong - put this into google
        // and look at the plot:   abs(x) - abs(x-0.5) + 0.5
        // It's too steep.

        // Also, they mishandle NaN and Inf.
        int sat = (js.prefixD >> (i * 2)) & 3;
        if (sat == 1) {
            // clamped = fabs(x) - fabs(x-0.5f) + 0.5f; // [ 0, 1]
            fpr.MapRegV(vregs[i], MAP_DIRTY);

            MOVI2F(S0, 0.0f, R0);
            MOVI2F(S1, 1.0f, R0);
            VCMP(fpr.V(vregs[i]), S0);
            VMRS_APSR(); // Move FP flags from FPSCR to APSR (regular flags).
            SetCC(CC_LE);
            VMOV(fpr.V(vregs[i]), S0);
            SetCC(CC_AL);
            VCMP(fpr.V(vregs[i]), S1);
            VMRS_APSR(); // Move FP flags from FPSCR to APSR (regular flags).
            SetCC(CC_GT);
            VMOV(fpr.V(vregs[i]), S1);
            SetCC(CC_AL);

            /*
            VABS(S1, fpr.V(vregs[i]));                  // S1 = fabs(x)
            VSUB(fpr.V(vregs[i]), fpr.V(vregs[i]), S0); // S2 = fabs(x-0.5f) {VABD}
            VABS(fpr.V(vregs[i]), fpr.V(vregs[i]));
            VSUB(fpr.V(vregs[i]), S1, fpr.V(vregs[i])); // v[i] = S1 - S2 + 0.5f
            VADD(fpr.V(vregs[i]), fpr.V(vregs[i]), S0);*/
        } else if (sat == 3) {
            fpr.MapRegV(vregs[i], MAP_DIRTY);

            MOVI2F(S0, -1.0f, R0);
            MOVI2F(S1, 1.0f, R0);
            VCMP(fpr.V(vregs[i]), S0);
            VMRS_APSR(); // Move FP flags from FPSCR to APSR (regular flags).
            SetCC(CC_LT);
            VMOV(fpr.V(vregs[i]), S0);
            SetCC(CC_AL);
            VCMP(fpr.V(vregs[i]), S1);
            VMRS_APSR(); // Move FP flags from FPSCR to APSR (regular flags).
            SetCC(CC_GT);
            VMOV(fpr.V(vregs[i]), S1);
            SetCC(CC_AL);

            // clamped = fabs(x) - fabs(x-1.0f);        // [-1, 1]
            /*
            fpr.MapRegV(vregs[i], MAP_DIRTY);
            MOVI2F(S0, 1.0f, R0);
            VABS(S1, fpr.V(vregs[i]));                  // S1 = fabs(x)
            VSUB(fpr.V(vregs[i]), fpr.V(vregs[i]), S0); // S2 = fabs(x-1.0f) {VABD}
            VABS(fpr.V(vregs[i]), fpr.V(vregs[i]));
            VSUB(fpr.V(vregs[i]), S1, fpr.V(vregs[i])); // v[i] = S1 - S2
            */
        }
    }
}