| 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 |