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 "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "arm64/lithium-codegen-arm64.h" | 7 #include "arm64/lithium-codegen-arm64.h" |
8 #include "arm64/lithium-gap-resolver-arm64.h" | 8 #include "arm64/lithium-gap-resolver-arm64.h" |
9 #include "code-stubs.h" | 9 #include "code-stubs.h" |
10 #include "stub-cache.h" | 10 #include "stub-cache.h" |
(...skipping 1258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1269 } | 1269 } |
1270 | 1270 |
1271 | 1271 |
1272 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { | 1272 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { |
1273 HConstant* constant = chunk_->LookupConstant(op); | 1273 HConstant* constant = chunk_->LookupConstant(op); |
1274 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); | 1274 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); |
1275 return constant->handle(isolate()); | 1275 return constant->handle(isolate()); |
1276 } | 1276 } |
1277 | 1277 |
1278 | 1278 |
| 1279 template<class LI> |
| 1280 Operand LCodeGen::ToShiftedRightOperand32(LOperand* right, LI* shift_info, |
| 1281 IntegerSignedness signedness) { |
| 1282 if (shift_info->shift() == NO_SHIFT) { |
| 1283 return (signedness == SIGNED_INT32) ? ToOperand32I(right) |
| 1284 : ToOperand32U(right); |
| 1285 } else { |
| 1286 return Operand( |
| 1287 ToRegister32(right), |
| 1288 shift_info->shift(), |
| 1289 JSShiftAmountFromLConstant(shift_info->shift_amount())); |
| 1290 } |
| 1291 } |
| 1292 |
| 1293 |
1279 bool LCodeGen::IsSmi(LConstantOperand* op) const { | 1294 bool LCodeGen::IsSmi(LConstantOperand* op) const { |
1280 return chunk_->LookupLiteralRepresentation(op).IsSmi(); | 1295 return chunk_->LookupLiteralRepresentation(op).IsSmi(); |
1281 } | 1296 } |
1282 | 1297 |
1283 | 1298 |
1284 bool LCodeGen::IsInteger32Constant(LConstantOperand* op) const { | 1299 bool LCodeGen::IsInteger32Constant(LConstantOperand* op) const { |
1285 return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); | 1300 return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); |
1286 } | 1301 } |
1287 | 1302 |
1288 | 1303 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 | 1480 |
1466 ASSERT(!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)); | 1481 ASSERT(!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)); |
1467 __ Add(result, left, right); | 1482 __ Add(result, left, right); |
1468 } | 1483 } |
1469 | 1484 |
1470 | 1485 |
1471 void LCodeGen::DoAddI(LAddI* instr) { | 1486 void LCodeGen::DoAddI(LAddI* instr) { |
1472 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1487 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
1473 Register result = ToRegister32(instr->result()); | 1488 Register result = ToRegister32(instr->result()); |
1474 Register left = ToRegister32(instr->left()); | 1489 Register left = ToRegister32(instr->left()); |
1475 Operand right = ToOperand32I(instr->right()); | 1490 Operand right = ToShiftedRightOperand32I(instr->right(), instr); |
| 1491 |
1476 if (can_overflow) { | 1492 if (can_overflow) { |
1477 __ Adds(result, left, right); | 1493 __ Adds(result, left, right); |
1478 DeoptimizeIf(vs, instr->environment()); | 1494 DeoptimizeIf(vs, instr->environment()); |
1479 } else { | 1495 } else { |
1480 __ Add(result, left, right); | 1496 __ Add(result, left, right); |
1481 } | 1497 } |
1482 } | 1498 } |
1483 | 1499 |
1484 | 1500 |
1485 void LCodeGen::DoAddS(LAddS* instr) { | 1501 void LCodeGen::DoAddS(LAddS* instr) { |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1743 ASSERT(ToRegister(instr->result()).is(x0)); | 1759 ASSERT(ToRegister(instr->result()).is(x0)); |
1744 | 1760 |
1745 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); | 1761 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); |
1746 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 1762 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1747 } | 1763 } |
1748 | 1764 |
1749 | 1765 |
1750 void LCodeGen::DoBitI(LBitI* instr) { | 1766 void LCodeGen::DoBitI(LBitI* instr) { |
1751 Register result = ToRegister32(instr->result()); | 1767 Register result = ToRegister32(instr->result()); |
1752 Register left = ToRegister32(instr->left()); | 1768 Register left = ToRegister32(instr->left()); |
1753 Operand right = ToOperand32U(instr->right()); | 1769 Operand right = ToShiftedRightOperand32U(instr->right(), instr); |
1754 | 1770 |
1755 switch (instr->op()) { | 1771 switch (instr->op()) { |
1756 case Token::BIT_AND: __ And(result, left, right); break; | 1772 case Token::BIT_AND: __ And(result, left, right); break; |
1757 case Token::BIT_OR: __ Orr(result, left, right); break; | 1773 case Token::BIT_OR: __ Orr(result, left, right); break; |
1758 case Token::BIT_XOR: __ Eor(result, left, right); break; | 1774 case Token::BIT_XOR: __ Eor(result, left, right); break; |
1759 default: | 1775 default: |
1760 UNREACHABLE(); | 1776 UNREACHABLE(); |
1761 break; | 1777 break; |
1762 } | 1778 } |
1763 } | 1779 } |
(...skipping 3048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4812 __ Cbnz(right, &right_not_zero); | 4828 __ Cbnz(right, &right_not_zero); |
4813 DeoptimizeIfNegative(left, instr->environment()); | 4829 DeoptimizeIfNegative(left, instr->environment()); |
4814 __ Bind(&right_not_zero); | 4830 __ Bind(&right_not_zero); |
4815 } | 4831 } |
4816 __ Lsr(result, left, right); | 4832 __ Lsr(result, left, right); |
4817 break; | 4833 break; |
4818 default: UNREACHABLE(); | 4834 default: UNREACHABLE(); |
4819 } | 4835 } |
4820 } else { | 4836 } else { |
4821 ASSERT(right_op->IsConstantOperand()); | 4837 ASSERT(right_op->IsConstantOperand()); |
4822 int shift_count = ToInteger32(LConstantOperand::cast(right_op)) & 0x1f; | 4838 int shift_count = JSShiftAmountFromLConstant(right_op); |
4823 if (shift_count == 0) { | 4839 if (shift_count == 0) { |
4824 if ((instr->op() == Token::SHR) && instr->can_deopt()) { | 4840 if ((instr->op() == Token::SHR) && instr->can_deopt()) { |
4825 DeoptimizeIfNegative(left, instr->environment()); | 4841 DeoptimizeIfNegative(left, instr->environment()); |
4826 } | 4842 } |
4827 __ Mov(result, left, kDiscardForSameWReg); | 4843 __ Mov(result, left, kDiscardForSameWReg); |
4828 } else { | 4844 } else { |
4829 switch (instr->op()) { | 4845 switch (instr->op()) { |
4830 case Token::ROR: __ Ror(result, left, shift_count); break; | 4846 case Token::ROR: __ Ror(result, left, shift_count); break; |
4831 case Token::SAR: __ Asr(result, left, shift_count); break; | 4847 case Token::SAR: __ Asr(result, left, shift_count); break; |
4832 case Token::SHL: __ Lsl(result, left, shift_count); break; | 4848 case Token::SHL: __ Lsl(result, left, shift_count); break; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4875 __ Bind(&right_not_zero); | 4891 __ Bind(&right_not_zero); |
4876 } | 4892 } |
4877 __ Ubfx(result, right, kSmiShift, 5); | 4893 __ Ubfx(result, right, kSmiShift, 5); |
4878 __ Lsr(result, left, result); | 4894 __ Lsr(result, left, result); |
4879 __ Bic(result, result, kSmiShiftMask); | 4895 __ Bic(result, result, kSmiShiftMask); |
4880 break; | 4896 break; |
4881 default: UNREACHABLE(); | 4897 default: UNREACHABLE(); |
4882 } | 4898 } |
4883 } else { | 4899 } else { |
4884 ASSERT(right_op->IsConstantOperand()); | 4900 ASSERT(right_op->IsConstantOperand()); |
4885 int shift_count = ToInteger32(LConstantOperand::cast(right_op)) & 0x1f; | 4901 int shift_count = JSShiftAmountFromLConstant(right_op); |
4886 if (shift_count == 0) { | 4902 if (shift_count == 0) { |
4887 if ((instr->op() == Token::SHR) && instr->can_deopt()) { | 4903 if ((instr->op() == Token::SHR) && instr->can_deopt()) { |
4888 DeoptimizeIfNegative(left, instr->environment()); | 4904 DeoptimizeIfNegative(left, instr->environment()); |
4889 } | 4905 } |
4890 __ Mov(result, left); | 4906 __ Mov(result, left); |
4891 } else { | 4907 } else { |
4892 switch (instr->op()) { | 4908 switch (instr->op()) { |
4893 case Token::ROR: | 4909 case Token::ROR: |
4894 __ SmiUntag(result, left); | 4910 __ SmiUntag(result, left); |
4895 __ Ror(result.W(), result.W(), shift_count); | 4911 __ Ror(result.W(), result.W(), shift_count); |
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5471 Condition condition = TokenToCondition(op, false); | 5487 Condition condition = TokenToCondition(op, false); |
5472 | 5488 |
5473 EmitCompareAndBranch(instr, condition, x0, 0); | 5489 EmitCompareAndBranch(instr, condition, x0, 0); |
5474 } | 5490 } |
5475 | 5491 |
5476 | 5492 |
5477 void LCodeGen::DoSubI(LSubI* instr) { | 5493 void LCodeGen::DoSubI(LSubI* instr) { |
5478 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 5494 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
5479 Register result = ToRegister32(instr->result()); | 5495 Register result = ToRegister32(instr->result()); |
5480 Register left = ToRegister32(instr->left()); | 5496 Register left = ToRegister32(instr->left()); |
5481 Operand right = ToOperand32I(instr->right()); | 5497 Operand right = ToShiftedRightOperand32I(instr->right(), instr); |
| 5498 |
5482 if (can_overflow) { | 5499 if (can_overflow) { |
5483 __ Subs(result, left, right); | 5500 __ Subs(result, left, right); |
5484 DeoptimizeIf(vs, instr->environment()); | 5501 DeoptimizeIf(vs, instr->environment()); |
5485 } else { | 5502 } else { |
5486 __ Sub(result, left, right); | 5503 __ Sub(result, left, right); |
5487 } | 5504 } |
5488 } | 5505 } |
5489 | 5506 |
5490 | 5507 |
5491 void LCodeGen::DoSubS(LSubS* instr) { | 5508 void LCodeGen::DoSubS(LSubS* instr) { |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5943 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5960 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
5944 // Index is equal to negated out of object property index plus 1. | 5961 // Index is equal to negated out of object property index plus 1. |
5945 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5962 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
5946 __ Ldr(result, FieldMemOperand(result, | 5963 __ Ldr(result, FieldMemOperand(result, |
5947 FixedArray::kHeaderSize - kPointerSize)); | 5964 FixedArray::kHeaderSize - kPointerSize)); |
5948 __ Bind(deferred->exit()); | 5965 __ Bind(deferred->exit()); |
5949 __ Bind(&done); | 5966 __ Bind(&done); |
5950 } | 5967 } |
5951 | 5968 |
5952 } } // namespace v8::internal | 5969 } } // namespace v8::internal |
OLD | NEW |