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 |