OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/x64/lithium-codegen-x64.h" | 9 #include "src/x64/lithium-codegen-x64.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 chunk_->IsDehoistedKey(chunk_->LookupConstant(op)); | 424 chunk_->IsDehoistedKey(chunk_->LookupConstant(op)); |
425 } | 425 } |
426 | 426 |
427 | 427 |
428 bool LCodeGen::IsSmiConstant(LConstantOperand* op) const { | 428 bool LCodeGen::IsSmiConstant(LConstantOperand* op) const { |
429 return chunk_->LookupLiteralRepresentation(op).IsSmi(); | 429 return chunk_->LookupLiteralRepresentation(op).IsSmi(); |
430 } | 430 } |
431 | 431 |
432 | 432 |
433 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { | 433 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { |
434 HConstant* constant = chunk_->LookupConstant(op); | 434 return ToRepresentation(op, Representation::Integer32()); |
435 return constant->Integer32Value(); | |
436 } | 435 } |
437 | 436 |
438 | 437 |
| 438 int32_t LCodeGen::ToRepresentation(LConstantOperand* op, |
| 439 const Representation& r) const { |
| 440 HConstant* constant = chunk_->LookupConstant(op); |
| 441 int32_t value = constant->Integer32Value(); |
| 442 if (r.IsInteger32()) return value; |
| 443 ASSERT(SmiValuesAre31Bits() && r.IsSmiOrTagged()); |
| 444 return static_cast<int32_t>(reinterpret_cast<intptr_t>(Smi::FromInt(value))); |
| 445 } |
| 446 |
| 447 |
439 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { | 448 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { |
440 HConstant* constant = chunk_->LookupConstant(op); | 449 HConstant* constant = chunk_->LookupConstant(op); |
441 return Smi::FromInt(constant->Integer32Value()); | 450 return Smi::FromInt(constant->Integer32Value()); |
442 } | 451 } |
443 | 452 |
444 | 453 |
445 double LCodeGen::ToDouble(LConstantOperand* op) const { | 454 double LCodeGen::ToDouble(LConstantOperand* op) const { |
446 HConstant* constant = chunk_->LookupConstant(op); | 455 HConstant* constant = chunk_->LookupConstant(op); |
447 ASSERT(constant->HasDoubleValue()); | 456 ASSERT(constant->HasDoubleValue()); |
448 return constant->DoubleValue(); | 457 return constant->DoubleValue(); |
(...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1450 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1459 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1451 // Bail out if the result is supposed to be negative zero. | 1460 // Bail out if the result is supposed to be negative zero. |
1452 Label done; | 1461 Label done; |
1453 if (instr->hydrogen_value()->representation().IsSmi()) { | 1462 if (instr->hydrogen_value()->representation().IsSmi()) { |
1454 __ testp(left, left); | 1463 __ testp(left, left); |
1455 } else { | 1464 } else { |
1456 __ testl(left, left); | 1465 __ testl(left, left); |
1457 } | 1466 } |
1458 __ j(not_zero, &done, Label::kNear); | 1467 __ j(not_zero, &done, Label::kNear); |
1459 if (right->IsConstantOperand()) { | 1468 if (right->IsConstantOperand()) { |
1460 // Constant can't be represented as Smi due to immediate size limit. | 1469 // Constant can't be represented as 32-bit Smi due to immediate size |
1461 ASSERT(!instr->hydrogen_value()->representation().IsSmi()); | 1470 // limit. |
| 1471 ASSERT(SmiValuesAre32Bits() |
| 1472 ? !instr->hydrogen_value()->representation().IsSmi() |
| 1473 : SmiValuesAre31Bits()); |
1462 if (ToInteger32(LConstantOperand::cast(right)) < 0) { | 1474 if (ToInteger32(LConstantOperand::cast(right)) < 0) { |
1463 DeoptimizeIf(no_condition, instr->environment()); | 1475 DeoptimizeIf(no_condition, instr->environment()); |
1464 } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { | 1476 } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { |
1465 __ cmpl(kScratchRegister, Immediate(0)); | 1477 __ cmpl(kScratchRegister, Immediate(0)); |
1466 DeoptimizeIf(less, instr->environment()); | 1478 DeoptimizeIf(less, instr->environment()); |
1467 } | 1479 } |
1468 } else if (right->IsStackSlot()) { | 1480 } else if (right->IsStackSlot()) { |
1469 if (instr->hydrogen_value()->representation().IsSmi()) { | 1481 if (instr->hydrogen_value()->representation().IsSmi()) { |
1470 __ orp(kScratchRegister, ToOperand(right)); | 1482 __ orp(kScratchRegister, ToOperand(right)); |
1471 } else { | 1483 } else { |
(...skipping 14 matching lines...) Expand all Loading... |
1486 } | 1498 } |
1487 | 1499 |
1488 | 1500 |
1489 void LCodeGen::DoBitI(LBitI* instr) { | 1501 void LCodeGen::DoBitI(LBitI* instr) { |
1490 LOperand* left = instr->left(); | 1502 LOperand* left = instr->left(); |
1491 LOperand* right = instr->right(); | 1503 LOperand* right = instr->right(); |
1492 ASSERT(left->Equals(instr->result())); | 1504 ASSERT(left->Equals(instr->result())); |
1493 ASSERT(left->IsRegister()); | 1505 ASSERT(left->IsRegister()); |
1494 | 1506 |
1495 if (right->IsConstantOperand()) { | 1507 if (right->IsConstantOperand()) { |
1496 int32_t right_operand = ToInteger32(LConstantOperand::cast(right)); | 1508 int32_t right_operand = |
| 1509 ToRepresentation(LConstantOperand::cast(right), |
| 1510 instr->hydrogen()->right()->representation()); |
1497 switch (instr->op()) { | 1511 switch (instr->op()) { |
1498 case Token::BIT_AND: | 1512 case Token::BIT_AND: |
1499 __ andl(ToRegister(left), Immediate(right_operand)); | 1513 __ andl(ToRegister(left), Immediate(right_operand)); |
1500 break; | 1514 break; |
1501 case Token::BIT_OR: | 1515 case Token::BIT_OR: |
1502 __ orl(ToRegister(left), Immediate(right_operand)); | 1516 __ orl(ToRegister(left), Immediate(right_operand)); |
1503 break; | 1517 break; |
1504 case Token::BIT_XOR: | 1518 case Token::BIT_XOR: |
1505 if (right_operand == int32_t(~0)) { | 1519 if (right_operand == int32_t(~0)) { |
1506 __ notl(ToRegister(left)); | 1520 __ notl(ToRegister(left)); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1618 if (shift_count != 0) { | 1632 if (shift_count != 0) { |
1619 __ shrl(ToRegister(left), Immediate(shift_count)); | 1633 __ shrl(ToRegister(left), Immediate(shift_count)); |
1620 } else if (instr->can_deopt()) { | 1634 } else if (instr->can_deopt()) { |
1621 __ testl(ToRegister(left), ToRegister(left)); | 1635 __ testl(ToRegister(left), ToRegister(left)); |
1622 DeoptimizeIf(negative, instr->environment()); | 1636 DeoptimizeIf(negative, instr->environment()); |
1623 } | 1637 } |
1624 break; | 1638 break; |
1625 case Token::SHL: | 1639 case Token::SHL: |
1626 if (shift_count != 0) { | 1640 if (shift_count != 0) { |
1627 if (instr->hydrogen_value()->representation().IsSmi()) { | 1641 if (instr->hydrogen_value()->representation().IsSmi()) { |
1628 __ shlp(ToRegister(left), Immediate(shift_count)); | 1642 if (SmiValuesAre32Bits()) { |
| 1643 __ shlp(ToRegister(left), Immediate(shift_count)); |
| 1644 } else { |
| 1645 ASSERT(SmiValuesAre31Bits()); |
| 1646 if (instr->can_deopt()) { |
| 1647 if (shift_count != 1) { |
| 1648 __ shll(ToRegister(left), Immediate(shift_count - 1)); |
| 1649 } |
| 1650 __ Integer32ToSmi(ToRegister(left), ToRegister(left)); |
| 1651 DeoptimizeIf(overflow, instr->environment()); |
| 1652 } else { |
| 1653 __ shll(ToRegister(left), Immediate(shift_count)); |
| 1654 } |
| 1655 } |
1629 } else { | 1656 } else { |
1630 __ shll(ToRegister(left), Immediate(shift_count)); | 1657 __ shll(ToRegister(left), Immediate(shift_count)); |
1631 } | 1658 } |
1632 } | 1659 } |
1633 break; | 1660 break; |
1634 default: | 1661 default: |
1635 UNREACHABLE(); | 1662 UNREACHABLE(); |
1636 break; | 1663 break; |
1637 } | 1664 } |
1638 } | 1665 } |
1639 } | 1666 } |
1640 | 1667 |
1641 | 1668 |
1642 void LCodeGen::DoSubI(LSubI* instr) { | 1669 void LCodeGen::DoSubI(LSubI* instr) { |
1643 LOperand* left = instr->left(); | 1670 LOperand* left = instr->left(); |
1644 LOperand* right = instr->right(); | 1671 LOperand* right = instr->right(); |
1645 ASSERT(left->Equals(instr->result())); | 1672 ASSERT(left->Equals(instr->result())); |
1646 | 1673 |
1647 if (right->IsConstantOperand()) { | 1674 if (right->IsConstantOperand()) { |
1648 __ subl(ToRegister(left), | 1675 int32_t right_operand = |
1649 Immediate(ToInteger32(LConstantOperand::cast(right)))); | 1676 ToRepresentation(LConstantOperand::cast(right), |
| 1677 instr->hydrogen()->right()->representation()); |
| 1678 __ subl(ToRegister(left), Immediate(right_operand)); |
1650 } else if (right->IsRegister()) { | 1679 } else if (right->IsRegister()) { |
1651 if (instr->hydrogen_value()->representation().IsSmi()) { | 1680 if (instr->hydrogen_value()->representation().IsSmi()) { |
1652 __ subp(ToRegister(left), ToRegister(right)); | 1681 __ subp(ToRegister(left), ToRegister(right)); |
1653 } else { | 1682 } else { |
1654 __ subl(ToRegister(left), ToRegister(right)); | 1683 __ subl(ToRegister(left), ToRegister(right)); |
1655 } | 1684 } |
1656 } else { | 1685 } else { |
1657 if (instr->hydrogen_value()->representation().IsSmi()) { | 1686 if (instr->hydrogen_value()->representation().IsSmi()) { |
1658 __ subp(ToRegister(left), ToOperand(right)); | 1687 __ subp(ToRegister(left), ToOperand(right)); |
1659 } else { | 1688 } else { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1840 | 1869 |
1841 void LCodeGen::DoAddI(LAddI* instr) { | 1870 void LCodeGen::DoAddI(LAddI* instr) { |
1842 LOperand* left = instr->left(); | 1871 LOperand* left = instr->left(); |
1843 LOperand* right = instr->right(); | 1872 LOperand* right = instr->right(); |
1844 | 1873 |
1845 Representation target_rep = instr->hydrogen()->representation(); | 1874 Representation target_rep = instr->hydrogen()->representation(); |
1846 bool is_p = target_rep.IsSmi() || target_rep.IsExternal(); | 1875 bool is_p = target_rep.IsSmi() || target_rep.IsExternal(); |
1847 | 1876 |
1848 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { | 1877 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { |
1849 if (right->IsConstantOperand()) { | 1878 if (right->IsConstantOperand()) { |
1850 ASSERT(!target_rep.IsSmi()); // No support for smi-immediates. | 1879 // No support for smi-immediates for 32-bit SMI. |
1851 int32_t offset = ToInteger32(LConstantOperand::cast(right)); | 1880 ASSERT(SmiValuesAre32Bits() ? !target_rep.IsSmi() : SmiValuesAre31Bits()); |
| 1881 int32_t offset = |
| 1882 ToRepresentation(LConstantOperand::cast(right), |
| 1883 instr->hydrogen()->right()->representation()); |
1852 if (is_p) { | 1884 if (is_p) { |
1853 __ leap(ToRegister(instr->result()), | 1885 __ leap(ToRegister(instr->result()), |
1854 MemOperand(ToRegister(left), offset)); | 1886 MemOperand(ToRegister(left), offset)); |
1855 } else { | 1887 } else { |
1856 __ leal(ToRegister(instr->result()), | 1888 __ leal(ToRegister(instr->result()), |
1857 MemOperand(ToRegister(left), offset)); | 1889 MemOperand(ToRegister(left), offset)); |
1858 } | 1890 } |
1859 } else { | 1891 } else { |
1860 Operand address(ToRegister(left), ToRegister(right), times_1, 0); | 1892 Operand address(ToRegister(left), ToRegister(right), times_1, 0); |
1861 if (is_p) { | 1893 if (is_p) { |
1862 __ leap(ToRegister(instr->result()), address); | 1894 __ leap(ToRegister(instr->result()), address); |
1863 } else { | 1895 } else { |
1864 __ leal(ToRegister(instr->result()), address); | 1896 __ leal(ToRegister(instr->result()), address); |
1865 } | 1897 } |
1866 } | 1898 } |
1867 } else { | 1899 } else { |
1868 if (right->IsConstantOperand()) { | 1900 if (right->IsConstantOperand()) { |
1869 ASSERT(!target_rep.IsSmi()); // No support for smi-immediates. | 1901 // No support for smi-immediates for 32-bit SMI. |
| 1902 ASSERT(SmiValuesAre32Bits() ? !target_rep.IsSmi() : SmiValuesAre31Bits()); |
| 1903 int32_t right_operand = |
| 1904 ToRepresentation(LConstantOperand::cast(right), |
| 1905 instr->hydrogen()->right()->representation()); |
1870 if (is_p) { | 1906 if (is_p) { |
1871 __ addp(ToRegister(left), | 1907 __ addp(ToRegister(left), Immediate(right_operand)); |
1872 Immediate(ToInteger32(LConstantOperand::cast(right)))); | |
1873 } else { | 1908 } else { |
1874 __ addl(ToRegister(left), | 1909 __ addl(ToRegister(left), Immediate(right_operand)); |
1875 Immediate(ToInteger32(LConstantOperand::cast(right)))); | |
1876 } | 1910 } |
1877 } else if (right->IsRegister()) { | 1911 } else if (right->IsRegister()) { |
1878 if (is_p) { | 1912 if (is_p) { |
1879 __ addp(ToRegister(left), ToRegister(right)); | 1913 __ addp(ToRegister(left), ToRegister(right)); |
1880 } else { | 1914 } else { |
1881 __ addl(ToRegister(left), ToRegister(right)); | 1915 __ addl(ToRegister(left), ToRegister(right)); |
1882 } | 1916 } |
1883 } else { | 1917 } else { |
1884 if (is_p) { | 1918 if (is_p) { |
1885 __ addp(ToRegister(left), ToOperand(right)); | 1919 __ addp(ToRegister(left), ToOperand(right)); |
(...skipping 13 matching lines...) Expand all Loading... |
1899 LOperand* right = instr->right(); | 1933 LOperand* right = instr->right(); |
1900 ASSERT(left->Equals(instr->result())); | 1934 ASSERT(left->Equals(instr->result())); |
1901 HMathMinMax::Operation operation = instr->hydrogen()->operation(); | 1935 HMathMinMax::Operation operation = instr->hydrogen()->operation(); |
1902 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { | 1936 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { |
1903 Label return_left; | 1937 Label return_left; |
1904 Condition condition = (operation == HMathMinMax::kMathMin) | 1938 Condition condition = (operation == HMathMinMax::kMathMin) |
1905 ? less_equal | 1939 ? less_equal |
1906 : greater_equal; | 1940 : greater_equal; |
1907 Register left_reg = ToRegister(left); | 1941 Register left_reg = ToRegister(left); |
1908 if (right->IsConstantOperand()) { | 1942 if (right->IsConstantOperand()) { |
1909 Immediate right_imm = | 1943 Immediate right_imm = Immediate( |
1910 Immediate(ToInteger32(LConstantOperand::cast(right))); | 1944 ToRepresentation(LConstantOperand::cast(right), |
1911 ASSERT(!instr->hydrogen_value()->representation().IsSmi()); | 1945 instr->hydrogen()->right()->representation())); |
| 1946 ASSERT(SmiValuesAre32Bits() |
| 1947 ? !instr->hydrogen()->representation().IsSmi() |
| 1948 : SmiValuesAre31Bits()); |
1912 __ cmpl(left_reg, right_imm); | 1949 __ cmpl(left_reg, right_imm); |
1913 __ j(condition, &return_left, Label::kNear); | 1950 __ j(condition, &return_left, Label::kNear); |
1914 __ movp(left_reg, right_imm); | 1951 __ movp(left_reg, right_imm); |
1915 } else if (right->IsRegister()) { | 1952 } else if (right->IsRegister()) { |
1916 Register right_reg = ToRegister(right); | 1953 Register right_reg = ToRegister(right); |
1917 if (instr->hydrogen_value()->representation().IsSmi()) { | 1954 if (instr->hydrogen_value()->representation().IsSmi()) { |
1918 __ cmpp(left_reg, right_reg); | 1955 __ cmpp(left_reg, right_reg); |
1919 } else { | 1956 } else { |
1920 __ cmpl(left_reg, right_reg); | 1957 __ cmpl(left_reg, right_reg); |
1921 } | 1958 } |
(...skipping 2769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4691 __ movp(reg, kScratchRegister); | 4728 __ movp(reg, kScratchRegister); |
4692 } | 4729 } |
4693 | 4730 |
4694 | 4731 |
4695 void LCodeGen::DoSmiTag(LSmiTag* instr) { | 4732 void LCodeGen::DoSmiTag(LSmiTag* instr) { |
4696 HChange* hchange = instr->hydrogen(); | 4733 HChange* hchange = instr->hydrogen(); |
4697 Register input = ToRegister(instr->value()); | 4734 Register input = ToRegister(instr->value()); |
4698 Register output = ToRegister(instr->result()); | 4735 Register output = ToRegister(instr->result()); |
4699 if (hchange->CheckFlag(HValue::kCanOverflow) && | 4736 if (hchange->CheckFlag(HValue::kCanOverflow) && |
4700 hchange->value()->CheckFlag(HValue::kUint32)) { | 4737 hchange->value()->CheckFlag(HValue::kUint32)) { |
4701 __ testl(input, input); | 4738 Condition is_smi = __ CheckUInteger32ValidSmiValue(input); |
4702 DeoptimizeIf(sign, instr->environment()); | 4739 DeoptimizeIf(NegateCondition(is_smi), instr->environment()); |
4703 } | 4740 } |
4704 __ Integer32ToSmi(output, input); | 4741 __ Integer32ToSmi(output, input); |
4705 if (hchange->CheckFlag(HValue::kCanOverflow) && | 4742 if (hchange->CheckFlag(HValue::kCanOverflow) && |
4706 !hchange->value()->CheckFlag(HValue::kUint32)) { | 4743 !hchange->value()->CheckFlag(HValue::kUint32)) { |
4707 DeoptimizeIf(overflow, instr->environment()); | 4744 DeoptimizeIf(overflow, instr->environment()); |
4708 } | 4745 } |
4709 } | 4746 } |
4710 | 4747 |
4711 | 4748 |
4712 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { | 4749 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { |
(...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5735 CallRuntime(Runtime::kHiddenPushBlockContext, 2, instr); | 5772 CallRuntime(Runtime::kHiddenPushBlockContext, 2, instr); |
5736 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5773 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5737 } | 5774 } |
5738 | 5775 |
5739 | 5776 |
5740 #undef __ | 5777 #undef __ |
5741 | 5778 |
5742 } } // namespace v8::internal | 5779 } } // namespace v8::internal |
5743 | 5780 |
5744 #endif // V8_TARGET_ARCH_X64 | 5781 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |