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 | 7 |
8 namespace v8 { | 8 namespace v8 { |
9 namespace internal { | 9 namespace internal { |
10 namespace compiler { | 10 namespace compiler { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 | 107 |
108 | 108 |
109 // Shared routine for multiple binary operations. | 109 // Shared routine for multiple binary operations. |
110 static void VisitBinop(InstructionSelector* selector, Node* node, | 110 static void VisitBinop(InstructionSelector* selector, Node* node, |
111 ArchOpcode opcode, ImmediateMode operand_mode, | 111 ArchOpcode opcode, ImmediateMode operand_mode, |
112 bool commutative) { | 112 bool commutative) { |
113 VisitRRO(selector, opcode, node, operand_mode); | 113 VisitRRO(selector, opcode, node, operand_mode); |
114 } | 114 } |
115 | 115 |
116 | 116 |
| 117 static void VisitBinopWithOverflow(InstructionSelector* selector, Node* node, |
| 118 InstructionCode opcode) { |
| 119 Arm64OperandGenerator g(selector); |
| 120 Int32BinopMatcher m(node); |
| 121 InstructionOperand* inputs[2]; |
| 122 size_t input_count = 0; |
| 123 InstructionOperand* outputs[2]; |
| 124 size_t output_count = 0; |
| 125 |
| 126 inputs[input_count++] = g.UseRegister(m.left().node()); |
| 127 inputs[input_count++] = g.UseRegister(m.right().node()); |
| 128 |
| 129 // Define outputs depending on the projections. |
| 130 Node* projections[2]; |
| 131 node->CollectProjections(ARRAY_SIZE(projections), projections); |
| 132 if (projections[0]) { |
| 133 outputs[output_count++] = g.DefineAsRegister(projections[0]); |
| 134 } |
| 135 if (projections[1]) { |
| 136 opcode |= FlagsModeField::encode(kFlags_set); |
| 137 opcode |= FlagsConditionField::encode(kOverflow); |
| 138 outputs[output_count++] = g.DefineAsRegister(projections[1]); |
| 139 } |
| 140 |
| 141 ASSERT_NE(0, input_count); |
| 142 ASSERT_NE(0, output_count); |
| 143 ASSERT_GE(ARRAY_SIZE(inputs), input_count); |
| 144 ASSERT_GE(ARRAY_SIZE(outputs), output_count); |
| 145 |
| 146 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
| 147 } |
| 148 |
| 149 |
117 void InstructionSelector::VisitLoad(Node* node) { | 150 void InstructionSelector::VisitLoad(Node* node) { |
118 MachineRepresentation rep = OpParameter<MachineRepresentation>(node); | 151 MachineRepresentation rep = OpParameter<MachineRepresentation>(node); |
119 Arm64OperandGenerator g(this); | 152 Arm64OperandGenerator g(this); |
120 Node* base = node->InputAt(0); | 153 Node* base = node->InputAt(0); |
121 Node* index = node->InputAt(1); | 154 Node* index = node->InputAt(1); |
122 | 155 |
123 InstructionOperand* result = rep == kMachineFloat64 | 156 InstructionOperand* result = rep == kMachineFloat64 |
124 ? g.DefineAsDoubleRegister(node) | 157 ? g.DefineAsDoubleRegister(node) |
125 : g.DefineAsRegister(node); | 158 : g.DefineAsRegister(node); |
126 | 159 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 void InstructionSelector::VisitWord64Sar(Node* node) { | 325 void InstructionSelector::VisitWord64Sar(Node* node) { |
293 VisitRRO(this, kArm64Sar, node, kShift64Imm); | 326 VisitRRO(this, kArm64Sar, node, kShift64Imm); |
294 } | 327 } |
295 | 328 |
296 | 329 |
297 void InstructionSelector::VisitInt32Add(Node* node) { | 330 void InstructionSelector::VisitInt32Add(Node* node) { |
298 VisitBinop(this, node, kArm64Add32, kArithimeticImm, true); | 331 VisitBinop(this, node, kArm64Add32, kArithimeticImm, true); |
299 } | 332 } |
300 | 333 |
301 | 334 |
| 335 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { |
| 336 VisitBinopWithOverflow(this, node, kArm64Add32); |
| 337 } |
| 338 |
| 339 |
302 void InstructionSelector::VisitInt64Add(Node* node) { | 340 void InstructionSelector::VisitInt64Add(Node* node) { |
303 VisitBinop(this, node, kArm64Add, kArithimeticImm, true); | 341 VisitBinop(this, node, kArm64Add, kArithimeticImm, true); |
304 } | 342 } |
305 | 343 |
306 | 344 |
307 template <typename T> | 345 template <typename T> |
308 static void VisitSub(InstructionSelector* selector, Node* node, | 346 static void VisitSub(InstructionSelector* selector, Node* node, |
309 ArchOpcode sub_opcode, ArchOpcode neg_opcode) { | 347 ArchOpcode sub_opcode, ArchOpcode neg_opcode) { |
310 Arm64OperandGenerator g(selector); | 348 Arm64OperandGenerator g(selector); |
311 BinopMatcher<IntMatcher<T>, IntMatcher<T> > m(node); | 349 BinopMatcher<IntMatcher<T>, IntMatcher<T> > m(node); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 // Caller clean up of stack for C-style calls. | 649 // Caller clean up of stack for C-style calls. |
612 if (is_c_frame && aligned_push_count > 0) { | 650 if (is_c_frame && aligned_push_count > 0) { |
613 ASSERT(deoptimization == NULL && continuation == NULL); | 651 ASSERT(deoptimization == NULL && continuation == NULL); |
614 Emit(kArm64Drop | MiscField::encode(aligned_push_count), NULL); | 652 Emit(kArm64Drop | MiscField::encode(aligned_push_count), NULL); |
615 } | 653 } |
616 } | 654 } |
617 | 655 |
618 } // namespace compiler | 656 } // namespace compiler |
619 } // namespace internal | 657 } // namespace internal |
620 } // namespace v8 | 658 } // namespace v8 |
OLD | NEW |