Chromium Code Reviews| 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 |