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 |