OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1075 } else if (v->IsInstanceOf()) { | 1075 } else if (v->IsInstanceOf()) { |
1076 HInstanceOf* instance_of = HInstanceOf::cast(v); | 1076 HInstanceOf* instance_of = HInstanceOf::cast(v); |
1077 LInstanceOfAndBranch* result = | 1077 LInstanceOfAndBranch* result = |
1078 new LInstanceOfAndBranch( | 1078 new LInstanceOfAndBranch( |
1079 UseFixed(instance_of->left(), InstanceofStub::left()), | 1079 UseFixed(instance_of->left(), InstanceofStub::left()), |
1080 UseFixed(instance_of->right(), InstanceofStub::right())); | 1080 UseFixed(instance_of->right(), InstanceofStub::right())); |
1081 return MarkAsCall(result, instr); | 1081 return MarkAsCall(result, instr); |
1082 } else if (v->IsTypeofIs()) { | 1082 } else if (v->IsTypeofIs()) { |
1083 HTypeofIs* typeof_is = HTypeofIs::cast(v); | 1083 HTypeofIs* typeof_is = HTypeofIs::cast(v); |
1084 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); | 1084 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); |
| 1085 } else if (v->IsIsConstructCall()) { |
| 1086 return new LIsConstructCallAndBranch(TempRegister()); |
1085 } else { | 1087 } else { |
1086 if (v->IsConstant()) { | 1088 if (v->IsConstant()) { |
1087 if (HConstant::cast(v)->handle()->IsTrue()) { | 1089 if (HConstant::cast(v)->handle()->IsTrue()) { |
1088 return new LGoto(instr->FirstSuccessor()->block_id()); | 1090 return new LGoto(instr->FirstSuccessor()->block_id()); |
1089 } else if (HConstant::cast(v)->handle()->IsFalse()) { | 1091 } else if (HConstant::cast(v)->handle()->IsFalse()) { |
1090 return new LGoto(instr->SecondSuccessor()->block_id()); | 1092 return new LGoto(instr->SecondSuccessor()->block_id()); |
1091 } | 1093 } |
1092 } | 1094 } |
1093 Abort("Undefined compare before branch"); | 1095 Abort("Undefined compare before branch"); |
1094 return NULL; | 1096 return NULL; |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1255 return DoBit(Token::BIT_OR, instr); | 1257 return DoBit(Token::BIT_OR, instr); |
1256 } | 1258 } |
1257 | 1259 |
1258 | 1260 |
1259 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) { | 1261 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) { |
1260 return DoBit(Token::BIT_XOR, instr); | 1262 return DoBit(Token::BIT_XOR, instr); |
1261 } | 1263 } |
1262 | 1264 |
1263 | 1265 |
1264 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1266 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
1265 Abort("Unimplemented: %s", "DoDiv"); | 1267 if (instr->representation().IsDouble()) { |
1266 return NULL; | 1268 return DoArithmeticD(Token::DIV, instr); |
| 1269 } else if (instr->representation().IsInteger32()) { |
| 1270 // The temporary operand is necessary to ensure that right is not allocated |
| 1271 // into rdx. |
| 1272 LOperand* temp = FixedTemp(rdx); |
| 1273 LOperand* dividend = UseFixed(instr->left(), rax); |
| 1274 LOperand* divisor = UseRegister(instr->right()); |
| 1275 LDivI* result = new LDivI(dividend, divisor, temp); |
| 1276 return AssignEnvironment(DefineFixed(result, rax)); |
| 1277 } else { |
| 1278 ASSERT(instr->representation().IsTagged()); |
| 1279 return DoArithmeticT(Token::DIV, instr); |
| 1280 } |
1267 } | 1281 } |
1268 | 1282 |
1269 | 1283 |
1270 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1284 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
1271 Abort("Unimplemented: %s", "DoMod"); | 1285 Abort("Unimplemented: %s", "DoMod"); |
1272 return NULL; | 1286 return NULL; |
1273 } | 1287 } |
1274 | 1288 |
1275 | 1289 |
1276 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1290 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
1277 Abort("Unimplemented: %s", "DoMul"); | 1291 if (instr->representation().IsInteger32()) { |
1278 return NULL; | 1292 ASSERT(instr->left()->representation().IsInteger32()); |
| 1293 ASSERT(instr->right()->representation().IsInteger32()); |
| 1294 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); |
| 1295 LOperand* right = UseOrConstant(instr->MostConstantOperand()); |
| 1296 LMulI* mul = new LMulI(left, right); |
| 1297 return AssignEnvironment(DefineSameAsFirst(mul)); |
| 1298 } else if (instr->representation().IsDouble()) { |
| 1299 return DoArithmeticD(Token::MUL, instr); |
| 1300 } else { |
| 1301 ASSERT(instr->representation().IsTagged()); |
| 1302 return DoArithmeticT(Token::MUL, instr); |
| 1303 } |
1279 } | 1304 } |
1280 | 1305 |
1281 | 1306 |
1282 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1307 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
1283 if (instr->representation().IsInteger32()) { | 1308 if (instr->representation().IsInteger32()) { |
1284 ASSERT(instr->left()->representation().IsInteger32()); | 1309 ASSERT(instr->left()->representation().IsInteger32()); |
1285 ASSERT(instr->right()->representation().IsInteger32()); | 1310 ASSERT(instr->right()->representation().IsInteger32()); |
1286 LOperand* left = UseRegisterAtStart(instr->left()); | 1311 LOperand* left = UseRegisterAtStart(instr->left()); |
1287 LOperand* right = UseOrConstantAtStart(instr->right()); | 1312 LOperand* right = UseOrConstantAtStart(instr->right()); |
1288 LSubI* sub = new LSubI(left, right); | 1313 LSubI* sub = new LSubI(left, right); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1432 | 1457 |
1433 | 1458 |
1434 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { | 1459 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { |
1435 // The control instruction marking the end of a block that completed | 1460 // The control instruction marking the end of a block that completed |
1436 // abruptly (e.g., threw an exception). There is nothing specific to do. | 1461 // abruptly (e.g., threw an exception). There is nothing specific to do. |
1437 return NULL; | 1462 return NULL; |
1438 } | 1463 } |
1439 | 1464 |
1440 | 1465 |
1441 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { | 1466 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { |
1442 Abort("Unimplemented: %s", "DoThrow"); | 1467 LOperand* value = UseFixed(instr->value(), rax); |
1443 return NULL; | 1468 return MarkAsCall(new LThrow(value), instr); |
1444 } | 1469 } |
1445 | 1470 |
1446 | 1471 |
1447 LInstruction* LChunkBuilder::DoChange(HChange* instr) { | 1472 LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
1448 Representation from = instr->from(); | 1473 Representation from = instr->from(); |
1449 Representation to = instr->to(); | 1474 Representation to = instr->to(); |
1450 if (from.IsTagged()) { | 1475 if (from.IsTagged()) { |
1451 if (to.IsDouble()) { | 1476 if (to.IsDouble()) { |
1452 LOperand* value = UseRegister(instr->value()); | 1477 LOperand* value = UseRegister(instr->value()); |
1453 LNumberUntagD* res = new LNumberUntagD(value); | 1478 LNumberUntagD* res = new LNumberUntagD(value); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 | 1570 |
1546 | 1571 |
1547 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 1572 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
1548 return new LReturn(UseFixed(instr->value(), rax)); | 1573 return new LReturn(UseFixed(instr->value(), rax)); |
1549 } | 1574 } |
1550 | 1575 |
1551 | 1576 |
1552 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1577 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
1553 Representation r = instr->representation(); | 1578 Representation r = instr->representation(); |
1554 if (r.IsInteger32()) { | 1579 if (r.IsInteger32()) { |
1555 int32_t value = instr->Integer32Value(); | 1580 return DefineAsRegister(new LConstantI); |
1556 return DefineAsRegister(new LConstantI(value)); | |
1557 } else if (r.IsDouble()) { | 1581 } else if (r.IsDouble()) { |
1558 double value = instr->DoubleValue(); | |
1559 LOperand* temp = TempRegister(); | 1582 LOperand* temp = TempRegister(); |
1560 return DefineAsRegister(new LConstantD(value, temp)); | 1583 return DefineAsRegister(new LConstantD(temp)); |
1561 } else if (r.IsTagged()) { | 1584 } else if (r.IsTagged()) { |
1562 return DefineAsRegister(new LConstantT(instr->handle())); | 1585 return DefineAsRegister(new LConstantT); |
1563 } else { | 1586 } else { |
1564 UNREACHABLE(); | 1587 UNREACHABLE(); |
1565 return NULL; | 1588 return NULL; |
1566 } | 1589 } |
1567 } | 1590 } |
1568 | 1591 |
1569 | 1592 |
1570 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { | 1593 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { |
1571 LLoadGlobal* result = new LLoadGlobal; | 1594 LLoadGlobal* result = new LLoadGlobal; |
1572 return instr->check_hole_value() | 1595 return instr->check_hole_value() |
(...skipping 22 matching lines...) Expand all Loading... |
1595 | 1618 |
1596 | 1619 |
1597 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 1620 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
1598 ASSERT(instr->representation().IsTagged()); | 1621 ASSERT(instr->representation().IsTagged()); |
1599 LOperand* obj = UseRegisterAtStart(instr->object()); | 1622 LOperand* obj = UseRegisterAtStart(instr->object()); |
1600 return DefineAsRegister(new LLoadNamedField(obj)); | 1623 return DefineAsRegister(new LLoadNamedField(obj)); |
1601 } | 1624 } |
1602 | 1625 |
1603 | 1626 |
1604 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 1627 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
1605 Abort("Unimplemented: %s", "DoLoadNamedGeneric"); | 1628 LOperand* object = UseFixed(instr->object(), rax); |
1606 return NULL; | 1629 LLoadNamedGeneric* result = new LLoadNamedGeneric(object); |
| 1630 return MarkAsCall(DefineFixed(result, rax), instr); |
1607 } | 1631 } |
1608 | 1632 |
1609 | 1633 |
1610 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( | 1634 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( |
1611 HLoadFunctionPrototype* instr) { | 1635 HLoadFunctionPrototype* instr) { |
1612 Abort("Unimplemented: %s", "DoLoadFunctionPrototype"); | 1636 Abort("Unimplemented: %s", "DoLoadFunctionPrototype"); |
1613 return NULL; | 1637 return NULL; |
1614 } | 1638 } |
1615 | 1639 |
1616 | 1640 |
(...skipping 15 matching lines...) Expand all Loading... |
1632 | 1656 |
1633 | 1657 |
1634 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 1658 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
1635 Abort("Unimplemented: %s", "DoLoadKeyedGeneric"); | 1659 Abort("Unimplemented: %s", "DoLoadKeyedGeneric"); |
1636 return NULL; | 1660 return NULL; |
1637 } | 1661 } |
1638 | 1662 |
1639 | 1663 |
1640 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( | 1664 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( |
1641 HStoreKeyedFastElement* instr) { | 1665 HStoreKeyedFastElement* instr) { |
1642 Abort("Unimplemented: %s", "DoStoreKeyedFastElement"); | 1666 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
1643 return NULL; | 1667 ASSERT(instr->value()->representation().IsTagged()); |
| 1668 ASSERT(instr->object()->representation().IsTagged()); |
| 1669 ASSERT(instr->key()->representation().IsInteger32()); |
| 1670 |
| 1671 LOperand* obj = UseTempRegister(instr->object()); |
| 1672 LOperand* val = needs_write_barrier |
| 1673 ? UseTempRegister(instr->value()) |
| 1674 : UseRegisterAtStart(instr->value()); |
| 1675 LOperand* key = needs_write_barrier |
| 1676 ? UseTempRegister(instr->key()) |
| 1677 : UseRegisterOrConstantAtStart(instr->key()); |
| 1678 |
| 1679 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); |
1644 } | 1680 } |
1645 | 1681 |
1646 | 1682 |
1647 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 1683 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
1648 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); | 1684 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); |
1649 return NULL; | 1685 return NULL; |
1650 } | 1686 } |
1651 | 1687 |
1652 | 1688 |
1653 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { | 1689 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1727 } | 1763 } |
1728 | 1764 |
1729 | 1765 |
1730 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 1766 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
1731 Abort("Unimplemented: %s", "DoUnknownOSRValue"); | 1767 Abort("Unimplemented: %s", "DoUnknownOSRValue"); |
1732 return NULL; | 1768 return NULL; |
1733 } | 1769 } |
1734 | 1770 |
1735 | 1771 |
1736 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 1772 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
1737 Abort("Unimplemented: %s", "DoCallStub"); | 1773 argument_count_ -= instr->argument_count(); |
1738 return NULL; | 1774 return MarkAsCall(DefineFixed(new LCallStub, rax), instr); |
1739 } | 1775 } |
1740 | 1776 |
1741 | 1777 |
1742 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 1778 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
1743 Abort("Unimplemented: %s", "DoArgumentsObject"); | 1779 Abort("Unimplemented: %s", "DoArgumentsObject"); |
1744 return NULL; | 1780 return NULL; |
1745 } | 1781 } |
1746 | 1782 |
1747 | 1783 |
1748 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { | 1784 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { |
1749 Abort("Unimplemented: %s", "DoAccessArgumentsAt"); | 1785 Abort("Unimplemented: %s", "DoAccessArgumentsAt"); |
1750 return NULL; | 1786 return NULL; |
1751 } | 1787 } |
1752 | 1788 |
1753 | 1789 |
1754 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 1790 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
1755 Abort("Unimplemented: %s", "DoTypeof"); | 1791 Abort("Unimplemented: %s", "DoTypeof"); |
1756 return NULL; | 1792 return NULL; |
1757 } | 1793 } |
1758 | 1794 |
1759 | 1795 |
1760 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { | 1796 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { |
1761 Abort("Unimplemented: %s", "DoTypeofIs"); | 1797 Abort("Unimplemented: %s", "DoTypeofIs"); |
1762 return NULL; | 1798 return NULL; |
1763 } | 1799 } |
1764 | 1800 |
| 1801 |
| 1802 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) { |
| 1803 return DefineAsRegister(new LIsConstructCall); |
| 1804 } |
| 1805 |
| 1806 |
1765 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 1807 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
1766 HEnvironment* env = current_block_->last_environment(); | 1808 HEnvironment* env = current_block_->last_environment(); |
1767 ASSERT(env != NULL); | 1809 ASSERT(env != NULL); |
1768 | 1810 |
1769 env->set_ast_id(instr->ast_id()); | 1811 env->set_ast_id(instr->ast_id()); |
1770 | 1812 |
1771 env->Drop(instr->pop_count()); | 1813 env->Drop(instr->pop_count()); |
1772 for (int i = 0; i < instr->values()->length(); ++i) { | 1814 for (int i = 0; i < instr->values()->length(); ++i) { |
1773 HValue* value = instr->values()->at(i); | 1815 HValue* value = instr->values()->at(i); |
1774 if (instr->HasAssignedIndexAt(i)) { | 1816 if (instr->HasAssignedIndexAt(i)) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1814 | 1856 |
1815 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 1857 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
1816 HEnvironment* outer = current_block_->last_environment()->outer(); | 1858 HEnvironment* outer = current_block_->last_environment()->outer(); |
1817 current_block_->UpdateEnvironment(outer); | 1859 current_block_->UpdateEnvironment(outer); |
1818 return NULL; | 1860 return NULL; |
1819 } | 1861 } |
1820 | 1862 |
1821 } } // namespace v8::internal | 1863 } } // namespace v8::internal |
1822 | 1864 |
1823 #endif // V8_TARGET_ARCH_X64 | 1865 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |