Skip to content

Commit

Permalink
Use integer comparisons in MAX/MINI to avoid issues with denormals.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpd002 committed Mar 8, 2025
1 parent f7f955f commit 901c93f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
49 changes: 42 additions & 7 deletions Source/ee/VUShared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,40 @@ void VUShared::PullIntegerRegister(CMipsJitter* codeGen, unsigned int regIdx)
codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[regIdx]));
}

void VUShared::MakeComparableFromFloat(CMipsJitter* codeGen)
{
uint32 valueCursor = codeGen->GetTopCursor();

//Compute mask
codeGen->PushCursor(valueCursor);
codeGen->MD_SraW(31);
uint32 maskCursor = codeGen->GetTopCursor();

//Make neg
codeGen->MD_PushCstExpand(0xFFFFFFFFU);
codeGen->PushCursor(valueCursor);
codeGen->MD_SubW();
codeGen->PushCursor(maskCursor);
codeGen->MD_And();

//Make pos
codeGen->MD_PushCstExpand(0x7FFFFFFFU);
codeGen->PushIdx(valueCursor);
codeGen->MD_AddW();
codeGen->PushCursor(maskCursor);
codeGen->MD_Not();
codeGen->MD_And();

codeGen->MD_Or();

//Make it signed comparable
codeGen->MD_PushCstExpand(0x80000000U);
codeGen->MD_SubW();

codeGen->PullTop();
codeGen->PullTop();
}

void VUShared::TestSZFlags(CMipsJitter* codeGen, uint8 dest, size_t regOffset, uint32 relativePipeTime, uint32 compileHints)
{
codeGen->MD_PushRel(regOffset);
Expand Down Expand Up @@ -579,12 +613,13 @@ void VUShared::MINI_base(CMipsJitter* codeGen, uint8 dest, size_t fd, size_t fs,
}
};

codeGen->MD_PushRel(fs);
codeGen->MD_ClampS();
pushFt();
codeGen->MD_ClampS();
MakeComparableFromFloat(codeGen);
codeGen->MD_PushRel(fs);
MakeComparableFromFloat(codeGen);

codeGen->MD_CmpLtS();
//Since we don't have a less-than operator, operands are reversed (ft > fs instead of fs < ft)
codeGen->MD_CmpGtW();
auto cmp = codeGen->GetTopCursor();

//Mask FT
Expand Down Expand Up @@ -618,11 +653,11 @@ void VUShared::MAX_base(CMipsJitter* codeGen, uint8 dest, size_t fd, size_t fs,
};

codeGen->MD_PushRel(fs);
codeGen->MD_ClampS();
MakeComparableFromFloat(codeGen);
pushFt();
codeGen->MD_ClampS();
MakeComparableFromFloat(codeGen);

codeGen->MD_CmpGtS();
codeGen->MD_CmpGtW();
auto cmp = codeGen->GetTopCursor();

//Mask FT
Expand Down
1 change: 1 addition & 0 deletions Source/ee/VUShared.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ namespace VUShared
void PushIntegerRegister(CMipsJitter*, unsigned int);
void PullIntegerRegister(CMipsJitter*, unsigned int);

void MakeComparableFromFloat(CMipsJitter*);
void TestSZFlags(CMipsJitter*, uint8, size_t, uint32, uint32);

void GetStatus(CMipsJitter*, size_t, uint32);
Expand Down

0 comments on commit 901c93f

Please sign in to comment.