OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "lithium-allocator-inl.h" | 7 #include "lithium-allocator-inl.h" |
8 #include "arm/lithium-arm.h" | 8 #include "arm/lithium-arm.h" |
9 #include "arm/lithium-codegen-arm.h" | 9 #include "arm/lithium-codegen-arm.h" |
10 #include "hydrogen-osr.h" | 10 #include "hydrogen-osr.h" |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 int vreg = allocator_->GetVirtualRegister(); | 621 int vreg = allocator_->GetVirtualRegister(); |
622 if (!allocator_->AllocationOk()) { | 622 if (!allocator_->AllocationOk()) { |
623 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); | 623 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); |
624 vreg = 0; | 624 vreg = 0; |
625 } | 625 } |
626 operand->set_virtual_register(vreg); | 626 operand->set_virtual_register(vreg); |
627 return operand; | 627 return operand; |
628 } | 628 } |
629 | 629 |
630 | 630 |
| 631 LUnallocated* LChunkBuilder::TempDoubleRegister() { |
| 632 LUnallocated* operand = |
| 633 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_DOUBLE_REGISTER); |
| 634 int vreg = allocator_->GetVirtualRegister(); |
| 635 if (!allocator_->AllocationOk()) { |
| 636 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); |
| 637 vreg = 0; |
| 638 } |
| 639 operand->set_virtual_register(vreg); |
| 640 return operand; |
| 641 } |
| 642 |
| 643 |
631 LOperand* LChunkBuilder::FixedTemp(Register reg) { | 644 LOperand* LChunkBuilder::FixedTemp(Register reg) { |
632 LUnallocated* operand = ToUnallocated(reg); | 645 LUnallocated* operand = ToUnallocated(reg); |
633 ASSERT(operand->HasFixedPolicy()); | 646 ASSERT(operand->HasFixedPolicy()); |
634 return operand; | 647 return operand; |
635 } | 648 } |
636 | 649 |
637 | 650 |
638 LOperand* LChunkBuilder::FixedTemp(DoubleRegister reg) { | 651 LOperand* LChunkBuilder::FixedTemp(DoubleRegister reg) { |
639 LUnallocated* operand = ToUnallocated(reg); | 652 LUnallocated* operand = ToUnallocated(reg); |
640 ASSERT(operand->HasFixedPolicy()); | 653 ASSERT(operand->HasFixedPolicy()); |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 | 1125 |
1113 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) { | 1126 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) { |
1114 LOperand* input = UseRegister(instr->value()); | 1127 LOperand* input = UseRegister(instr->value()); |
1115 LMathFloor* result = new(zone()) LMathFloor(input); | 1128 LMathFloor* result = new(zone()) LMathFloor(input); |
1116 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 1129 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
1117 } | 1130 } |
1118 | 1131 |
1119 | 1132 |
1120 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) { | 1133 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) { |
1121 LOperand* input = UseRegister(instr->value()); | 1134 LOperand* input = UseRegister(instr->value()); |
1122 LOperand* temp = FixedTemp(d3); | 1135 LOperand* temp = TempDoubleRegister(); |
1123 LMathRound* result = new(zone()) LMathRound(input, temp); | 1136 LMathRound* result = new(zone()) LMathRound(input, temp); |
1124 return AssignEnvironment(DefineAsRegister(result)); | 1137 return AssignEnvironment(DefineAsRegister(result)); |
1125 } | 1138 } |
1126 | 1139 |
1127 | 1140 |
1128 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { | 1141 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { |
1129 Representation r = instr->value()->representation(); | 1142 Representation r = instr->value()->representation(); |
1130 LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32()) | 1143 LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32()) |
1131 ? NULL | 1144 ? NULL |
1132 : UseFixed(instr->context(), cp); | 1145 : UseFixed(instr->context(), cp); |
(...skipping 20 matching lines...) Expand all Loading... |
1153 return DefineAsRegister(result); | 1166 return DefineAsRegister(result); |
1154 } | 1167 } |
1155 | 1168 |
1156 | 1169 |
1157 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { | 1170 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { |
1158 ASSERT(instr->representation().IsDouble()); | 1171 ASSERT(instr->representation().IsDouble()); |
1159 ASSERT(instr->value()->representation().IsDouble()); | 1172 ASSERT(instr->value()->representation().IsDouble()); |
1160 LOperand* input = UseRegister(instr->value()); | 1173 LOperand* input = UseRegister(instr->value()); |
1161 LOperand* temp1 = TempRegister(); | 1174 LOperand* temp1 = TempRegister(); |
1162 LOperand* temp2 = TempRegister(); | 1175 LOperand* temp2 = TempRegister(); |
1163 LOperand* double_temp = FixedTemp(d3); // Chosen by fair dice roll. | 1176 LOperand* double_temp = TempDoubleRegister(); |
1164 LMathExp* result = new(zone()) LMathExp(input, double_temp, temp1, temp2); | 1177 LMathExp* result = new(zone()) LMathExp(input, double_temp, temp1, temp2); |
1165 return DefineAsRegister(result); | 1178 return DefineAsRegister(result); |
1166 } | 1179 } |
1167 | 1180 |
1168 | 1181 |
1169 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { | 1182 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { |
1170 LOperand* input = UseRegisterAtStart(instr->value()); | 1183 LOperand* input = UseRegisterAtStart(instr->value()); |
1171 LMathSqrt* result = new(zone()) LMathSqrt(input); | 1184 LMathSqrt* result = new(zone()) LMathSqrt(input); |
1172 return DefineAsRegister(result); | 1185 return DefineAsRegister(result); |
1173 } | 1186 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 return result; | 1292 return result; |
1280 } | 1293 } |
1281 | 1294 |
1282 | 1295 |
1283 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) { | 1296 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) { |
1284 ASSERT(instr->representation().IsSmiOrInteger32()); | 1297 ASSERT(instr->representation().IsSmiOrInteger32()); |
1285 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1298 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1286 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1299 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1287 LOperand* dividend = UseRegister(instr->left()); | 1300 LOperand* dividend = UseRegister(instr->left()); |
1288 LOperand* divisor = UseRegister(instr->right()); | 1301 LOperand* divisor = UseRegister(instr->right()); |
1289 LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4); | 1302 LOperand* temp = |
| 1303 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); |
1290 LInstruction* result = | 1304 LInstruction* result = |
1291 DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp)); | 1305 DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp)); |
1292 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1306 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
1293 instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1307 instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
1294 (instr->CheckFlag(HValue::kCanOverflow) && | 1308 (instr->CheckFlag(HValue::kCanOverflow) && |
1295 (!CpuFeatures::IsSupported(SUDIV) || | 1309 (!CpuFeatures::IsSupported(SUDIV) || |
1296 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) || | 1310 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) || |
1297 (!instr->IsMathFloorOfDiv() && | 1311 (!instr->IsMathFloorOfDiv() && |
1298 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) { | 1312 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) { |
1299 result = AssignEnvironment(result); | 1313 result = AssignEnvironment(result); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1351 return result; | 1365 return result; |
1352 } | 1366 } |
1353 | 1367 |
1354 | 1368 |
1355 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { | 1369 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { |
1356 ASSERT(instr->representation().IsSmiOrInteger32()); | 1370 ASSERT(instr->representation().IsSmiOrInteger32()); |
1357 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1371 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1358 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1372 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1359 LOperand* dividend = UseRegister(instr->left()); | 1373 LOperand* dividend = UseRegister(instr->left()); |
1360 LOperand* divisor = UseRegister(instr->right()); | 1374 LOperand* divisor = UseRegister(instr->right()); |
1361 LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4); | 1375 LOperand* temp = |
| 1376 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); |
1362 LFlooringDivI* div = new(zone()) LFlooringDivI(dividend, divisor, temp); | 1377 LFlooringDivI* div = new(zone()) LFlooringDivI(dividend, divisor, temp); |
1363 return AssignEnvironment(DefineAsRegister(div)); | 1378 return AssignEnvironment(DefineAsRegister(div)); |
1364 } | 1379 } |
1365 | 1380 |
1366 | 1381 |
1367 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { | 1382 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
1368 if (instr->RightIsPowerOf2()) { | 1383 if (instr->RightIsPowerOf2()) { |
1369 return DoFlooringDivByPowerOf2I(instr); | 1384 return DoFlooringDivByPowerOf2I(instr); |
1370 } else if (instr->right()->IsConstant()) { | 1385 } else if (instr->right()->IsConstant()) { |
1371 return DoFlooringDivByConstI(instr); | 1386 return DoFlooringDivByConstI(instr); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1404 return result; | 1419 return result; |
1405 } | 1420 } |
1406 | 1421 |
1407 | 1422 |
1408 LInstruction* LChunkBuilder::DoModI(HMod* instr) { | 1423 LInstruction* LChunkBuilder::DoModI(HMod* instr) { |
1409 ASSERT(instr->representation().IsSmiOrInteger32()); | 1424 ASSERT(instr->representation().IsSmiOrInteger32()); |
1410 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1425 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1411 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1426 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1412 LOperand* dividend = UseRegister(instr->left()); | 1427 LOperand* dividend = UseRegister(instr->left()); |
1413 LOperand* divisor = UseRegister(instr->right()); | 1428 LOperand* divisor = UseRegister(instr->right()); |
1414 LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d10); | 1429 LOperand* temp = |
1415 LOperand* temp2 = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d11); | 1430 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); |
| 1431 LOperand* temp2 = |
| 1432 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); |
1416 LInstruction* result = DefineAsRegister(new(zone()) LModI( | 1433 LInstruction* result = DefineAsRegister(new(zone()) LModI( |
1417 dividend, divisor, temp, temp2)); | 1434 dividend, divisor, temp, temp2)); |
1418 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1435 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
1419 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1436 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1420 result = AssignEnvironment(result); | 1437 result = AssignEnvironment(result); |
1421 } | 1438 } |
1422 return result; | 1439 return result; |
1423 } | 1440 } |
1424 | 1441 |
1425 | 1442 |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1885 } | 1902 } |
1886 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); | 1903 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); |
1887 } else { | 1904 } else { |
1888 ASSERT(to.IsInteger32()); | 1905 ASSERT(to.IsInteger32()); |
1889 if (val->type().IsSmi() || val->representation().IsSmi()) { | 1906 if (val->type().IsSmi() || val->representation().IsSmi()) { |
1890 LOperand* value = UseRegisterAtStart(val); | 1907 LOperand* value = UseRegisterAtStart(val); |
1891 return DefineAsRegister(new(zone()) LSmiUntag(value, false)); | 1908 return DefineAsRegister(new(zone()) LSmiUntag(value, false)); |
1892 } else { | 1909 } else { |
1893 LOperand* value = UseRegister(val); | 1910 LOperand* value = UseRegister(val); |
1894 LOperand* temp1 = TempRegister(); | 1911 LOperand* temp1 = TempRegister(); |
1895 LOperand* temp2 = FixedTemp(d11); | 1912 LOperand* temp2 = TempDoubleRegister(); |
1896 LInstruction* result = | 1913 LInstruction* result = |
1897 DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2)); | 1914 DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2)); |
1898 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1915 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
1899 return result; | 1916 return result; |
1900 } | 1917 } |
1901 } | 1918 } |
1902 } else if (from.IsDouble()) { | 1919 } else if (from.IsDouble()) { |
1903 if (to.IsTagged()) { | 1920 if (to.IsTagged()) { |
1904 info()->MarkAsDeferredCalling(); | 1921 info()->MarkAsDeferredCalling(); |
1905 LOperand* value = UseRegister(val); | 1922 LOperand* value = UseRegister(val); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2003 Representation input_rep = value->representation(); | 2020 Representation input_rep = value->representation(); |
2004 LOperand* reg = UseRegister(value); | 2021 LOperand* reg = UseRegister(value); |
2005 if (input_rep.IsDouble()) { | 2022 if (input_rep.IsDouble()) { |
2006 return DefineAsRegister(new(zone()) LClampDToUint8(reg)); | 2023 return DefineAsRegister(new(zone()) LClampDToUint8(reg)); |
2007 } else if (input_rep.IsInteger32()) { | 2024 } else if (input_rep.IsInteger32()) { |
2008 return DefineAsRegister(new(zone()) LClampIToUint8(reg)); | 2025 return DefineAsRegister(new(zone()) LClampIToUint8(reg)); |
2009 } else { | 2026 } else { |
2010 ASSERT(input_rep.IsSmiOrTagged()); | 2027 ASSERT(input_rep.IsSmiOrTagged()); |
2011 // Register allocator doesn't (yet) support allocation of double | 2028 // Register allocator doesn't (yet) support allocation of double |
2012 // temps. Reserve d1 explicitly. | 2029 // temps. Reserve d1 explicitly. |
2013 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, FixedTemp(d11)); | 2030 LClampTToUint8* result = |
| 2031 new(zone()) LClampTToUint8(reg, TempDoubleRegister()); |
2014 return AssignEnvironment(DefineAsRegister(result)); | 2032 return AssignEnvironment(DefineAsRegister(result)); |
2015 } | 2033 } |
2016 } | 2034 } |
2017 | 2035 |
2018 | 2036 |
2019 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { | 2037 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { |
2020 HValue* value = instr->value(); | 2038 HValue* value = instr->value(); |
2021 ASSERT(value->representation().IsDouble()); | 2039 ASSERT(value->representation().IsDouble()); |
2022 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); | 2040 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); |
2023 } | 2041 } |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2569 | 2587 |
2570 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2588 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2571 LOperand* object = UseRegister(instr->object()); | 2589 LOperand* object = UseRegister(instr->object()); |
2572 LOperand* index = UseTempRegister(instr->index()); | 2590 LOperand* index = UseTempRegister(instr->index()); |
2573 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); | 2591 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); |
2574 LInstruction* result = DefineSameAsFirst(load); | 2592 LInstruction* result = DefineSameAsFirst(load); |
2575 return AssignPointerMap(result); | 2593 return AssignPointerMap(result); |
2576 } | 2594 } |
2577 | 2595 |
2578 } } // namespace v8::internal | 2596 } } // namespace v8::internal |
OLD | NEW |