| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
| 6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
| 7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 918 | 918 |
| 919 | 919 |
| 920 void InstructionSelector::VisitFloat64Add(Node* node) { | 920 void InstructionSelector::VisitFloat64Add(Node* node) { |
| 921 // TODO(mbrandy): detect multiply-add | 921 // TODO(mbrandy): detect multiply-add |
| 922 VisitRRRFloat64(this, node, kPPC_AddFloat64); | 922 VisitRRRFloat64(this, node, kPPC_AddFloat64); |
| 923 } | 923 } |
| 924 | 924 |
| 925 | 925 |
| 926 void InstructionSelector::VisitFloat64Sub(Node* node) { | 926 void InstructionSelector::VisitFloat64Sub(Node* node) { |
| 927 // TODO(mbrandy): detect multiply-subtract | 927 // TODO(mbrandy): detect multiply-subtract |
| 928 PPCOperandGenerator g(this); |
| 929 Float64BinopMatcher m(node); |
| 930 if (m.left().IsMinusZero() && m.right().IsFloat64RoundDown() && |
| 931 CanCover(m.node(), m.right().node())) { |
| 932 if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub && |
| 933 CanCover(m.right().node(), m.right().InputAt(0))) { |
| 934 Float64BinopMatcher mright0(m.right().InputAt(0)); |
| 935 if (mright0.left().IsMinusZero()) { |
| 936 // -floor(-x) = ceil(x) |
| 937 Emit(kPPC_CeilFloat64, g.DefineAsRegister(node), |
| 938 g.UseRegister(mright0.right().node())); |
| 939 return; |
| 940 } |
| 941 } |
| 942 } |
| 928 VisitRRRFloat64(this, node, kPPC_SubFloat64); | 943 VisitRRRFloat64(this, node, kPPC_SubFloat64); |
| 929 } | 944 } |
| 930 | 945 |
| 931 | 946 |
| 932 void InstructionSelector::VisitFloat64Mul(Node* node) { | 947 void InstructionSelector::VisitFloat64Mul(Node* node) { |
| 933 // TODO(mbrandy): detect negate | 948 // TODO(mbrandy): detect negate |
| 934 VisitRRRFloat64(this, node, kPPC_MulFloat64); | 949 VisitRRRFloat64(this, node, kPPC_MulFloat64); |
| 935 } | 950 } |
| 936 | 951 |
| 937 | 952 |
| 938 void InstructionSelector::VisitFloat64Div(Node* node) { | 953 void InstructionSelector::VisitFloat64Div(Node* node) { |
| 939 VisitRRRFloat64(this, node, kPPC_DivFloat64); | 954 VisitRRRFloat64(this, node, kPPC_DivFloat64); |
| 940 } | 955 } |
| 941 | 956 |
| 942 | 957 |
| 943 void InstructionSelector::VisitFloat64Mod(Node* node) { | 958 void InstructionSelector::VisitFloat64Mod(Node* node) { |
| 944 PPCOperandGenerator g(this); | 959 PPCOperandGenerator g(this); |
| 945 Emit(kPPC_ModFloat64, g.DefineAsFixed(node, d1), | 960 Emit(kPPC_ModFloat64, g.DefineAsFixed(node, d1), |
| 946 g.UseFixed(node->InputAt(0), d1), | 961 g.UseFixed(node->InputAt(0), d1), |
| 947 g.UseFixed(node->InputAt(1), d2))->MarkAsCall(); | 962 g.UseFixed(node->InputAt(1), d2))->MarkAsCall(); |
| 948 } | 963 } |
| 949 | 964 |
| 950 | 965 |
| 951 void InstructionSelector::VisitFloat64Sqrt(Node* node) { | 966 void InstructionSelector::VisitFloat64Sqrt(Node* node) { |
| 952 VisitRRFloat64(this, kPPC_SqrtFloat64, node); | 967 VisitRRFloat64(this, kPPC_SqrtFloat64, node); |
| 953 } | 968 } |
| 954 | 969 |
| 955 | 970 |
| 956 void InstructionSelector::VisitFloat64Floor(Node* node) { | 971 void InstructionSelector::VisitFloat64RoundDown(Node* node) { |
| 957 VisitRRFloat64(this, kPPC_FloorFloat64, node); | 972 VisitRRFloat64(this, kPPC_FloorFloat64, node); |
| 958 } | 973 } |
| 959 | 974 |
| 960 | 975 |
| 961 void InstructionSelector::VisitFloat64Ceil(Node* node) { | |
| 962 VisitRRFloat64(this, kPPC_CeilFloat64, node); | |
| 963 } | |
| 964 | |
| 965 | |
| 966 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 976 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
| 967 VisitRRFloat64(this, kPPC_TruncateFloat64, node); | 977 VisitRRFloat64(this, kPPC_TruncateFloat64, node); |
| 968 } | 978 } |
| 969 | 979 |
| 970 | 980 |
| 971 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 981 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
| 972 VisitRRFloat64(this, kPPC_RoundFloat64, node); | 982 VisitRRFloat64(this, kPPC_RoundFloat64, node); |
| 973 } | 983 } |
| 974 | 984 |
| 975 | 985 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 case IrOpcode::kInt32LessThanOrEqual: | 1114 case IrOpcode::kInt32LessThanOrEqual: |
| 1105 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); | 1115 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); |
| 1106 return VisitWord32Compare(selector, value, cont); | 1116 return VisitWord32Compare(selector, value, cont); |
| 1107 case IrOpcode::kUint32LessThan: | 1117 case IrOpcode::kUint32LessThan: |
| 1108 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1118 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1109 return VisitWord32Compare(selector, value, cont); | 1119 return VisitWord32Compare(selector, value, cont); |
| 1110 case IrOpcode::kUint32LessThanOrEqual: | 1120 case IrOpcode::kUint32LessThanOrEqual: |
| 1111 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); | 1121 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
| 1112 return VisitWord32Compare(selector, value, cont); | 1122 return VisitWord32Compare(selector, value, cont); |
| 1113 #if V8_TARGET_ARCH_PPC64 | 1123 #if V8_TARGET_ARCH_PPC64 |
| 1114 case IrOpcode::kWord64Equal: { | 1124 case IrOpcode::kWord64Equal: |
| 1115 // Combine with comparisons against 0 by simply inverting the | |
| 1116 // continuation. | |
| 1117 Int64BinopMatcher m(value); | |
| 1118 if (m.right().Is(0)) { | |
| 1119 user = value; | |
| 1120 value = m.left().node(); | |
| 1121 cont->Negate(); | |
| 1122 continue; | |
| 1123 } | |
| 1124 cont->OverwriteAndNegateIfEqual(kEqual); | 1125 cont->OverwriteAndNegateIfEqual(kEqual); |
| 1125 return VisitWord64Compare(selector, value, cont); | 1126 return VisitWord64Compare(selector, value, cont); |
| 1126 } | |
| 1127 case IrOpcode::kInt64LessThan: | 1127 case IrOpcode::kInt64LessThan: |
| 1128 cont->OverwriteAndNegateIfEqual(kSignedLessThan); | 1128 cont->OverwriteAndNegateIfEqual(kSignedLessThan); |
| 1129 return VisitWord64Compare(selector, value, cont); | 1129 return VisitWord64Compare(selector, value, cont); |
| 1130 case IrOpcode::kInt64LessThanOrEqual: | 1130 case IrOpcode::kInt64LessThanOrEqual: |
| 1131 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); | 1131 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); |
| 1132 return VisitWord64Compare(selector, value, cont); | 1132 return VisitWord64Compare(selector, value, cont); |
| 1133 case IrOpcode::kUint64LessThan: | 1133 case IrOpcode::kUint64LessThan: |
| 1134 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1134 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1135 return VisitWord64Compare(selector, value, cont); | 1135 return VisitWord64Compare(selector, value, cont); |
| 1136 #endif | 1136 #endif |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1429 // Emit the call instruction. | 1429 // Emit the call instruction. |
| 1430 InstructionOperand* first_output = | 1430 InstructionOperand* first_output = |
| 1431 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; | 1431 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; |
| 1432 Instruction* call_instr = | 1432 Instruction* call_instr = |
| 1433 Emit(opcode, buffer.outputs.size(), first_output, | 1433 Emit(opcode, buffer.outputs.size(), first_output, |
| 1434 buffer.instruction_args.size(), &buffer.instruction_args.front()); | 1434 buffer.instruction_args.size(), &buffer.instruction_args.front()); |
| 1435 call_instr->MarkAsCall(); | 1435 call_instr->MarkAsCall(); |
| 1436 } | 1436 } |
| 1437 | 1437 |
| 1438 | 1438 |
| 1439 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { |
| 1440 PPCOperandGenerator g(this); |
| 1441 Emit(kPPC_Float64ExtractLowWord32, g.DefineAsRegister(node), |
| 1442 g.UseRegister(node->InputAt(0))); |
| 1443 } |
| 1444 |
| 1445 |
| 1446 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { |
| 1447 PPCOperandGenerator g(this); |
| 1448 Emit(kPPC_Float64ExtractHighWord32, g.DefineAsRegister(node), |
| 1449 g.UseRegister(node->InputAt(0))); |
| 1450 } |
| 1451 |
| 1452 |
| 1453 void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) { |
| 1454 PPCOperandGenerator g(this); |
| 1455 Node* left = node->InputAt(0); |
| 1456 Node* right = node->InputAt(1); |
| 1457 if (left->opcode() == IrOpcode::kFloat64InsertHighWord32 && |
| 1458 CanCover(node, left)) { |
| 1459 left = left->InputAt(1); |
| 1460 Emit(kPPC_Float64Construct, g.DefineAsRegister(node), g.UseRegister(left), |
| 1461 g.UseRegister(right)); |
| 1462 return; |
| 1463 } |
| 1464 Emit(kPPC_Float64InsertLowWord32, g.DefineSameAsFirst(node), |
| 1465 g.UseRegister(left), g.UseRegister(right)); |
| 1466 } |
| 1467 |
| 1468 |
| 1469 void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { |
| 1470 PPCOperandGenerator g(this); |
| 1471 Node* left = node->InputAt(0); |
| 1472 Node* right = node->InputAt(1); |
| 1473 if (left->opcode() == IrOpcode::kFloat64InsertLowWord32 && |
| 1474 CanCover(node, left)) { |
| 1475 left = left->InputAt(1); |
| 1476 Emit(kPPC_Float64Construct, g.DefineAsRegister(node), g.UseRegister(right), |
| 1477 g.UseRegister(left)); |
| 1478 return; |
| 1479 } |
| 1480 Emit(kPPC_Float64InsertHighWord32, g.DefineSameAsFirst(node), |
| 1481 g.UseRegister(left), g.UseRegister(right)); |
| 1482 } |
| 1483 |
| 1484 |
| 1439 // static | 1485 // static |
| 1440 MachineOperatorBuilder::Flags | 1486 MachineOperatorBuilder::Flags |
| 1441 InstructionSelector::SupportedMachineOperatorFlags() { | 1487 InstructionSelector::SupportedMachineOperatorFlags() { |
| 1442 return MachineOperatorBuilder::kFloat64Floor | | 1488 return MachineOperatorBuilder::kFloat64RoundDown | |
| 1443 MachineOperatorBuilder::kFloat64Ceil | | |
| 1444 MachineOperatorBuilder::kFloat64RoundTruncate | | 1489 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1445 MachineOperatorBuilder::kFloat64RoundTiesAway; | 1490 MachineOperatorBuilder::kFloat64RoundTiesAway; |
| 1446 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. | 1491 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. |
| 1447 } | 1492 } |
| 1448 | 1493 |
| 1449 } // namespace compiler | 1494 } // namespace compiler |
| 1450 } // namespace internal | 1495 } // namespace internal |
| 1451 } // namespace v8 | 1496 } // namespace v8 |
| OLD | NEW |