OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
404 } | 404 } |
405 | 405 |
406 | 406 |
407 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { | 407 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { |
408 return op->IsConstantOperand() && | 408 return op->IsConstantOperand() && |
409 chunk_->LookupLiteralRepresentation(op).IsTagged(); | 409 chunk_->LookupLiteralRepresentation(op).IsTagged(); |
410 } | 410 } |
411 | 411 |
412 | 412 |
413 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { | 413 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { |
414 HConstant* constant = chunk_->LookupConstant(op); | 414 return ToRepresentation(op, Representation::Integer32()); |
415 return constant->Integer32Value(); | |
416 } | 415 } |
417 | 416 |
418 | 417 |
418 int32_t LCodeGen::ToRepresentation(LConstantOperand* op, | |
419 const Representation& r) const { | |
420 HConstant* constant = chunk_->LookupConstant(op); | |
421 int32_t value = constant->Integer32Value(); | |
422 if (r.IsInteger32()) return value; | |
423 ASSERT(r.IsSmiOrTagged()); | |
424 return static_cast<int32_t>(reinterpret_cast<intptr_t>(Smi::FromInt(value))); | |
425 } | |
426 | |
427 | |
419 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { | 428 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { |
420 HConstant* constant = chunk_->LookupConstant(op); | 429 HConstant* constant = chunk_->LookupConstant(op); |
421 return Smi::FromInt(constant->Integer32Value()); | 430 return Smi::FromInt(constant->Integer32Value()); |
422 } | 431 } |
423 | 432 |
424 | 433 |
425 double LCodeGen::ToDouble(LConstantOperand* op) const { | 434 double LCodeGen::ToDouble(LConstantOperand* op) const { |
426 HConstant* constant = chunk_->LookupConstant(op); | 435 HConstant* constant = chunk_->LookupConstant(op); |
427 ASSERT(constant->HasDoubleValue()); | 436 ASSERT(constant->HasDoubleValue()); |
428 return constant->DoubleValue(); | 437 return constant->DoubleValue(); |
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1294 default: | 1303 default: |
1295 __ imull(left, left, Immediate(right_value)); | 1304 __ imull(left, left, Immediate(right_value)); |
1296 break; | 1305 break; |
1297 } | 1306 } |
1298 } else { | 1307 } else { |
1299 __ imull(left, left, Immediate(right_value)); | 1308 __ imull(left, left, Immediate(right_value)); |
1300 } | 1309 } |
1301 } else if (right->IsStackSlot()) { | 1310 } else if (right->IsStackSlot()) { |
1302 if (instr->hydrogen_value()->representation().IsSmi()) { | 1311 if (instr->hydrogen_value()->representation().IsSmi()) { |
1303 __ SmiToInteger32(left, left); | 1312 __ SmiToInteger32(left, left); |
1304 __ imul(left, ToOperand(right)); | 1313 if (kSmiValueSize == 32) { |
1314 __ imul(left, ToOperand(right)); | |
danno
2013/08/01 16:45:41
Move this switching into the macro assembler, you
| |
1315 } else { | |
1316 ASSERT(kSmiValueSize == 31); | |
1317 __ imull(left, ToOperand(right)); | |
1318 } | |
1305 } else { | 1319 } else { |
1306 __ imull(left, ToOperand(right)); | 1320 __ imull(left, ToOperand(right)); |
1307 } | 1321 } |
1308 } else { | 1322 } else { |
1309 if (instr->hydrogen_value()->representation().IsSmi()) { | 1323 if (instr->hydrogen_value()->representation().IsSmi()) { |
1310 __ SmiToInteger32(left, left); | 1324 __ SmiToInteger32(left, left); |
1311 __ imul(left, ToRegister(right)); | 1325 if (kSmiValueSize == 32) { |
1326 __ imul(left, ToOperand(right)); | |
1327 } else { | |
1328 ASSERT(kSmiValueSize == 31); | |
1329 __ imull(left, ToOperand(right)); | |
1330 } | |
1312 } else { | 1331 } else { |
1313 __ imull(left, ToRegister(right)); | 1332 __ imull(left, ToRegister(right)); |
1314 } | 1333 } |
1315 } | 1334 } |
1316 | 1335 |
1317 if (can_overflow) { | 1336 if (can_overflow) { |
1318 DeoptimizeIf(overflow, instr->environment()); | 1337 DeoptimizeIf(overflow, instr->environment()); |
1319 } | 1338 } |
1320 | 1339 |
1340 if (kSmiValueSize == 31 && | |
1341 instr->hydrogen_value()->representation().IsSmi()) { | |
1342 __ movsxlq(left, left); | |
1343 } | |
1344 | |
1321 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1345 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1322 // Bail out if the result is supposed to be negative zero. | 1346 // Bail out if the result is supposed to be negative zero. |
1323 Label done; | 1347 Label done; |
1324 __ testl(left, left); | 1348 __ testl(left, left); |
1325 __ j(not_zero, &done, Label::kNear); | 1349 __ j(not_zero, &done, Label::kNear); |
1326 if (right->IsConstantOperand()) { | 1350 if (right->IsConstantOperand()) { |
1327 if (ToInteger32(LConstantOperand::cast(right)) < 0) { | 1351 if (ToInteger32(LConstantOperand::cast(right)) < 0) { |
1328 DeoptimizeIf(no_condition, instr->environment()); | 1352 DeoptimizeIf(no_condition, instr->environment()); |
1329 } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { | 1353 } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { |
1330 __ cmpl(kScratchRegister, Immediate(0)); | 1354 __ cmpl(kScratchRegister, Immediate(0)); |
(...skipping 12 matching lines...) Expand all Loading... | |
1343 } | 1367 } |
1344 | 1368 |
1345 | 1369 |
1346 void LCodeGen::DoBitI(LBitI* instr) { | 1370 void LCodeGen::DoBitI(LBitI* instr) { |
1347 LOperand* left = instr->left(); | 1371 LOperand* left = instr->left(); |
1348 LOperand* right = instr->right(); | 1372 LOperand* right = instr->right(); |
1349 ASSERT(left->Equals(instr->result())); | 1373 ASSERT(left->Equals(instr->result())); |
1350 ASSERT(left->IsRegister()); | 1374 ASSERT(left->IsRegister()); |
1351 | 1375 |
1352 if (right->IsConstantOperand()) { | 1376 if (right->IsConstantOperand()) { |
1353 int right_operand = ToInteger32(LConstantOperand::cast(right)); | 1377 int right_operand = ToRepresentation(LConstantOperand::cast(right), |
1378 instr->hydrogen()->representation()); | |
1354 switch (instr->op()) { | 1379 switch (instr->op()) { |
1355 case Token::BIT_AND: | 1380 case Token::BIT_AND: |
1356 __ andl(ToRegister(left), Immediate(right_operand)); | 1381 if (instr->hydrogen()->representation().IsSmi()) { |
1382 __ and_(ToRegister(left), Immediate(right_operand)); | |
1383 } else { | |
1384 __ andl(ToRegister(left), Immediate(right_operand)); | |
1385 } | |
1357 break; | 1386 break; |
1358 case Token::BIT_OR: | 1387 case Token::BIT_OR: |
1359 __ orl(ToRegister(left), Immediate(right_operand)); | 1388 if (instr->hydrogen()->representation().IsSmi()) { |
1389 __ or_(ToRegister(left), Immediate(right_operand)); | |
1390 } else { | |
1391 __ orl(ToRegister(left), Immediate(right_operand)); | |
1392 } | |
1360 break; | 1393 break; |
1361 case Token::BIT_XOR: | 1394 case Token::BIT_XOR: |
1362 __ xorl(ToRegister(left), Immediate(right_operand)); | 1395 if (instr->hydrogen()->representation().IsSmi()) { |
1396 __ xor_(ToRegister(left), Immediate(right_operand)); | |
1397 } else { | |
1398 __ xorl(ToRegister(left), Immediate(right_operand)); | |
1399 } | |
1363 break; | 1400 break; |
1364 default: | 1401 default: |
1365 UNREACHABLE(); | 1402 UNREACHABLE(); |
1366 break; | 1403 break; |
1367 } | 1404 } |
1368 } else if (right->IsStackSlot()) { | 1405 } else if (right->IsStackSlot()) { |
1369 switch (instr->op()) { | 1406 switch (instr->op()) { |
1370 case Token::BIT_AND: | 1407 case Token::BIT_AND: |
1371 __ and_(ToRegister(left), ToOperand(right)); | 1408 __ and_(ToRegister(left), ToOperand(right)); |
1372 break; | 1409 break; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1468 } | 1505 } |
1469 | 1506 |
1470 | 1507 |
1471 void LCodeGen::DoSubI(LSubI* instr) { | 1508 void LCodeGen::DoSubI(LSubI* instr) { |
1472 LOperand* left = instr->left(); | 1509 LOperand* left = instr->left(); |
1473 LOperand* right = instr->right(); | 1510 LOperand* right = instr->right(); |
1474 ASSERT(left->Equals(instr->result())); | 1511 ASSERT(left->Equals(instr->result())); |
1475 | 1512 |
1476 if (right->IsConstantOperand()) { | 1513 if (right->IsConstantOperand()) { |
1477 __ subl(ToRegister(left), | 1514 __ subl(ToRegister(left), |
1478 Immediate(ToInteger32(LConstantOperand::cast(right)))); | 1515 Immediate(ToRepresentation(LConstantOperand::cast(right), |
1516 instr->hydrogen()->representation()))); | |
1479 } else if (right->IsRegister()) { | 1517 } else if (right->IsRegister()) { |
1480 if (instr->hydrogen_value()->representation().IsSmi()) { | 1518 if (instr->hydrogen_value()->representation().IsSmi()) { |
1481 __ subq(ToRegister(left), ToRegister(right)); | 1519 if (kSmiValueSize == 32) { |
1520 __ subq(ToRegister(left), ToRegister(right)); | |
1521 } else { | |
1522 ASSERT(kSmiValueSize == 31); | |
1523 __ subl(ToRegister(left), ToRegister(right)); | |
1524 } | |
1482 } else { | 1525 } else { |
1483 __ subl(ToRegister(left), ToRegister(right)); | 1526 __ subl(ToRegister(left), ToRegister(right)); |
1484 } | 1527 } |
1485 } else { | 1528 } else { |
1486 if (instr->hydrogen_value()->representation().IsSmi()) { | 1529 if (instr->hydrogen_value()->representation().IsSmi()) { |
1487 __ subq(ToRegister(left), ToOperand(right)); | 1530 if (kSmiValueSize == 32) { |
1531 __ subq(ToRegister(left), ToOperand(right)); | |
1532 } else { | |
1533 ASSERT(kSmiValueSize == 31); | |
1534 __ subl(ToRegister(left), ToOperand(right)); | |
1535 } | |
1488 } else { | 1536 } else { |
1489 __ subl(ToRegister(left), ToOperand(right)); | 1537 __ subl(ToRegister(left), ToOperand(right)); |
1490 } | 1538 } |
1491 } | 1539 } |
1492 | 1540 |
1493 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1541 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
1494 DeoptimizeIf(overflow, instr->environment()); | 1542 DeoptimizeIf(overflow, instr->environment()); |
1495 } | 1543 } |
1544 | |
1545 if (kSmiValueSize == 31 && | |
1546 instr->hydrogen_value()->representation().IsSmi()) { | |
1547 __ movsxlq(ToRegister(left), ToRegister(left)); | |
1548 } | |
1496 } | 1549 } |
1497 | 1550 |
1498 | 1551 |
1499 void LCodeGen::DoConstantI(LConstantI* instr) { | 1552 void LCodeGen::DoConstantI(LConstantI* instr) { |
1500 __ Set(ToRegister(instr->result()), instr->value()); | 1553 __ Set(ToRegister(instr->result()), instr->value()); |
1501 } | 1554 } |
1502 | 1555 |
1503 | 1556 |
1504 void LCodeGen::DoConstantS(LConstantS* instr) { | 1557 void LCodeGen::DoConstantS(LConstantS* instr) { |
1505 __ Move(ToRegister(instr->result()), instr->value()); | 1558 __ Move(ToRegister(instr->result()), instr->value()); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1656 } | 1709 } |
1657 } | 1710 } |
1658 | 1711 |
1659 | 1712 |
1660 void LCodeGen::DoAddI(LAddI* instr) { | 1713 void LCodeGen::DoAddI(LAddI* instr) { |
1661 LOperand* left = instr->left(); | 1714 LOperand* left = instr->left(); |
1662 LOperand* right = instr->right(); | 1715 LOperand* right = instr->right(); |
1663 | 1716 |
1664 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { | 1717 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { |
1665 if (right->IsConstantOperand()) { | 1718 if (right->IsConstantOperand()) { |
1666 int32_t offset = ToInteger32(LConstantOperand::cast(right)); | 1719 int32_t offset = ToRepresentation(LConstantOperand::cast(right), |
1667 __ leal(ToRegister(instr->result()), | 1720 instr->hydrogen()->representation()); |
1668 MemOperand(ToRegister(left), offset)); | 1721 if (instr->hydrogen()->representation().IsSmi()) { |
1722 __ lea(ToRegister(instr->result()), | |
1723 MemOperand(ToRegister(left), offset)); | |
1724 } else { | |
1725 __ leal(ToRegister(instr->result()), | |
1726 MemOperand(ToRegister(left), offset)); | |
1727 } | |
1669 } else { | 1728 } else { |
1670 Operand address(ToRegister(left), ToRegister(right), times_1, 0); | 1729 Operand address(ToRegister(left), ToRegister(right), times_1, 0); |
1671 if (instr->hydrogen()->representation().IsSmi()) { | 1730 if (instr->hydrogen()->representation().IsSmi()) { |
1672 __ lea(ToRegister(instr->result()), address); | 1731 __ lea(ToRegister(instr->result()), address); |
1673 } else { | 1732 } else { |
1674 __ leal(ToRegister(instr->result()), address); | 1733 __ leal(ToRegister(instr->result()), address); |
1675 } | 1734 } |
1676 } | 1735 } |
1677 } else { | 1736 } else { |
1678 if (right->IsConstantOperand()) { | 1737 if (right->IsConstantOperand()) { |
1679 __ addl(ToRegister(left), | 1738 __ addl(ToRegister(left), |
1680 Immediate(ToInteger32(LConstantOperand::cast(right)))); | 1739 Immediate(ToRepresentation(LConstantOperand::cast(right), |
1740 instr->hydrogen()->representation()))); | |
1681 } else if (right->IsRegister()) { | 1741 } else if (right->IsRegister()) { |
1682 if (instr->hydrogen_value()->representation().IsSmi()) { | 1742 if (instr->hydrogen_value()->representation().IsSmi()) { |
1683 __ addq(ToRegister(left), ToRegister(right)); | 1743 if (kSmiValueSize == 32) { |
1744 __ addq(ToRegister(left), ToRegister(right)); | |
1745 } else { | |
1746 ASSERT(kSmiValueSize == 31); | |
1747 __ addl(ToRegister(left), ToRegister(right)); | |
1748 } | |
1684 } else { | 1749 } else { |
1685 __ addl(ToRegister(left), ToRegister(right)); | 1750 __ addl(ToRegister(left), ToRegister(right)); |
1686 } | 1751 } |
1687 } else { | 1752 } else { |
1688 if (instr->hydrogen_value()->representation().IsSmi()) { | 1753 if (instr->hydrogen_value()->representation().IsSmi()) { |
1689 __ addq(ToRegister(left), ToOperand(right)); | 1754 if (kSmiValueSize == 32) { |
1755 __ addq(ToRegister(left), ToOperand(right)); | |
1756 } else { | |
1757 ASSERT(kSmiValueSize == 31); | |
1758 __ addl(ToRegister(left), ToOperand(right)); | |
1759 } | |
1690 } else { | 1760 } else { |
1691 __ addl(ToRegister(left), ToOperand(right)); | 1761 __ addl(ToRegister(left), ToOperand(right)); |
1692 } | 1762 } |
1693 } | 1763 } |
1694 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1764 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
1695 DeoptimizeIf(overflow, instr->environment()); | 1765 DeoptimizeIf(overflow, instr->environment()); |
1696 } | 1766 } |
1767 | |
1768 if (kSmiValueSize == 31 && | |
1769 instr->hydrogen_value()->representation().IsSmi()) { | |
1770 __ movsxlq(ToRegister(left), ToRegister(left)); | |
1771 } | |
1697 } | 1772 } |
1698 } | 1773 } |
1699 | 1774 |
1700 | 1775 |
1701 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 1776 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
1702 LOperand* left = instr->left(); | 1777 LOperand* left = instr->left(); |
1703 LOperand* right = instr->right(); | 1778 LOperand* right = instr->right(); |
1704 ASSERT(left->Equals(instr->result())); | 1779 ASSERT(left->Equals(instr->result())); |
1705 HMathMinMax::Operation operation = instr->hydrogen()->operation(); | 1780 HMathMinMax::Operation operation = instr->hydrogen()->operation(); |
1706 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { | 1781 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { |
1707 Label return_left; | 1782 Label return_left; |
1708 Condition condition = (operation == HMathMinMax::kMathMin) | 1783 Condition condition = (operation == HMathMinMax::kMathMin) |
1709 ? less_equal | 1784 ? less_equal |
1710 : greater_equal; | 1785 : greater_equal; |
1711 Register left_reg = ToRegister(left); | 1786 Register left_reg = ToRegister(left); |
1712 if (right->IsConstantOperand()) { | 1787 if (right->IsConstantOperand()) { |
1713 Immediate right_imm = | 1788 Immediate right_imm = |
1714 Immediate(ToInteger32(LConstantOperand::cast(right))); | 1789 Immediate(ToRepresentation(LConstantOperand::cast(right), |
1715 ASSERT(!instr->hydrogen_value()->representation().IsSmi()); | 1790 instr->hydrogen()->representation())); |
1716 __ cmpl(left_reg, right_imm); | 1791 __ cmpl(left_reg, right_imm); |
1717 __ j(condition, &return_left, Label::kNear); | 1792 __ j(condition, &return_left, Label::kNear); |
1718 __ movq(left_reg, right_imm); | 1793 __ movq(left_reg, right_imm); |
1719 } else if (right->IsRegister()) { | 1794 } else if (right->IsRegister()) { |
1720 Register right_reg = ToRegister(right); | 1795 Register right_reg = ToRegister(right); |
1721 if (instr->hydrogen_value()->representation().IsSmi()) { | 1796 if (instr->hydrogen_value()->representation().IsSmi()) { |
1722 __ cmpq(left_reg, right_reg); | 1797 __ cmpq(left_reg, right_reg); |
1723 } else { | 1798 } else { |
1724 __ cmpl(left_reg, right_reg); | 1799 __ cmpl(left_reg, right_reg); |
1725 } | 1800 } |
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2903 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 2978 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
2904 ElementsKind elements_kind = instr->elements_kind(); | 2979 ElementsKind elements_kind = instr->elements_kind(); |
2905 LOperand* key = instr->key(); | 2980 LOperand* key = instr->key(); |
2906 if (!key->IsConstantOperand()) { | 2981 if (!key->IsConstantOperand()) { |
2907 Register key_reg = ToRegister(key); | 2982 Register key_reg = ToRegister(key); |
2908 // Even though the HLoad/StoreKeyed (in this case) instructions force | 2983 // Even though the HLoad/StoreKeyed (in this case) instructions force |
2909 // the input representation for the key to be an integer, the input | 2984 // the input representation for the key to be an integer, the input |
2910 // gets replaced during bound check elimination with the index argument | 2985 // gets replaced during bound check elimination with the index argument |
2911 // to the bounds check, which can be tagged, so that case must be | 2986 // to the bounds check, which can be tagged, so that case must be |
2912 // handled here, too. | 2987 // handled here, too. |
2913 if (instr->hydrogen()->IsDehoisted()) { | 2988 if (kSmiValueSize == 31 && |
2989 instr->hydrogen()->key()->representation().IsSmi()) { | |
2990 __ SmiToInteger64(key_reg, key_reg); | |
2991 } else if (instr->hydrogen()->IsDehoisted()) { | |
2914 // Sign extend key because it could be a 32 bit negative value | 2992 // Sign extend key because it could be a 32 bit negative value |
2915 // and the dehoisted address computation happens in 64 bits | 2993 // and the dehoisted address computation happens in 64 bits |
2916 __ movsxlq(key_reg, key_reg); | 2994 __ movsxlq(key_reg, key_reg); |
2917 } | 2995 } |
2918 } | 2996 } |
2919 Operand operand(BuildFastArrayOperand( | 2997 Operand operand(BuildFastArrayOperand( |
2920 instr->elements(), | 2998 instr->elements(), |
2921 key, | 2999 key, |
2922 elements_kind, | 3000 elements_kind, |
2923 0, | 3001 0, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2974 | 3052 |
2975 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3053 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
2976 XMMRegister result(ToDoubleRegister(instr->result())); | 3054 XMMRegister result(ToDoubleRegister(instr->result())); |
2977 LOperand* key = instr->key(); | 3055 LOperand* key = instr->key(); |
2978 if (!key->IsConstantOperand()) { | 3056 if (!key->IsConstantOperand()) { |
2979 Register key_reg = ToRegister(key); | 3057 Register key_reg = ToRegister(key); |
2980 // Even though the HLoad/StoreKeyed instructions force the input | 3058 // Even though the HLoad/StoreKeyed instructions force the input |
2981 // representation for the key to be an integer, the input gets replaced | 3059 // representation for the key to be an integer, the input gets replaced |
2982 // during bound check elimination with the index argument to the bounds | 3060 // during bound check elimination with the index argument to the bounds |
2983 // check, which can be tagged, so that case must be handled here, too. | 3061 // check, which can be tagged, so that case must be handled here, too. |
2984 if (instr->hydrogen()->IsDehoisted()) { | 3062 if (kSmiValueSize == 31 && |
3063 instr->hydrogen()->key()->representation().IsSmi()) { | |
3064 __ SmiToInteger64(key_reg, key_reg); | |
3065 } else if (instr->hydrogen()->IsDehoisted()) { | |
2985 // Sign extend key because it could be a 32 bit negative value | 3066 // Sign extend key because it could be a 32 bit negative value |
2986 // and the dehoisted address computation happens in 64 bits | 3067 // and the dehoisted address computation happens in 64 bits |
2987 __ movsxlq(key_reg, key_reg); | 3068 __ movsxlq(key_reg, key_reg); |
2988 } | 3069 } |
2989 } | 3070 } |
2990 | 3071 |
2991 if (instr->hydrogen()->RequiresHoleCheck()) { | 3072 if (instr->hydrogen()->RequiresHoleCheck()) { |
2992 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | 3073 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
2993 sizeof(kHoleNanLower32); | 3074 sizeof(kHoleNanLower32); |
2994 Operand hole_check_operand = BuildFastArrayOperand( | 3075 Operand hole_check_operand = BuildFastArrayOperand( |
(...skipping 19 matching lines...) Expand all Loading... | |
3014 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3095 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
3015 Register result = ToRegister(instr->result()); | 3096 Register result = ToRegister(instr->result()); |
3016 LOperand* key = instr->key(); | 3097 LOperand* key = instr->key(); |
3017 if (!key->IsConstantOperand()) { | 3098 if (!key->IsConstantOperand()) { |
3018 Register key_reg = ToRegister(key); | 3099 Register key_reg = ToRegister(key); |
3019 // Even though the HLoad/StoreKeyedFastElement instructions force | 3100 // Even though the HLoad/StoreKeyedFastElement instructions force |
3020 // the input representation for the key to be an integer, the input | 3101 // the input representation for the key to be an integer, the input |
3021 // gets replaced during bound check elimination with the index | 3102 // gets replaced during bound check elimination with the index |
3022 // argument to the bounds check, which can be tagged, so that | 3103 // argument to the bounds check, which can be tagged, so that |
3023 // case must be handled here, too. | 3104 // case must be handled here, too. |
3024 if (instr->hydrogen()->IsDehoisted()) { | 3105 if (kSmiValueSize == 31 && |
3106 instr->hydrogen()->key()->representation().IsSmi()) { | |
3107 __ SmiToInteger64(key_reg, key_reg); | |
3108 } else if (instr->hydrogen()->IsDehoisted()) { | |
3025 // Sign extend key because it could be a 32 bit negative value | 3109 // Sign extend key because it could be a 32 bit negative value |
3026 // and the dehoisted address computation happens in 64 bits | 3110 // and the dehoisted address computation happens in 64 bits |
3027 __ movsxlq(key_reg, key_reg); | 3111 __ movsxlq(key_reg, key_reg); |
3028 } | 3112 } |
3029 } | 3113 } |
3030 | 3114 |
3031 // Load the result. | 3115 // Load the result. |
3032 __ movq(result, | 3116 __ movq(result, |
3033 BuildFastArrayOperand(instr->elements(), | 3117 BuildFastArrayOperand(instr->elements(), |
3034 key, | 3118 key, |
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4090 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4174 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
4091 ElementsKind elements_kind = instr->elements_kind(); | 4175 ElementsKind elements_kind = instr->elements_kind(); |
4092 LOperand* key = instr->key(); | 4176 LOperand* key = instr->key(); |
4093 if (!key->IsConstantOperand()) { | 4177 if (!key->IsConstantOperand()) { |
4094 Register key_reg = ToRegister(key); | 4178 Register key_reg = ToRegister(key); |
4095 // Even though the HLoad/StoreKeyedFastElement instructions force | 4179 // Even though the HLoad/StoreKeyedFastElement instructions force |
4096 // the input representation for the key to be an integer, the input | 4180 // the input representation for the key to be an integer, the input |
4097 // gets replaced during bound check elimination with the index | 4181 // gets replaced during bound check elimination with the index |
4098 // argument to the bounds check, which can be tagged, so that case | 4182 // argument to the bounds check, which can be tagged, so that case |
4099 // must be handled here, too. | 4183 // must be handled here, too. |
4100 if (instr->hydrogen()->IsDehoisted()) { | 4184 if (kSmiValueSize == 31 && |
4185 instr->hydrogen()->key()->representation().IsSmi()) { | |
4186 __ SmiToInteger64(key_reg, key_reg); | |
4187 } else if (instr->hydrogen()->IsDehoisted()) { | |
4101 // Sign extend key because it could be a 32 bit negative value | 4188 // Sign extend key because it could be a 32 bit negative value |
4102 // and the dehoisted address computation happens in 64 bits | 4189 // and the dehoisted address computation happens in 64 bits |
4103 __ movsxlq(key_reg, key_reg); | 4190 __ movsxlq(key_reg, key_reg); |
4104 } | 4191 } |
4105 } | 4192 } |
4106 Operand operand(BuildFastArrayOperand( | 4193 Operand operand(BuildFastArrayOperand( |
4107 instr->elements(), | 4194 instr->elements(), |
4108 key, | 4195 key, |
4109 elements_kind, | 4196 elements_kind, |
4110 0, | 4197 0, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4152 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4239 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
4153 XMMRegister value = ToDoubleRegister(instr->value()); | 4240 XMMRegister value = ToDoubleRegister(instr->value()); |
4154 LOperand* key = instr->key(); | 4241 LOperand* key = instr->key(); |
4155 if (!key->IsConstantOperand()) { | 4242 if (!key->IsConstantOperand()) { |
4156 Register key_reg = ToRegister(key); | 4243 Register key_reg = ToRegister(key); |
4157 // Even though the HLoad/StoreKeyedFastElement instructions force | 4244 // Even though the HLoad/StoreKeyedFastElement instructions force |
4158 // the input representation for the key to be an integer, the | 4245 // the input representation for the key to be an integer, the |
4159 // input gets replaced during bound check elimination with the index | 4246 // input gets replaced during bound check elimination with the index |
4160 // argument to the bounds check, which can be tagged, so that case | 4247 // argument to the bounds check, which can be tagged, so that case |
4161 // must be handled here, too. | 4248 // must be handled here, too. |
4162 if (instr->hydrogen()->IsDehoisted()) { | 4249 if (kSmiValueSize == 31 && |
4250 instr->hydrogen()->key()->representation().IsSmi()) { | |
4251 __ SmiToInteger64(key_reg, key_reg); | |
4252 } else if (instr->hydrogen()->IsDehoisted()) { | |
4163 // Sign extend key because it could be a 32 bit negative value | 4253 // Sign extend key because it could be a 32 bit negative value |
4164 // and the dehoisted address computation happens in 64 bits | 4254 // and the dehoisted address computation happens in 64 bits |
4165 __ movsxlq(key_reg, key_reg); | 4255 __ movsxlq(key_reg, key_reg); |
4166 } | 4256 } |
4167 } | 4257 } |
4168 | 4258 |
4169 if (instr->NeedsCanonicalization()) { | 4259 if (instr->NeedsCanonicalization()) { |
4170 Label have_value; | 4260 Label have_value; |
4171 | 4261 |
4172 __ ucomisd(value, value); | 4262 __ ucomisd(value, value); |
(...skipping 20 matching lines...) Expand all Loading... | |
4193 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4283 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
4194 Register elements = ToRegister(instr->elements()); | 4284 Register elements = ToRegister(instr->elements()); |
4195 LOperand* key = instr->key(); | 4285 LOperand* key = instr->key(); |
4196 if (!key->IsConstantOperand()) { | 4286 if (!key->IsConstantOperand()) { |
4197 Register key_reg = ToRegister(key); | 4287 Register key_reg = ToRegister(key); |
4198 // Even though the HLoad/StoreKeyedFastElement instructions force | 4288 // Even though the HLoad/StoreKeyedFastElement instructions force |
4199 // the input representation for the key to be an integer, the | 4289 // the input representation for the key to be an integer, the |
4200 // input gets replaced during bound check elimination with the index | 4290 // input gets replaced during bound check elimination with the index |
4201 // argument to the bounds check, which can be tagged, so that case | 4291 // argument to the bounds check, which can be tagged, so that case |
4202 // must be handled here, too. | 4292 // must be handled here, too. |
4203 if (instr->hydrogen()->IsDehoisted()) { | 4293 if (kSmiValueSize == 31 && |
4294 instr->hydrogen()->key()->representation().IsSmi()) { | |
4295 __ SmiToInteger64(key_reg, key_reg); | |
4296 } else if (instr->hydrogen()->IsDehoisted()) { | |
4204 // Sign extend key because it could be a 32 bit negative value | 4297 // Sign extend key because it could be a 32 bit negative value |
4205 // and the dehoisted address computation happens in 64 bits | 4298 // and the dehoisted address computation happens in 64 bits |
4206 __ movsxlq(key_reg, key_reg); | 4299 __ movsxlq(key_reg, key_reg); |
4207 } | 4300 } |
4208 } | 4301 } |
4209 | 4302 |
4210 Operand operand = | 4303 Operand operand = |
4211 BuildFastArrayOperand(instr->elements(), | 4304 BuildFastArrayOperand(instr->elements(), |
4212 key, | 4305 key, |
4213 FAST_ELEMENTS, | 4306 FAST_ELEMENTS, |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4479 LOperand* output = instr->result(); | 4572 LOperand* output = instr->result(); |
4480 LOperand* temp = instr->temp(); | 4573 LOperand* temp = instr->temp(); |
4481 | 4574 |
4482 __ LoadUint32(ToDoubleRegister(output), | 4575 __ LoadUint32(ToDoubleRegister(output), |
4483 ToRegister(input), | 4576 ToRegister(input), |
4484 ToDoubleRegister(temp)); | 4577 ToDoubleRegister(temp)); |
4485 } | 4578 } |
4486 | 4579 |
4487 | 4580 |
4488 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4581 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
4489 LOperand* input = instr->value(); | 4582 if (kSmiValueSize == 32) { |
4490 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 4583 LOperand* input = instr->value(); |
4491 Register reg = ToRegister(input); | 4584 ASSERT(input->IsRegister() && input->Equals(instr->result())); |
4585 Register reg = ToRegister(input); | |
4492 | 4586 |
4493 __ Integer32ToSmi(reg, reg); | 4587 __ Integer32ToSmi(reg, reg); |
4588 } else { | |
4589 ASSERT(kSmiValueSize == 31); | |
4590 class DeferredNumberTagI: public LDeferredCode { | |
4591 public: | |
4592 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) | |
4593 : LDeferredCode(codegen), instr_(instr) { } | |
4594 virtual void Generate() { | |
4595 codegen()->DoDeferredNumberTagI(instr_); | |
4596 } | |
4597 virtual LInstruction* instr() { return instr_; } | |
4598 private: | |
4599 LNumberTagI* instr_; | |
4600 }; | |
4601 | |
4602 LOperand* input = instr->value(); | |
4603 ASSERT(input->IsRegister() && input->Equals(instr->result())); | |
4604 Register reg = ToRegister(input); | |
4605 | |
4606 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); | |
4607 __ shll(reg, Immediate(kSmiTagSize + kSmiShiftSize)); | |
4608 __ j(overflow, deferred->entry()); | |
4609 __ movsxlq(reg, reg); | |
4610 __ bind(deferred->exit()); | |
4611 } | |
4494 } | 4612 } |
4495 | 4613 |
4496 | 4614 |
4615 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { | |
4616 Label slow; | |
4617 Register reg = ToRegister(instr->value()); | |
4618 Register tmp = reg.is(rax) ? kScratchRegister : rax; | |
4619 | |
4620 // Preserve the value of all registers. | |
4621 PushSafepointRegistersScope scope(this); | |
4622 | |
4623 Label done; | |
4624 // There was overflow, so bits 30 and 31 of the original integer | |
4625 // disagree. Try to allocate a heap number in new space and store | |
4626 // the value in there. If that fails, call the runtime system. | |
4627 __ SmiToInteger32(reg, reg); | |
4628 __ xorl(reg, Immediate(0x80000000)); | |
4629 __ cvtlsi2sd(xmm1, reg); | |
4630 | |
4631 if (FLAG_inline_new) { | |
4632 __ AllocateHeapNumber(reg, tmp, &slow); | |
4633 __ jmp(&done, Label::kNear); | |
4634 } | |
4635 | |
4636 // Slow case: Call the runtime system to do the number allocation. | |
4637 __ bind(&slow); | |
4638 | |
4639 // Put a valid pointer value in the stack slot where the result | |
4640 // register is stored, as this register is in the pointer map, but contains an | |
4641 // integer value. | |
4642 __ StoreToSafepointRegisterSlot(reg, Immediate(0)); | |
4643 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | |
4644 // Set the pointer to the new heap number in tmp. | |
4645 if (!reg.is(rax)) __ movq(reg, rax); | |
4646 | |
4647 // Heap number allocated. Put the value in xmm0 into the value of the | |
4648 // allocated heap number. | |
4649 __ bind(&done); | |
4650 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm1); | |
4651 __ StoreToSafepointRegisterSlot(reg, reg); | |
4652 } | |
4653 | |
4654 | |
4497 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { | 4655 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { |
4498 class DeferredNumberTagU: public LDeferredCode { | 4656 class DeferredNumberTagU: public LDeferredCode { |
4499 public: | 4657 public: |
4500 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) | 4658 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) |
4501 : LDeferredCode(codegen), instr_(instr) { } | 4659 : LDeferredCode(codegen), instr_(instr) { } |
4502 virtual void Generate() { | 4660 virtual void Generate() { |
4503 codegen()->DoDeferredNumberTagU(instr_); | 4661 codegen()->DoDeferredNumberTagU(instr_); |
4504 } | 4662 } |
4505 virtual LInstruction* instr() { return instr_; } | 4663 virtual LInstruction* instr() { return instr_; } |
4506 private: | 4664 private: |
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5559 FixedArray::kHeaderSize - kPointerSize)); | 5717 FixedArray::kHeaderSize - kPointerSize)); |
5560 __ bind(&done); | 5718 __ bind(&done); |
5561 } | 5719 } |
5562 | 5720 |
5563 | 5721 |
5564 #undef __ | 5722 #undef __ |
5565 | 5723 |
5566 } } // namespace v8::internal | 5724 } } // namespace v8::internal |
5567 | 5725 |
5568 #endif // V8_TARGET_ARCH_X64 | 5726 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |