| 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 |