From: yangguo@chromium.org Date: Fri, 4 May 2012 15:50:43 +0000 (+0000) Subject: Handle negative number in Math.floor,ia32,non-SSE4.1 code path. X-Git-Tag: upstream/4.7.83~16746 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=718ec5eb6464fc06cdbc91e8a5a79296242c867a;p=platform%2Fupstream%2Fv8.git Handle negative number in Math.floor,ia32,non-SSE4.1 code path. Zheng Liu zheng.z.liu@intel.com Review URL: https://chromiumcodereview.appspot.com/10168001 Patch from Zheng Liu . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11517 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index d416662..053bcb6 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -2925,11 +2925,13 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { __ cmp(output_reg, 0x80000000u); DeoptimizeIf(equal, instr->environment()); } else { + Label negative_sign; Label done; - // Deoptimize on negative numbers. + // Deoptimize on unordered. __ xorps(xmm_scratch, xmm_scratch); // Zero the register. __ ucomisd(input_reg, xmm_scratch); - DeoptimizeIf(below, instr->environment()); + DeoptimizeIf(parity_even, instr->environment()); + __ j(below, &negative_sign, Label::kNear); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { // Check for negative zero. @@ -2945,10 +2947,21 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { // Use truncating instruction (OK because input is positive). __ cvttsd2si(output_reg, Operand(input_reg)); - // Overflow is signalled with minint. __ cmp(output_reg, 0x80000000u); DeoptimizeIf(equal, instr->environment()); + __ jmp(&done, Label::kNear); + + // Non-zero negative reaches here + __ bind(&negative_sign); + // Truncate, then compare and compensate + __ cvttsd2si(output_reg, Operand(input_reg)); + __ cvtsi2sd(xmm_scratch, output_reg); + __ ucomisd(input_reg, xmm_scratch); + __ j(equal, &done, Label::kNear); + __ sub(output_reg, Immediate(1)); + DeoptimizeIf(overflow, instr->environment()); + __ bind(&done); } }