| 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;
|
|
|