diff --git a/vm/jitrino/src/codegenerator/CodeGenIntfc.h b/vm/jitrino/src/codegenerator/CodeGenIntfc.h index e435829..9073542 100644 --- a/vm/jitrino/src/codegenerator/CodeGenIntfc.h +++ b/vm/jitrino/src/codegenerator/CodeGenIntfc.h @@ -218,7 +218,7 @@ public: virtual CG_OpndHandle* select(CompareOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2, CG_OpndHandle* src3) = 0; // BEGIN PRED DEPRECATED - virtual CG_OpndHandle* cmp(CompareOp::Operators,CompareOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) = 0; + virtual CG_OpndHandle* cmp(CompareOp::Operators,CompareOp::Types, CG_OpndHandle* src1,CG_OpndHandle* src2,int ifNaNResult=0) = 0; virtual CG_OpndHandle* cmp3(CompareOp::Operators,CompareOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2) { return 0; }; virtual CG_OpndHandle* czero(CompareZeroOp::Types,CG_OpndHandle* src) = 0; virtual CG_OpndHandle* cnzero(CompareZeroOp::Types,CG_OpndHandle* src) = 0; diff --git a/vm/jitrino/src/codegenerator/ia32/Ia32CodeSelector.cpp b/vm/jitrino/src/codegenerator/ia32/Ia32CodeSelector.cpp index b53e549..1f547a2 100644 --- a/vm/jitrino/src/codegenerator/ia32/Ia32CodeSelector.cpp +++ b/vm/jitrino/src/codegenerator/ia32/Ia32CodeSelector.cpp @@ -422,11 +422,11 @@ void CfgCodeSelector::fixNodeInfo() //now fix prev branch successors BranchInst* prevBranch = (BranchInst*)prevInst; assert(prevBranch->getTrueTarget() == NULL && prevBranch->getFalseTarget() == NULL); - prevBranch->setTrueTarget(nextDB); + prevBranch->setTrueTarget(lastInst->getMnemonic() == Mnemonic_JZ? nextFT : nextDB); prevBranch->setFalseTarget(newBB); - fg->addEdge(node, nextDB, 0); + fg->addEdge(node, lastInst->getMnemonic() == Mnemonic_JZ? nextFT : nextDB, 0); fg->addEdge(node, newBB, 0); fg->addEdge(newBB, nextDB, 0); fg->addEdge(newBB, nextFT, 0); diff --git a/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp b/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp index c5817a8..ea45cba 100644 --- a/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp +++ b/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp @@ -134,41 +134,13 @@ float __stdcall convI8F4 (uint64 // FP remainder internal helpers (temp solution to be optimized) float __stdcall remF4 (float v0, float v1)stdcall__; -float __stdcall remF4 (float v0, float v1) { - if(_isnan(v0) || _isnan(v1)|| (!_finite(v0)) || (v1==float(0.0))) { - return fnan; - } else if (!_finite(v1)){ - return v0; - } - float result = v0-float(int64(v0/v1))*v1; - if (result == 0 && v1 < 0) { -#ifdef PLATFORM_POSIX - return copysign(result, v1); -#else - return (float)_copysign(result, v1); -#endif - } else { - return result; - } +float __stdcall remF4 (float v0, float v1) { + return fmodf(v0,v1); } double __stdcall remF8 (double v0, double v1)stdcall__; double __stdcall remF8 (double v0, double v1) { - if(_isnan(v0) || _isnan(v1) || (!_finite(v0)) || (v1==double(0.0))) { - return dnan; - } else if (!_finite(v1)){ - return v0; - } - double result = v0-double(int64(v0/v1))*v1; - if (result == 0 && v1 < 0) { -#ifdef PLATFORM_POSIX - return copysign(result, v1); -#else - return _copysign(result, v1); -#endif - } else { - return result; - } + return fmod(v0,v1); } void __stdcall initialize_array(uint8* array, uint32 elems_offset, uint8* data, uint32 num_elems) stdcall__; @@ -1119,7 +1091,7 @@ CG_OpndHandle* InstCodeSelector::select CG_OpndHandle* InstCodeSelector::cmp(CompareOp::Operators cmpOp, CompareOp::Types opType, CG_OpndHandle* src1, - CG_OpndHandle* src2) + CG_OpndHandle* src2, int ifNaNResult) { Opnd * dst=irManager.newOpnd(typeManager.getInt32Type()); bool swapped=cmpToEflags(cmpOp, opType, (Opnd*)src1, (Opnd*)src2); @@ -1128,11 +1100,9 @@ CG_OpndHandle* InstCodeSelector::cmp(Co cm=swapConditionMnemonic(cm); appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, dst, irManager.newImmOpnd(typeManager.getInt32Type(), 0))); appendInsts(irManager.newInstEx(getMnemonic(Mnemonic_SETcc, cm), 1, dst)); -#ifndef _EM64T_ - if (((opType==CompareOp::F) ||(opType==CompareOp::S) ||(opType==CompareOp::D)) && ((cmpOp == CompareOp::Geu) || (cmpOp == CompareOp::Gtu))) { - appendInsts(irManager.newInstEx(Mnemonic_CMOVP,1,dst,irManager.newImmOpnd(typeManager.getInt32Type(), 0))); + if (ifNaNResult == 1 || (ifNaNResult ==0 && ((opType==CompareOp::F) ||(opType==CompareOp::S) ||(opType==CompareOp::D)) && ((cmpOp == CompareOp::Geu) || (cmpOp == CompareOp::Gtu) || (cmpOp == CompareOp::Ne) || (cmpOp == CompareOp::Eq)))) { + appendInsts(irManager.newInstEx(Mnemonic_CMOVP,1,dst,irManager.newImmOpnd(typeManager.getInt32Type(), ifNaNResult))); } -#endif return dst; } @@ -1222,14 +1192,6 @@ #else Opnd * srcOpnd2=src2?(Opnd*)convert(src2, srcType):irManager.newFPConstantMemOpnd((double)0.0); #endif appendInsts(irManager.newInst(Mnemonic_UCOMISD, srcOpnd1, srcOpnd2)); -#ifndef _EM64T_ - if(cmpOp == CompareOp::Eq || cmpOp == CompareOp::Ne) { - Opnd * ah = irManager.newOpnd(typeManager.getInt32Type()); - appendInsts(irManager.newInst(Mnemonic_LAHF,ah)); - Opnd * dst = (Opnd *)and_(IntegerOp::I4, ah, irManager.newImmOpnd(typeManager.getInt32Type(),UNORD_FLAGS_MASK)); - appendInsts(irManager.newInst(Mnemonic_CMP, dst, irManager.newImmOpnd(typeManager.getInt32Type(),ZF))); - } -#endif break; } case CompareOp::S: @@ -1243,14 +1205,6 @@ #else Opnd * srcOpnd2=src2?(Opnd*)convert(src2, srcType):irManager.newFPConstantMemOpnd((float)0.0); #endif appendInsts(irManager.newInst(Mnemonic_UCOMISS, srcOpnd1, srcOpnd2)); -#ifndef _EM64T_ - if(cmpOp == CompareOp::Eq || cmpOp == CompareOp::Ne) { - Opnd * ah = irManager.newOpnd(typeManager.getInt32Type()); - appendInsts(irManager.newInst(Mnemonic_LAHF,ah)); - Opnd * dst = (Opnd *)and_(IntegerOp::I4, ah, irManager.newImmOpnd(typeManager.getInt32Type(),UNORD_FLAGS_MASK)); - appendInsts(irManager.newInst(Mnemonic_CMP, dst, irManager.newImmOpnd(typeManager.getInt32Type(),ZF))); - } -#endif break; } default: @@ -1270,7 +1224,7 @@ void InstCodeSelector::branch(CompareOp: bool swapped=cmpToEflags(cmpOp, opType, (Opnd*)src1, (Opnd*)src2); ConditionMnemonic cm=getConditionMnemonicFromCompareOperator(cmpOp, opType); #ifndef _EM64T_ - if (((opType==CompareOp::F) ||(opType==CompareOp::S) ||(opType==CompareOp::D)) && ((cmpOp == CompareOp::Geu) || (cmpOp == CompareOp::Gtu))) { + if (((opType==CompareOp::F) ||(opType==CompareOp::S) ||(opType==CompareOp::D)) && ((cmpOp == CompareOp::Geu) || (cmpOp == CompareOp::Gtu)|| (cmpOp == CompareOp::Ne) || (cmpOp == CompareOp::Eq))) { //! branch true&false edges & new block for this branch will be added in CodeSelector::fixNodeInfo appendInsts(irManager.newBranchInst(Mnemonic_JP, NULL, NULL)); } diff --git a/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h b/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h index 713cf27..ca97b1f 100644 --- a/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h +++ b/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h @@ -100,7 +100,7 @@ public: CG_OpndHandle* shr(IntegerOp::Types,CG_OpndHandle* value,CG_OpndHandle* shiftAmount); CG_OpndHandle* shru(IntegerOp::Types,CG_OpndHandle* value,CG_OpndHandle* shiftAmount); CG_OpndHandle* select(CompareOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2,CG_OpndHandle* src3); - CG_OpndHandle* cmp(CompareOp::Operators,CompareOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2); + CG_OpndHandle* cmp(CompareOp::Operators,CompareOp::Types, CG_OpndHandle* src1,CG_OpndHandle* src2, int ifNaNResult); CG_OpndHandle* czero(CompareZeroOp::Types opType,CG_OpndHandle* src); CG_OpndHandle* cnzero(CompareZeroOp::Types opType,CG_OpndHandle* src); void branch(CompareOp::Operators,CompareOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2); diff --git a/vm/jitrino/src/optimizer/CodeGenerator.cpp b/vm/jitrino/src/optimizer/CodeGenerator.cpp index b4de642..f2bc1b1 100644 --- a/vm/jitrino/src/optimizer/CodeGenerator.cpp +++ b/vm/jitrino/src/optimizer/CodeGenerator.cpp @@ -722,28 +722,33 @@ #ifndef BACKEND_HAS_CMP3 CompareOp::Types opType = mapToCompareOpType(inst); CompareOp::Operators cmpOp = mapToComparisonOp(inst); CompareOp::Operators cmpOp2 = cmpOp; - + + int ifNaNResult = -1; + if (cmpOp == CompareOp::Gtu || cmpOp == CompareOp::Geu) + ifNaNResult = 1; + + CG_OpndHandle* cgInst1 = + instructionCallback.cmp(cmpOp, opType, + getCGInst(inst->getSrc(0)), + getCGInst(inst->getSrc(1)), ifNaNResult); + // second operator has opposite NaN behavior for Floats if ((opType==CompareOp::F) || (opType==CompareOp::S) || (opType==CompareOp::D)) { switch (cmpOp) { - case CompareOp::Gt: cmpOp2 = CompareOp::Gtu; break; - case CompareOp::Gtu: cmpOp2 = CompareOp::Gt; break; - case CompareOp::Ge: cmpOp2 = CompareOp::Geu; break; - case CompareOp::Geu: cmpOp2 = CompareOp::Ge; break; + case CompareOp::Gt: cmpOp2 = CompareOp::Gtu; ifNaNResult = 1; break; + case CompareOp::Gtu: cmpOp2 = CompareOp::Gt; ifNaNResult = -1; break; + case CompareOp::Ge: cmpOp2 = CompareOp::Geu; ifNaNResult = 1; break; + case CompareOp::Geu: cmpOp2 = CompareOp::Ge; ifNaNResult = -1; break; default: break; }; } - CG_OpndHandle* cgInst1 = - instructionCallback.cmp(cmpOp, opType, - getCGInst(inst->getSrc(0)), - getCGInst(inst->getSrc(1))); CG_OpndHandle* cgInst2 = - instructionCallback.cmp(cmpOp2, opType, + instructionCallback.cmp(cmpOp2, opType, getCGInst(inst->getSrc(1)), - getCGInst(inst->getSrc(0))); + getCGInst(inst->getSrc(0)), ifNaNResult); cgInst = instructionCallback.sub(ArithmeticOp::I4, cgInst1,