| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #include "src/arm/lithium-codegen-arm.h" | 7 #include "src/arm/lithium-codegen-arm.h" |
| 8 #include "src/arm/lithium-gap-resolver-arm.h" | 8 #include "src/arm/lithium-gap-resolver-arm.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/hydrogen-osr.h" | 10 #include "src/hydrogen-osr.h" |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); | 473 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); |
| 474 return constant->handle(isolate()); | 474 return constant->handle(isolate()); |
| 475 } | 475 } |
| 476 | 476 |
| 477 | 477 |
| 478 bool LCodeGen::IsInteger32(LConstantOperand* op) const { | 478 bool LCodeGen::IsInteger32(LConstantOperand* op) const { |
| 479 return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); | 479 return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); |
| 480 } | 480 } |
| 481 | 481 |
| 482 | 482 |
| 483 template<class LI> | |
| 484 Operand LCodeGen::ToShiftedRightOperand(LOperand* right, LI* shift_info) { | |
| 485 if (shift_info->shift() == NO_SHIFT) { | |
| 486 return ToOperand(right); | |
| 487 } else { | |
| 488 return Operand( | |
| 489 ToRegister(right), | |
| 490 shift_info->shift(), | |
| 491 JSShiftAmountFromLConstant(shift_info->shift_amount())); | |
| 492 } | |
| 493 } | |
| 494 | |
| 495 | |
| 496 bool LCodeGen::IsSmi(LConstantOperand* op) const { | 483 bool LCodeGen::IsSmi(LConstantOperand* op) const { |
| 497 return chunk_->LookupLiteralRepresentation(op).IsSmi(); | 484 return chunk_->LookupLiteralRepresentation(op).IsSmi(); |
| 498 } | 485 } |
| 499 | 486 |
| 500 | 487 |
| 501 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { | 488 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { |
| 502 return ToRepresentation(op, Representation::Integer32()); | 489 return ToRepresentation(op, Representation::Integer32()); |
| 503 } | 490 } |
| 504 | 491 |
| 505 | 492 |
| (...skipping 1212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1718 | 1705 |
| 1719 | 1706 |
| 1720 void LCodeGen::DoBitI(LBitI* instr) { | 1707 void LCodeGen::DoBitI(LBitI* instr) { |
| 1721 LOperand* left_op = instr->left(); | 1708 LOperand* left_op = instr->left(); |
| 1722 LOperand* right_op = instr->right(); | 1709 LOperand* right_op = instr->right(); |
| 1723 ASSERT(left_op->IsRegister()); | 1710 ASSERT(left_op->IsRegister()); |
| 1724 Register left = ToRegister(left_op); | 1711 Register left = ToRegister(left_op); |
| 1725 Register result = ToRegister(instr->result()); | 1712 Register result = ToRegister(instr->result()); |
| 1726 Operand right(no_reg); | 1713 Operand right(no_reg); |
| 1727 | 1714 |
| 1728 ASSERT(right_op->IsRegister() || (instr->shift() == NO_SHIFT)); | |
| 1729 | |
| 1730 if (right_op->IsStackSlot()) { | 1715 if (right_op->IsStackSlot()) { |
| 1731 right = Operand(EmitLoadRegister(right_op, ip)); | 1716 right = Operand(EmitLoadRegister(right_op, ip)); |
| 1732 } else { | 1717 } else { |
| 1733 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand()); | 1718 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand()); |
| 1734 right = ToShiftedRightOperand(right_op, instr); | 1719 right = ToOperand(right_op); |
| 1735 } | 1720 } |
| 1736 | 1721 |
| 1737 switch (instr->op()) { | 1722 switch (instr->op()) { |
| 1738 case Token::BIT_AND: | 1723 case Token::BIT_AND: |
| 1739 __ and_(result, left, right); | 1724 __ and_(result, left, right); |
| 1740 break; | 1725 break; |
| 1741 case Token::BIT_OR: | 1726 case Token::BIT_OR: |
| 1742 __ orr(result, left, right); | 1727 __ orr(result, left, right); |
| 1743 break; | 1728 break; |
| 1744 case Token::BIT_XOR: | 1729 case Token::BIT_XOR: |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1781 } | 1766 } |
| 1782 break; | 1767 break; |
| 1783 case Token::SHL: | 1768 case Token::SHL: |
| 1784 __ mov(result, Operand(left, LSL, scratch)); | 1769 __ mov(result, Operand(left, LSL, scratch)); |
| 1785 break; | 1770 break; |
| 1786 default: | 1771 default: |
| 1787 UNREACHABLE(); | 1772 UNREACHABLE(); |
| 1788 break; | 1773 break; |
| 1789 } | 1774 } |
| 1790 } else { | 1775 } else { |
| 1791 int shift_count = JSShiftAmountFromLConstant(right_op); | 1776 // Mask the right_op operand. |
| 1777 int value = ToInteger32(LConstantOperand::cast(right_op)); |
| 1778 uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); |
| 1792 switch (instr->op()) { | 1779 switch (instr->op()) { |
| 1793 case Token::ROR: | 1780 case Token::ROR: |
| 1794 if (shift_count != 0) { | 1781 if (shift_count != 0) { |
| 1795 __ mov(result, Operand(left, ROR, shift_count)); | 1782 __ mov(result, Operand(left, ROR, shift_count)); |
| 1796 } else { | 1783 } else { |
| 1797 __ Move(result, left); | 1784 __ Move(result, left); |
| 1798 } | 1785 } |
| 1799 break; | 1786 break; |
| 1800 case Token::SAR: | 1787 case Token::SAR: |
| 1801 if (shift_count != 0) { | 1788 if (shift_count != 0) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1841 } | 1828 } |
| 1842 | 1829 |
| 1843 | 1830 |
| 1844 void LCodeGen::DoSubI(LSubI* instr) { | 1831 void LCodeGen::DoSubI(LSubI* instr) { |
| 1845 LOperand* left = instr->left(); | 1832 LOperand* left = instr->left(); |
| 1846 LOperand* right = instr->right(); | 1833 LOperand* right = instr->right(); |
| 1847 LOperand* result = instr->result(); | 1834 LOperand* result = instr->result(); |
| 1848 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1835 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| 1849 SBit set_cond = can_overflow ? SetCC : LeaveCC; | 1836 SBit set_cond = can_overflow ? SetCC : LeaveCC; |
| 1850 | 1837 |
| 1851 ASSERT(right->IsRegister() || (instr->shift() == NO_SHIFT)); | |
| 1852 | |
| 1853 if (right->IsStackSlot()) { | 1838 if (right->IsStackSlot()) { |
| 1854 Register right_reg = EmitLoadRegister(right, ip); | 1839 Register right_reg = EmitLoadRegister(right, ip); |
| 1855 __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); | 1840 __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); |
| 1856 } else { | 1841 } else { |
| 1857 ASSERT(right->IsRegister() || right->IsConstantOperand()); | 1842 ASSERT(right->IsRegister() || right->IsConstantOperand()); |
| 1858 __ sub(ToRegister(result), ToRegister(left), | 1843 __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); |
| 1859 ToShiftedRightOperand(right, instr), set_cond); | |
| 1860 } | 1844 } |
| 1861 | 1845 |
| 1862 if (can_overflow) { | 1846 if (can_overflow) { |
| 1863 DeoptimizeIf(vs, instr->environment()); | 1847 DeoptimizeIf(vs, instr->environment()); |
| 1864 } | 1848 } |
| 1865 } | 1849 } |
| 1866 | 1850 |
| 1867 | 1851 |
| 1868 void LCodeGen::DoRSubI(LRSubI* instr) { | 1852 void LCodeGen::DoRSubI(LRSubI* instr) { |
| 1869 LOperand* left = instr->left(); | 1853 LOperand* left = instr->left(); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2038 } | 2022 } |
| 2039 | 2023 |
| 2040 | 2024 |
| 2041 void LCodeGen::DoAddI(LAddI* instr) { | 2025 void LCodeGen::DoAddI(LAddI* instr) { |
| 2042 LOperand* left = instr->left(); | 2026 LOperand* left = instr->left(); |
| 2043 LOperand* right = instr->right(); | 2027 LOperand* right = instr->right(); |
| 2044 LOperand* result = instr->result(); | 2028 LOperand* result = instr->result(); |
| 2045 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 2029 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| 2046 SBit set_cond = can_overflow ? SetCC : LeaveCC; | 2030 SBit set_cond = can_overflow ? SetCC : LeaveCC; |
| 2047 | 2031 |
| 2048 ASSERT(right->IsRegister() || (instr->shift() == NO_SHIFT)); | |
| 2049 | |
| 2050 if (right->IsStackSlot()) { | 2032 if (right->IsStackSlot()) { |
| 2051 Register right_reg = EmitLoadRegister(right, ip); | 2033 Register right_reg = EmitLoadRegister(right, ip); |
| 2052 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); | 2034 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); |
| 2053 } else { | 2035 } else { |
| 2054 ASSERT(right->IsRegister() || right->IsConstantOperand()); | 2036 ASSERT(right->IsRegister() || right->IsConstantOperand()); |
| 2055 __ add(ToRegister(result), ToRegister(left), | 2037 __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); |
| 2056 ToShiftedRightOperand(right, instr), set_cond); | |
| 2057 } | 2038 } |
| 2058 | 2039 |
| 2059 if (can_overflow) { | 2040 if (can_overflow) { |
| 2060 DeoptimizeIf(vs, instr->environment()); | 2041 DeoptimizeIf(vs, instr->environment()); |
| 2061 } | 2042 } |
| 2062 } | 2043 } |
| 2063 | 2044 |
| 2064 | 2045 |
| 2065 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 2046 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
| 2066 LOperand* left = instr->left(); | 2047 LOperand* left = instr->left(); |
| (...skipping 3777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5844 __ Push(scope_info); | 5825 __ Push(scope_info); |
| 5845 __ push(ToRegister(instr->function())); | 5826 __ push(ToRegister(instr->function())); |
| 5846 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5827 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 5847 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5828 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 5848 } | 5829 } |
| 5849 | 5830 |
| 5850 | 5831 |
| 5851 #undef __ | 5832 #undef __ |
| 5852 | 5833 |
| 5853 } } // namespace v8::internal | 5834 } } // namespace v8::internal |
| OLD | NEW |