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 #include "src/arm64/lithium-codegen-arm64.h" | 7 #include "src/arm64/lithium-codegen-arm64.h" |
8 #include "src/arm64/lithium-gap-resolver-arm64.h" | 8 #include "src/arm64/lithium-gap-resolver-arm64.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 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1219 } else if (op->IsDoubleRegister()) { | 1219 } else if (op->IsDoubleRegister()) { |
1220 Abort(kToOperandIsDoubleRegisterUnimplemented); | 1220 Abort(kToOperandIsDoubleRegisterUnimplemented); |
1221 return Operand(0); | 1221 return Operand(0); |
1222 } | 1222 } |
1223 // Stack slots not implemented, use ToMemOperand instead. | 1223 // Stack slots not implemented, use ToMemOperand instead. |
1224 UNREACHABLE(); | 1224 UNREACHABLE(); |
1225 return Operand(0); | 1225 return Operand(0); |
1226 } | 1226 } |
1227 | 1227 |
1228 | 1228 |
1229 Operand LCodeGen::ToOperand32I(LOperand* op) { | 1229 Operand LCodeGen::ToOperand32(LOperand* op) { |
1230 return ToOperand32(op, SIGNED_INT32); | |
1231 } | |
1232 | |
1233 | |
1234 Operand LCodeGen::ToOperand32U(LOperand* op) { | |
1235 return ToOperand32(op, UNSIGNED_INT32); | |
1236 } | |
1237 | |
1238 | |
1239 Operand LCodeGen::ToOperand32(LOperand* op, IntegerSignedness signedness) { | |
1240 DCHECK(op != NULL); | 1230 DCHECK(op != NULL); |
1241 if (op->IsRegister()) { | 1231 if (op->IsRegister()) { |
1242 return Operand(ToRegister32(op)); | 1232 return Operand(ToRegister32(op)); |
1243 } else if (op->IsConstantOperand()) { | 1233 } else if (op->IsConstantOperand()) { |
1244 LConstantOperand* const_op = LConstantOperand::cast(op); | 1234 LConstantOperand* const_op = LConstantOperand::cast(op); |
1245 HConstant* constant = chunk()->LookupConstant(const_op); | 1235 HConstant* constant = chunk()->LookupConstant(const_op); |
1246 Representation r = chunk_->LookupLiteralRepresentation(const_op); | 1236 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
1247 if (r.IsInteger32()) { | 1237 if (r.IsInteger32()) { |
1248 DCHECK(constant->HasInteger32Value()); | 1238 return Operand(constant->Integer32Value()); |
1249 return (signedness == SIGNED_INT32) | |
1250 ? Operand(constant->Integer32Value()) | |
1251 : Operand(static_cast<uint32_t>(constant->Integer32Value())); | |
1252 } else { | 1239 } else { |
1253 // Other constants not implemented. | 1240 // Other constants not implemented. |
1254 Abort(kToOperand32UnsupportedImmediate); | 1241 Abort(kToOperand32UnsupportedImmediate); |
1255 } | 1242 } |
1256 } | 1243 } |
1257 // Other cases are not implemented. | 1244 // Other cases are not implemented. |
1258 UNREACHABLE(); | 1245 UNREACHABLE(); |
1259 return Operand(0); | 1246 return Operand(0); |
1260 } | 1247 } |
1261 | 1248 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 } | 1294 } |
1308 | 1295 |
1309 | 1296 |
1310 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { | 1297 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { |
1311 HConstant* constant = chunk_->LookupConstant(op); | 1298 HConstant* constant = chunk_->LookupConstant(op); |
1312 DCHECK(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); | 1299 DCHECK(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); |
1313 return constant->handle(isolate()); | 1300 return constant->handle(isolate()); |
1314 } | 1301 } |
1315 | 1302 |
1316 | 1303 |
1317 template<class LI> | 1304 template <class LI> |
1318 Operand LCodeGen::ToShiftedRightOperand32(LOperand* right, LI* shift_info, | 1305 Operand LCodeGen::ToShiftedRightOperand32(LOperand* right, LI* shift_info) { |
1319 IntegerSignedness signedness) { | |
1320 if (shift_info->shift() == NO_SHIFT) { | 1306 if (shift_info->shift() == NO_SHIFT) { |
1321 return (signedness == SIGNED_INT32) ? ToOperand32I(right) | 1307 return ToOperand32(right); |
1322 : ToOperand32U(right); | |
1323 } else { | 1308 } else { |
1324 return Operand( | 1309 return Operand( |
1325 ToRegister32(right), | 1310 ToRegister32(right), |
1326 shift_info->shift(), | 1311 shift_info->shift(), |
1327 JSShiftAmountFromLConstant(shift_info->shift_amount())); | 1312 JSShiftAmountFromLConstant(shift_info->shift_amount())); |
1328 } | 1313 } |
1329 } | 1314 } |
1330 | 1315 |
1331 | 1316 |
1332 bool LCodeGen::IsSmi(LConstantOperand* op) const { | 1317 bool LCodeGen::IsSmi(LConstantOperand* op) const { |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1494 int index = ToInteger32(LConstantOperand::cast(instr->index())); | 1479 int index = ToInteger32(LConstantOperand::cast(instr->index())); |
1495 int loc = index - 1; | 1480 int loc = index - 1; |
1496 if (loc != 0) { | 1481 if (loc != 0) { |
1497 __ Sub(result.W(), length, loc); | 1482 __ Sub(result.W(), length, loc); |
1498 __ Ldr(result, MemOperand(arguments, result, UXTW, kPointerSizeLog2)); | 1483 __ Ldr(result, MemOperand(arguments, result, UXTW, kPointerSizeLog2)); |
1499 } else { | 1484 } else { |
1500 __ Ldr(result, MemOperand(arguments, length, UXTW, kPointerSizeLog2)); | 1485 __ Ldr(result, MemOperand(arguments, length, UXTW, kPointerSizeLog2)); |
1501 } | 1486 } |
1502 } else { | 1487 } else { |
1503 Register length = ToRegister32(instr->length()); | 1488 Register length = ToRegister32(instr->length()); |
1504 Operand index = ToOperand32I(instr->index()); | 1489 Operand index = ToOperand32(instr->index()); |
1505 __ Sub(result.W(), length, index); | 1490 __ Sub(result.W(), length, index); |
1506 __ Add(result.W(), result.W(), 1); | 1491 __ Add(result.W(), result.W(), 1); |
1507 __ Ldr(result, MemOperand(arguments, result, UXTW, kPointerSizeLog2)); | 1492 __ Ldr(result, MemOperand(arguments, result, UXTW, kPointerSizeLog2)); |
1508 } | 1493 } |
1509 } | 1494 } |
1510 | 1495 |
1511 | 1496 |
1512 void LCodeGen::DoAddE(LAddE* instr) { | 1497 void LCodeGen::DoAddE(LAddE* instr) { |
1513 Register result = ToRegister(instr->result()); | 1498 Register result = ToRegister(instr->result()); |
1514 Register left = ToRegister(instr->left()); | 1499 Register left = ToRegister(instr->left()); |
1515 Operand right = (instr->right()->IsConstantOperand()) | 1500 Operand right = (instr->right()->IsConstantOperand()) |
1516 ? ToInteger32(LConstantOperand::cast(instr->right())) | 1501 ? ToInteger32(LConstantOperand::cast(instr->right())) |
1517 : Operand(ToRegister32(instr->right()), SXTW); | 1502 : Operand(ToRegister32(instr->right()), SXTW); |
1518 | 1503 |
1519 DCHECK(!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)); | 1504 DCHECK(!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)); |
1520 __ Add(result, left, right); | 1505 __ Add(result, left, right); |
1521 } | 1506 } |
1522 | 1507 |
1523 | 1508 |
1524 void LCodeGen::DoAddI(LAddI* instr) { | 1509 void LCodeGen::DoAddI(LAddI* instr) { |
1525 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1510 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
1526 Register result = ToRegister32(instr->result()); | 1511 Register result = ToRegister32(instr->result()); |
1527 Register left = ToRegister32(instr->left()); | 1512 Register left = ToRegister32(instr->left()); |
1528 Operand right = ToShiftedRightOperand32I(instr->right(), instr); | 1513 Operand right = ToShiftedRightOperand32(instr->right(), instr); |
1529 | 1514 |
1530 if (can_overflow) { | 1515 if (can_overflow) { |
1531 __ Adds(result, left, right); | 1516 __ Adds(result, left, right); |
1532 DeoptimizeIf(vs, instr->environment()); | 1517 DeoptimizeIf(vs, instr->environment()); |
1533 } else { | 1518 } else { |
1534 __ Add(result, left, right); | 1519 __ Add(result, left, right); |
1535 } | 1520 } |
1536 } | 1521 } |
1537 | 1522 |
1538 | 1523 |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1797 DCHECK(ToRegister(instr->result()).is(x0)); | 1782 DCHECK(ToRegister(instr->result()).is(x0)); |
1798 | 1783 |
1799 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); | 1784 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); |
1800 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 1785 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1801 } | 1786 } |
1802 | 1787 |
1803 | 1788 |
1804 void LCodeGen::DoBitI(LBitI* instr) { | 1789 void LCodeGen::DoBitI(LBitI* instr) { |
1805 Register result = ToRegister32(instr->result()); | 1790 Register result = ToRegister32(instr->result()); |
1806 Register left = ToRegister32(instr->left()); | 1791 Register left = ToRegister32(instr->left()); |
1807 Operand right = ToShiftedRightOperand32U(instr->right(), instr); | 1792 Operand right = ToShiftedRightOperand32(instr->right(), instr); |
1808 | 1793 |
1809 switch (instr->op()) { | 1794 switch (instr->op()) { |
1810 case Token::BIT_AND: __ And(result, left, right); break; | 1795 case Token::BIT_AND: __ And(result, left, right); break; |
1811 case Token::BIT_OR: __ Orr(result, left, right); break; | 1796 case Token::BIT_OR: __ Orr(result, left, right); break; |
1812 case Token::BIT_XOR: __ Eor(result, left, right); break; | 1797 case Token::BIT_XOR: __ Eor(result, left, right); break; |
1813 default: | 1798 default: |
1814 UNREACHABLE(); | 1799 UNREACHABLE(); |
1815 break; | 1800 break; |
1816 } | 1801 } |
1817 } | 1802 } |
(...skipping 13 matching lines...) Expand all Loading... |
1831 break; | 1816 break; |
1832 } | 1817 } |
1833 } | 1818 } |
1834 | 1819 |
1835 | 1820 |
1836 void LCodeGen::DoBoundsCheck(LBoundsCheck *instr) { | 1821 void LCodeGen::DoBoundsCheck(LBoundsCheck *instr) { |
1837 Condition cond = instr->hydrogen()->allow_equality() ? hi : hs; | 1822 Condition cond = instr->hydrogen()->allow_equality() ? hi : hs; |
1838 DCHECK(instr->hydrogen()->index()->representation().IsInteger32()); | 1823 DCHECK(instr->hydrogen()->index()->representation().IsInteger32()); |
1839 DCHECK(instr->hydrogen()->length()->representation().IsInteger32()); | 1824 DCHECK(instr->hydrogen()->length()->representation().IsInteger32()); |
1840 if (instr->index()->IsConstantOperand()) { | 1825 if (instr->index()->IsConstantOperand()) { |
1841 Operand index = ToOperand32I(instr->index()); | 1826 Operand index = ToOperand32(instr->index()); |
1842 Register length = ToRegister32(instr->length()); | 1827 Register length = ToRegister32(instr->length()); |
1843 __ Cmp(length, index); | 1828 __ Cmp(length, index); |
1844 cond = CommuteCondition(cond); | 1829 cond = CommuteCondition(cond); |
1845 } else { | 1830 } else { |
1846 Register index = ToRegister32(instr->index()); | 1831 Register index = ToRegister32(instr->index()); |
1847 Operand length = ToOperand32I(instr->length()); | 1832 Operand length = ToOperand32(instr->length()); |
1848 __ Cmp(index, length); | 1833 __ Cmp(index, length); |
1849 } | 1834 } |
1850 if (FLAG_debug_code && instr->hydrogen()->skip_check()) { | 1835 if (FLAG_debug_code && instr->hydrogen()->skip_check()) { |
1851 __ Assert(NegateCondition(cond), kEliminatedBoundsCheckFailed); | 1836 __ Assert(NegateCondition(cond), kEliminatedBoundsCheckFailed); |
1852 } else { | 1837 } else { |
1853 DeoptimizeIf(cond, instr->environment()); | 1838 DeoptimizeIf(cond, instr->environment()); |
1854 } | 1839 } |
1855 } | 1840 } |
1856 | 1841 |
1857 | 1842 |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2479 if (instr->is_double()) { | 2464 if (instr->is_double()) { |
2480 __ Fcmp(ToDoubleRegister(left), ToDoubleRegister(right)); | 2465 __ Fcmp(ToDoubleRegister(left), ToDoubleRegister(right)); |
2481 | 2466 |
2482 // If a NaN is involved, i.e. the result is unordered (V set), | 2467 // If a NaN is involved, i.e. the result is unordered (V set), |
2483 // jump to false block label. | 2468 // jump to false block label. |
2484 __ B(vs, instr->FalseLabel(chunk_)); | 2469 __ B(vs, instr->FalseLabel(chunk_)); |
2485 EmitBranch(instr, cond); | 2470 EmitBranch(instr, cond); |
2486 } else { | 2471 } else { |
2487 if (instr->hydrogen_value()->representation().IsInteger32()) { | 2472 if (instr->hydrogen_value()->representation().IsInteger32()) { |
2488 if (right->IsConstantOperand()) { | 2473 if (right->IsConstantOperand()) { |
2489 EmitCompareAndBranch(instr, | 2474 EmitCompareAndBranch(instr, cond, ToRegister32(left), |
2490 cond, | 2475 ToOperand32(right)); |
2491 ToRegister32(left), | |
2492 ToOperand32I(right)); | |
2493 } else { | 2476 } else { |
2494 // Commute the operands and the condition. | 2477 // Commute the operands and the condition. |
2495 EmitCompareAndBranch(instr, | 2478 EmitCompareAndBranch(instr, CommuteCondition(cond), |
2496 CommuteCondition(cond), | 2479 ToRegister32(right), ToOperand32(left)); |
2497 ToRegister32(right), | |
2498 ToOperand32I(left)); | |
2499 } | 2480 } |
2500 } else { | 2481 } else { |
2501 DCHECK(instr->hydrogen_value()->representation().IsSmi()); | 2482 DCHECK(instr->hydrogen_value()->representation().IsSmi()); |
2502 if (right->IsConstantOperand()) { | 2483 if (right->IsConstantOperand()) { |
2503 int32_t value = ToInteger32(LConstantOperand::cast(right)); | 2484 int32_t value = ToInteger32(LConstantOperand::cast(right)); |
2504 EmitCompareAndBranch(instr, | 2485 EmitCompareAndBranch(instr, |
2505 cond, | 2486 cond, |
2506 ToRegister(left), | 2487 ToRegister(left), |
2507 Operand(Smi::FromInt(value))); | 2488 Operand(Smi::FromInt(value))); |
2508 } else if (left->IsConstantOperand()) { | 2489 } else if (left->IsConstantOperand()) { |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3010 } | 2991 } |
3011 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); | 2992 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); |
3012 EmitBranch(instr, BranchCondition(instr->hydrogen())); | 2993 EmitBranch(instr, BranchCondition(instr->hydrogen())); |
3013 } | 2994 } |
3014 | 2995 |
3015 | 2996 |
3016 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { | 2997 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { |
3017 Register result = ToRegister(instr->result()); | 2998 Register result = ToRegister(instr->result()); |
3018 Register base = ToRegister(instr->base_object()); | 2999 Register base = ToRegister(instr->base_object()); |
3019 if (instr->offset()->IsConstantOperand()) { | 3000 if (instr->offset()->IsConstantOperand()) { |
3020 __ Add(result, base, ToOperand32I(instr->offset())); | 3001 __ Add(result, base, ToOperand32(instr->offset())); |
3021 } else { | 3002 } else { |
3022 __ Add(result, base, Operand(ToRegister32(instr->offset()), SXTW)); | 3003 __ Add(result, base, Operand(ToRegister32(instr->offset()), SXTW)); |
3023 } | 3004 } |
3024 } | 3005 } |
3025 | 3006 |
3026 | 3007 |
3027 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { | 3008 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { |
3028 DCHECK(ToRegister(instr->context()).is(cp)); | 3009 DCHECK(ToRegister(instr->context()).is(cp)); |
3029 // Assert that the arguments are in the registers expected by InstanceofStub. | 3010 // Assert that the arguments are in the registers expected by InstanceofStub. |
3030 DCHECK(ToRegister(instr->left()).Is(InstanceofStub::left())); | 3011 DCHECK(ToRegister(instr->left()).Is(InstanceofStub::left())); |
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4213 DoubleRegister result = ToDoubleRegister(instr->result()); | 4194 DoubleRegister result = ToDoubleRegister(instr->result()); |
4214 __ Fsqrt(result, input); | 4195 __ Fsqrt(result, input); |
4215 } | 4196 } |
4216 | 4197 |
4217 | 4198 |
4218 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 4199 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
4219 HMathMinMax::Operation op = instr->hydrogen()->operation(); | 4200 HMathMinMax::Operation op = instr->hydrogen()->operation(); |
4220 if (instr->hydrogen()->representation().IsInteger32()) { | 4201 if (instr->hydrogen()->representation().IsInteger32()) { |
4221 Register result = ToRegister32(instr->result()); | 4202 Register result = ToRegister32(instr->result()); |
4222 Register left = ToRegister32(instr->left()); | 4203 Register left = ToRegister32(instr->left()); |
4223 Operand right = ToOperand32I(instr->right()); | 4204 Operand right = ToOperand32(instr->right()); |
4224 | 4205 |
4225 __ Cmp(left, right); | 4206 __ Cmp(left, right); |
4226 __ Csel(result, left, right, (op == HMathMinMax::kMathMax) ? ge : le); | 4207 __ Csel(result, left, right, (op == HMathMinMax::kMathMax) ? ge : le); |
4227 } else if (instr->hydrogen()->representation().IsSmi()) { | 4208 } else if (instr->hydrogen()->representation().IsSmi()) { |
4228 Register result = ToRegister(instr->result()); | 4209 Register result = ToRegister(instr->result()); |
4229 Register left = ToRegister(instr->left()); | 4210 Register left = ToRegister(instr->left()); |
4230 Operand right = ToOperand(instr->right()); | 4211 Operand right = ToOperand(instr->right()); |
4231 | 4212 |
4232 __ Cmp(left, right); | 4213 __ Cmp(left, right); |
4233 __ Csel(result, left, right, (op == HMathMinMax::kMathMax) ? ge : le); | 4214 __ Csel(result, left, right, (op == HMathMinMax::kMathMax) ? ge : le); |
(...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5564 Condition condition = TokenToCondition(op, false); | 5545 Condition condition = TokenToCondition(op, false); |
5565 | 5546 |
5566 EmitCompareAndBranch(instr, condition, x0, 0); | 5547 EmitCompareAndBranch(instr, condition, x0, 0); |
5567 } | 5548 } |
5568 | 5549 |
5569 | 5550 |
5570 void LCodeGen::DoSubI(LSubI* instr) { | 5551 void LCodeGen::DoSubI(LSubI* instr) { |
5571 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 5552 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
5572 Register result = ToRegister32(instr->result()); | 5553 Register result = ToRegister32(instr->result()); |
5573 Register left = ToRegister32(instr->left()); | 5554 Register left = ToRegister32(instr->left()); |
5574 Operand right = ToShiftedRightOperand32I(instr->right(), instr); | 5555 Operand right = ToShiftedRightOperand32(instr->right(), instr); |
5575 | 5556 |
5576 if (can_overflow) { | 5557 if (can_overflow) { |
5577 __ Subs(result, left, right); | 5558 __ Subs(result, left, right); |
5578 DeoptimizeIf(vs, instr->environment()); | 5559 DeoptimizeIf(vs, instr->environment()); |
5579 } else { | 5560 } else { |
5580 __ Sub(result, left, right); | 5561 __ Sub(result, left, right); |
5581 } | 5562 } |
5582 } | 5563 } |
5583 | 5564 |
5584 | 5565 |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6046 Handle<ScopeInfo> scope_info = instr->scope_info(); | 6027 Handle<ScopeInfo> scope_info = instr->scope_info(); |
6047 __ Push(scope_info); | 6028 __ Push(scope_info); |
6048 __ Push(ToRegister(instr->function())); | 6029 __ Push(ToRegister(instr->function())); |
6049 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6030 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
6050 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6031 RecordSafepoint(Safepoint::kNoLazyDeopt); |
6051 } | 6032 } |
6052 | 6033 |
6053 | 6034 |
6054 | 6035 |
6055 } } // namespace v8::internal | 6036 } } // namespace v8::internal |
OLD | NEW |