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/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/base/bits.h" | 6 #include "src/base/bits.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 | 10 |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 if (base::bits::IsPowerOfTwo32(value + 1)) { | 412 if (base::bits::IsPowerOfTwo32(value + 1)) { |
413 InstructionOperand temp = g.TempRegister(); | 413 InstructionOperand temp = g.TempRegister(); |
414 Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp, | 414 Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp, |
415 g.UseRegister(m.left().node()), | 415 g.UseRegister(m.left().node()), |
416 g.TempImmediate(WhichPowerOf2(value + 1))); | 416 g.TempImmediate(WhichPowerOf2(value + 1))); |
417 Emit(kMips64Sub | AddressingModeField::encode(kMode_None), | 417 Emit(kMips64Sub | AddressingModeField::encode(kMode_None), |
418 g.DefineAsRegister(node), temp, g.UseRegister(m.left().node())); | 418 g.DefineAsRegister(node), temp, g.UseRegister(m.left().node())); |
419 return; | 419 return; |
420 } | 420 } |
421 } | 421 } |
| 422 Node* left = node->InputAt(0); |
| 423 Node* right = node->InputAt(1); |
| 424 if (CanCover(node, left) && CanCover(node, right)) { |
| 425 if (left->opcode() == IrOpcode::kWord64Sar && |
| 426 right->opcode() == IrOpcode::kWord64Sar) { |
| 427 Int64BinopMatcher leftInput(left), rightInput(right); |
| 428 if (leftInput.right().Is(32) && rightInput.right().Is(32)) { |
| 429 // Combine untagging shifts with Dmul high. |
| 430 Emit(kMips64DMulHigh, g.DefineSameAsFirst(node), |
| 431 g.UseRegister(leftInput.left().node()), |
| 432 g.UseRegister(rightInput.left().node())); |
| 433 return; |
| 434 } |
| 435 } |
| 436 } |
422 VisitRRR(this, kMips64Mul, node); | 437 VisitRRR(this, kMips64Mul, node); |
423 } | 438 } |
424 | 439 |
425 | 440 |
426 void InstructionSelector::VisitInt32MulHigh(Node* node) { | 441 void InstructionSelector::VisitInt32MulHigh(Node* node) { |
427 VisitRRR(this, kMips64MulHigh, node); | 442 VisitRRR(this, kMips64MulHigh, node); |
428 } | 443 } |
429 | 444 |
430 | 445 |
431 void InstructionSelector::VisitUint32MulHigh(Node* node) { | 446 void InstructionSelector::VisitUint32MulHigh(Node* node) { |
432 Mips64OperandGenerator g(this); | 447 VisitRRR(this, kMips64MulHighU, node); |
433 InstructionOperand const dmul_operand = g.TempRegister(); | |
434 Emit(kMips64MulHighU, dmul_operand, g.UseRegister(node->InputAt(0)), | |
435 g.UseRegister(node->InputAt(1))); | |
436 Emit(kMips64Ext, g.DefineAsRegister(node), dmul_operand, g.TempImmediate(0), | |
437 g.TempImmediate(32)); | |
438 } | 448 } |
439 | 449 |
440 | 450 |
441 void InstructionSelector::VisitInt64Mul(Node* node) { | 451 void InstructionSelector::VisitInt64Mul(Node* node) { |
442 Mips64OperandGenerator g(this); | 452 Mips64OperandGenerator g(this); |
443 Int64BinopMatcher m(node); | 453 Int64BinopMatcher m(node); |
444 // TODO(dusmil): Add optimization for shifts larger than 32. | 454 // TODO(dusmil): Add optimization for shifts larger than 32. |
445 if (m.right().HasValue() && m.right().Value() > 0) { | 455 if (m.right().HasValue() && m.right().Value() > 0) { |
446 int32_t value = static_cast<int32_t>(m.right().Value()); | 456 int32_t value = static_cast<int32_t>(m.right().Value()); |
447 if (base::bits::IsPowerOfTwo32(value)) { | 457 if (base::bits::IsPowerOfTwo32(value)) { |
(...skipping 22 matching lines...) Expand all Loading... |
470 } | 480 } |
471 } | 481 } |
472 Emit(kMips64Dmul, g.DefineAsRegister(node), g.UseRegister(m.left().node()), | 482 Emit(kMips64Dmul, g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
473 g.UseRegister(m.right().node())); | 483 g.UseRegister(m.right().node())); |
474 } | 484 } |
475 | 485 |
476 | 486 |
477 void InstructionSelector::VisitInt32Div(Node* node) { | 487 void InstructionSelector::VisitInt32Div(Node* node) { |
478 Mips64OperandGenerator g(this); | 488 Mips64OperandGenerator g(this); |
479 Int32BinopMatcher m(node); | 489 Int32BinopMatcher m(node); |
| 490 Node* left = node->InputAt(0); |
| 491 Node* right = node->InputAt(1); |
| 492 if (CanCover(node, left) && CanCover(node, right)) { |
| 493 if (left->opcode() == IrOpcode::kWord64Sar && |
| 494 right->opcode() == IrOpcode::kWord64Sar) { |
| 495 Int64BinopMatcher rightInput(right), leftInput(left); |
| 496 if (rightInput.right().Is(32) && leftInput.right().Is(32)) { |
| 497 // Combine both shifted operands with Ddiv. |
| 498 Emit(kMips64Ddiv, g.DefineSameAsFirst(node), |
| 499 g.UseRegister(leftInput.left().node()), |
| 500 g.UseRegister(rightInput.left().node())); |
| 501 return; |
| 502 } |
| 503 } |
| 504 } |
480 Emit(kMips64Div, g.DefineAsRegister(node), g.UseRegister(m.left().node()), | 505 Emit(kMips64Div, g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
481 g.UseRegister(m.right().node())); | 506 g.UseRegister(m.right().node())); |
482 } | 507 } |
483 | 508 |
484 | 509 |
485 void InstructionSelector::VisitUint32Div(Node* node) { | 510 void InstructionSelector::VisitUint32Div(Node* node) { |
486 Mips64OperandGenerator g(this); | 511 Mips64OperandGenerator g(this); |
487 Int32BinopMatcher m(node); | 512 Int32BinopMatcher m(node); |
488 Emit(kMips64DivU, g.DefineAsRegister(node), g.UseRegister(m.left().node()), | 513 Emit(kMips64DivU, g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
489 g.UseRegister(m.right().node())); | 514 g.UseRegister(m.right().node())); |
490 } | 515 } |
491 | 516 |
492 | 517 |
493 void InstructionSelector::VisitInt32Mod(Node* node) { | 518 void InstructionSelector::VisitInt32Mod(Node* node) { |
494 Mips64OperandGenerator g(this); | 519 Mips64OperandGenerator g(this); |
495 Int32BinopMatcher m(node); | 520 Int32BinopMatcher m(node); |
| 521 Node* left = node->InputAt(0); |
| 522 Node* right = node->InputAt(1); |
| 523 if (CanCover(node, left) && CanCover(node, right)) { |
| 524 if (left->opcode() == IrOpcode::kWord64Sar && |
| 525 right->opcode() == IrOpcode::kWord64Sar) { |
| 526 Int64BinopMatcher rightInput(right), leftInput(left); |
| 527 if (rightInput.right().Is(32) && leftInput.right().Is(32)) { |
| 528 // Combine both shifted operands with Dmod. |
| 529 Emit(kMips64Dmod, g.DefineSameAsFirst(node), |
| 530 g.UseRegister(leftInput.left().node()), |
| 531 g.UseRegister(rightInput.left().node())); |
| 532 return; |
| 533 } |
| 534 } |
| 535 } |
496 Emit(kMips64Mod, g.DefineAsRegister(node), g.UseRegister(m.left().node()), | 536 Emit(kMips64Mod, g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
497 g.UseRegister(m.right().node())); | 537 g.UseRegister(m.right().node())); |
498 } | 538 } |
499 | 539 |
500 | 540 |
501 void InstructionSelector::VisitUint32Mod(Node* node) { | 541 void InstructionSelector::VisitUint32Mod(Node* node) { |
502 Mips64OperandGenerator g(this); | 542 Mips64OperandGenerator g(this); |
503 Int32BinopMatcher m(node); | 543 Int32BinopMatcher m(node); |
504 Emit(kMips64ModU, g.DefineAsRegister(node), g.UseRegister(m.left().node()), | 544 Emit(kMips64ModU, g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
505 g.UseRegister(m.right().node())); | 545 g.UseRegister(m.right().node())); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { | 620 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { |
581 Mips64OperandGenerator g(this); | 621 Mips64OperandGenerator g(this); |
582 Node* value = node->InputAt(0); | 622 Node* value = node->InputAt(0); |
583 if (CanCover(node, value)) { | 623 if (CanCover(node, value)) { |
584 switch (value->opcode()) { | 624 switch (value->opcode()) { |
585 case IrOpcode::kWord64Sar: { | 625 case IrOpcode::kWord64Sar: { |
586 Int64BinopMatcher m(value); | 626 Int64BinopMatcher m(value); |
587 if (m.right().IsInRange(32, 63)) { | 627 if (m.right().IsInRange(32, 63)) { |
588 // After smi untagging no need for truncate. Combine sequence. | 628 // After smi untagging no need for truncate. Combine sequence. |
589 Emit(kMips64Dsar, g.DefineSameAsFirst(node), | 629 Emit(kMips64Dsar, g.DefineSameAsFirst(node), |
590 g.UseRegister(m.left().node()), g.TempImmediate(kSmiShift)); | 630 g.UseRegister(m.left().node()), |
| 631 g.UseImmediate(m.right().node())); |
591 return; | 632 return; |
592 } | 633 } |
593 break; | 634 break; |
594 } | 635 } |
595 default: | 636 default: |
596 break; | 637 break; |
597 } | 638 } |
598 } | 639 } |
599 Emit(kMips64Ext, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)), | 640 Emit(kMips64Ext, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)), |
600 g.TempImmediate(0), g.TempImmediate(32)); | 641 g.TempImmediate(0), g.TempImmediate(32)); |
(...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1403 MachineOperatorBuilder::kFloat32Max | | 1444 MachineOperatorBuilder::kFloat32Max | |
1404 MachineOperatorBuilder::kFloat64RoundDown | | 1445 MachineOperatorBuilder::kFloat64RoundDown | |
1405 MachineOperatorBuilder::kFloat64RoundUp | | 1446 MachineOperatorBuilder::kFloat64RoundUp | |
1406 MachineOperatorBuilder::kFloat64RoundTruncate | | 1447 MachineOperatorBuilder::kFloat64RoundTruncate | |
1407 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1448 MachineOperatorBuilder::kFloat64RoundTiesEven; |
1408 } | 1449 } |
1409 | 1450 |
1410 } // namespace compiler | 1451 } // namespace compiler |
1411 } // namespace internal | 1452 } // namespace internal |
1412 } // namespace v8 | 1453 } // namespace v8 |
OLD | NEW |