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