Skip to content
Permalink
Browse files

Merge pull request #681 from phire/non-sse4_1

Fix PPC_FP on non-sse4.1 code paths.
  • Loading branch information...
lioncash committed Jul 31, 2014
2 parents 83838a6 + 8c857b4 commit f5078273990e381a8437e945828444cefc410417
Showing with 18 additions and 5 deletions.
  1. +16 −4 Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp
  2. +2 −1 Source/Core/Core/PowerPC/JitCommon/Jit_Util.h
@@ -551,6 +551,8 @@ void EmuCodeBlock::ForceSinglePrecisionP(X64Reg xmm) {
static u32 GC_ALIGNED16(temp32);
static u64 GC_ALIGNED16(temp64);

static const float GC_ALIGNED16(m_zero[]) = { 0.0f, 0.0f, 0.0f, 0.0f };

#if _M_X86_64
static const __m128i GC_ALIGNED16(single_qnan_bit) = _mm_set_epi64x(0, 0x0000000000400000);
static const __m128i GC_ALIGNED16(single_exponent) = _mm_set_epi64x(0, 0x000000007f800000);
@@ -669,8 +671,13 @@ void EmuCodeBlock::ConvertDoubleToSingle(X64Reg dst, X64Reg src)
PTEST(XMM1, M((void *)&double_exponent));
cond = CC_NC;
} else {
FNSTSW_AX();
TEST(16, R(AX), Imm16(x87_InvalidOperation));
// emulate PTEST; checking FPU flags is incorrect because the NaN bits
// are sticky (persist between instructions)
MOVSD(XMM0, M((void *)&double_exponent));
PAND(XMM0, R(XMM1));
PCMPEQB(XMM0, M((void *)&m_zero));
PMOVMSKB(EAX, R(XMM0));
CMP(32, R(EAX), Imm32(0xffff));
cond = CC_Z;
}
FSTP(32, M(&temp32));
@@ -706,8 +713,13 @@ void EmuCodeBlock::ConvertSingleToDouble(X64Reg dst, X64Reg src, bool src_is_gpr
PTEST(XMM1, M((void *)&single_exponent));
cond = CC_NC;
} else {
FNSTSW_AX();
TEST(16, R(AX), Imm16(x87_InvalidOperation));
// emulate PTEST; checking FPU flags is incorrect because the NaN bits
// are sticky (persist between instructions)
MOVSS(XMM0, M((void *)&single_exponent));
PAND(XMM0, R(XMM1));
PCMPEQB(XMM0, M((void *)&m_zero));
PMOVMSKB(EAX, R(XMM0));
CMP(32, R(EAX), Imm32(0xffff));
cond = CC_Z;
}
FSTP(64, M(&temp64));
@@ -57,8 +57,9 @@ class EmuCodeBlock : public Gen::X64CodeBlock
void ForceSinglePrecisionS(Gen::X64Reg xmm);
void ForceSinglePrecisionP(Gen::X64Reg xmm);

// AX might get trashed
// EAX might get trashed
void ConvertSingleToDouble(Gen::X64Reg dst, Gen::X64Reg src, bool src_is_gpr = false);
// EAX might get trashed
void ConvertDoubleToSingle(Gen::X64Reg dst, Gen::X64Reg src);
protected:
std::unordered_map<u8 *, u32> registersInUseAtLoc;

0 comments on commit f507827

Please sign in to comment.
You can’t perform that action at this time.