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/generic-node-inl.h" | 5 #include "src/compiler/generic-node-inl.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 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 Int32BinopMatcher m(node); | 234 Int32BinopMatcher m(node); |
235 Node* left = m.left().node(); | 235 Node* left = m.left().node(); |
236 Node* right = m.right().node(); | 236 Node* right = m.right().node(); |
237 InstructionOperand* inputs[4]; | 237 InstructionOperand* inputs[4]; |
238 size_t input_count = 0; | 238 size_t input_count = 0; |
239 InstructionOperand* outputs[2]; | 239 InstructionOperand* outputs[2]; |
240 size_t output_count = 0; | 240 size_t output_count = 0; |
241 | 241 |
242 // TODO(turbofan): match complex addressing modes. | 242 // TODO(turbofan): match complex addressing modes. |
243 if (g.CanBeImmediate(right)) { | 243 if (g.CanBeImmediate(right)) { |
244 inputs[input_count++] = g.Use(left); | 244 inputs[input_count++] = g.UseRegister(left); |
245 inputs[input_count++] = g.UseImmediate(right); | 245 inputs[input_count++] = g.UseImmediate(right); |
246 } else { | 246 } else { |
247 if (node->op()->HasProperty(Operator::kCommutative) && | 247 if (node->op()->HasProperty(Operator::kCommutative) && |
248 g.CanBeBetterLeftOperand(right)) { | 248 g.CanBeBetterLeftOperand(right)) { |
249 std::swap(left, right); | 249 std::swap(left, right); |
250 } | 250 } |
251 inputs[input_count++] = g.UseRegister(left); | 251 inputs[input_count++] = g.UseRegister(left); |
252 inputs[input_count++] = g.Use(right); | 252 inputs[input_count++] = g.Use(right); |
253 } | 253 } |
254 | 254 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 | 298 |
299 void InstructionSelector::VisitWord64Or(Node* node) { | 299 void InstructionSelector::VisitWord64Or(Node* node) { |
300 VisitBinop(this, node, kX64Or); | 300 VisitBinop(this, node, kX64Or); |
301 } | 301 } |
302 | 302 |
303 | 303 |
304 void InstructionSelector::VisitWord32Xor(Node* node) { | 304 void InstructionSelector::VisitWord32Xor(Node* node) { |
305 X64OperandGenerator g(this); | 305 X64OperandGenerator g(this); |
306 Uint32BinopMatcher m(node); | 306 Uint32BinopMatcher m(node); |
307 if (m.right().Is(-1)) { | 307 if (m.right().Is(-1)) { |
308 Emit(kX64Not32, g.DefineSameAsFirst(node), g.Use(m.left().node())); | 308 Emit(kX64Not32, g.DefineSameAsFirst(node), g.UseRegister(m.left().node())); |
309 } else { | 309 } else { |
310 VisitBinop(this, node, kX64Xor32); | 310 VisitBinop(this, node, kX64Xor32); |
311 } | 311 } |
312 } | 312 } |
313 | 313 |
314 | 314 |
315 void InstructionSelector::VisitWord64Xor(Node* node) { | 315 void InstructionSelector::VisitWord64Xor(Node* node) { |
316 X64OperandGenerator g(this); | 316 X64OperandGenerator g(this); |
317 Uint64BinopMatcher m(node); | 317 Uint64BinopMatcher m(node); |
318 if (m.right().Is(-1)) { | 318 if (m.right().Is(-1)) { |
319 Emit(kX64Not, g.DefineSameAsFirst(node), g.Use(m.left().node())); | 319 Emit(kX64Not, g.DefineSameAsFirst(node), g.UseRegister(m.left().node())); |
320 } else { | 320 } else { |
321 VisitBinop(this, node, kX64Xor); | 321 VisitBinop(this, node, kX64Xor); |
322 } | 322 } |
323 } | 323 } |
324 | 324 |
325 | 325 |
326 // Shared routine for multiple 32-bit shift operations. | 326 // Shared routine for multiple 32-bit shift operations. |
327 // TODO(bmeurer): Merge this with VisitWord64Shift using template magic? | 327 // TODO(bmeurer): Merge this with VisitWord64Shift using template magic? |
328 static void VisitWord32Shift(InstructionSelector* selector, Node* node, | 328 static void VisitWord32Shift(InstructionSelector* selector, Node* node, |
329 ArchOpcode opcode) { | 329 ArchOpcode opcode) { |
330 X64OperandGenerator g(selector); | 330 X64OperandGenerator g(selector); |
331 Node* left = node->InputAt(0); | 331 Node* left = node->InputAt(0); |
332 Node* right = node->InputAt(1); | 332 Node* right = node->InputAt(1); |
333 | 333 |
334 if (g.CanBeImmediate(right)) { | 334 if (g.CanBeImmediate(right)) { |
335 selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), | 335 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), |
336 g.UseImmediate(right)); | 336 g.UseImmediate(right)); |
337 } else { | 337 } else { |
338 Int32BinopMatcher m(node); | 338 Int32BinopMatcher m(node); |
339 if (m.right().IsWord32And()) { | 339 if (m.right().IsWord32And()) { |
340 Int32BinopMatcher mright(right); | 340 Int32BinopMatcher mright(right); |
341 if (mright.right().Is(0x1F)) { | 341 if (mright.right().Is(0x1F)) { |
342 right = mright.left().node(); | 342 right = mright.left().node(); |
343 } | 343 } |
344 } | 344 } |
345 selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), | 345 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), |
346 g.UseFixed(right, rcx)); | 346 g.UseFixed(right, rcx)); |
347 } | 347 } |
348 } | 348 } |
349 | 349 |
350 | 350 |
351 // Shared routine for multiple 64-bit shift operations. | 351 // Shared routine for multiple 64-bit shift operations. |
352 // TODO(bmeurer): Merge this with VisitWord32Shift using template magic? | 352 // TODO(bmeurer): Merge this with VisitWord32Shift using template magic? |
353 static void VisitWord64Shift(InstructionSelector* selector, Node* node, | 353 static void VisitWord64Shift(InstructionSelector* selector, Node* node, |
354 ArchOpcode opcode) { | 354 ArchOpcode opcode) { |
355 X64OperandGenerator g(selector); | 355 X64OperandGenerator g(selector); |
356 Node* left = node->InputAt(0); | 356 Node* left = node->InputAt(0); |
357 Node* right = node->InputAt(1); | 357 Node* right = node->InputAt(1); |
358 | 358 |
359 if (g.CanBeImmediate(right)) { | 359 if (g.CanBeImmediate(right)) { |
360 selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), | 360 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), |
361 g.UseImmediate(right)); | 361 g.UseImmediate(right)); |
362 } else { | 362 } else { |
363 Int64BinopMatcher m(node); | 363 Int64BinopMatcher m(node); |
364 if (m.right().IsWord64And()) { | 364 if (m.right().IsWord64And()) { |
365 Int64BinopMatcher mright(right); | 365 Int64BinopMatcher mright(right); |
366 if (mright.right().Is(0x3F)) { | 366 if (mright.right().Is(0x3F)) { |
367 right = mright.left().node(); | 367 right = mright.left().node(); |
368 } | 368 } |
369 } | 369 } |
370 selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), | 370 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), |
371 g.UseFixed(right, rcx)); | 371 g.UseFixed(right, rcx)); |
372 } | 372 } |
373 } | 373 } |
374 | 374 |
375 | 375 |
376 void InstructionSelector::VisitWord32Shl(Node* node) { | 376 void InstructionSelector::VisitWord32Shl(Node* node) { |
377 VisitWord32Shift(this, node, kX64Shl32); | 377 VisitWord32Shift(this, node, kX64Shl32); |
378 } | 378 } |
379 | 379 |
380 | 380 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 void InstructionSelector::VisitInt64Add(Node* node) { | 465 void InstructionSelector::VisitInt64Add(Node* node) { |
466 if (TryEmitLeaMultAdd(this, node, kX64Lea)) return; | 466 if (TryEmitLeaMultAdd(this, node, kX64Lea)) return; |
467 VisitBinop(this, node, kX64Add); | 467 VisitBinop(this, node, kX64Add); |
468 } | 468 } |
469 | 469 |
470 | 470 |
471 void InstructionSelector::VisitInt32Sub(Node* node) { | 471 void InstructionSelector::VisitInt32Sub(Node* node) { |
472 X64OperandGenerator g(this); | 472 X64OperandGenerator g(this); |
473 Int32BinopMatcher m(node); | 473 Int32BinopMatcher m(node); |
474 if (m.left().Is(0)) { | 474 if (m.left().Is(0)) { |
475 Emit(kX64Neg32, g.DefineSameAsFirst(node), g.Use(m.right().node())); | 475 Emit(kX64Neg32, g.DefineSameAsFirst(node), g.UseRegister(m.right().node())); |
476 } else { | 476 } else { |
477 VisitBinop(this, node, kX64Sub32); | 477 VisitBinop(this, node, kX64Sub32); |
478 } | 478 } |
479 } | 479 } |
480 | 480 |
481 | 481 |
482 void InstructionSelector::VisitInt64Sub(Node* node) { | 482 void InstructionSelector::VisitInt64Sub(Node* node) { |
483 X64OperandGenerator g(this); | 483 X64OperandGenerator g(this); |
484 Int64BinopMatcher m(node); | 484 Int64BinopMatcher m(node); |
485 if (m.left().Is(0)) { | 485 if (m.left().Is(0)) { |
486 Emit(kX64Neg, g.DefineSameAsFirst(node), g.Use(m.right().node())); | 486 Emit(kX64Neg, g.DefineSameAsFirst(node), g.UseRegister(m.right().node())); |
487 } else { | 487 } else { |
488 VisitBinop(this, node, kX64Sub); | 488 VisitBinop(this, node, kX64Sub); |
489 } | 489 } |
490 } | 490 } |
491 | 491 |
492 | 492 |
493 static bool TryEmitLeaMult(InstructionSelector* selector, Node* node, | 493 static bool TryEmitLeaMult(InstructionSelector* selector, Node* node, |
494 ArchOpcode opcode) { | 494 ArchOpcode opcode) { |
495 LeaMultiplyMatcher lea(node); | 495 LeaMultiplyMatcher lea(node); |
496 // Try to match lea. | 496 // Try to match lea. |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 call_instr->MarkAsCall(); | 852 call_instr->MarkAsCall(); |
853 if (deoptimization != NULL) { | 853 if (deoptimization != NULL) { |
854 DCHECK(continuation != NULL); | 854 DCHECK(continuation != NULL); |
855 call_instr->MarkAsControl(); | 855 call_instr->MarkAsControl(); |
856 } | 856 } |
857 } | 857 } |
858 | 858 |
859 } // namespace compiler | 859 } // namespace compiler |
860 } // namespace internal | 860 } // namespace internal |
861 } // namespace v8 | 861 } // namespace v8 |
OLD | NEW |