| 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/base/bits.h" | 5 #include "src/base/bits.h" |
| 6 #include "src/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
| 7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
| 8 #include "src/compiler/node-properties.h" |
| 8 | 9 |
| 9 namespace v8 { | 10 namespace v8 { |
| 10 namespace internal { | 11 namespace internal { |
| 11 namespace compiler { | 12 namespace compiler { |
| 12 | 13 |
| 13 // Adds Arm-specific methods for generating InstructionOperands. | 14 // Adds Arm-specific methods for generating InstructionOperands. |
| 14 class ArmOperandGenerator : public OperandGenerator { | 15 class ArmOperandGenerator : public OperandGenerator { |
| 15 public: | 16 public: |
| 16 explicit ArmOperandGenerator(InstructionSelector* selector) | 17 explicit ArmOperandGenerator(InstructionSelector* selector) |
| 17 : OperandGenerator(selector) {} | 18 : OperandGenerator(selector) {} |
| (...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1028 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | 1029 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
| 1029 | 1030 |
| 1030 // Compute InstructionOperands for inputs and outputs. | 1031 // Compute InstructionOperands for inputs and outputs. |
| 1031 // TODO(turbofan): on ARM64 it's probably better to use the code object in a | 1032 // TODO(turbofan): on ARM64 it's probably better to use the code object in a |
| 1032 // register if there are multiple uses of it. Improve constant pool and the | 1033 // register if there are multiple uses of it. Improve constant pool and the |
| 1033 // heuristics in the register allocator for where to emit constants. | 1034 // heuristics in the register allocator for where to emit constants. |
| 1034 InitializeCallBuffer(node, &buffer, true, false); | 1035 InitializeCallBuffer(node, &buffer, true, false); |
| 1035 | 1036 |
| 1036 // TODO(dcarney): might be possible to use claim/poke instead | 1037 // TODO(dcarney): might be possible to use claim/poke instead |
| 1037 // Push any stack arguments. | 1038 // Push any stack arguments. |
| 1038 for (NodeVectorRIter input = buffer.pushed_nodes.rbegin(); | 1039 for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); |
| 1039 input != buffer.pushed_nodes.rend(); input++) { | 1040 ++i) { |
| 1040 Emit(kArmPush, NULL, g.UseRegister(*input)); | 1041 Emit(kArmPush, nullptr, g.UseRegister(*i)); |
| 1041 } | 1042 } |
| 1042 | 1043 |
| 1043 // Select the appropriate opcode based on the call type. | 1044 // Select the appropriate opcode based on the call type. |
| 1044 InstructionCode opcode; | 1045 InstructionCode opcode; |
| 1045 switch (descriptor->kind()) { | 1046 switch (descriptor->kind()) { |
| 1046 case CallDescriptor::kCallCodeObject: { | 1047 case CallDescriptor::kCallCodeObject: { |
| 1047 opcode = kArchCallCodeObject; | 1048 opcode = kArchCallCodeObject; |
| 1048 break; | 1049 break; |
| 1049 } | 1050 } |
| 1050 case CallDescriptor::kCallJSFunction: | 1051 case CallDescriptor::kCallJSFunction: |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 return VisitFloat64Compare(selector, value, cont); | 1174 return VisitFloat64Compare(selector, value, cont); |
| 1174 case IrOpcode::kFloat64LessThan: | 1175 case IrOpcode::kFloat64LessThan: |
| 1175 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1176 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1176 return VisitFloat64Compare(selector, value, cont); | 1177 return VisitFloat64Compare(selector, value, cont); |
| 1177 case IrOpcode::kFloat64LessThanOrEqual: | 1178 case IrOpcode::kFloat64LessThanOrEqual: |
| 1178 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); | 1179 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
| 1179 return VisitFloat64Compare(selector, value, cont); | 1180 return VisitFloat64Compare(selector, value, cont); |
| 1180 case IrOpcode::kProjection: | 1181 case IrOpcode::kProjection: |
| 1181 // Check if this is the overflow output projection of an | 1182 // Check if this is the overflow output projection of an |
| 1182 // <Operation>WithOverflow node. | 1183 // <Operation>WithOverflow node. |
| 1183 if (OpParameter<size_t>(value) == 1u) { | 1184 if (ProjectionIndexOf(value->op()) == 1u) { |
| 1184 // We cannot combine the <Operation>WithOverflow with this branch | 1185 // We cannot combine the <Operation>WithOverflow with this branch |
| 1185 // unless the 0th projection (the use of the actual value of the | 1186 // unless the 0th projection (the use of the actual value of the |
| 1186 // <Operation> is either NULL, which means there's no use of the | 1187 // <Operation> is either NULL, which means there's no use of the |
| 1187 // actual value, or was already defined, which means it is scheduled | 1188 // actual value, or was already defined, which means it is scheduled |
| 1188 // *AFTER* this branch). | 1189 // *AFTER* this branch). |
| 1189 Node* const node = value->InputAt(0); | 1190 Node* const node = value->InputAt(0); |
| 1190 Node* const result = node->FindProjection(0); | 1191 Node* const result = NodeProperties::FindProjection(node, 0); |
| 1191 if (!result || selector->IsDefined(result)) { | 1192 if (!result || selector->IsDefined(result)) { |
| 1192 switch (node->opcode()) { | 1193 switch (node->opcode()) { |
| 1193 case IrOpcode::kInt32AddWithOverflow: | 1194 case IrOpcode::kInt32AddWithOverflow: |
| 1194 cont->OverwriteAndNegateIfEqual(kOverflow); | 1195 cont->OverwriteAndNegateIfEqual(kOverflow); |
| 1195 return VisitBinop(selector, node, kArmAdd, kArmAdd, cont); | 1196 return VisitBinop(selector, node, kArmAdd, kArmAdd, cont); |
| 1196 case IrOpcode::kInt32SubWithOverflow: | 1197 case IrOpcode::kInt32SubWithOverflow: |
| 1197 cont->OverwriteAndNegateIfEqual(kOverflow); | 1198 cont->OverwriteAndNegateIfEqual(kOverflow); |
| 1198 return VisitBinop(selector, node, kArmSub, kArmRsb, cont); | 1199 return VisitBinop(selector, node, kArmSub, kArmRsb, cont); |
| 1199 default: | 1200 default: |
| 1200 break; | 1201 break; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1279 } | 1280 } |
| 1280 | 1281 |
| 1281 | 1282 |
| 1282 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { | 1283 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { |
| 1283 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); | 1284 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); |
| 1284 VisitWordCompare(this, node, &cont); | 1285 VisitWordCompare(this, node, &cont); |
| 1285 } | 1286 } |
| 1286 | 1287 |
| 1287 | 1288 |
| 1288 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { | 1289 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { |
| 1289 if (Node* ovf = node->FindProjection(1)) { | 1290 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| 1290 FlagsContinuation cont(kOverflow, ovf); | 1291 FlagsContinuation cont(kOverflow, ovf); |
| 1291 return VisitBinop(this, node, kArmAdd, kArmAdd, &cont); | 1292 return VisitBinop(this, node, kArmAdd, kArmAdd, &cont); |
| 1292 } | 1293 } |
| 1293 FlagsContinuation cont; | 1294 FlagsContinuation cont; |
| 1294 VisitBinop(this, node, kArmAdd, kArmAdd, &cont); | 1295 VisitBinop(this, node, kArmAdd, kArmAdd, &cont); |
| 1295 } | 1296 } |
| 1296 | 1297 |
| 1297 | 1298 |
| 1298 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { | 1299 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
| 1299 if (Node* ovf = node->FindProjection(1)) { | 1300 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| 1300 FlagsContinuation cont(kOverflow, ovf); | 1301 FlagsContinuation cont(kOverflow, ovf); |
| 1301 return VisitBinop(this, node, kArmSub, kArmRsb, &cont); | 1302 return VisitBinop(this, node, kArmSub, kArmRsb, &cont); |
| 1302 } | 1303 } |
| 1303 FlagsContinuation cont; | 1304 FlagsContinuation cont; |
| 1304 VisitBinop(this, node, kArmSub, kArmRsb, &cont); | 1305 VisitBinop(this, node, kArmSub, kArmRsb, &cont); |
| 1305 } | 1306 } |
| 1306 | 1307 |
| 1307 | 1308 |
| 1308 void InstructionSelector::VisitFloat64Equal(Node* node) { | 1309 void InstructionSelector::VisitFloat64Equal(Node* node) { |
| 1309 FlagsContinuation cont(kEqual, node); | 1310 FlagsContinuation cont(kEqual, node); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1335 MachineOperatorBuilder::kFloat64Ceil | | 1336 MachineOperatorBuilder::kFloat64Ceil | |
| 1336 MachineOperatorBuilder::kFloat64RoundTruncate | | 1337 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1337 MachineOperatorBuilder::kFloat64RoundTiesAway; | 1338 MachineOperatorBuilder::kFloat64RoundTiesAway; |
| 1338 } | 1339 } |
| 1339 return flags; | 1340 return flags; |
| 1340 } | 1341 } |
| 1341 | 1342 |
| 1342 } // namespace compiler | 1343 } // namespace compiler |
| 1343 } // namespace internal | 1344 } // namespace internal |
| 1344 } // namespace v8 | 1345 } // namespace v8 |
| OLD | NEW |