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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 codegen_->RecordSafepoint(pointers_, deopt_mode_); | 57 codegen_->RecordSafepoint(pointers_, deopt_mode_); |
| 58 } | 58 } |
| 59 | 59 |
| 60 private: | 60 private: |
| 61 LCodeGen* codegen_; | 61 LCodeGen* codegen_; |
| 62 LPointerMap* pointers_; | 62 LPointerMap* pointers_; |
| 63 Safepoint::DeoptMode deopt_mode_; | 63 Safepoint::DeoptMode deopt_mode_; |
| 64 }; | 64 }; |
| 65 | 65 |
| 66 | 66 |
| 67 class LSmiFunctionInvoker : public MacroAssembler::SmiFunctionInvoker { | |
| 68 public: | |
| 69 LSmiFunctionInvoker(LCodeGen* codegen, | |
| 70 LEnvironment* environment, | |
| 71 bool check_minus_zero) | |
| 72 : MacroAssembler::SmiFunctionInvoker(NULL), | |
| 73 codegen_(codegen), | |
| 74 environment_(environment), | |
| 75 check_minus_zero_(check_minus_zero) { } | |
| 76 virtual ~LSmiFunctionInvoker() { } | |
| 77 virtual void Bailout() { | |
| 78 codegen_->DeoptimizeIf(no_condition, environment_); | |
| 79 } | |
| 80 virtual Label* on_not_smi_result() { return NULL; } | |
| 81 virtual bool reserve_source_operands() { return false; } | |
| 82 virtual bool check_minus_zero() { return check_minus_zero_; } | |
| 83 | |
| 84 private: | |
| 85 LCodeGen* codegen_; | |
| 86 LEnvironment* environment_; | |
| 87 bool check_minus_zero_; | |
| 88 }; | |
| 89 | |
| 90 | |
| 67 #define __ masm()-> | 91 #define __ masm()-> |
| 68 | 92 |
| 69 bool LCodeGen::GenerateCode() { | 93 bool LCodeGen::GenerateCode() { |
| 70 LPhase phase("Z_Code generation", chunk()); | 94 LPhase phase("Z_Code generation", chunk()); |
| 71 ASSERT(is_unused()); | 95 ASSERT(is_unused()); |
| 72 status_ = GENERATING; | 96 status_ = GENERATING; |
| 73 | 97 |
| 74 // Open a frame scope to indicate that there is a frame on the stack. The | 98 // Open a frame scope to indicate that there is a frame on the stack. The |
| 75 // MANUAL indicates that the scope shouldn't actually generate code to set up | 99 // MANUAL indicates that the scope shouldn't actually generate code to set up |
| 76 // the frame (that is done in GeneratePrologue). | 100 // the frame (that is done in GeneratePrologue). |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 } | 433 } |
| 410 | 434 |
| 411 | 435 |
| 412 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { | 436 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { |
| 413 return op->IsConstantOperand() && | 437 return op->IsConstantOperand() && |
| 414 chunk_->LookupLiteralRepresentation(op).IsTagged(); | 438 chunk_->LookupLiteralRepresentation(op).IsTagged(); |
| 415 } | 439 } |
| 416 | 440 |
| 417 | 441 |
| 418 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { | 442 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { |
| 419 HConstant* constant = chunk_->LookupConstant(op); | 443 return ToRepresentation(op, Representation::Integer32()); |
| 420 return constant->Integer32Value(); | |
| 421 } | 444 } |
| 422 | 445 |
| 423 | 446 |
| 447 int32_t LCodeGen::ToRepresentation(LConstantOperand* op, | |
| 448 const Representation& r) const { | |
| 449 HConstant* constant = chunk_->LookupConstant(op); | |
| 450 int32_t value = constant->Integer32Value(); | |
| 451 if (r.IsInteger32()) return value; | |
| 452 ASSERT(r.IsSmiOrTagged()); | |
| 453 return static_cast<int32_t>(reinterpret_cast<intptr_t>(Smi::FromInt(value))); | |
| 454 } | |
| 455 | |
| 456 | |
| 424 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { | 457 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { |
| 425 HConstant* constant = chunk_->LookupConstant(op); | 458 HConstant* constant = chunk_->LookupConstant(op); |
| 426 return Smi::FromInt(constant->Integer32Value()); | 459 return Smi::FromInt(constant->Integer32Value()); |
| 427 } | 460 } |
| 428 | 461 |
| 429 | 462 |
| 430 double LCodeGen::ToDouble(LConstantOperand* op) const { | 463 double LCodeGen::ToDouble(LConstantOperand* op) const { |
| 431 HConstant* constant = chunk_->LookupConstant(op); | 464 HConstant* constant = chunk_->LookupConstant(op); |
| 432 ASSERT(constant->HasDoubleValue()); | 465 ASSERT(constant->HasDoubleValue()); |
| 433 return constant->DoubleValue(); | 466 return constant->DoubleValue(); |
| (...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1355 } | 1388 } |
| 1356 | 1389 |
| 1357 | 1390 |
| 1358 void LCodeGen::DoBitI(LBitI* instr) { | 1391 void LCodeGen::DoBitI(LBitI* instr) { |
| 1359 LOperand* left = instr->left(); | 1392 LOperand* left = instr->left(); |
| 1360 LOperand* right = instr->right(); | 1393 LOperand* right = instr->right(); |
| 1361 ASSERT(left->Equals(instr->result())); | 1394 ASSERT(left->Equals(instr->result())); |
| 1362 ASSERT(left->IsRegister()); | 1395 ASSERT(left->IsRegister()); |
| 1363 | 1396 |
| 1364 if (right->IsConstantOperand()) { | 1397 if (right->IsConstantOperand()) { |
| 1365 int right_operand = ToInteger32(LConstantOperand::cast(right)); | 1398 int right_operand = ToRepresentation(LConstantOperand::cast(right), |
| 1399 instr->hydrogen()->representation()); | |
| 1366 switch (instr->op()) { | 1400 switch (instr->op()) { |
| 1367 case Token::BIT_AND: | 1401 case Token::BIT_AND: |
| 1368 __ andl(ToRegister(left), Immediate(right_operand)); | 1402 if (instr->hydrogen()->representation().IsSmi()) { |
|
danno
2013/08/07 18:41:26
Is this really correct (here and below)? The non-s
haitao.feng
2013/08/12 09:54:24
It is really correct. This code utilizes a hardwar
| |
| 1403 __ and_(ToRegister(left), Immediate(right_operand)); | |
| 1404 } else { | |
| 1405 __ andl(ToRegister(left), Immediate(right_operand)); | |
| 1406 } | |
| 1369 break; | 1407 break; |
| 1370 case Token::BIT_OR: | 1408 case Token::BIT_OR: |
| 1371 __ orl(ToRegister(left), Immediate(right_operand)); | 1409 if (instr->hydrogen()->representation().IsSmi()) { |
| 1410 __ or_(ToRegister(left), Immediate(right_operand)); | |
|
danno
2013/08/07 18:41:26
Same here.
haitao.feng
2013/08/12 09:54:24
Explained above.
| |
| 1411 } else { | |
| 1412 __ orl(ToRegister(left), Immediate(right_operand)); | |
| 1413 } | |
| 1372 break; | 1414 break; |
| 1373 case Token::BIT_XOR: | 1415 case Token::BIT_XOR: |
| 1374 __ xorl(ToRegister(left), Immediate(right_operand)); | 1416 if (instr->hydrogen()->representation().IsSmi()) { |
|
danno
2013/08/07 18:41:26
Same here.
haitao.feng
2013/08/12 09:54:24
Explained above.
| |
| 1417 __ xor_(ToRegister(left), Immediate(right_operand)); | |
| 1418 } else { | |
| 1419 __ xorl(ToRegister(left), Immediate(right_operand)); | |
| 1420 } | |
| 1375 break; | 1421 break; |
| 1376 default: | 1422 default: |
| 1377 UNREACHABLE(); | 1423 UNREACHABLE(); |
| 1378 break; | 1424 break; |
| 1379 } | 1425 } |
| 1380 } else if (right->IsStackSlot()) { | 1426 } else if (right->IsStackSlot()) { |
| 1381 switch (instr->op()) { | 1427 switch (instr->op()) { |
| 1382 case Token::BIT_AND: | 1428 case Token::BIT_AND: |
| 1383 __ and_(ToRegister(left), ToOperand(right)); | 1429 __ and_(ToRegister(left), ToOperand(right)); |
| 1384 break; | 1430 break; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1459 if (shift_count == 0 && instr->can_deopt()) { | 1505 if (shift_count == 0 && instr->can_deopt()) { |
| 1460 __ testl(ToRegister(left), ToRegister(left)); | 1506 __ testl(ToRegister(left), ToRegister(left)); |
| 1461 DeoptimizeIf(negative, instr->environment()); | 1507 DeoptimizeIf(negative, instr->environment()); |
| 1462 } else { | 1508 } else { |
| 1463 __ shrl(ToRegister(left), Immediate(shift_count)); | 1509 __ shrl(ToRegister(left), Immediate(shift_count)); |
| 1464 } | 1510 } |
| 1465 break; | 1511 break; |
| 1466 case Token::SHL: | 1512 case Token::SHL: |
| 1467 if (shift_count != 0) { | 1513 if (shift_count != 0) { |
| 1468 if (instr->hydrogen_value()->representation().IsSmi()) { | 1514 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1469 __ shl(ToRegister(left), Immediate(shift_count)); | 1515 if (kSmiValueSize == 32 || !instr->can_deopt()) { |
| 1516 __ shl(ToRegister(left), Immediate(shift_count)); | |
| 1517 } else { | |
| 1518 ASSERT(kSmiValueSize == 31 && instr->can_deopt()); | |
| 1519 LSmiFunctionInvoker invoker(this, instr->environment(), false); | |
| 1520 __ SmiShiftLeftConstant(ToRegister(left), ToRegister(left), | |
| 1521 shift_count, invoker); | |
| 1522 } | |
| 1470 } else { | 1523 } else { |
| 1471 __ shll(ToRegister(left), Immediate(shift_count)); | 1524 __ shll(ToRegister(left), Immediate(shift_count)); |
| 1472 } | 1525 } |
| 1473 } | 1526 } |
| 1474 break; | 1527 break; |
| 1475 default: | 1528 default: |
| 1476 UNREACHABLE(); | 1529 UNREACHABLE(); |
| 1477 break; | 1530 break; |
| 1478 } | 1531 } |
| 1479 } | 1532 } |
| 1480 } | 1533 } |
| 1481 | 1534 |
| 1482 | 1535 |
| 1483 void LCodeGen::DoSubI(LSubI* instr) { | 1536 void LCodeGen::DoSubI(LSubI* instr) { |
| 1484 LOperand* left = instr->left(); | 1537 LOperand* left = instr->left(); |
| 1485 LOperand* right = instr->right(); | 1538 LOperand* right = instr->right(); |
| 1486 ASSERT(left->Equals(instr->result())); | 1539 ASSERT(left->Equals(instr->result())); |
| 1487 | 1540 |
| 1488 if (right->IsConstantOperand()) { | 1541 if (right->IsConstantOperand()) { |
| 1489 __ subl(ToRegister(left), | 1542 __ subl(ToRegister(left), |
| 1490 Immediate(ToInteger32(LConstantOperand::cast(right)))); | 1543 Immediate(ToRepresentation(LConstantOperand::cast(right), |
| 1544 instr->hydrogen()->representation()))); | |
| 1491 } else if (right->IsRegister()) { | 1545 } else if (right->IsRegister()) { |
| 1492 if (instr->hydrogen_value()->representation().IsSmi()) { | 1546 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1493 __ subq(ToRegister(left), ToRegister(right)); | 1547 if (kSmiValueSize == 32) { |
| 1548 __ subq(ToRegister(left), ToRegister(right)); | |
| 1549 } else { | |
| 1550 ASSERT(kSmiValueSize == 31); | |
| 1551 __ subl(ToRegister(left), ToRegister(right)); | |
| 1552 } | |
| 1494 } else { | 1553 } else { |
| 1495 __ subl(ToRegister(left), ToRegister(right)); | 1554 __ subl(ToRegister(left), ToRegister(right)); |
| 1496 } | 1555 } |
| 1497 } else { | 1556 } else { |
| 1498 if (instr->hydrogen_value()->representation().IsSmi()) { | 1557 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1499 __ subq(ToRegister(left), ToOperand(right)); | 1558 if (kSmiValueSize == 32) { |
| 1559 __ subq(ToRegister(left), ToOperand(right)); | |
| 1560 } else { | |
| 1561 ASSERT(kSmiValueSize == 31); | |
| 1562 __ subl(ToRegister(left), ToOperand(right)); | |
| 1563 } | |
| 1500 } else { | 1564 } else { |
| 1501 __ subl(ToRegister(left), ToOperand(right)); | 1565 __ subl(ToRegister(left), ToOperand(right)); |
| 1502 } | 1566 } |
| 1503 } | 1567 } |
| 1504 | 1568 |
| 1505 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1569 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 1506 DeoptimizeIf(overflow, instr->environment()); | 1570 DeoptimizeIf(overflow, instr->environment()); |
| 1507 } | 1571 } |
| 1572 | |
| 1573 if (kSmiValueSize == 31 && | |
| 1574 instr->hydrogen_value()->representation().IsSmi()) { | |
| 1575 __ movsxlq(ToRegister(left), ToRegister(left)); | |
| 1576 } | |
| 1508 } | 1577 } |
| 1509 | 1578 |
| 1510 | 1579 |
| 1511 void LCodeGen::DoConstantI(LConstantI* instr) { | 1580 void LCodeGen::DoConstantI(LConstantI* instr) { |
| 1512 __ Set(ToRegister(instr->result()), instr->value()); | 1581 __ Set(ToRegister(instr->result()), instr->value()); |
| 1513 } | 1582 } |
| 1514 | 1583 |
| 1515 | 1584 |
| 1516 void LCodeGen::DoConstantS(LConstantS* instr) { | 1585 void LCodeGen::DoConstantS(LConstantS* instr) { |
| 1517 __ Move(ToRegister(instr->result()), instr->value()); | 1586 __ Move(ToRegister(instr->result()), instr->value()); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1673 } | 1742 } |
| 1674 } | 1743 } |
| 1675 | 1744 |
| 1676 | 1745 |
| 1677 void LCodeGen::DoAddI(LAddI* instr) { | 1746 void LCodeGen::DoAddI(LAddI* instr) { |
| 1678 LOperand* left = instr->left(); | 1747 LOperand* left = instr->left(); |
| 1679 LOperand* right = instr->right(); | 1748 LOperand* right = instr->right(); |
| 1680 | 1749 |
| 1681 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { | 1750 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { |
| 1682 if (right->IsConstantOperand()) { | 1751 if (right->IsConstantOperand()) { |
| 1683 int32_t offset = ToInteger32(LConstantOperand::cast(right)); | 1752 int32_t offset = ToRepresentation(LConstantOperand::cast(right), |
| 1684 __ leal(ToRegister(instr->result()), | 1753 instr->hydrogen()->representation()); |
| 1685 MemOperand(ToRegister(left), offset)); | 1754 if (instr->hydrogen()->representation().IsSmi()) { |
| 1755 __ lea(ToRegister(instr->result()), | |
|
danno
2013/08/07 18:41:26
Here and below, I think all Smi operations should
haitao.feng
2013/08/12 09:54:24
Done.
| |
| 1756 MemOperand(ToRegister(left), offset)); | |
| 1757 } else { | |
| 1758 __ leal(ToRegister(instr->result()), | |
| 1759 MemOperand(ToRegister(left), offset)); | |
| 1760 } | |
| 1686 } else { | 1761 } else { |
| 1687 Operand address(ToRegister(left), ToRegister(right), times_1, 0); | 1762 Operand address(ToRegister(left), ToRegister(right), times_1, 0); |
| 1688 if (instr->hydrogen()->representation().IsSmi()) { | 1763 if (instr->hydrogen()->representation().IsSmi()) { |
| 1689 __ lea(ToRegister(instr->result()), address); | 1764 __ lea(ToRegister(instr->result()), address); |
| 1690 } else { | 1765 } else { |
| 1691 __ leal(ToRegister(instr->result()), address); | 1766 __ leal(ToRegister(instr->result()), address); |
| 1692 } | 1767 } |
| 1693 } | 1768 } |
| 1694 } else { | 1769 } else { |
| 1695 if (right->IsConstantOperand()) { | 1770 if (right->IsConstantOperand()) { |
| 1696 __ addl(ToRegister(left), | 1771 __ addl(ToRegister(left), |
| 1697 Immediate(ToInteger32(LConstantOperand::cast(right)))); | 1772 Immediate(ToRepresentation(LConstantOperand::cast(right), |
| 1773 instr->hydrogen()->representation()))); | |
| 1698 } else if (right->IsRegister()) { | 1774 } else if (right->IsRegister()) { |
| 1699 if (instr->hydrogen_value()->representation().IsSmi()) { | 1775 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1700 __ addq(ToRegister(left), ToRegister(right)); | 1776 if (kSmiValueSize == 32) { |
| 1777 __ addq(ToRegister(left), ToRegister(right)); | |
| 1778 } else { | |
| 1779 ASSERT(kSmiValueSize == 31); | |
| 1780 __ addl(ToRegister(left), ToRegister(right)); | |
| 1781 } | |
| 1701 } else { | 1782 } else { |
| 1702 __ addl(ToRegister(left), ToRegister(right)); | 1783 __ addl(ToRegister(left), ToRegister(right)); |
| 1703 } | 1784 } |
| 1704 } else { | 1785 } else { |
| 1705 if (instr->hydrogen_value()->representation().IsSmi()) { | 1786 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1706 __ addq(ToRegister(left), ToOperand(right)); | 1787 if (kSmiValueSize == 32) { |
| 1788 __ addq(ToRegister(left), ToOperand(right)); | |
| 1789 } else { | |
| 1790 ASSERT(kSmiValueSize == 31); | |
| 1791 __ addl(ToRegister(left), ToOperand(right)); | |
| 1792 } | |
| 1707 } else { | 1793 } else { |
| 1708 __ addl(ToRegister(left), ToOperand(right)); | 1794 __ addl(ToRegister(left), ToOperand(right)); |
| 1709 } | 1795 } |
| 1710 } | 1796 } |
| 1711 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1797 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 1712 DeoptimizeIf(overflow, instr->environment()); | 1798 DeoptimizeIf(overflow, instr->environment()); |
| 1713 } | 1799 } |
| 1800 | |
| 1801 if (kSmiValueSize == 31 && | |
| 1802 instr->hydrogen_value()->representation().IsSmi()) { | |
| 1803 __ movsxlq(ToRegister(left), ToRegister(left)); | |
| 1804 } | |
| 1714 } | 1805 } |
| 1715 } | 1806 } |
| 1716 | 1807 |
| 1717 | 1808 |
| 1718 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 1809 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
| 1719 LOperand* left = instr->left(); | 1810 LOperand* left = instr->left(); |
| 1720 LOperand* right = instr->right(); | 1811 LOperand* right = instr->right(); |
| 1721 ASSERT(left->Equals(instr->result())); | 1812 ASSERT(left->Equals(instr->result())); |
| 1722 HMathMinMax::Operation operation = instr->hydrogen()->operation(); | 1813 HMathMinMax::Operation operation = instr->hydrogen()->operation(); |
| 1723 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { | 1814 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { |
| 1724 Label return_left; | 1815 Label return_left; |
| 1725 Condition condition = (operation == HMathMinMax::kMathMin) | 1816 Condition condition = (operation == HMathMinMax::kMathMin) |
| 1726 ? less_equal | 1817 ? less_equal |
| 1727 : greater_equal; | 1818 : greater_equal; |
| 1728 Register left_reg = ToRegister(left); | 1819 Register left_reg = ToRegister(left); |
| 1729 if (right->IsConstantOperand()) { | 1820 if (right->IsConstantOperand()) { |
| 1730 Immediate right_imm = | 1821 Immediate right_imm = |
| 1731 Immediate(ToInteger32(LConstantOperand::cast(right))); | 1822 Immediate(ToRepresentation(LConstantOperand::cast(right), |
| 1732 ASSERT(!instr->hydrogen_value()->representation().IsSmi()); | 1823 instr->hydrogen()->representation())); |
| 1733 __ cmpl(left_reg, right_imm); | 1824 __ cmpl(left_reg, right_imm); |
| 1734 __ j(condition, &return_left, Label::kNear); | 1825 __ j(condition, &return_left, Label::kNear); |
| 1735 __ movq(left_reg, right_imm); | 1826 __ movq(left_reg, right_imm); |
| 1736 } else if (right->IsRegister()) { | 1827 } else if (right->IsRegister()) { |
| 1737 Register right_reg = ToRegister(right); | 1828 Register right_reg = ToRegister(right); |
| 1738 if (instr->hydrogen_value()->representation().IsSmi()) { | 1829 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1739 __ cmpq(left_reg, right_reg); | 1830 __ cmpq(left_reg, right_reg); |
| 1740 } else { | 1831 } else { |
| 1741 __ cmpl(left_reg, right_reg); | 1832 __ cmpl(left_reg, right_reg); |
| 1742 } | 1833 } |
| (...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2920 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 3011 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
| 2921 ElementsKind elements_kind = instr->elements_kind(); | 3012 ElementsKind elements_kind = instr->elements_kind(); |
| 2922 LOperand* key = instr->key(); | 3013 LOperand* key = instr->key(); |
| 2923 if (!key->IsConstantOperand()) { | 3014 if (!key->IsConstantOperand()) { |
| 2924 Register key_reg = ToRegister(key); | 3015 Register key_reg = ToRegister(key); |
| 2925 // Even though the HLoad/StoreKeyed (in this case) instructions force | 3016 // Even though the HLoad/StoreKeyed (in this case) instructions force |
| 2926 // the input representation for the key to be an integer, the input | 3017 // the input representation for the key to be an integer, the input |
| 2927 // gets replaced during bound check elimination with the index argument | 3018 // gets replaced during bound check elimination with the index argument |
| 2928 // to the bounds check, which can be tagged, so that case must be | 3019 // to the bounds check, which can be tagged, so that case must be |
| 2929 // handled here, too. | 3020 // handled here, too. |
| 2930 if (instr->hydrogen()->IsDehoisted()) { | 3021 if (kSmiValueSize == 31 && |
| 3022 instr->hydrogen()->key()->representation().IsSmi()) { | |
| 3023 __ SmiToInteger64(key_reg, key_reg); | |
| 3024 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 2931 // Sign extend key because it could be a 32 bit negative value | 3025 // Sign extend key because it could be a 32 bit negative value |
| 2932 // and the dehoisted address computation happens in 64 bits | 3026 // and the dehoisted address computation happens in 64 bits |
| 2933 __ movsxlq(key_reg, key_reg); | 3027 __ movsxlq(key_reg, key_reg); |
| 2934 } | 3028 } |
| 2935 } | 3029 } |
| 2936 Operand operand(BuildFastArrayOperand( | 3030 Operand operand(BuildFastArrayOperand( |
| 2937 instr->elements(), | 3031 instr->elements(), |
| 2938 key, | 3032 key, |
| 2939 elements_kind, | 3033 elements_kind, |
| 2940 0, | 3034 0, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2991 | 3085 |
| 2992 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3086 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
| 2993 XMMRegister result(ToDoubleRegister(instr->result())); | 3087 XMMRegister result(ToDoubleRegister(instr->result())); |
| 2994 LOperand* key = instr->key(); | 3088 LOperand* key = instr->key(); |
| 2995 if (!key->IsConstantOperand()) { | 3089 if (!key->IsConstantOperand()) { |
| 2996 Register key_reg = ToRegister(key); | 3090 Register key_reg = ToRegister(key); |
| 2997 // Even though the HLoad/StoreKeyed instructions force the input | 3091 // Even though the HLoad/StoreKeyed instructions force the input |
| 2998 // representation for the key to be an integer, the input gets replaced | 3092 // representation for the key to be an integer, the input gets replaced |
| 2999 // during bound check elimination with the index argument to the bounds | 3093 // during bound check elimination with the index argument to the bounds |
| 3000 // check, which can be tagged, so that case must be handled here, too. | 3094 // check, which can be tagged, so that case must be handled here, too. |
| 3001 if (instr->hydrogen()->IsDehoisted()) { | 3095 if (kSmiValueSize == 31 && |
| 3096 instr->hydrogen()->key()->representation().IsSmi()) { | |
| 3097 __ SmiToInteger64(key_reg, key_reg); | |
| 3098 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 3002 // Sign extend key because it could be a 32 bit negative value | 3099 // Sign extend key because it could be a 32 bit negative value |
| 3003 // and the dehoisted address computation happens in 64 bits | 3100 // and the dehoisted address computation happens in 64 bits |
| 3004 __ movsxlq(key_reg, key_reg); | 3101 __ movsxlq(key_reg, key_reg); |
| 3005 } | 3102 } |
| 3006 } | 3103 } |
| 3007 | 3104 |
| 3008 if (instr->hydrogen()->RequiresHoleCheck()) { | 3105 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3009 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | 3106 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
| 3010 sizeof(kHoleNanLower32); | 3107 sizeof(kHoleNanLower32); |
| 3011 Operand hole_check_operand = BuildFastArrayOperand( | 3108 Operand hole_check_operand = BuildFastArrayOperand( |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 3031 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3128 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 3032 Register result = ToRegister(instr->result()); | 3129 Register result = ToRegister(instr->result()); |
| 3033 LOperand* key = instr->key(); | 3130 LOperand* key = instr->key(); |
| 3034 if (!key->IsConstantOperand()) { | 3131 if (!key->IsConstantOperand()) { |
| 3035 Register key_reg = ToRegister(key); | 3132 Register key_reg = ToRegister(key); |
| 3036 // Even though the HLoad/StoreKeyedFastElement instructions force | 3133 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 3037 // the input representation for the key to be an integer, the input | 3134 // the input representation for the key to be an integer, the input |
| 3038 // gets replaced during bound check elimination with the index | 3135 // gets replaced during bound check elimination with the index |
| 3039 // argument to the bounds check, which can be tagged, so that | 3136 // argument to the bounds check, which can be tagged, so that |
| 3040 // case must be handled here, too. | 3137 // case must be handled here, too. |
| 3041 if (instr->hydrogen()->IsDehoisted()) { | 3138 if (kSmiValueSize == 31 && |
| 3139 instr->hydrogen()->key()->representation().IsSmi()) { | |
| 3140 __ SmiToInteger64(key_reg, key_reg); | |
| 3141 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 3042 // Sign extend key because it could be a 32 bit negative value | 3142 // Sign extend key because it could be a 32 bit negative value |
| 3043 // and the dehoisted address computation happens in 64 bits | 3143 // and the dehoisted address computation happens in 64 bits |
| 3044 __ movsxlq(key_reg, key_reg); | 3144 __ movsxlq(key_reg, key_reg); |
| 3045 } | 3145 } |
| 3046 } | 3146 } |
| 3047 | 3147 |
| 3048 // Load the result. | 3148 // Load the result. |
| 3049 __ movq(result, | 3149 __ movq(result, |
| 3050 BuildFastArrayOperand(instr->elements(), | 3150 BuildFastArrayOperand(instr->elements(), |
| 3051 key, | 3151 key, |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3419 Register input_reg = ToRegister(instr->value()); | 3519 Register input_reg = ToRegister(instr->value()); |
| 3420 __ testl(input_reg, input_reg); | 3520 __ testl(input_reg, input_reg); |
| 3421 Label is_positive; | 3521 Label is_positive; |
| 3422 __ j(not_sign, &is_positive, Label::kNear); | 3522 __ j(not_sign, &is_positive, Label::kNear); |
| 3423 __ negl(input_reg); // Sets flags. | 3523 __ negl(input_reg); // Sets flags. |
| 3424 DeoptimizeIf(negative, instr->environment()); | 3524 DeoptimizeIf(negative, instr->environment()); |
| 3425 __ bind(&is_positive); | 3525 __ bind(&is_positive); |
| 3426 } | 3526 } |
| 3427 | 3527 |
| 3428 | 3528 |
| 3429 void LCodeGen::EmitInteger64MathAbs(LMathAbs* instr) { | 3529 void LCodeGen::EmitSmiMathAbs(LMathAbs* instr) { |
|
haitao.feng
2013/08/06 07:58:56
Please ignore this part as Weiliang submitted a CL
| |
| 3430 Register input_reg = ToRegister(instr->value()); | 3530 Register input_reg = ToRegister(instr->value()); |
| 3431 __ testq(input_reg, input_reg); | 3531 __ testq(input_reg, input_reg); |
| 3432 Label is_positive; | 3532 Label is_positive; |
| 3433 __ j(not_sign, &is_positive, Label::kNear); | 3533 __ j(not_sign, &is_positive, Label::kNear); |
| 3434 __ neg(input_reg); // Sets flags. | 3534 if (kSmiValueSize == 32) { |
| 3535 __ neg(input_reg); // Sets flags. | |
| 3536 } else { | |
| 3537 ASSERT(kSmiValueSize == 31); | |
| 3538 __ negl(input_reg); // Sets flags. | |
| 3539 } | |
| 3435 DeoptimizeIf(negative, instr->environment()); | 3540 DeoptimizeIf(negative, instr->environment()); |
| 3436 __ bind(&is_positive); | 3541 __ bind(&is_positive); |
| 3437 } | 3542 } |
| 3438 | 3543 |
| 3439 | 3544 |
| 3440 void LCodeGen::DoMathAbs(LMathAbs* instr) { | 3545 void LCodeGen::DoMathAbs(LMathAbs* instr) { |
| 3441 // Class for deferred case. | 3546 // Class for deferred case. |
| 3442 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 3547 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
| 3443 public: | 3548 public: |
| 3444 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) | 3549 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 3456 | 3561 |
| 3457 if (r.IsDouble()) { | 3562 if (r.IsDouble()) { |
| 3458 XMMRegister scratch = xmm0; | 3563 XMMRegister scratch = xmm0; |
| 3459 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3564 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3460 __ xorps(scratch, scratch); | 3565 __ xorps(scratch, scratch); |
| 3461 __ subsd(scratch, input_reg); | 3566 __ subsd(scratch, input_reg); |
| 3462 __ andpd(input_reg, scratch); | 3567 __ andpd(input_reg, scratch); |
| 3463 } else if (r.IsInteger32()) { | 3568 } else if (r.IsInteger32()) { |
| 3464 EmitIntegerMathAbs(instr); | 3569 EmitIntegerMathAbs(instr); |
| 3465 } else if (r.IsSmi()) { | 3570 } else if (r.IsSmi()) { |
| 3466 EmitInteger64MathAbs(instr); | 3571 EmitSmiMathAbs(instr); |
| 3467 } else { // Tagged case. | 3572 } else { // Tagged case. |
| 3468 DeferredMathAbsTaggedHeapNumber* deferred = | 3573 DeferredMathAbsTaggedHeapNumber* deferred = |
| 3469 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); | 3574 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); |
| 3470 Register input_reg = ToRegister(instr->value()); | 3575 Register input_reg = ToRegister(instr->value()); |
| 3471 // Smi check. | 3576 // Smi check. |
| 3472 __ JumpIfNotSmi(input_reg, deferred->entry()); | 3577 __ JumpIfNotSmi(input_reg, deferred->entry()); |
| 3473 __ SmiToInteger32(input_reg, input_reg); | 3578 EmitSmiMathAbs(instr); |
| 3474 EmitIntegerMathAbs(instr); | |
| 3475 __ Integer32ToSmi(input_reg, input_reg); | |
| 3476 __ bind(deferred->exit()); | 3579 __ bind(deferred->exit()); |
| 3477 } | 3580 } |
| 3478 } | 3581 } |
| 3479 | 3582 |
| 3480 | 3583 |
| 3481 void LCodeGen::DoMathFloor(LMathFloor* instr) { | 3584 void LCodeGen::DoMathFloor(LMathFloor* instr) { |
| 3482 XMMRegister xmm_scratch = xmm0; | 3585 XMMRegister xmm_scratch = xmm0; |
| 3483 Register output_reg = ToRegister(instr->result()); | 3586 Register output_reg = ToRegister(instr->result()); |
| 3484 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3587 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3485 | 3588 |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4133 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4236 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
| 4134 ElementsKind elements_kind = instr->elements_kind(); | 4237 ElementsKind elements_kind = instr->elements_kind(); |
| 4135 LOperand* key = instr->key(); | 4238 LOperand* key = instr->key(); |
| 4136 if (!key->IsConstantOperand()) { | 4239 if (!key->IsConstantOperand()) { |
| 4137 Register key_reg = ToRegister(key); | 4240 Register key_reg = ToRegister(key); |
| 4138 // Even though the HLoad/StoreKeyedFastElement instructions force | 4241 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 4139 // the input representation for the key to be an integer, the input | 4242 // the input representation for the key to be an integer, the input |
| 4140 // gets replaced during bound check elimination with the index | 4243 // gets replaced during bound check elimination with the index |
| 4141 // argument to the bounds check, which can be tagged, so that case | 4244 // argument to the bounds check, which can be tagged, so that case |
| 4142 // must be handled here, too. | 4245 // must be handled here, too. |
| 4143 if (instr->hydrogen()->IsDehoisted()) { | 4246 if (kSmiValueSize == 31 && |
| 4247 instr->hydrogen()->key()->representation().IsSmi()) { | |
| 4248 __ SmiToInteger64(key_reg, key_reg); | |
| 4249 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 4144 // Sign extend key because it could be a 32 bit negative value | 4250 // Sign extend key because it could be a 32 bit negative value |
| 4145 // and the dehoisted address computation happens in 64 bits | 4251 // and the dehoisted address computation happens in 64 bits |
| 4146 __ movsxlq(key_reg, key_reg); | 4252 __ movsxlq(key_reg, key_reg); |
| 4147 } | 4253 } |
| 4148 } | 4254 } |
| 4149 Operand operand(BuildFastArrayOperand( | 4255 Operand operand(BuildFastArrayOperand( |
| 4150 instr->elements(), | 4256 instr->elements(), |
| 4151 key, | 4257 key, |
| 4152 elements_kind, | 4258 elements_kind, |
| 4153 0, | 4259 0, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4195 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4301 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
| 4196 XMMRegister value = ToDoubleRegister(instr->value()); | 4302 XMMRegister value = ToDoubleRegister(instr->value()); |
| 4197 LOperand* key = instr->key(); | 4303 LOperand* key = instr->key(); |
| 4198 if (!key->IsConstantOperand()) { | 4304 if (!key->IsConstantOperand()) { |
| 4199 Register key_reg = ToRegister(key); | 4305 Register key_reg = ToRegister(key); |
| 4200 // Even though the HLoad/StoreKeyedFastElement instructions force | 4306 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 4201 // the input representation for the key to be an integer, the | 4307 // the input representation for the key to be an integer, the |
| 4202 // input gets replaced during bound check elimination with the index | 4308 // input gets replaced during bound check elimination with the index |
| 4203 // argument to the bounds check, which can be tagged, so that case | 4309 // argument to the bounds check, which can be tagged, so that case |
| 4204 // must be handled here, too. | 4310 // must be handled here, too. |
| 4205 if (instr->hydrogen()->IsDehoisted()) { | 4311 if (kSmiValueSize == 31 && |
| 4312 instr->hydrogen()->key()->representation().IsSmi()) { | |
| 4313 __ SmiToInteger64(key_reg, key_reg); | |
| 4314 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 4206 // Sign extend key because it could be a 32 bit negative value | 4315 // Sign extend key because it could be a 32 bit negative value |
| 4207 // and the dehoisted address computation happens in 64 bits | 4316 // and the dehoisted address computation happens in 64 bits |
| 4208 __ movsxlq(key_reg, key_reg); | 4317 __ movsxlq(key_reg, key_reg); |
| 4209 } | 4318 } |
| 4210 } | 4319 } |
| 4211 | 4320 |
| 4212 if (instr->NeedsCanonicalization()) { | 4321 if (instr->NeedsCanonicalization()) { |
| 4213 Label have_value; | 4322 Label have_value; |
| 4214 | 4323 |
| 4215 __ ucomisd(value, value); | 4324 __ ucomisd(value, value); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 4236 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4345 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 4237 Register elements = ToRegister(instr->elements()); | 4346 Register elements = ToRegister(instr->elements()); |
| 4238 LOperand* key = instr->key(); | 4347 LOperand* key = instr->key(); |
| 4239 if (!key->IsConstantOperand()) { | 4348 if (!key->IsConstantOperand()) { |
| 4240 Register key_reg = ToRegister(key); | 4349 Register key_reg = ToRegister(key); |
| 4241 // Even though the HLoad/StoreKeyedFastElement instructions force | 4350 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 4242 // the input representation for the key to be an integer, the | 4351 // the input representation for the key to be an integer, the |
| 4243 // input gets replaced during bound check elimination with the index | 4352 // input gets replaced during bound check elimination with the index |
| 4244 // argument to the bounds check, which can be tagged, so that case | 4353 // argument to the bounds check, which can be tagged, so that case |
| 4245 // must be handled here, too. | 4354 // must be handled here, too. |
| 4246 if (instr->hydrogen()->IsDehoisted()) { | 4355 if (kSmiValueSize == 31 && |
| 4356 instr->hydrogen()->key()->representation().IsSmi()) { | |
| 4357 __ SmiToInteger64(key_reg, key_reg); | |
| 4358 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 4247 // Sign extend key because it could be a 32 bit negative value | 4359 // Sign extend key because it could be a 32 bit negative value |
| 4248 // and the dehoisted address computation happens in 64 bits | 4360 // and the dehoisted address computation happens in 64 bits |
| 4249 __ movsxlq(key_reg, key_reg); | 4361 __ movsxlq(key_reg, key_reg); |
| 4250 } | 4362 } |
| 4251 } | 4363 } |
| 4252 | 4364 |
| 4253 Operand operand = | 4365 Operand operand = |
| 4254 BuildFastArrayOperand(instr->elements(), | 4366 BuildFastArrayOperand(instr->elements(), |
| 4255 key, | 4367 key, |
| 4256 FAST_ELEMENTS, | 4368 FAST_ELEMENTS, |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4493 LOperand* output = instr->result(); | 4605 LOperand* output = instr->result(); |
| 4494 LOperand* temp = instr->temp(); | 4606 LOperand* temp = instr->temp(); |
| 4495 | 4607 |
| 4496 __ LoadUint32(ToDoubleRegister(output), | 4608 __ LoadUint32(ToDoubleRegister(output), |
| 4497 ToRegister(input), | 4609 ToRegister(input), |
| 4498 ToDoubleRegister(temp)); | 4610 ToDoubleRegister(temp)); |
| 4499 } | 4611 } |
| 4500 | 4612 |
| 4501 | 4613 |
| 4502 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4614 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
| 4503 LOperand* input = instr->value(); | 4615 if (kSmiValueSize == 32) { |
| 4504 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 4616 LOperand* input = instr->value(); |
| 4505 Register reg = ToRegister(input); | 4617 ASSERT(input->IsRegister() && input->Equals(instr->result())); |
| 4618 Register reg = ToRegister(input); | |
| 4506 | 4619 |
| 4507 __ Integer32ToSmi(reg, reg); | 4620 __ Integer32ToSmi(reg, reg); |
| 4621 } else { | |
| 4622 ASSERT(kSmiValueSize == 31); | |
| 4623 class DeferredNumberTagI: public LDeferredCode { | |
| 4624 public: | |
| 4625 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) | |
| 4626 : LDeferredCode(codegen), instr_(instr) { } | |
| 4627 virtual void Generate() { | |
| 4628 codegen()->DoDeferredNumberTagI(instr_); | |
| 4629 } | |
| 4630 virtual LInstruction* instr() { return instr_; } | |
| 4631 private: | |
| 4632 LNumberTagI* instr_; | |
| 4633 }; | |
| 4634 | |
| 4635 LOperand* input = instr->value(); | |
| 4636 ASSERT(input->IsRegister() && input->Equals(instr->result())); | |
| 4637 Register reg = ToRegister(input); | |
| 4638 | |
| 4639 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); | |
| 4640 __ shll(reg, Immediate(kSmiTagSize + kSmiShiftSize)); | |
| 4641 __ j(overflow, deferred->entry()); | |
| 4642 __ movsxlq(reg, reg); | |
| 4643 __ bind(deferred->exit()); | |
| 4644 } | |
| 4508 } | 4645 } |
| 4509 | 4646 |
| 4510 | 4647 |
| 4648 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { | |
| 4649 ASSERT(kSmiValueSize == 31); | |
| 4650 Label slow; | |
| 4651 Register reg = ToRegister(instr->value()); | |
| 4652 Register tmp = reg.is(rax) ? kScratchRegister : rax; | |
| 4653 | |
| 4654 // Preserve the value of all registers. | |
| 4655 PushSafepointRegistersScope scope(this); | |
| 4656 | |
| 4657 Label done; | |
| 4658 // There was overflow, so bits 30 and 31 of the original integer | |
| 4659 // disagree. Try to allocate a heap number in new space and store | |
| 4660 // the value in there. If that fails, call the runtime system. | |
| 4661 __ SmiToInteger32(reg, reg); | |
| 4662 __ xorl(reg, Immediate(0x80000000)); | |
| 4663 __ cvtlsi2sd(xmm1, reg); | |
| 4664 | |
| 4665 if (FLAG_inline_new) { | |
| 4666 __ AllocateHeapNumber(reg, tmp, &slow); | |
| 4667 __ jmp(&done, Label::kNear); | |
| 4668 } | |
| 4669 | |
| 4670 // Slow case: Call the runtime system to do the number allocation. | |
| 4671 __ bind(&slow); | |
| 4672 | |
| 4673 // Put a valid pointer value in the stack slot where the result | |
| 4674 // register is stored, as this register is in the pointer map, but contains an | |
| 4675 // integer value. | |
| 4676 __ StoreToSafepointRegisterSlot(reg, Immediate(0)); | |
| 4677 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | |
| 4678 // Set the pointer to the new heap number in tmp. | |
| 4679 if (!reg.is(rax)) __ movq(reg, rax); | |
| 4680 | |
| 4681 // Heap number allocated. Put the value in xmm0 into the value of the | |
| 4682 // allocated heap number. | |
| 4683 __ bind(&done); | |
| 4684 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm1); | |
| 4685 __ StoreToSafepointRegisterSlot(reg, reg); | |
| 4686 } | |
| 4687 | |
| 4688 | |
| 4511 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { | 4689 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { |
| 4512 class DeferredNumberTagU: public LDeferredCode { | 4690 class DeferredNumberTagU: public LDeferredCode { |
| 4513 public: | 4691 public: |
| 4514 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) | 4692 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) |
| 4515 : LDeferredCode(codegen), instr_(instr) { } | 4693 : LDeferredCode(codegen), instr_(instr) { } |
| 4516 virtual void Generate() { | 4694 virtual void Generate() { |
| 4517 codegen()->DoDeferredNumberTagU(instr_); | 4695 codegen()->DoDeferredNumberTagU(instr_); |
| 4518 } | 4696 } |
| 4519 virtual LInstruction* instr() { return instr_; } | 4697 virtual LInstruction* instr() { return instr_; } |
| 4520 private: | 4698 private: |
| (...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5577 FixedArray::kHeaderSize - kPointerSize)); | 5755 FixedArray::kHeaderSize - kPointerSize)); |
| 5578 __ bind(&done); | 5756 __ bind(&done); |
| 5579 } | 5757 } |
| 5580 | 5758 |
| 5581 | 5759 |
| 5582 #undef __ | 5760 #undef __ |
| 5583 | 5761 |
| 5584 } } // namespace v8::internal | 5762 } } // namespace v8::internal |
| 5585 | 5763 |
| 5586 #endif // V8_TARGET_ARCH_X64 | 5764 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |