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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 chunk_->LookupLiteralRepresentation(op).IsSmi(); | 403 chunk_->LookupLiteralRepresentation(op).IsSmi(); |
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 #if !V8_USE_31_BITS_SMI_VALUE |
413 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { | 414 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { |
414 HConstant* constant = chunk_->LookupConstant(op); | 415 HConstant* constant = chunk_->LookupConstant(op); |
415 return constant->Integer32Value(); | 416 return constant->Integer32Value(); |
416 } | 417 } |
| 418 #else |
| 419 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { |
| 420 return ToRepresentation(op, Representation::Integer32()); |
| 421 } |
| 422 |
| 423 |
| 424 int32_t LCodeGen::ToRepresentation(LConstantOperand* op, |
| 425 const Representation& r) const { |
| 426 HConstant* constant = chunk_->LookupConstant(op); |
| 427 int32_t value = constant->Integer32Value(); |
| 428 if (r.IsInteger32()) return value; |
| 429 ASSERT(r.IsSmiOrTagged()); |
| 430 return static_cast<int32_t>(reinterpret_cast<intptr_t>(Smi::FromInt(value))); |
| 431 } |
| 432 #endif |
417 | 433 |
418 | 434 |
419 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { | 435 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { |
420 HConstant* constant = chunk_->LookupConstant(op); | 436 HConstant* constant = chunk_->LookupConstant(op); |
421 return Smi::FromInt(constant->Integer32Value()); | 437 return Smi::FromInt(constant->Integer32Value()); |
422 } | 438 } |
423 | 439 |
424 | 440 |
425 double LCodeGen::ToDouble(LConstantOperand* op) const { | 441 double LCodeGen::ToDouble(LConstantOperand* op) const { |
426 HConstant* constant = chunk_->LookupConstant(op); | 442 HConstant* constant = chunk_->LookupConstant(op); |
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 default: | 1310 default: |
1295 __ imull(left, left, Immediate(right_value)); | 1311 __ imull(left, left, Immediate(right_value)); |
1296 break; | 1312 break; |
1297 } | 1313 } |
1298 } else { | 1314 } else { |
1299 __ imull(left, left, Immediate(right_value)); | 1315 __ imull(left, left, Immediate(right_value)); |
1300 } | 1316 } |
1301 } else if (right->IsStackSlot()) { | 1317 } else if (right->IsStackSlot()) { |
1302 if (instr->hydrogen_value()->representation().IsSmi()) { | 1318 if (instr->hydrogen_value()->representation().IsSmi()) { |
1303 __ SmiToInteger32(left, left); | 1319 __ SmiToInteger32(left, left); |
| 1320 #if !V8_USE_31_BITS_SMI_VALUE |
1304 __ imul(left, ToOperand(right)); | 1321 __ imul(left, ToOperand(right)); |
| 1322 #else |
| 1323 __ imull(left, ToOperand(right)); |
| 1324 #endif |
1305 } else { | 1325 } else { |
1306 __ imull(left, ToOperand(right)); | 1326 __ imull(left, ToOperand(right)); |
1307 } | 1327 } |
1308 } else { | 1328 } else { |
1309 if (instr->hydrogen_value()->representation().IsSmi()) { | 1329 if (instr->hydrogen_value()->representation().IsSmi()) { |
1310 __ SmiToInteger32(left, left); | 1330 __ SmiToInteger32(left, left); |
1311 __ imul(left, ToRegister(right)); | 1331 #if !V8_USE_31_BITS_SMI_VALUE |
| 1332 __ imul(left, ToOperand(right)); |
| 1333 #else |
| 1334 __ imull(left, ToOperand(right)); |
| 1335 #endif |
1312 } else { | 1336 } else { |
1313 __ imull(left, ToRegister(right)); | 1337 __ imull(left, ToRegister(right)); |
1314 } | 1338 } |
1315 } | 1339 } |
1316 | 1340 |
1317 if (can_overflow) { | 1341 if (can_overflow) { |
1318 DeoptimizeIf(overflow, instr->environment()); | 1342 DeoptimizeIf(overflow, instr->environment()); |
1319 } | 1343 } |
1320 | 1344 |
| 1345 #if V8_USE_31_BITS_SMI_VALUE |
| 1346 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1347 __ movsxlq(left, left); |
| 1348 } |
| 1349 #endif |
| 1350 |
1321 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1351 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1322 // Bail out if the result is supposed to be negative zero. | 1352 // Bail out if the result is supposed to be negative zero. |
1323 Label done; | 1353 Label done; |
1324 __ testl(left, left); | 1354 __ testl(left, left); |
1325 __ j(not_zero, &done, Label::kNear); | 1355 __ j(not_zero, &done, Label::kNear); |
1326 if (right->IsConstantOperand()) { | 1356 if (right->IsConstantOperand()) { |
1327 if (ToInteger32(LConstantOperand::cast(right)) < 0) { | 1357 if (ToInteger32(LConstantOperand::cast(right)) < 0) { |
1328 DeoptimizeIf(no_condition, instr->environment()); | 1358 DeoptimizeIf(no_condition, instr->environment()); |
1329 } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { | 1359 } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { |
1330 __ cmpl(kScratchRegister, Immediate(0)); | 1360 __ cmpl(kScratchRegister, Immediate(0)); |
(...skipping 12 matching lines...) Expand all Loading... |
1343 } | 1373 } |
1344 | 1374 |
1345 | 1375 |
1346 void LCodeGen::DoBitI(LBitI* instr) { | 1376 void LCodeGen::DoBitI(LBitI* instr) { |
1347 LOperand* left = instr->left(); | 1377 LOperand* left = instr->left(); |
1348 LOperand* right = instr->right(); | 1378 LOperand* right = instr->right(); |
1349 ASSERT(left->Equals(instr->result())); | 1379 ASSERT(left->Equals(instr->result())); |
1350 ASSERT(left->IsRegister()); | 1380 ASSERT(left->IsRegister()); |
1351 | 1381 |
1352 if (right->IsConstantOperand()) { | 1382 if (right->IsConstantOperand()) { |
| 1383 #if !V8_USE_31_BITS_SMI_VALUE |
1353 int right_operand = ToInteger32(LConstantOperand::cast(right)); | 1384 int right_operand = ToInteger32(LConstantOperand::cast(right)); |
| 1385 #else |
| 1386 int right_operand = ToRepresentation(LConstantOperand::cast(right), |
| 1387 instr->hydrogen()->representation()); |
| 1388 #endif |
1354 switch (instr->op()) { | 1389 switch (instr->op()) { |
1355 case Token::BIT_AND: | 1390 case Token::BIT_AND: |
| 1391 #if !V8_USE_31_BITS_SMI_VALUE |
1356 __ andl(ToRegister(left), Immediate(right_operand)); | 1392 __ andl(ToRegister(left), Immediate(right_operand)); |
| 1393 #else |
| 1394 if (instr->hydrogen()->representation().IsSmi()) { |
| 1395 __ and_(ToRegister(left), Immediate(right_operand)); |
| 1396 } else { |
| 1397 __ andl(ToRegister(left), Immediate(right_operand)); |
| 1398 } |
| 1399 #endif |
1357 break; | 1400 break; |
1358 case Token::BIT_OR: | 1401 case Token::BIT_OR: |
| 1402 #if !V8_USE_31_BITS_SMI_VALUE |
1359 __ orl(ToRegister(left), Immediate(right_operand)); | 1403 __ orl(ToRegister(left), Immediate(right_operand)); |
| 1404 #else |
| 1405 if (instr->hydrogen()->representation().IsSmi()) { |
| 1406 __ or_(ToRegister(left), Immediate(right_operand)); |
| 1407 } else { |
| 1408 __ orl(ToRegister(left), Immediate(right_operand)); |
| 1409 } |
| 1410 #endif |
1360 break; | 1411 break; |
1361 case Token::BIT_XOR: | 1412 case Token::BIT_XOR: |
| 1413 #if !V8_USE_31_BITS_SMI_VALUE |
1362 __ xorl(ToRegister(left), Immediate(right_operand)); | 1414 __ xorl(ToRegister(left), Immediate(right_operand)); |
| 1415 #else |
| 1416 if (instr->hydrogen()->representation().IsSmi()) { |
| 1417 __ xor_(ToRegister(left), Immediate(right_operand)); |
| 1418 } else { |
| 1419 __ xorl(ToRegister(left), Immediate(right_operand)); |
| 1420 } |
| 1421 #endif |
1363 break; | 1422 break; |
1364 default: | 1423 default: |
1365 UNREACHABLE(); | 1424 UNREACHABLE(); |
1366 break; | 1425 break; |
1367 } | 1426 } |
1368 } else if (right->IsStackSlot()) { | 1427 } else if (right->IsStackSlot()) { |
1369 switch (instr->op()) { | 1428 switch (instr->op()) { |
1370 case Token::BIT_AND: | 1429 case Token::BIT_AND: |
1371 __ and_(ToRegister(left), ToOperand(right)); | 1430 __ and_(ToRegister(left), ToOperand(right)); |
1372 break; | 1431 break; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 } | 1526 } |
1468 } | 1527 } |
1469 | 1528 |
1470 | 1529 |
1471 void LCodeGen::DoSubI(LSubI* instr) { | 1530 void LCodeGen::DoSubI(LSubI* instr) { |
1472 LOperand* left = instr->left(); | 1531 LOperand* left = instr->left(); |
1473 LOperand* right = instr->right(); | 1532 LOperand* right = instr->right(); |
1474 ASSERT(left->Equals(instr->result())); | 1533 ASSERT(left->Equals(instr->result())); |
1475 | 1534 |
1476 if (right->IsConstantOperand()) { | 1535 if (right->IsConstantOperand()) { |
| 1536 #if !V8_USE_31_BITS_SMI_VALUE |
1477 __ subl(ToRegister(left), | 1537 __ subl(ToRegister(left), |
1478 Immediate(ToInteger32(LConstantOperand::cast(right)))); | 1538 Immediate(ToInteger32(LConstantOperand::cast(right)))); |
| 1539 #else |
| 1540 __ subl(ToRegister(left), |
| 1541 Immediate(ToRepresentation(LConstantOperand::cast(right), |
| 1542 instr->hydrogen()->representation()))); |
| 1543 #endif |
1479 } else if (right->IsRegister()) { | 1544 } else if (right->IsRegister()) { |
1480 if (instr->hydrogen_value()->representation().IsSmi()) { | 1545 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1546 #if !V8_USE_31_BITS_SMI_VALUE |
1481 __ subq(ToRegister(left), ToRegister(right)); | 1547 __ subq(ToRegister(left), ToRegister(right)); |
| 1548 #else |
| 1549 __ subl(ToRegister(left), ToRegister(right)); |
| 1550 #endif |
1482 } else { | 1551 } else { |
1483 __ subl(ToRegister(left), ToRegister(right)); | 1552 __ subl(ToRegister(left), ToRegister(right)); |
1484 } | 1553 } |
1485 } else { | 1554 } else { |
1486 if (instr->hydrogen_value()->representation().IsSmi()) { | 1555 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1556 #if !V8_USE_31_BITS_SMI_VALUE |
1487 __ subq(ToRegister(left), ToOperand(right)); | 1557 __ subq(ToRegister(left), ToOperand(right)); |
| 1558 #else |
| 1559 __ subl(ToRegister(left), ToOperand(right)); |
| 1560 #endif |
1488 } else { | 1561 } else { |
1489 __ subl(ToRegister(left), ToOperand(right)); | 1562 __ subl(ToRegister(left), ToOperand(right)); |
1490 } | 1563 } |
1491 } | 1564 } |
1492 | 1565 |
1493 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1566 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
1494 DeoptimizeIf(overflow, instr->environment()); | 1567 DeoptimizeIf(overflow, instr->environment()); |
1495 } | 1568 } |
| 1569 |
| 1570 #if V8_USE_31_BITS_SMI_VALUE |
| 1571 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1572 __ movsxlq(ToRegister(left), ToRegister(left)); |
| 1573 } |
| 1574 #endif |
1496 } | 1575 } |
1497 | 1576 |
1498 | 1577 |
1499 void LCodeGen::DoConstantI(LConstantI* instr) { | 1578 void LCodeGen::DoConstantI(LConstantI* instr) { |
1500 __ Set(ToRegister(instr->result()), instr->value()); | 1579 __ Set(ToRegister(instr->result()), instr->value()); |
1501 } | 1580 } |
1502 | 1581 |
1503 | 1582 |
1504 void LCodeGen::DoConstantS(LConstantS* instr) { | 1583 void LCodeGen::DoConstantS(LConstantS* instr) { |
1505 __ Move(ToRegister(instr->result()), instr->value()); | 1584 __ Move(ToRegister(instr->result()), instr->value()); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 } | 1735 } |
1657 } | 1736 } |
1658 | 1737 |
1659 | 1738 |
1660 void LCodeGen::DoAddI(LAddI* instr) { | 1739 void LCodeGen::DoAddI(LAddI* instr) { |
1661 LOperand* left = instr->left(); | 1740 LOperand* left = instr->left(); |
1662 LOperand* right = instr->right(); | 1741 LOperand* right = instr->right(); |
1663 | 1742 |
1664 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { | 1743 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { |
1665 if (right->IsConstantOperand()) { | 1744 if (right->IsConstantOperand()) { |
| 1745 #if !V8_USE_31_BITS_SMI_VALUE |
1666 int32_t offset = ToInteger32(LConstantOperand::cast(right)); | 1746 int32_t offset = ToInteger32(LConstantOperand::cast(right)); |
1667 __ leal(ToRegister(instr->result()), | 1747 __ leal(ToRegister(instr->result()), |
1668 MemOperand(ToRegister(left), offset)); | 1748 MemOperand(ToRegister(left), offset)); |
| 1749 #else |
| 1750 int32_t offset = ToRepresentation(LConstantOperand::cast(right), |
| 1751 instr->hydrogen()->representation()); |
| 1752 if (instr->hydrogen()->representation().IsSmi()) { |
| 1753 __ lea(ToRegister(instr->result()), |
| 1754 MemOperand(ToRegister(left), offset)); |
| 1755 } else { |
| 1756 __ leal(ToRegister(instr->result()), |
| 1757 MemOperand(ToRegister(left), offset)); |
| 1758 } |
| 1759 #endif |
1669 } else { | 1760 } else { |
1670 Operand address(ToRegister(left), ToRegister(right), times_1, 0); | 1761 Operand address(ToRegister(left), ToRegister(right), times_1, 0); |
1671 if (instr->hydrogen()->representation().IsSmi()) { | 1762 if (instr->hydrogen()->representation().IsSmi()) { |
1672 __ lea(ToRegister(instr->result()), address); | 1763 __ lea(ToRegister(instr->result()), address); |
1673 } else { | 1764 } else { |
1674 __ leal(ToRegister(instr->result()), address); | 1765 __ leal(ToRegister(instr->result()), address); |
1675 } | 1766 } |
1676 } | 1767 } |
1677 } else { | 1768 } else { |
1678 if (right->IsConstantOperand()) { | 1769 if (right->IsConstantOperand()) { |
| 1770 #if !V8_USE_31_BITS_SMI_VALUE |
1679 __ addl(ToRegister(left), | 1771 __ addl(ToRegister(left), |
1680 Immediate(ToInteger32(LConstantOperand::cast(right)))); | 1772 Immediate(ToInteger32(LConstantOperand::cast(right)))); |
| 1773 #else |
| 1774 __ addl(ToRegister(left), |
| 1775 Immediate(ToRepresentation(LConstantOperand::cast(right), |
| 1776 instr->hydrogen()->representation()))); |
| 1777 #endif |
1681 } else if (right->IsRegister()) { | 1778 } else if (right->IsRegister()) { |
1682 if (instr->hydrogen_value()->representation().IsSmi()) { | 1779 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1780 #if !V8_USE_31_BITS_SMI_VALUE |
1683 __ addq(ToRegister(left), ToRegister(right)); | 1781 __ addq(ToRegister(left), ToRegister(right)); |
| 1782 #else |
| 1783 __ addl(ToRegister(left), ToRegister(right)); |
| 1784 #endif |
1684 } else { | 1785 } else { |
1685 __ addl(ToRegister(left), ToRegister(right)); | 1786 __ addl(ToRegister(left), ToRegister(right)); |
1686 } | 1787 } |
1687 } else { | 1788 } else { |
1688 if (instr->hydrogen_value()->representation().IsSmi()) { | 1789 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1790 #if !V8_USE_31_BITS_SMI_VALUE |
1689 __ addq(ToRegister(left), ToOperand(right)); | 1791 __ addq(ToRegister(left), ToOperand(right)); |
| 1792 #else |
| 1793 __ addl(ToRegister(left), ToOperand(right)); |
| 1794 #endif |
1690 } else { | 1795 } else { |
1691 __ addl(ToRegister(left), ToOperand(right)); | 1796 __ addl(ToRegister(left), ToOperand(right)); |
1692 } | 1797 } |
1693 } | 1798 } |
1694 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1799 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
1695 DeoptimizeIf(overflow, instr->environment()); | 1800 DeoptimizeIf(overflow, instr->environment()); |
1696 } | 1801 } |
| 1802 #if V8_USE_31_BITS_SMI_VALUE |
| 1803 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1804 __ movsxlq(ToRegister(left), ToRegister(left)); |
| 1805 } |
| 1806 #endif |
1697 } | 1807 } |
1698 } | 1808 } |
1699 | 1809 |
1700 | 1810 |
1701 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 1811 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
1702 LOperand* left = instr->left(); | 1812 LOperand* left = instr->left(); |
1703 LOperand* right = instr->right(); | 1813 LOperand* right = instr->right(); |
1704 ASSERT(left->Equals(instr->result())); | 1814 ASSERT(left->Equals(instr->result())); |
1705 HMathMinMax::Operation operation = instr->hydrogen()->operation(); | 1815 HMathMinMax::Operation operation = instr->hydrogen()->operation(); |
1706 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { | 1816 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { |
1707 Label return_left; | 1817 Label return_left; |
1708 Condition condition = (operation == HMathMinMax::kMathMin) | 1818 Condition condition = (operation == HMathMinMax::kMathMin) |
1709 ? less_equal | 1819 ? less_equal |
1710 : greater_equal; | 1820 : greater_equal; |
1711 Register left_reg = ToRegister(left); | 1821 Register left_reg = ToRegister(left); |
1712 if (right->IsConstantOperand()) { | 1822 if (right->IsConstantOperand()) { |
| 1823 #if !V8_USE_31_BITS_SMI_VALUE |
1713 Immediate right_imm = | 1824 Immediate right_imm = |
1714 Immediate(ToInteger32(LConstantOperand::cast(right))); | 1825 Immediate(ToInteger32(LConstantOperand::cast(right))); |
1715 ASSERT(!instr->hydrogen_value()->representation().IsSmi()); | 1826 ASSERT(!instr->hydrogen_value()->representation().IsSmi()); |
| 1827 #else |
| 1828 Immediate right_imm = |
| 1829 Immediate(ToRepresentation(LConstantOperand::cast(right), |
| 1830 instr->hydrogen()->representation())); |
| 1831 #endif |
1716 __ cmpl(left_reg, right_imm); | 1832 __ cmpl(left_reg, right_imm); |
1717 __ j(condition, &return_left, Label::kNear); | 1833 __ j(condition, &return_left, Label::kNear); |
1718 __ movq(left_reg, right_imm); | 1834 __ movq(left_reg, right_imm); |
1719 } else if (right->IsRegister()) { | 1835 } else if (right->IsRegister()) { |
1720 Register right_reg = ToRegister(right); | 1836 Register right_reg = ToRegister(right); |
1721 if (instr->hydrogen_value()->representation().IsSmi()) { | 1837 if (instr->hydrogen_value()->representation().IsSmi()) { |
1722 __ cmpq(left_reg, right_reg); | 1838 __ cmpq(left_reg, right_reg); |
1723 } else { | 1839 } else { |
1724 __ cmpl(left_reg, right_reg); | 1840 __ cmpl(left_reg, right_reg); |
1725 } | 1841 } |
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2903 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 3019 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
2904 ElementsKind elements_kind = instr->elements_kind(); | 3020 ElementsKind elements_kind = instr->elements_kind(); |
2905 LOperand* key = instr->key(); | 3021 LOperand* key = instr->key(); |
2906 if (!key->IsConstantOperand()) { | 3022 if (!key->IsConstantOperand()) { |
2907 Register key_reg = ToRegister(key); | 3023 Register key_reg = ToRegister(key); |
2908 // Even though the HLoad/StoreKeyed (in this case) instructions force | 3024 // Even though the HLoad/StoreKeyed (in this case) instructions force |
2909 // the input representation for the key to be an integer, the input | 3025 // the input representation for the key to be an integer, the input |
2910 // gets replaced during bound check elimination with the index argument | 3026 // gets replaced during bound check elimination with the index argument |
2911 // to the bounds check, which can be tagged, so that case must be | 3027 // to the bounds check, which can be tagged, so that case must be |
2912 // handled here, too. | 3028 // handled here, too. |
| 3029 #if !V8_USE_31_BITS_SMI_VALUE |
2913 if (instr->hydrogen()->IsDehoisted()) { | 3030 if (instr->hydrogen()->IsDehoisted()) { |
| 3031 #else |
| 3032 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 3033 __ SmiToInteger64(key_reg, key_reg); |
| 3034 } else if (instr->hydrogen()->IsDehoisted()) { |
| 3035 #endif |
2914 // Sign extend key because it could be a 32 bit negative value | 3036 // Sign extend key because it could be a 32 bit negative value |
2915 // and the dehoisted address computation happens in 64 bits | 3037 // and the dehoisted address computation happens in 64 bits |
2916 __ movsxlq(key_reg, key_reg); | 3038 __ movsxlq(key_reg, key_reg); |
2917 } | 3039 } |
2918 } | 3040 } |
2919 Operand operand(BuildFastArrayOperand( | 3041 Operand operand(BuildFastArrayOperand( |
2920 instr->elements(), | 3042 instr->elements(), |
2921 key, | 3043 key, |
2922 elements_kind, | 3044 elements_kind, |
2923 0, | 3045 0, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2974 | 3096 |
2975 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3097 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
2976 XMMRegister result(ToDoubleRegister(instr->result())); | 3098 XMMRegister result(ToDoubleRegister(instr->result())); |
2977 LOperand* key = instr->key(); | 3099 LOperand* key = instr->key(); |
2978 if (!key->IsConstantOperand()) { | 3100 if (!key->IsConstantOperand()) { |
2979 Register key_reg = ToRegister(key); | 3101 Register key_reg = ToRegister(key); |
2980 // Even though the HLoad/StoreKeyed instructions force the input | 3102 // Even though the HLoad/StoreKeyed instructions force the input |
2981 // representation for the key to be an integer, the input gets replaced | 3103 // representation for the key to be an integer, the input gets replaced |
2982 // during bound check elimination with the index argument to the bounds | 3104 // 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. | 3105 // check, which can be tagged, so that case must be handled here, too. |
| 3106 #if !V8_USE_31_BITS_SMI_VALUE |
2984 if (instr->hydrogen()->IsDehoisted()) { | 3107 if (instr->hydrogen()->IsDehoisted()) { |
| 3108 #else |
| 3109 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 3110 __ SmiToInteger64(key_reg, key_reg); |
| 3111 } else if (instr->hydrogen()->IsDehoisted()) { |
| 3112 #endif |
2985 // Sign extend key because it could be a 32 bit negative value | 3113 // Sign extend key because it could be a 32 bit negative value |
2986 // and the dehoisted address computation happens in 64 bits | 3114 // and the dehoisted address computation happens in 64 bits |
2987 __ movsxlq(key_reg, key_reg); | 3115 __ movsxlq(key_reg, key_reg); |
2988 } | 3116 } |
2989 } | 3117 } |
2990 | 3118 |
2991 if (instr->hydrogen()->RequiresHoleCheck()) { | 3119 if (instr->hydrogen()->RequiresHoleCheck()) { |
2992 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | 3120 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
2993 sizeof(kHoleNanLower32); | 3121 sizeof(kHoleNanLower32); |
2994 Operand hole_check_operand = BuildFastArrayOperand( | 3122 Operand hole_check_operand = BuildFastArrayOperand( |
(...skipping 19 matching lines...) Expand all Loading... |
3014 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3142 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
3015 Register result = ToRegister(instr->result()); | 3143 Register result = ToRegister(instr->result()); |
3016 LOperand* key = instr->key(); | 3144 LOperand* key = instr->key(); |
3017 if (!key->IsConstantOperand()) { | 3145 if (!key->IsConstantOperand()) { |
3018 Register key_reg = ToRegister(key); | 3146 Register key_reg = ToRegister(key); |
3019 // Even though the HLoad/StoreKeyedFastElement instructions force | 3147 // Even though the HLoad/StoreKeyedFastElement instructions force |
3020 // the input representation for the key to be an integer, the input | 3148 // the input representation for the key to be an integer, the input |
3021 // gets replaced during bound check elimination with the index | 3149 // gets replaced during bound check elimination with the index |
3022 // argument to the bounds check, which can be tagged, so that | 3150 // argument to the bounds check, which can be tagged, so that |
3023 // case must be handled here, too. | 3151 // case must be handled here, too. |
| 3152 #if !V8_USE_31_BITS_SMI_VALUE |
3024 if (instr->hydrogen()->IsDehoisted()) { | 3153 if (instr->hydrogen()->IsDehoisted()) { |
| 3154 #else |
| 3155 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 3156 __ SmiToInteger64(key_reg, key_reg); |
| 3157 } else if (instr->hydrogen()->IsDehoisted()) { |
| 3158 #endif |
3025 // Sign extend key because it could be a 32 bit negative value | 3159 // Sign extend key because it could be a 32 bit negative value |
3026 // and the dehoisted address computation happens in 64 bits | 3160 // and the dehoisted address computation happens in 64 bits |
3027 __ movsxlq(key_reg, key_reg); | 3161 __ movsxlq(key_reg, key_reg); |
3028 } | 3162 } |
3029 } | 3163 } |
3030 | 3164 |
3031 // Load the result. | 3165 // Load the result. |
3032 __ movq(result, | 3166 __ movq(result, |
3033 BuildFastArrayOperand(instr->elements(), | 3167 BuildFastArrayOperand(instr->elements(), |
3034 key, | 3168 key, |
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4090 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4224 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
4091 ElementsKind elements_kind = instr->elements_kind(); | 4225 ElementsKind elements_kind = instr->elements_kind(); |
4092 LOperand* key = instr->key(); | 4226 LOperand* key = instr->key(); |
4093 if (!key->IsConstantOperand()) { | 4227 if (!key->IsConstantOperand()) { |
4094 Register key_reg = ToRegister(key); | 4228 Register key_reg = ToRegister(key); |
4095 // Even though the HLoad/StoreKeyedFastElement instructions force | 4229 // Even though the HLoad/StoreKeyedFastElement instructions force |
4096 // the input representation for the key to be an integer, the input | 4230 // the input representation for the key to be an integer, the input |
4097 // gets replaced during bound check elimination with the index | 4231 // gets replaced during bound check elimination with the index |
4098 // argument to the bounds check, which can be tagged, so that case | 4232 // argument to the bounds check, which can be tagged, so that case |
4099 // must be handled here, too. | 4233 // must be handled here, too. |
| 4234 #if !V8_USE_31_BITS_SMI_VALUE |
4100 if (instr->hydrogen()->IsDehoisted()) { | 4235 if (instr->hydrogen()->IsDehoisted()) { |
| 4236 #else |
| 4237 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 4238 __ SmiToInteger64(key_reg, key_reg); |
| 4239 } else if (instr->hydrogen()->IsDehoisted()) { |
| 4240 #endif |
4101 // Sign extend key because it could be a 32 bit negative value | 4241 // Sign extend key because it could be a 32 bit negative value |
4102 // and the dehoisted address computation happens in 64 bits | 4242 // and the dehoisted address computation happens in 64 bits |
4103 __ movsxlq(key_reg, key_reg); | 4243 __ movsxlq(key_reg, key_reg); |
4104 } | 4244 } |
4105 } | 4245 } |
4106 Operand operand(BuildFastArrayOperand( | 4246 Operand operand(BuildFastArrayOperand( |
4107 instr->elements(), | 4247 instr->elements(), |
4108 key, | 4248 key, |
4109 elements_kind, | 4249 elements_kind, |
4110 0, | 4250 0, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4152 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4292 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
4153 XMMRegister value = ToDoubleRegister(instr->value()); | 4293 XMMRegister value = ToDoubleRegister(instr->value()); |
4154 LOperand* key = instr->key(); | 4294 LOperand* key = instr->key(); |
4155 if (!key->IsConstantOperand()) { | 4295 if (!key->IsConstantOperand()) { |
4156 Register key_reg = ToRegister(key); | 4296 Register key_reg = ToRegister(key); |
4157 // Even though the HLoad/StoreKeyedFastElement instructions force | 4297 // Even though the HLoad/StoreKeyedFastElement instructions force |
4158 // the input representation for the key to be an integer, the | 4298 // the input representation for the key to be an integer, the |
4159 // input gets replaced during bound check elimination with the index | 4299 // input gets replaced during bound check elimination with the index |
4160 // argument to the bounds check, which can be tagged, so that case | 4300 // argument to the bounds check, which can be tagged, so that case |
4161 // must be handled here, too. | 4301 // must be handled here, too. |
| 4302 #if !V8_USE_31_BITS_SMI_VALUE |
4162 if (instr->hydrogen()->IsDehoisted()) { | 4303 if (instr->hydrogen()->IsDehoisted()) { |
| 4304 #else |
| 4305 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 4306 __ SmiToInteger64(key_reg, key_reg); |
| 4307 } else if (instr->hydrogen()->IsDehoisted()) { |
| 4308 #endif |
4163 // Sign extend key because it could be a 32 bit negative value | 4309 // Sign extend key because it could be a 32 bit negative value |
4164 // and the dehoisted address computation happens in 64 bits | 4310 // and the dehoisted address computation happens in 64 bits |
4165 __ movsxlq(key_reg, key_reg); | 4311 __ movsxlq(key_reg, key_reg); |
4166 } | 4312 } |
4167 } | 4313 } |
4168 | 4314 |
4169 if (instr->NeedsCanonicalization()) { | 4315 if (instr->NeedsCanonicalization()) { |
4170 Label have_value; | 4316 Label have_value; |
4171 | 4317 |
4172 __ ucomisd(value, value); | 4318 __ ucomisd(value, value); |
(...skipping 20 matching lines...) Expand all Loading... |
4193 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4339 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
4194 Register elements = ToRegister(instr->elements()); | 4340 Register elements = ToRegister(instr->elements()); |
4195 LOperand* key = instr->key(); | 4341 LOperand* key = instr->key(); |
4196 if (!key->IsConstantOperand()) { | 4342 if (!key->IsConstantOperand()) { |
4197 Register key_reg = ToRegister(key); | 4343 Register key_reg = ToRegister(key); |
4198 // Even though the HLoad/StoreKeyedFastElement instructions force | 4344 // Even though the HLoad/StoreKeyedFastElement instructions force |
4199 // the input representation for the key to be an integer, the | 4345 // the input representation for the key to be an integer, the |
4200 // input gets replaced during bound check elimination with the index | 4346 // input gets replaced during bound check elimination with the index |
4201 // argument to the bounds check, which can be tagged, so that case | 4347 // argument to the bounds check, which can be tagged, so that case |
4202 // must be handled here, too. | 4348 // must be handled here, too. |
| 4349 #if !V8_USE_31_BITS_SMI_VALUE |
4203 if (instr->hydrogen()->IsDehoisted()) { | 4350 if (instr->hydrogen()->IsDehoisted()) { |
| 4351 #else |
| 4352 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 4353 __ SmiToInteger64(key_reg, key_reg); |
| 4354 } else if (instr->hydrogen()->IsDehoisted()) { |
| 4355 #endif |
4204 // Sign extend key because it could be a 32 bit negative value | 4356 // Sign extend key because it could be a 32 bit negative value |
4205 // and the dehoisted address computation happens in 64 bits | 4357 // and the dehoisted address computation happens in 64 bits |
4206 __ movsxlq(key_reg, key_reg); | 4358 __ movsxlq(key_reg, key_reg); |
4207 } | 4359 } |
4208 } | 4360 } |
4209 | 4361 |
4210 Operand operand = | 4362 Operand operand = |
4211 BuildFastArrayOperand(instr->elements(), | 4363 BuildFastArrayOperand(instr->elements(), |
4212 key, | 4364 key, |
4213 FAST_ELEMENTS, | 4365 FAST_ELEMENTS, |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4479 LOperand* output = instr->result(); | 4631 LOperand* output = instr->result(); |
4480 LOperand* temp = instr->temp(); | 4632 LOperand* temp = instr->temp(); |
4481 | 4633 |
4482 __ LoadUint32(ToDoubleRegister(output), | 4634 __ LoadUint32(ToDoubleRegister(output), |
4483 ToRegister(input), | 4635 ToRegister(input), |
4484 ToDoubleRegister(temp)); | 4636 ToDoubleRegister(temp)); |
4485 } | 4637 } |
4486 | 4638 |
4487 | 4639 |
4488 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4640 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
| 4641 #if !V8_USE_31_BITS_SMI_VALUE |
4489 LOperand* input = instr->value(); | 4642 LOperand* input = instr->value(); |
4490 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 4643 ASSERT(input->IsRegister() && input->Equals(instr->result())); |
4491 Register reg = ToRegister(input); | 4644 Register reg = ToRegister(input); |
4492 | 4645 |
4493 __ Integer32ToSmi(reg, reg); | 4646 __ Integer32ToSmi(reg, reg); |
| 4647 #else |
| 4648 class DeferredNumberTagI: public LDeferredCode { |
| 4649 public: |
| 4650 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) |
| 4651 : LDeferredCode(codegen), instr_(instr) { } |
| 4652 virtual void Generate() { |
| 4653 codegen()->DoDeferredNumberTagI(instr_); |
| 4654 } |
| 4655 virtual LInstruction* instr() { return instr_; } |
| 4656 private: |
| 4657 LNumberTagI* instr_; |
| 4658 }; |
| 4659 |
| 4660 LOperand* input = instr->value(); |
| 4661 ASSERT(input->IsRegister() && input->Equals(instr->result())); |
| 4662 Register reg = ToRegister(input); |
| 4663 |
| 4664 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); |
| 4665 __ shll(reg, Immediate(kSmiTagSize + kSmiShiftSize)); |
| 4666 __ j(overflow, deferred->entry()); |
| 4667 __ movsxlq(reg, reg); |
| 4668 __ bind(deferred->exit()); |
| 4669 #endif |
4494 } | 4670 } |
4495 | 4671 |
4496 | 4672 |
| 4673 #if V8_USE_31_BITS_SMI_VALUE |
| 4674 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { |
| 4675 Label slow; |
| 4676 Register reg = ToRegister(instr->value()); |
| 4677 Register tmp = reg.is(rax) ? kScratchRegister : rax; |
| 4678 |
| 4679 // Preserve the value of all registers. |
| 4680 PushSafepointRegistersScope scope(this); |
| 4681 |
| 4682 Label done; |
| 4683 // There was overflow, so bits 30 and 31 of the original integer |
| 4684 // disagree. Try to allocate a heap number in new space and store |
| 4685 // the value in there. If that fails, call the runtime system. |
| 4686 __ SmiToInteger32(reg, reg); |
| 4687 __ xorl(reg, Immediate(0x80000000)); |
| 4688 __ cvtlsi2sd(xmm1, reg); |
| 4689 |
| 4690 if (FLAG_inline_new) { |
| 4691 __ AllocateHeapNumber(reg, tmp, &slow); |
| 4692 __ jmp(&done, Label::kNear); |
| 4693 } |
| 4694 |
| 4695 // Slow case: Call the runtime system to do the number allocation. |
| 4696 __ bind(&slow); |
| 4697 |
| 4698 // Put a valid pointer value in the stack slot where the result |
| 4699 // register is stored, as this register is in the pointer map, but contains an |
| 4700 // integer value. |
| 4701 __ StoreToSafepointRegisterSlot(reg, Immediate(0)); |
| 4702 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
| 4703 // Set the pointer to the new heap number in tmp. |
| 4704 if (!reg.is(rax)) __ movq(reg, rax); |
| 4705 |
| 4706 // Heap number allocated. Put the value in xmm0 into the value of the |
| 4707 // allocated heap number. |
| 4708 __ bind(&done); |
| 4709 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm1); |
| 4710 __ StoreToSafepointRegisterSlot(reg, reg); |
| 4711 } |
| 4712 #endif |
| 4713 |
| 4714 |
4497 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { | 4715 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { |
4498 class DeferredNumberTagU: public LDeferredCode { | 4716 class DeferredNumberTagU: public LDeferredCode { |
4499 public: | 4717 public: |
4500 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) | 4718 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) |
4501 : LDeferredCode(codegen), instr_(instr) { } | 4719 : LDeferredCode(codegen), instr_(instr) { } |
4502 virtual void Generate() { | 4720 virtual void Generate() { |
4503 codegen()->DoDeferredNumberTagU(instr_); | 4721 codegen()->DoDeferredNumberTagU(instr_); |
4504 } | 4722 } |
4505 virtual LInstruction* instr() { return instr_; } | 4723 virtual LInstruction* instr() { return instr_; } |
4506 private: | 4724 private: |
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5559 FixedArray::kHeaderSize - kPointerSize)); | 5777 FixedArray::kHeaderSize - kPointerSize)); |
5560 __ bind(&done); | 5778 __ bind(&done); |
5561 } | 5779 } |
5562 | 5780 |
5563 | 5781 |
5564 #undef __ | 5782 #undef __ |
5565 | 5783 |
5566 } } // namespace v8::internal | 5784 } } // namespace v8::internal |
5567 | 5785 |
5568 #endif // V8_TARGET_ARCH_X64 | 5786 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |