Index: src/compiler/ia32/instruction-selector-ia32.cc |
diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc |
index 5835d13ee815af25e7fd47edf37ced5544bcc9a7..7b22fff5d446525b8d9887e48cdfa3ec4a8c5bd7 100644 |
--- a/src/compiler/ia32/instruction-selector-ia32.cc |
+++ b/src/compiler/ia32/instruction-selector-ia32.cc |
@@ -124,14 +124,38 @@ class IA32OperandGenerator FINAL : public OperandGenerator { |
}; |
-static void VisitRRFloat64(InstructionSelector* selector, |
- InstructionCode opcode, Node* node) { |
+namespace { |
+ |
+void VisitROFloat(InstructionSelector* selector, Node* node, |
+ ArchOpcode opcode) { |
+ IA32OperandGenerator g(selector); |
+ selector->Emit(opcode, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
+} |
+ |
+ |
+void VisitRRFloat(InstructionSelector* selector, Node* node, |
+ InstructionCode opcode) { |
IA32OperandGenerator g(selector); |
selector->Emit(opcode, g.DefineAsRegister(node), |
g.UseRegister(node->InputAt(0))); |
} |
+void VisitRROFloat(InstructionSelector* selector, Node* node, |
+ ArchOpcode avx_opcode, ArchOpcode sse_opcode) { |
+ IA32OperandGenerator g(selector); |
+ InstructionOperand operand0 = g.UseRegister(node->InputAt(0)); |
+ InstructionOperand operand1 = g.Use(node->InputAt(1)); |
+ if (selector->IsSupported(AVX)) { |
+ selector->Emit(avx_opcode, g.DefineAsRegister(node), operand0, operand1); |
+ } else { |
+ selector->Emit(sse_opcode, g.DefineSameAsFirst(node), operand0, operand1); |
+ } |
+} |
+ |
+} // namespace |
+ |
+ |
void InstructionSelector::VisitLoad(Node* node) { |
MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); |
MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); |
@@ -606,7 +630,7 @@ void InstructionSelector::VisitUint32Mod(Node* node) { |
void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { |
IA32OperandGenerator g(this); |
- Emit(kSSECvtss2sd, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
+ Emit(kSSEFloat32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
} |
@@ -636,19 +660,22 @@ void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { |
void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { |
IA32OperandGenerator g(this); |
- Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
+ Emit(kSSEFloat64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
+} |
+ |
+ |
+void InstructionSelector::VisitFloat32Add(Node* node) { |
+ VisitRROFloat(this, node, kAVXFloat32Add, kSSEFloat32Add); |
} |
void InstructionSelector::VisitFloat64Add(Node* node) { |
- IA32OperandGenerator g(this); |
- if (IsSupported(AVX)) { |
- Emit(kAVXFloat64Add, g.DefineAsRegister(node), |
- g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); |
- } else { |
- Emit(kSSEFloat64Add, g.DefineSameAsFirst(node), |
- g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); |
- } |
+ VisitRROFloat(this, node, kAVXFloat64Add, kSSEFloat64Add); |
+} |
+ |
+ |
+void InstructionSelector::VisitFloat32Sub(Node* node) { |
+ VisitRROFloat(this, node, kAVXFloat32Sub, kSSEFloat32Sub); |
} |
@@ -667,37 +694,27 @@ void InstructionSelector::VisitFloat64Sub(Node* node) { |
} |
} |
} |
- if (IsSupported(AVX)) { |
- Emit(kAVXFloat64Sub, g.DefineAsRegister(node), |
- g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); |
- } else { |
- Emit(kSSEFloat64Sub, g.DefineSameAsFirst(node), |
- g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); |
- } |
+ VisitRROFloat(this, node, kAVXFloat64Sub, kSSEFloat64Sub); |
+} |
+ |
+ |
+void InstructionSelector::VisitFloat32Mul(Node* node) { |
+ VisitRROFloat(this, node, kAVXFloat32Mul, kSSEFloat32Mul); |
} |
void InstructionSelector::VisitFloat64Mul(Node* node) { |
- IA32OperandGenerator g(this); |
- if (IsSupported(AVX)) { |
- Emit(kAVXFloat64Mul, g.DefineAsRegister(node), |
- g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); |
- } else { |
- Emit(kSSEFloat64Mul, g.DefineSameAsFirst(node), |
- g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); |
- } |
+ VisitRROFloat(this, node, kAVXFloat64Mul, kSSEFloat64Mul); |
+} |
+ |
+ |
+void InstructionSelector::VisitFloat32Div(Node* node) { |
+ VisitRROFloat(this, node, kAVXFloat32Div, kSSEFloat32Div); |
} |
void InstructionSelector::VisitFloat64Div(Node* node) { |
- IA32OperandGenerator g(this); |
- if (IsSupported(AVX)) { |
- Emit(kAVXFloat64Div, g.DefineAsRegister(node), |
- g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); |
- } else { |
- Emit(kSSEFloat64Div, g.DefineSameAsFirst(node), |
- g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); |
- } |
+ VisitRROFloat(this, node, kAVXFloat64Div, kSSEFloat64Div); |
} |
@@ -710,44 +727,43 @@ void InstructionSelector::VisitFloat64Mod(Node* node) { |
} |
+void InstructionSelector::VisitFloat32Max(Node* node) { |
+ VisitRROFloat(this, node, kAVXFloat32Max, kSSEFloat32Max); |
+} |
+ |
+ |
void InstructionSelector::VisitFloat64Max(Node* node) { |
- IA32OperandGenerator g(this); |
- if (IsSupported(AVX)) { |
- Emit(kAVXFloat64Max, g.DefineAsRegister(node), |
- g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); |
- } else { |
- Emit(kSSEFloat64Max, g.DefineSameAsFirst(node), |
- g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); |
- } |
+ VisitRROFloat(this, node, kAVXFloat64Max, kSSEFloat64Max); |
+} |
+ |
+ |
+void InstructionSelector::VisitFloat32Min(Node* node) { |
+ VisitRROFloat(this, node, kAVXFloat32Min, kSSEFloat32Min); |
} |
void InstructionSelector::VisitFloat64Min(Node* node) { |
- IA32OperandGenerator g(this); |
- if (IsSupported(AVX)) { |
- Emit(kAVXFloat64Min, g.DefineAsRegister(node), |
- g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); |
- } else { |
- Emit(kSSEFloat64Min, g.DefineSameAsFirst(node), |
- g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); |
- } |
+ VisitRROFloat(this, node, kAVXFloat64Min, kSSEFloat64Min); |
+} |
+ |
+ |
+void InstructionSelector::VisitFloat32Sqrt(Node* node) { |
+ VisitROFloat(this, node, kSSEFloat32Sqrt); |
} |
void InstructionSelector::VisitFloat64Sqrt(Node* node) { |
- IA32OperandGenerator g(this); |
- Emit(kSSEFloat64Sqrt, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
+ VisitROFloat(this, node, kSSEFloat64Sqrt); |
} |
void InstructionSelector::VisitFloat64RoundDown(Node* node) { |
- VisitRRFloat64(this, kSSEFloat64Round | MiscField::encode(kRoundDown), node); |
+ VisitRRFloat(this, node, kSSEFloat64Round | MiscField::encode(kRoundDown)); |
} |
void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
- VisitRRFloat64(this, kSSEFloat64Round | MiscField::encode(kRoundToZero), |
- node); |
+ VisitRRFloat(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero)); |
} |
@@ -846,6 +862,15 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
} |
+// Shared routine for multiple float32 compare operations (inputs commuted). |
+void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
+ FlagsContinuation* cont) { |
+ Node* const left = node->InputAt(0); |
+ Node* const right = node->InputAt(1); |
+ VisitCompare(selector, kSSEFloat32Cmp, right, left, cont, false); |
+} |
+ |
+ |
// Shared routine for multiple float64 compare operations (inputs commuted). |
void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
FlagsContinuation* cont) { |
@@ -932,6 +957,15 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
case IrOpcode::kUint32LessThanOrEqual: |
cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
return VisitWordCompare(selector, value, cont); |
+ case IrOpcode::kFloat32Equal: |
+ cont->OverwriteAndNegateIfEqual(kUnorderedEqual); |
+ return VisitFloat32Compare(selector, value, cont); |
+ case IrOpcode::kFloat32LessThan: |
+ cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan); |
+ return VisitFloat32Compare(selector, value, cont); |
+ case IrOpcode::kFloat32LessThanOrEqual: |
+ cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual); |
+ return VisitFloat32Compare(selector, value, cont); |
case IrOpcode::kFloat64Equal: |
cont->OverwriteAndNegateIfEqual(kUnorderedEqual); |
return VisitFloat64Compare(selector, value, cont); |
@@ -1073,6 +1107,24 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
} |
+void InstructionSelector::VisitFloat32Equal(Node* node) { |
+ FlagsContinuation cont(kUnorderedEqual, node); |
+ VisitFloat32Compare(this, node, &cont); |
+} |
+ |
+ |
+void InstructionSelector::VisitFloat32LessThan(Node* node) { |
+ FlagsContinuation cont(kUnsignedGreaterThan, node); |
+ VisitFloat32Compare(this, node, &cont); |
+} |
+ |
+ |
+void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { |
+ FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node); |
+ VisitFloat32Compare(this, node, &cont); |
+} |
+ |
+ |
void InstructionSelector::VisitFloat64Equal(Node* node) { |
FlagsContinuation cont(kUnorderedEqual, node); |
VisitFloat64Compare(this, node, &cont); |
@@ -1132,6 +1184,8 @@ void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { |
MachineOperatorBuilder::Flags |
InstructionSelector::SupportedMachineOperatorFlags() { |
MachineOperatorBuilder::Flags flags = |
+ MachineOperatorBuilder::kFloat32Max | |
+ MachineOperatorBuilder::kFloat32Min | |
MachineOperatorBuilder::kFloat64Max | |
MachineOperatorBuilder::kFloat64Min | |
MachineOperatorBuilder::kWord32ShiftIsSafe; |