OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 |
11 // with the distribution. | 11 // with the distribution. |
12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
15 // | 15 // |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #if defined(V8_TARGET_ARCH_IA32) | 30 #if V8_TARGET_ARCH_IA32 |
31 | 31 |
32 #include "lithium-allocator-inl.h" | 32 #include "lithium-allocator-inl.h" |
33 #include "ia32/lithium-ia32.h" | 33 #include "ia32/lithium-ia32.h" |
34 #include "ia32/lithium-codegen-ia32.h" | 34 #include "ia32/lithium-codegen-ia32.h" |
35 | 35 |
36 namespace v8 { | 36 namespace v8 { |
37 namespace internal { | 37 namespace internal { |
38 | 38 |
39 #define DEFINE_COMPILE(type) \ | 39 #define DEFINE_COMPILE(type) \ |
40 void L##type::CompileToNative(LCodeGen* generator) { \ | 40 void L##type::CompileToNative(LCodeGen* generator) { \ |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 stream->Add("B%d", block_id()); | 194 stream->Add("B%d", block_id()); |
195 } | 195 } |
196 | 196 |
197 | 197 |
198 void LBranch::PrintDataTo(StringStream* stream) { | 198 void LBranch::PrintDataTo(StringStream* stream) { |
199 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); | 199 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); |
200 value()->PrintTo(stream); | 200 value()->PrintTo(stream); |
201 } | 201 } |
202 | 202 |
203 | 203 |
204 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) { | 204 void LCompareNumericAndBranch::PrintDataTo(StringStream* stream) { |
205 stream->Add("if "); | 205 stream->Add("if "); |
206 left()->PrintTo(stream); | 206 left()->PrintTo(stream); |
207 stream->Add(" %s ", Token::String(op())); | 207 stream->Add(" %s ", Token::String(op())); |
208 right()->PrintTo(stream); | 208 right()->PrintTo(stream); |
209 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); | 209 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); |
210 } | 210 } |
211 | 211 |
212 | 212 |
213 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) { | 213 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) { |
214 stream->Add("if is_object("); | 214 stream->Add("if is_object("); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 stream->Add(" #%d / ", arity()); | 343 stream->Add(" #%d / ", arity()); |
344 } | 344 } |
345 | 345 |
346 | 346 |
347 void LCallNewArray::PrintDataTo(StringStream* stream) { | 347 void LCallNewArray::PrintDataTo(StringStream* stream) { |
348 stream->Add("= "); | 348 stream->Add("= "); |
349 context()->PrintTo(stream); | 349 context()->PrintTo(stream); |
350 stream->Add(" "); | 350 stream->Add(" "); |
351 constructor()->PrintTo(stream); | 351 constructor()->PrintTo(stream); |
352 stream->Add(" #%d / ", arity()); | 352 stream->Add(" #%d / ", arity()); |
353 ASSERT(hydrogen()->property_cell()->value()->IsSmi()); | 353 ElementsKind kind = hydrogen()->elements_kind(); |
354 ElementsKind kind = static_cast<ElementsKind>( | |
355 Smi::cast(hydrogen()->property_cell()->value())->value()); | |
356 stream->Add(" (%s) ", ElementsKindToString(kind)); | 354 stream->Add(" (%s) ", ElementsKindToString(kind)); |
357 } | 355 } |
358 | 356 |
359 | 357 |
360 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { | 358 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { |
361 arguments()->PrintTo(stream); | 359 arguments()->PrintTo(stream); |
362 | 360 |
363 stream->Add(" length "); | 361 stream->Add(" length "); |
364 length()->PrintTo(stream); | 362 length()->PrintTo(stream); |
365 | 363 |
(...skipping 1206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1572 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1570 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1573 temp = TempRegister(); | 1571 temp = TempRegister(); |
1574 } | 1572 } |
1575 LMulI* mul = new(zone()) LMulI(left, right, temp); | 1573 LMulI* mul = new(zone()) LMulI(left, right, temp); |
1576 if (instr->CheckFlag(HValue::kCanOverflow) || | 1574 if (instr->CheckFlag(HValue::kCanOverflow) || |
1577 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1575 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1578 AssignEnvironment(mul); | 1576 AssignEnvironment(mul); |
1579 } | 1577 } |
1580 return DefineSameAsFirst(mul); | 1578 return DefineSameAsFirst(mul); |
1581 } else if (instr->representation().IsDouble()) { | 1579 } else if (instr->representation().IsDouble()) { |
1582 return DoArithmeticD(Token::MUL, instr); | 1580 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| 1581 return DoArithmeticD(Token::MUL, instr); |
| 1582 } |
| 1583 ASSERT(instr->right()->IsConstant() && |
| 1584 static_cast<HConstant*>(instr->right())->DoubleValue() == -1); |
| 1585 // TODO(olivf) This is currently just a hack to support the UnaryOp Minus |
| 1586 // Stub. This will go away once we can use more than one X87 register, |
| 1587 // thus fully support binary instructions without SSE2. |
| 1588 LOperand* left = UseX87TopOfStack(instr->left()); |
| 1589 LNegateNoSSE2D* result = new(zone()) LNegateNoSSE2D(left); |
| 1590 return DefineX87TOS(result); |
1583 } else { | 1591 } else { |
1584 ASSERT(instr->representation().IsSmiOrTagged()); | 1592 ASSERT(instr->representation().IsSmiOrTagged()); |
1585 return DoArithmeticT(Token::MUL, instr); | 1593 return DoArithmeticT(Token::MUL, instr); |
1586 } | 1594 } |
1587 } | 1595 } |
1588 | 1596 |
1589 | 1597 |
1590 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1598 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
1591 if (instr->representation().IsInteger32()) { | 1599 if (instr->representation().IsInteger32()) { |
1592 ASSERT(instr->left()->representation().IsInteger32()); | 1600 ASSERT(instr->left()->representation().IsInteger32()); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1689 ASSERT(instr->left()->representation().IsSmiOrTagged()); | 1697 ASSERT(instr->left()->representation().IsSmiOrTagged()); |
1690 ASSERT(instr->right()->representation().IsSmiOrTagged()); | 1698 ASSERT(instr->right()->representation().IsSmiOrTagged()); |
1691 LOperand* context = UseFixed(instr->context(), esi); | 1699 LOperand* context = UseFixed(instr->context(), esi); |
1692 LOperand* left = UseFixed(instr->left(), edx); | 1700 LOperand* left = UseFixed(instr->left(), edx); |
1693 LOperand* right = UseFixed(instr->right(), eax); | 1701 LOperand* right = UseFixed(instr->right(), eax); |
1694 LCmpT* result = new(zone()) LCmpT(context, left, right); | 1702 LCmpT* result = new(zone()) LCmpT(context, left, right); |
1695 return MarkAsCall(DefineFixed(result, eax), instr); | 1703 return MarkAsCall(DefineFixed(result, eax), instr); |
1696 } | 1704 } |
1697 | 1705 |
1698 | 1706 |
1699 LInstruction* LChunkBuilder::DoCompareIDAndBranch( | 1707 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( |
1700 HCompareIDAndBranch* instr) { | 1708 HCompareNumericAndBranch* instr) { |
1701 Representation r = instr->representation(); | 1709 Representation r = instr->representation(); |
1702 if (r.IsSmiOrInteger32()) { | 1710 if (r.IsSmiOrInteger32()) { |
1703 ASSERT(instr->left()->representation().IsSmiOrInteger32()); | 1711 ASSERT(instr->left()->representation().IsSmiOrInteger32()); |
1704 ASSERT(instr->left()->representation().Equals( | 1712 ASSERT(instr->left()->representation().Equals( |
1705 instr->right()->representation())); | 1713 instr->right()->representation())); |
1706 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); | 1714 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); |
1707 LOperand* right = UseOrConstantAtStart(instr->right()); | 1715 LOperand* right = UseOrConstantAtStart(instr->right()); |
1708 return new(zone()) LCmpIDAndBranch(left, right); | 1716 return new(zone()) LCompareNumericAndBranch(left, right); |
1709 } else { | 1717 } else { |
1710 ASSERT(r.IsDouble()); | 1718 ASSERT(r.IsDouble()); |
1711 ASSERT(instr->left()->representation().IsDouble()); | 1719 ASSERT(instr->left()->representation().IsDouble()); |
1712 ASSERT(instr->right()->representation().IsDouble()); | 1720 ASSERT(instr->right()->representation().IsDouble()); |
1713 LOperand* left; | 1721 LOperand* left; |
1714 LOperand* right; | 1722 LOperand* right; |
1715 if (instr->left()->IsConstant() && instr->right()->IsConstant()) { | 1723 if (instr->left()->IsConstant() && instr->right()->IsConstant()) { |
1716 left = UseRegisterOrConstantAtStart(instr->left()); | 1724 left = UseRegisterOrConstantAtStart(instr->left()); |
1717 right = UseRegisterOrConstantAtStart(instr->right()); | 1725 right = UseRegisterOrConstantAtStart(instr->right()); |
1718 } else { | 1726 } else { |
1719 left = UseRegisterAtStart(instr->left()); | 1727 left = UseRegisterAtStart(instr->left()); |
1720 right = UseRegisterAtStart(instr->right()); | 1728 right = UseRegisterAtStart(instr->right()); |
1721 } | 1729 } |
1722 return new(zone()) LCmpIDAndBranch(left, right); | 1730 return new(zone()) LCompareNumericAndBranch(left, right); |
1723 } | 1731 } |
1724 } | 1732 } |
1725 | 1733 |
1726 | 1734 |
1727 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( | 1735 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( |
1728 HCompareObjectEqAndBranch* instr) { | 1736 HCompareObjectEqAndBranch* instr) { |
1729 LOperand* left = UseRegisterAtStart(instr->left()); | 1737 LOperand* left = UseRegisterAtStart(instr->left()); |
1730 LOperand* right = UseOrConstantAtStart(instr->right()); | 1738 LOperand* right = UseOrConstantAtStart(instr->right()); |
1731 return new(zone()) LCmpObjectEqAndBranch(left, right); | 1739 return new(zone()) LCmpObjectEqAndBranch(left, right); |
1732 } | 1740 } |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1810 | 1818 |
1811 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( | 1819 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( |
1812 HClassOfTestAndBranch* instr) { | 1820 HClassOfTestAndBranch* instr) { |
1813 ASSERT(instr->value()->representation().IsTagged()); | 1821 ASSERT(instr->value()->representation().IsTagged()); |
1814 return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()), | 1822 return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()), |
1815 TempRegister(), | 1823 TempRegister(), |
1816 TempRegister()); | 1824 TempRegister()); |
1817 } | 1825 } |
1818 | 1826 |
1819 | 1827 |
1820 LInstruction* LChunkBuilder::DoFixedArrayBaseLength( | |
1821 HFixedArrayBaseLength* instr) { | |
1822 LOperand* array = UseRegisterAtStart(instr->value()); | |
1823 return DefineAsRegister(new(zone()) LFixedArrayBaseLength(array)); | |
1824 } | |
1825 | |
1826 | |
1827 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { | 1828 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { |
1828 LOperand* map = UseRegisterAtStart(instr->value()); | 1829 LOperand* map = UseRegisterAtStart(instr->value()); |
1829 return DefineAsRegister(new(zone()) LMapEnumLength(map)); | 1830 return DefineAsRegister(new(zone()) LMapEnumLength(map)); |
1830 } | 1831 } |
1831 | 1832 |
1832 | 1833 |
1833 LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) { | 1834 LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) { |
1834 LOperand* object = UseRegisterAtStart(instr->value()); | 1835 LOperand* object = UseRegisterAtStart(instr->value()); |
1835 return DefineAsRegister(new(zone()) LElementsKind(object)); | 1836 return DefineAsRegister(new(zone()) LElementsKind(object)); |
1836 } | 1837 } |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2039 return NULL; | 2040 return NULL; |
2040 } | 2041 } |
2041 | 2042 |
2042 | 2043 |
2043 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) { | 2044 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) { |
2044 LOperand* value = UseAtStart(instr->value()); | 2045 LOperand* value = UseAtStart(instr->value()); |
2045 return AssignEnvironment(new(zone()) LCheckNonSmi(value)); | 2046 return AssignEnvironment(new(zone()) LCheckNonSmi(value)); |
2046 } | 2047 } |
2047 | 2048 |
2048 | 2049 |
| 2050 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { |
| 2051 LOperand* value = UseRegisterAtStart(instr->value()); |
| 2052 return AssignEnvironment(new(zone()) LCheckSmi(value)); |
| 2053 } |
| 2054 |
| 2055 |
| 2056 LInstruction* LChunkBuilder::DoIsNumberAndBranch(HIsNumberAndBranch* instr) { |
| 2057 return new(zone()) |
| 2058 LIsNumberAndBranch(UseRegisterOrConstantAtStart(instr->value())); |
| 2059 } |
| 2060 |
| 2061 |
2049 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { | 2062 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { |
2050 LOperand* value = UseRegisterAtStart(instr->value()); | 2063 LOperand* value = UseRegisterAtStart(instr->value()); |
2051 LOperand* temp = TempRegister(); | 2064 LOperand* temp = TempRegister(); |
2052 LCheckInstanceType* result = new(zone()) LCheckInstanceType(value, temp); | 2065 LCheckInstanceType* result = new(zone()) LCheckInstanceType(value, temp); |
2053 return AssignEnvironment(result); | 2066 return AssignEnvironment(result); |
2054 } | 2067 } |
2055 | 2068 |
2056 | 2069 |
2057 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { | 2070 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { |
2058 LUnallocated* temp = TempRegister(); | 2071 LUnallocated* temp = TempRegister(); |
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2790 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2803 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2791 LOperand* object = UseRegister(instr->object()); | 2804 LOperand* object = UseRegister(instr->object()); |
2792 LOperand* index = UseTempRegister(instr->index()); | 2805 LOperand* index = UseTempRegister(instr->index()); |
2793 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2806 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
2794 } | 2807 } |
2795 | 2808 |
2796 | 2809 |
2797 } } // namespace v8::internal | 2810 } } // namespace v8::internal |
2798 | 2811 |
2799 #endif // V8_TARGET_ARCH_IA32 | 2812 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |