| 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 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1345 | 1345 |
| 1346 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1346 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1347 if (instr->representation().IsInteger32()) { | 1347 if (instr->representation().IsInteger32()) { |
| 1348 // TODO(1042) The fixed register allocation | 1348 // TODO(1042) The fixed register allocation |
| 1349 // is needed because we call GenericBinaryOpStub from | 1349 // is needed because we call GenericBinaryOpStub from |
| 1350 // the generated code, which requires registers r0 | 1350 // the generated code, which requires registers r0 |
| 1351 // and r1 to be used. We should remove that | 1351 // and r1 to be used. We should remove that |
| 1352 // when we provide a native implementation. | 1352 // when we provide a native implementation. |
| 1353 ASSERT(instr->left()->representation().IsInteger32()); | 1353 ASSERT(instr->left()->representation().IsInteger32()); |
| 1354 ASSERT(instr->right()->representation().IsInteger32()); | 1354 ASSERT(instr->right()->representation().IsInteger32()); |
| 1355 LOperand* value = UseFixed(instr->left(), r0); | 1355 |
| 1356 LOperand* divisor = UseFixed(instr->right(), r1); | 1356 LInstruction* result; |
| 1357 LInstruction* result = DefineFixed(new LModI(value, divisor), r0); | 1357 if (instr->HasPowerOf2Divisor()) { |
| 1358 result = AssignEnvironment(AssignPointerMap(result)); | 1358 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); |
| 1359 LOperand* value = UseRegisterAtStart(instr->left()); |
| 1360 LModI* mod = new LModI(value, UseOrConstant(instr->right())); |
| 1361 result = DefineSameAsFirst(mod); |
| 1362 result = AssignEnvironment(result); |
| 1363 } else { |
| 1364 LOperand* value = UseFixed(instr->left(), r0); |
| 1365 LOperand* divisor = UseFixed(instr->right(), r1); |
| 1366 result = DefineFixed(new LModI(value, divisor), r0); |
| 1367 result = AssignEnvironment(AssignPointerMap(result)); |
| 1368 } |
| 1369 |
| 1359 return result; | 1370 return result; |
| 1360 } else if (instr->representation().IsTagged()) { | 1371 } else if (instr->representation().IsTagged()) { |
| 1361 return DoArithmeticT(Token::MOD, instr); | 1372 return DoArithmeticT(Token::MOD, instr); |
| 1362 } else { | 1373 } else { |
| 1363 ASSERT(instr->representation().IsDouble()); | 1374 ASSERT(instr->representation().IsDouble()); |
| 1364 // We call a C function for double modulo. It can't trigger a GC. | 1375 // We call a C function for double modulo. It can't trigger a GC. |
| 1365 // We need to use fixed result register for the call. | 1376 // We need to use fixed result register for the call. |
| 1366 // TODO(fschneider): Allow any register as input registers. | 1377 // TODO(fschneider): Allow any register as input registers. |
| 1367 LOperand* left = UseFixedDouble(instr->left(), d1); | 1378 LOperand* left = UseFixedDouble(instr->left(), d1); |
| 1368 LOperand* right = UseFixedDouble(instr->right(), d2); | 1379 LOperand* right = UseFixedDouble(instr->right(), d2); |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1594 if (from.IsTagged()) { | 1605 if (from.IsTagged()) { |
| 1595 if (to.IsDouble()) { | 1606 if (to.IsDouble()) { |
| 1596 LOperand* value = UseRegister(instr->value()); | 1607 LOperand* value = UseRegister(instr->value()); |
| 1597 LNumberUntagD* res = new LNumberUntagD(value); | 1608 LNumberUntagD* res = new LNumberUntagD(value); |
| 1598 return AssignEnvironment(DefineAsRegister(res)); | 1609 return AssignEnvironment(DefineAsRegister(res)); |
| 1599 } else { | 1610 } else { |
| 1600 ASSERT(to.IsInteger32()); | 1611 ASSERT(to.IsInteger32()); |
| 1601 LOperand* value = UseRegister(instr->value()); | 1612 LOperand* value = UseRegister(instr->value()); |
| 1602 bool needs_check = !instr->value()->type().IsSmi(); | 1613 bool needs_check = !instr->value()->type().IsSmi(); |
| 1603 LInstruction* res = NULL; | 1614 LInstruction* res = NULL; |
| 1604 if (needs_check) { | 1615 if (!needs_check) { |
| 1605 res = DefineSameAsFirst(new LTaggedToI(value, FixedTemp(d1))); | 1616 res = DefineSameAsFirst(new LSmiUntag(value, needs_check)); |
| 1606 } else { | 1617 } else { |
| 1607 res = DefineSameAsFirst(new LSmiUntag(value, needs_check)); | 1618 LOperand* temp1 = TempRegister(); |
| 1608 } | 1619 LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister() |
| 1609 if (needs_check) { | 1620 : NULL; |
| 1621 LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(d3) |
| 1622 : NULL; |
| 1623 res = DefineSameAsFirst(new LTaggedToI(value, temp1, temp2, temp3)); |
| 1610 res = AssignEnvironment(res); | 1624 res = AssignEnvironment(res); |
| 1611 } | 1625 } |
| 1612 return res; | 1626 return res; |
| 1613 } | 1627 } |
| 1614 } else if (from.IsDouble()) { | 1628 } else if (from.IsDouble()) { |
| 1615 if (to.IsTagged()) { | 1629 if (to.IsTagged()) { |
| 1616 LOperand* value = UseRegister(instr->value()); | 1630 LOperand* value = UseRegister(instr->value()); |
| 1617 LOperand* temp1 = TempRegister(); | 1631 LOperand* temp1 = TempRegister(); |
| 1618 LOperand* temp2 = TempRegister(); | 1632 LOperand* temp2 = TempRegister(); |
| 1619 | 1633 |
| 1620 // Make sure that the temp and result_temp registers are | 1634 // Make sure that the temp and result_temp registers are |
| 1621 // different. | 1635 // different. |
| 1622 LUnallocated* result_temp = TempRegister(); | 1636 LUnallocated* result_temp = TempRegister(); |
| 1623 LNumberTagD* result = new LNumberTagD(value, temp1, temp2); | 1637 LNumberTagD* result = new LNumberTagD(value, temp1, temp2); |
| 1624 Define(result, result_temp); | 1638 Define(result, result_temp); |
| 1625 return AssignPointerMap(result); | 1639 return AssignPointerMap(result); |
| 1626 } else { | 1640 } else { |
| 1627 ASSERT(to.IsInteger32()); | 1641 ASSERT(to.IsInteger32()); |
| 1628 LOperand* value = UseRegister(instr->value()); | 1642 LOperand* value = UseRegister(instr->value()); |
| 1629 LDoubleToI* res = new LDoubleToI(value, TempRegister()); | 1643 LDoubleToI* res = |
| 1644 new LDoubleToI(value, |
| 1645 TempRegister(), |
| 1646 instr->CanTruncateToInt32() ? TempRegister() : NULL); |
| 1630 return AssignEnvironment(DefineAsRegister(res)); | 1647 return AssignEnvironment(DefineAsRegister(res)); |
| 1631 } | 1648 } |
| 1632 } else if (from.IsInteger32()) { | 1649 } else if (from.IsInteger32()) { |
| 1633 if (to.IsTagged()) { | 1650 if (to.IsTagged()) { |
| 1634 HValue* val = instr->value(); | 1651 HValue* val = instr->value(); |
| 1635 LOperand* value = UseRegister(val); | 1652 LOperand* value = UseRegister(val); |
| 1636 if (val->HasRange() && val->range()->IsInSmiRange()) { | 1653 if (val->HasRange() && val->range()->IsInSmiRange()) { |
| 1637 return DefineSameAsFirst(new LSmiTag(value)); | 1654 return DefineSameAsFirst(new LSmiTag(value)); |
| 1638 } else { | 1655 } else { |
| 1639 LNumberTagI* result = new LNumberTagI(value); | 1656 LNumberTagI* result = new LNumberTagI(value); |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1888 | 1905 |
| 1889 | 1906 |
| 1890 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { | 1907 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 1891 LOperand* string = UseRegister(instr->string()); | 1908 LOperand* string = UseRegister(instr->string()); |
| 1892 LOperand* index = UseRegisterOrConstant(instr->index()); | 1909 LOperand* index = UseRegisterOrConstant(instr->index()); |
| 1893 LStringCharCodeAt* result = new LStringCharCodeAt(string, index); | 1910 LStringCharCodeAt* result = new LStringCharCodeAt(string, index); |
| 1894 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 1911 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 1895 } | 1912 } |
| 1896 | 1913 |
| 1897 | 1914 |
| 1915 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { |
| 1916 LOperand* char_code = UseRegister(instr->value()); |
| 1917 LStringCharFromCode* result = new LStringCharFromCode(char_code); |
| 1918 return AssignPointerMap(DefineAsRegister(result)); |
| 1919 } |
| 1920 |
| 1921 |
| 1898 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { | 1922 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { |
| 1899 LOperand* string = UseRegisterAtStart(instr->value()); | 1923 LOperand* string = UseRegisterAtStart(instr->value()); |
| 1900 return DefineAsRegister(new LStringLength(string)); | 1924 return DefineAsRegister(new LStringLength(string)); |
| 1901 } | 1925 } |
| 1902 | 1926 |
| 1903 | 1927 |
| 1904 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 1928 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { |
| 1905 return MarkAsCall(DefineFixed(new LArrayLiteral, r0), instr); | 1929 return MarkAsCall(DefineFixed(new LArrayLiteral, r0), instr); |
| 1906 } | 1930 } |
| 1907 | 1931 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2040 | 2064 |
| 2041 | 2065 |
| 2042 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2066 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 2043 HEnvironment* outer = current_block_->last_environment()->outer(); | 2067 HEnvironment* outer = current_block_->last_environment()->outer(); |
| 2044 current_block_->UpdateEnvironment(outer); | 2068 current_block_->UpdateEnvironment(outer); |
| 2045 return NULL; | 2069 return NULL; |
| 2046 } | 2070 } |
| 2047 | 2071 |
| 2048 | 2072 |
| 2049 } } // namespace v8::internal | 2073 } } // namespace v8::internal |
| OLD | NEW |