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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 } else if (commutative && g.CanBeImmediate(left)) { | 189 } else if (commutative && g.CanBeImmediate(left)) { |
190 selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(right), | 190 selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(right), |
191 g.UseImmediate(left)); | 191 g.UseImmediate(left)); |
192 } else { | 192 } else { |
193 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), | 193 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), |
194 g.Use(right)); | 194 g.Use(right)); |
195 } | 195 } |
196 } | 196 } |
197 | 197 |
198 | 198 |
| 199 static void VisitBinopWithOverflow(InstructionSelector* selector, Node* node, |
| 200 InstructionCode opcode) { |
| 201 X64OperandGenerator g(selector); |
| 202 Int32BinopMatcher m(node); |
| 203 InstructionOperand* inputs[2]; |
| 204 size_t input_count = 0; |
| 205 InstructionOperand* outputs[2]; |
| 206 size_t output_count = 0; |
| 207 |
| 208 // TODO(turbofan): match complex addressing modes. |
| 209 // TODO(turbofan): if commutative, pick the non-live-in operand as the left as |
| 210 // this might be the last use and therefore its register can be reused. |
| 211 if (g.CanBeImmediate(m.right().node())) { |
| 212 inputs[input_count++] = g.Use(m.left().node()); |
| 213 inputs[input_count++] = g.UseImmediate(m.right().node()); |
| 214 } else { |
| 215 inputs[input_count++] = g.UseRegister(m.left().node()); |
| 216 inputs[input_count++] = g.Use(m.right().node()); |
| 217 } |
| 218 |
| 219 // Define outputs depending on the projections. |
| 220 Node* projections[2]; |
| 221 node->CollectProjections(ARRAY_SIZE(projections), projections); |
| 222 if (projections[0]) { |
| 223 outputs[output_count++] = g.DefineSameAsFirst(projections[0]); |
| 224 } |
| 225 if (projections[1]) { |
| 226 opcode |= FlagsModeField::encode(kFlags_set); |
| 227 opcode |= FlagsConditionField::encode(kOverflow); |
| 228 outputs[output_count++] = |
| 229 (projections[0] ? g.DefineAsRegister(projections[1]) |
| 230 : g.DefineSameAsFirst(projections[1])); |
| 231 } |
| 232 |
| 233 ASSERT_NE(0, input_count); |
| 234 ASSERT_NE(0, output_count); |
| 235 ASSERT_GE(ARRAY_SIZE(inputs), input_count); |
| 236 ASSERT_GE(ARRAY_SIZE(outputs), output_count); |
| 237 |
| 238 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
| 239 } |
| 240 |
| 241 |
199 void InstructionSelector::VisitWord32And(Node* node) { | 242 void InstructionSelector::VisitWord32And(Node* node) { |
200 VisitBinop(this, node, kX64And32, true); | 243 VisitBinop(this, node, kX64And32, true); |
201 } | 244 } |
202 | 245 |
203 | 246 |
204 void InstructionSelector::VisitWord64And(Node* node) { | 247 void InstructionSelector::VisitWord64And(Node* node) { |
205 VisitBinop(this, node, kX64And, true); | 248 VisitBinop(this, node, kX64And, true); |
206 } | 249 } |
207 | 250 |
208 | 251 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 void InstructionSelector::VisitWord64Sar(Node* node) { | 363 void InstructionSelector::VisitWord64Sar(Node* node) { |
321 VisitWord64Shift(this, node, kX64Sar); | 364 VisitWord64Shift(this, node, kX64Sar); |
322 } | 365 } |
323 | 366 |
324 | 367 |
325 void InstructionSelector::VisitInt32Add(Node* node) { | 368 void InstructionSelector::VisitInt32Add(Node* node) { |
326 VisitBinop(this, node, kX64Add32, true); | 369 VisitBinop(this, node, kX64Add32, true); |
327 } | 370 } |
328 | 371 |
329 | 372 |
| 373 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { |
| 374 VisitBinopWithOverflow(this, node, kX64Add32); |
| 375 } |
| 376 |
| 377 |
330 void InstructionSelector::VisitInt64Add(Node* node) { | 378 void InstructionSelector::VisitInt64Add(Node* node) { |
331 VisitBinop(this, node, kX64Add, true); | 379 VisitBinop(this, node, kX64Add, true); |
332 } | 380 } |
333 | 381 |
334 | 382 |
335 template <typename T> | 383 template <typename T> |
336 static void VisitSub(InstructionSelector* selector, Node* node, | 384 static void VisitSub(InstructionSelector* selector, Node* node, |
337 ArchOpcode sub_opcode, ArchOpcode neg_opcode) { | 385 ArchOpcode sub_opcode, ArchOpcode neg_opcode) { |
338 X64OperandGenerator g(selector); | 386 X64OperandGenerator g(selector); |
339 BinopMatcher<IntMatcher<T>, IntMatcher<T> > m(node); | 387 BinopMatcher<IntMatcher<T>, IntMatcher<T> > m(node); |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 ASSERT(deoptimization == NULL && continuation == NULL); | 725 ASSERT(deoptimization == NULL && continuation == NULL); |
678 Emit(kPopStack | MiscField::encode(buffer.pushed_count), NULL); | 726 Emit(kPopStack | MiscField::encode(buffer.pushed_count), NULL); |
679 } | 727 } |
680 } | 728 } |
681 | 729 |
682 #endif | 730 #endif |
683 | 731 |
684 } // namespace compiler | 732 } // namespace compiler |
685 } // namespace internal | 733 } // namespace internal |
686 } // namespace v8 | 734 } // namespace v8 |
OLD | NEW |