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/stub-cache.h" | 10 #include "src/stub-cache.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 |
483 bool LCodeGen::IsSmi(LConstantOperand* op) const { | 496 bool LCodeGen::IsSmi(LConstantOperand* op) const { |
484 return chunk_->LookupLiteralRepresentation(op).IsSmi(); | 497 return chunk_->LookupLiteralRepresentation(op).IsSmi(); |
485 } | 498 } |
486 | 499 |
487 | 500 |
488 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { | 501 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { |
489 return ToRepresentation(op, Representation::Integer32()); | 502 return ToRepresentation(op, Representation::Integer32()); |
490 } | 503 } |
491 | 504 |
492 | 505 |
(...skipping 1210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1703 | 1716 |
1704 | 1717 |
1705 void LCodeGen::DoBitI(LBitI* instr) { | 1718 void LCodeGen::DoBitI(LBitI* instr) { |
1706 LOperand* left_op = instr->left(); | 1719 LOperand* left_op = instr->left(); |
1707 LOperand* right_op = instr->right(); | 1720 LOperand* right_op = instr->right(); |
1708 ASSERT(left_op->IsRegister()); | 1721 ASSERT(left_op->IsRegister()); |
1709 Register left = ToRegister(left_op); | 1722 Register left = ToRegister(left_op); |
1710 Register result = ToRegister(instr->result()); | 1723 Register result = ToRegister(instr->result()); |
1711 Operand right(no_reg); | 1724 Operand right(no_reg); |
1712 | 1725 |
| 1726 ASSERT(right_op->IsRegister() || (instr->shift() == NO_SHIFT)); |
| 1727 |
1713 if (right_op->IsStackSlot()) { | 1728 if (right_op->IsStackSlot()) { |
1714 right = Operand(EmitLoadRegister(right_op, ip)); | 1729 right = Operand(EmitLoadRegister(right_op, ip)); |
1715 } else { | 1730 } else { |
1716 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand()); | 1731 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand()); |
1717 right = ToOperand(right_op); | 1732 right = ToShiftedRightOperand(right_op, instr); |
1718 } | 1733 } |
1719 | 1734 |
1720 switch (instr->op()) { | 1735 switch (instr->op()) { |
1721 case Token::BIT_AND: | 1736 case Token::BIT_AND: |
1722 __ and_(result, left, right); | 1737 __ and_(result, left, right); |
1723 break; | 1738 break; |
1724 case Token::BIT_OR: | 1739 case Token::BIT_OR: |
1725 __ orr(result, left, right); | 1740 __ orr(result, left, right); |
1726 break; | 1741 break; |
1727 case Token::BIT_XOR: | 1742 case Token::BIT_XOR: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1764 } | 1779 } |
1765 break; | 1780 break; |
1766 case Token::SHL: | 1781 case Token::SHL: |
1767 __ mov(result, Operand(left, LSL, scratch)); | 1782 __ mov(result, Operand(left, LSL, scratch)); |
1768 break; | 1783 break; |
1769 default: | 1784 default: |
1770 UNREACHABLE(); | 1785 UNREACHABLE(); |
1771 break; | 1786 break; |
1772 } | 1787 } |
1773 } else { | 1788 } else { |
1774 // Mask the right_op operand. | 1789 int shift_count = JSShiftAmountFromLConstant(right_op); |
1775 int value = ToInteger32(LConstantOperand::cast(right_op)); | |
1776 uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); | |
1777 switch (instr->op()) { | 1790 switch (instr->op()) { |
1778 case Token::ROR: | 1791 case Token::ROR: |
1779 if (shift_count != 0) { | 1792 if (shift_count != 0) { |
1780 __ mov(result, Operand(left, ROR, shift_count)); | 1793 __ mov(result, Operand(left, ROR, shift_count)); |
1781 } else { | 1794 } else { |
1782 __ Move(result, left); | 1795 __ Move(result, left); |
1783 } | 1796 } |
1784 break; | 1797 break; |
1785 case Token::SAR: | 1798 case Token::SAR: |
1786 if (shift_count != 0) { | 1799 if (shift_count != 0) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1826 } | 1839 } |
1827 | 1840 |
1828 | 1841 |
1829 void LCodeGen::DoSubI(LSubI* instr) { | 1842 void LCodeGen::DoSubI(LSubI* instr) { |
1830 LOperand* left = instr->left(); | 1843 LOperand* left = instr->left(); |
1831 LOperand* right = instr->right(); | 1844 LOperand* right = instr->right(); |
1832 LOperand* result = instr->result(); | 1845 LOperand* result = instr->result(); |
1833 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1846 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
1834 SBit set_cond = can_overflow ? SetCC : LeaveCC; | 1847 SBit set_cond = can_overflow ? SetCC : LeaveCC; |
1835 | 1848 |
| 1849 ASSERT(right->IsRegister() || (instr->shift() == NO_SHIFT)); |
| 1850 |
1836 if (right->IsStackSlot()) { | 1851 if (right->IsStackSlot()) { |
1837 Register right_reg = EmitLoadRegister(right, ip); | 1852 Register right_reg = EmitLoadRegister(right, ip); |
1838 __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); | 1853 __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); |
1839 } else { | 1854 } else { |
1840 ASSERT(right->IsRegister() || right->IsConstantOperand()); | 1855 ASSERT(right->IsRegister() || right->IsConstantOperand()); |
1841 __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); | 1856 __ sub(ToRegister(result), ToRegister(left), |
| 1857 ToShiftedRightOperand(right, instr), set_cond); |
1842 } | 1858 } |
1843 | 1859 |
1844 if (can_overflow) { | 1860 if (can_overflow) { |
1845 DeoptimizeIf(vs, instr->environment()); | 1861 DeoptimizeIf(vs, instr->environment()); |
1846 } | 1862 } |
1847 } | 1863 } |
1848 | 1864 |
1849 | 1865 |
1850 void LCodeGen::DoRSubI(LRSubI* instr) { | 1866 void LCodeGen::DoRSubI(LRSubI* instr) { |
1851 LOperand* left = instr->left(); | 1867 LOperand* left = instr->left(); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2020 } | 2036 } |
2021 | 2037 |
2022 | 2038 |
2023 void LCodeGen::DoAddI(LAddI* instr) { | 2039 void LCodeGen::DoAddI(LAddI* instr) { |
2024 LOperand* left = instr->left(); | 2040 LOperand* left = instr->left(); |
2025 LOperand* right = instr->right(); | 2041 LOperand* right = instr->right(); |
2026 LOperand* result = instr->result(); | 2042 LOperand* result = instr->result(); |
2027 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 2043 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
2028 SBit set_cond = can_overflow ? SetCC : LeaveCC; | 2044 SBit set_cond = can_overflow ? SetCC : LeaveCC; |
2029 | 2045 |
| 2046 ASSERT(right->IsRegister() || (instr->shift() == NO_SHIFT)); |
| 2047 |
2030 if (right->IsStackSlot()) { | 2048 if (right->IsStackSlot()) { |
2031 Register right_reg = EmitLoadRegister(right, ip); | 2049 Register right_reg = EmitLoadRegister(right, ip); |
2032 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); | 2050 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); |
2033 } else { | 2051 } else { |
2034 ASSERT(right->IsRegister() || right->IsConstantOperand()); | 2052 ASSERT(right->IsRegister() || right->IsConstantOperand()); |
2035 __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); | 2053 __ add(ToRegister(result), ToRegister(left), |
| 2054 ToShiftedRightOperand(right, instr), set_cond); |
2036 } | 2055 } |
2037 | 2056 |
2038 if (can_overflow) { | 2057 if (can_overflow) { |
2039 DeoptimizeIf(vs, instr->environment()); | 2058 DeoptimizeIf(vs, instr->environment()); |
2040 } | 2059 } |
2041 } | 2060 } |
2042 | 2061 |
2043 | 2062 |
2044 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 2063 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
2045 LOperand* left = instr->left(); | 2064 LOperand* left = instr->left(); |
(...skipping 3785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5831 __ Push(scope_info); | 5850 __ Push(scope_info); |
5832 __ push(ToRegister(instr->function())); | 5851 __ push(ToRegister(instr->function())); |
5833 CallRuntime(Runtime::kHiddenPushBlockContext, 2, instr); | 5852 CallRuntime(Runtime::kHiddenPushBlockContext, 2, instr); |
5834 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5853 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5835 } | 5854 } |
5836 | 5855 |
5837 | 5856 |
5838 #undef __ | 5857 #undef __ |
5839 | 5858 |
5840 } } // namespace v8::internal | 5859 } } // namespace v8::internal |
OLD | NEW |