X87: [turbofan] Add Float32(Max|Min) machine operators.

port 2027b0bed1 (r38784)

  original commit message:
  The new operators are implemented similar to the Float64(Max|Min) which
  already exist. The purpose of the new operators is the implementation
  of the F32Max and F32Min instructions in WebAssembly.

BUG=

Review-Url: https://codereview.chromium.org/2270193003
Cr-Commit-Position: refs/heads/master@{#38857}
This commit is contained in:
zhengxing.li 2016-08-24 01:54:09 -07:00 committed by Commit bot
parent 60908503ac
commit 909641fd5e
3 changed files with 86 additions and 0 deletions

View File

@ -1300,6 +1300,42 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ lea(esp, Operand(esp, 2 * kDoubleSize));
break;
}
case kX87Float32Max: {
Label compare_swap, done_compare;
if (FLAG_debug_code && FLAG_enable_slow_asserts) {
__ VerifyX87StackDepth(1);
}
__ fstp(0);
__ fld_s(MemOperand(esp, kFloatSize));
__ fld_s(MemOperand(esp, 0));
__ fld(1);
__ fld(1);
__ FCmp();
auto ool =
new (zone()) OutOfLineLoadFloat32NaN(this, i.OutputDoubleRegister());
__ j(parity_even, ool->entry());
__ j(below, &done_compare, Label::kNear);
__ j(above, &compare_swap, Label::kNear);
__ push(eax);
__ lea(esp, Operand(esp, -kFloatSize));
__ fld(1);
__ fstp_s(Operand(esp, 0));
__ mov(eax, MemOperand(esp, 0));
__ and_(eax, Immediate(0x80000000));
__ lea(esp, Operand(esp, kFloatSize));
__ pop(eax);
__ j(zero, &done_compare, Label::kNear);
__ bind(&compare_swap);
__ bind(ool->exit());
__ fxch(1);
__ bind(&done_compare);
__ fstp(0);
__ lea(esp, Operand(esp, 2 * kFloatSize));
break;
}
case kX87Float64Max: {
Label compare_swap, done_compare;
if (FLAG_debug_code && FLAG_enable_slow_asserts) {
@ -1336,6 +1372,42 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ lea(esp, Operand(esp, 2 * kDoubleSize));
break;
}
case kX87Float32Min: {
Label compare_swap, done_compare;
if (FLAG_debug_code && FLAG_enable_slow_asserts) {
__ VerifyX87StackDepth(1);
}
__ fstp(0);
__ fld_s(MemOperand(esp, kFloatSize));
__ fld_s(MemOperand(esp, 0));
__ fld(1);
__ fld(1);
__ FCmp();
auto ool =
new (zone()) OutOfLineLoadFloat32NaN(this, i.OutputDoubleRegister());
__ j(parity_even, ool->entry());
__ j(above, &done_compare, Label::kNear);
__ j(below, &compare_swap, Label::kNear);
__ push(eax);
__ lea(esp, Operand(esp, -kFloatSize));
__ fld(0);
__ fstp_s(Operand(esp, 0));
__ mov(eax, MemOperand(esp, 0));
__ and_(eax, Immediate(0x80000000));
__ lea(esp, Operand(esp, kFloatSize));
__ pop(eax);
__ j(zero, &done_compare, Label::kNear);
__ bind(&compare_swap);
__ bind(ool->exit());
__ fxch(1);
__ bind(&done_compare);
__ fstp(0);
__ lea(esp, Operand(esp, 2 * kFloatSize));
break;
}
case kX87Float64Min: {
Label compare_swap, done_compare;
if (FLAG_debug_code && FLAG_enable_slow_asserts) {

View File

@ -59,7 +59,9 @@ namespace compiler {
V(X87Float64Mul) \
V(X87Float64Div) \
V(X87Float64Mod) \
V(X87Float32Max) \
V(X87Float64Max) \
V(X87Float32Min) \
V(X87Float64Min) \
V(X87Float64Abs) \
V(X87Float64Neg) \

View File

@ -972,6 +972,12 @@ void InstructionSelector::VisitFloat64Mod(Node* node) {
Emit(kX87Float64Mod, g.DefineAsFixed(node, stX_0), 1, temps)->MarkAsCall();
}
void InstructionSelector::VisitFloat32Max(Node* node) {
X87OperandGenerator g(this);
Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0)));
Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1)));
Emit(kX87Float32Max, g.DefineAsFixed(node, stX_0), 0, nullptr);
}
void InstructionSelector::VisitFloat64Max(Node* node) {
X87OperandGenerator g(this);
@ -980,6 +986,12 @@ void InstructionSelector::VisitFloat64Max(Node* node) {
Emit(kX87Float64Max, g.DefineAsFixed(node, stX_0), 0, nullptr);
}
void InstructionSelector::VisitFloat32Min(Node* node) {
X87OperandGenerator g(this);
Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0)));
Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1)));
Emit(kX87Float32Min, g.DefineAsFixed(node, stX_0), 0, nullptr);
}
void InstructionSelector::VisitFloat64Min(Node* node) {
X87OperandGenerator g(this);