Commit a337d159 authored by zhengxing.li's avatar zhengxing.li Committed by Commit bot

X87: [TurboFan] Change the implementation of Float32's NaN comparision's...

X87: [TurboFan] Change the implementation of Float32's NaN comparision's return value in kX87Float32Min and kX87Float32Max.

  The CL 32796(https://codereview.chromium.org/1512023002) adds many Float32 comparision test data which including the NaN comparision.

  As there's no Specification for the return value of NaN comparision, Current x87 will check the Float comparision instruction's first
  operand, if it's NaN, return the second operand. Otherwise, return itself.

  But this conflicts with the Gcc compiler's implementation and cause the RunFloat32MinP and RunFloat32MaxP tests failed.

  For (a < b) comparision, The Gcc compiler will treat the NaN comparision's result same as a GT b and return b.
  The minss sse instruction in IA32 has the similar behavior.

  So this CL will make the implementation of NaN comparision's return value in kX87Float32Min and kX87Float32Max same as Gcc and IA32.

BUG=

Review URL: https://codereview.chromium.org/1522333002

Cr-Commit-Position: refs/heads/master@{#32866}
parent bead2448
......@@ -744,7 +744,10 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ fld(1);
__ fld(1);
__ FCmp();
__ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN.
// At least one NaN.
// Return the second operands if one of the two operands is NaN
__ j(parity_even, &return_right, Label::kNear);
__ j(equal, &check_zero, Label::kNear); // left == right.
__ j(condition, &return_left, Label::kNear);
__ jmp(&return_right, Label::kNear);
......@@ -758,12 +761,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ fadd(1);
__ jmp(&return_left, Label::kNear);
__ bind(&check_nan_left);
__ fld(0);
__ fld(0);
__ FCmp(); // NaN check.
__ j(parity_even, &return_left, Label::kNear); // left == NaN.
__ bind(&return_right);
__ fxch();
......@@ -781,7 +778,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ fld(1);
__ fld(1);
__ FCmp();
__ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN.
// At least one NaN.
// Return the second operands if one of the two operands is NaN
__ j(parity_even, &return_right, Label::kNear);
__ j(equal, &check_zero, Label::kNear); // left == right.
__ j(condition, &return_left, Label::kNear);
__ jmp(&return_right, Label::kNear);
......@@ -808,11 +807,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ pop(eax); // restore esp
__ jmp(&return_left, Label::kNear);
__ bind(&check_nan_left);
__ fld(0);
__ fld(0);
__ FCmp(); // NaN check.
__ j(parity_even, &return_left, Label::kNear); // left == NaN.
__ bind(&return_right);
__ fxch();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment