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:
parent
60908503ac
commit
909641fd5e
@ -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) {
|
||||
|
@ -59,7 +59,9 @@ namespace compiler {
|
||||
V(X87Float64Mul) \
|
||||
V(X87Float64Div) \
|
||||
V(X87Float64Mod) \
|
||||
V(X87Float32Max) \
|
||||
V(X87Float64Max) \
|
||||
V(X87Float32Min) \
|
||||
V(X87Float64Min) \
|
||||
V(X87Float64Abs) \
|
||||
V(X87Float64Neg) \
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user