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 |
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
699 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); | 699 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); |
700 } | 700 } |
701 | 701 |
702 | 702 |
703 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) { | 703 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) { |
704 UNREACHABLE(); | 704 UNREACHABLE(); |
705 return NULL; | 705 return NULL; |
706 } | 706 } |
707 | 707 |
708 | 708 |
709 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) { | |
710 return AssignEnvironment(new(zone()) LDeoptimize); | |
711 } | |
712 | |
713 | |
714 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 709 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
715 return AssignEnvironment(new(zone()) LDeoptimize); | 710 return AssignEnvironment(new(zone()) LDeoptimize); |
716 } | 711 } |
717 | 712 |
718 | 713 |
719 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 714 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
720 HBitwiseBinaryOperation* instr) { | 715 HBitwiseBinaryOperation* instr) { |
721 if (instr->representation().IsSmiOrTagged()) { | 716 if (instr->representation().IsTagged()) { |
722 ASSERT(instr->left()->representation().IsSmiOrTagged()); | 717 ASSERT(instr->left()->representation().IsTagged()); |
723 ASSERT(instr->right()->representation().IsSmiOrTagged()); | 718 ASSERT(instr->right()->representation().IsTagged()); |
724 | 719 |
725 LOperand* left = UseFixed(instr->left(), a1); | 720 LOperand* left = UseFixed(instr->left(), a1); |
726 LOperand* right = UseFixed(instr->right(), a0); | 721 LOperand* right = UseFixed(instr->right(), a0); |
727 LArithmeticT* result = new(zone()) LArithmeticT(op, left, right); | 722 LArithmeticT* result = new(zone()) LArithmeticT(op, left, right); |
728 return MarkAsCall(DefineFixed(result, v0), instr); | 723 return MarkAsCall(DefineFixed(result, v0), instr); |
729 } | 724 } |
730 | 725 |
731 ASSERT(instr->representation().IsInteger32()); | 726 ASSERT(instr->representation().IsSmiOrInteger32()); |
732 ASSERT(instr->left()->representation().IsInteger32()); | 727 ASSERT(instr->left()->representation().Equals(instr->representation())); |
733 ASSERT(instr->right()->representation().IsInteger32()); | 728 ASSERT(instr->right()->representation().Equals(instr->representation())); |
734 LOperand* left = UseRegisterAtStart(instr->left()); | 729 LOperand* left = UseRegisterAtStart(instr->left()); |
735 | 730 |
736 HValue* right_value = instr->right(); | 731 HValue* right_value = instr->right(); |
737 LOperand* right = NULL; | 732 LOperand* right = NULL; |
738 int constant_value = 0; | 733 int constant_value = 0; |
| 734 bool does_deopt = false; |
739 if (right_value->IsConstant()) { | 735 if (right_value->IsConstant()) { |
740 HConstant* constant = HConstant::cast(right_value); | 736 HConstant* constant = HConstant::cast(right_value); |
741 right = chunk_->DefineConstantOperand(constant); | 737 right = chunk_->DefineConstantOperand(constant); |
742 constant_value = constant->Integer32Value() & 0x1f; | 738 constant_value = constant->Integer32Value() & 0x1f; |
| 739 // Left shifts can deoptimize if we shift by > 0 and the result cannot be |
| 740 // truncated to smi. |
| 741 if (instr->representation().IsSmi() && constant_value > 0) { |
| 742 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { |
| 743 if (!it.value()->CheckFlag(HValue::kTruncatingToSmi)) { |
| 744 does_deopt = true; |
| 745 break; |
| 746 } |
| 747 } |
| 748 } |
743 } else { | 749 } else { |
744 right = UseRegisterAtStart(right_value); | 750 right = UseRegisterAtStart(right_value); |
745 } | 751 } |
746 | 752 |
747 // Shift operations can only deoptimize if we do a logical shift | 753 // Shift operations can deoptimize if we do a logical shift |
748 // by 0 and the result cannot be truncated to int32. | 754 // by 0 and the result cannot be truncated to int32. |
749 bool does_deopt = false; | |
750 if (op == Token::SHR && constant_value == 0) { | 755 if (op == Token::SHR && constant_value == 0) { |
751 if (FLAG_opt_safe_uint32_operations) { | 756 if (FLAG_opt_safe_uint32_operations) { |
752 does_deopt = !instr->CheckFlag(HInstruction::kUint32); | 757 does_deopt = !instr->CheckFlag(HInstruction::kUint32); |
753 } else { | 758 } else { |
754 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { | 759 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { |
755 if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) { | 760 if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) { |
756 does_deopt = true; | 761 does_deopt = true; |
757 break; | 762 break; |
758 } | 763 } |
759 } | 764 } |
(...skipping 21 matching lines...) Expand all Loading... |
781 | 786 |
782 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 787 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
783 HArithmeticBinaryOperation* instr) { | 788 HArithmeticBinaryOperation* instr) { |
784 ASSERT(op == Token::ADD || | 789 ASSERT(op == Token::ADD || |
785 op == Token::DIV || | 790 op == Token::DIV || |
786 op == Token::MOD || | 791 op == Token::MOD || |
787 op == Token::MUL || | 792 op == Token::MUL || |
788 op == Token::SUB); | 793 op == Token::SUB); |
789 HValue* left = instr->left(); | 794 HValue* left = instr->left(); |
790 HValue* right = instr->right(); | 795 HValue* right = instr->right(); |
791 ASSERT(left->representation().IsSmiOrTagged()); | 796 ASSERT(left->representation().IsTagged()); |
792 ASSERT(right->representation().IsSmiOrTagged()); | 797 ASSERT(right->representation().IsTagged()); |
793 LOperand* left_operand = UseFixed(left, a1); | 798 LOperand* left_operand = UseFixed(left, a1); |
794 LOperand* right_operand = UseFixed(right, a0); | 799 LOperand* right_operand = UseFixed(right, a0); |
795 LArithmeticT* result = | 800 LArithmeticT* result = |
796 new(zone()) LArithmeticT(op, left_operand, right_operand); | 801 new(zone()) LArithmeticT(op, left_operand, right_operand); |
797 return MarkAsCall(DefineFixed(result, v0), instr); | 802 return MarkAsCall(DefineFixed(result, v0), instr); |
798 } | 803 } |
799 | 804 |
800 | 805 |
801 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 806 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
802 ASSERT(is_building()); | 807 ASSERT(is_building()); |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1313 return DoShift(Token::SAR, instr); | 1318 return DoShift(Token::SAR, instr); |
1314 } | 1319 } |
1315 | 1320 |
1316 | 1321 |
1317 LInstruction* LChunkBuilder::DoShl(HShl* instr) { | 1322 LInstruction* LChunkBuilder::DoShl(HShl* instr) { |
1318 return DoShift(Token::SHL, instr); | 1323 return DoShift(Token::SHL, instr); |
1319 } | 1324 } |
1320 | 1325 |
1321 | 1326 |
1322 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { | 1327 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { |
1323 if (instr->representation().IsInteger32()) { | 1328 if (instr->representation().IsSmiOrInteger32()) { |
1324 ASSERT(instr->left()->representation().IsInteger32()); | 1329 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1325 ASSERT(instr->right()->representation().IsInteger32()); | 1330 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1326 | 1331 |
1327 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1332 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1328 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1333 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); |
1329 return DefineAsRegister(new(zone()) LBitI(left, right)); | 1334 return DefineAsRegister(new(zone()) LBitI(left, right)); |
1330 } else { | 1335 } else { |
1331 ASSERT(instr->representation().IsSmiOrTagged()); | 1336 ASSERT(instr->representation().IsTagged()); |
1332 ASSERT(instr->left()->representation().IsSmiOrTagged()); | 1337 ASSERT(instr->left()->representation().IsTagged()); |
1333 ASSERT(instr->right()->representation().IsSmiOrTagged()); | 1338 ASSERT(instr->right()->representation().IsTagged()); |
1334 | 1339 |
1335 LOperand* left = UseFixed(instr->left(), a1); | 1340 LOperand* left = UseFixed(instr->left(), a1); |
1336 LOperand* right = UseFixed(instr->right(), a0); | 1341 LOperand* right = UseFixed(instr->right(), a0); |
1337 LArithmeticT* result = new(zone()) LArithmeticT(instr->op(), left, right); | 1342 LArithmeticT* result = new(zone()) LArithmeticT(instr->op(), left, right); |
1338 return MarkAsCall(DefineFixed(result, v0), instr); | 1343 return MarkAsCall(DefineFixed(result, v0), instr); |
1339 } | 1344 } |
1340 } | 1345 } |
1341 | 1346 |
1342 | 1347 |
1343 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { | 1348 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { |
1344 ASSERT(instr->value()->representation().IsInteger32()); | 1349 ASSERT(instr->value()->representation().IsInteger32()); |
1345 ASSERT(instr->representation().IsInteger32()); | 1350 ASSERT(instr->representation().IsInteger32()); |
1346 if (instr->HasNoUses()) return NULL; | 1351 if (instr->HasNoUses()) return NULL; |
1347 LOperand* value = UseRegisterAtStart(instr->value()); | 1352 LOperand* value = UseRegisterAtStart(instr->value()); |
1348 return DefineAsRegister(new(zone()) LBitNotI(value)); | 1353 return DefineAsRegister(new(zone()) LBitNotI(value)); |
1349 } | 1354 } |
1350 | 1355 |
1351 | 1356 |
1352 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1357 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
1353 if (instr->representation().IsDouble()) { | 1358 if (instr->representation().IsDouble()) { |
1354 return DoArithmeticD(Token::DIV, instr); | 1359 return DoArithmeticD(Token::DIV, instr); |
1355 } else if (instr->representation().IsInteger32()) { | 1360 } else if (instr->representation().IsSmiOrInteger32()) { |
| 1361 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1362 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1356 LOperand* dividend = UseRegister(instr->left()); | 1363 LOperand* dividend = UseRegister(instr->left()); |
1357 LOperand* divisor = UseRegister(instr->right()); | 1364 LOperand* divisor = UseRegister(instr->right()); |
1358 LDivI* div = new(zone()) LDivI(dividend, divisor); | 1365 LDivI* div = new(zone()) LDivI(dividend, divisor); |
1359 return AssignEnvironment(DefineAsRegister(div)); | 1366 return AssignEnvironment(DefineAsRegister(div)); |
1360 } else { | 1367 } else { |
1361 return DoArithmeticT(Token::DIV, instr); | 1368 return DoArithmeticT(Token::DIV, instr); |
1362 } | 1369 } |
1363 } | 1370 } |
1364 | 1371 |
1365 | 1372 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1412 ASSERT(right->IsConstant() && | 1419 ASSERT(right->IsConstant() && |
1413 HConstant::cast(right)->HasInteger32Value()); | 1420 HConstant::cast(right)->HasInteger32Value()); |
1414 return AssignEnvironment(DefineAsRegister( | 1421 return AssignEnvironment(DefineAsRegister( |
1415 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); | 1422 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); |
1416 } | 1423 } |
1417 | 1424 |
1418 | 1425 |
1419 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1426 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
1420 HValue* left = instr->left(); | 1427 HValue* left = instr->left(); |
1421 HValue* right = instr->right(); | 1428 HValue* right = instr->right(); |
1422 if (instr->representation().IsInteger32()) { | 1429 if (instr->representation().IsSmiOrInteger32()) { |
1423 ASSERT(left->representation().IsInteger32()); | 1430 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1424 ASSERT(right->representation().IsInteger32()); | 1431 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1425 if (instr->HasPowerOf2Divisor()) { | 1432 if (instr->HasPowerOf2Divisor()) { |
1426 ASSERT(!right->CanBeZero()); | 1433 ASSERT(!right->CanBeZero()); |
1427 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), | 1434 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), |
1428 UseOrConstant(right)); | 1435 UseOrConstant(right)); |
1429 LInstruction* result = DefineAsRegister(mod); | 1436 LInstruction* result = DefineAsRegister(mod); |
1430 return (left->CanBeNegative() && | 1437 return (left->CanBeNegative() && |
1431 instr->CheckFlag(HValue::kBailoutOnMinusZero)) | 1438 instr->CheckFlag(HValue::kBailoutOnMinusZero)) |
1432 ? AssignEnvironment(result) | 1439 ? AssignEnvironment(result) |
1433 : result; | 1440 : result; |
1434 } else if (instr->fixed_right_arg().has_value) { | 1441 } else if (instr->fixed_right_arg().has_value) { |
1435 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), | 1442 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), |
1436 UseRegisterAtStart(right)); | 1443 UseRegisterAtStart(right)); |
1437 return AssignEnvironment(DefineAsRegister(mod)); | 1444 return AssignEnvironment(DefineAsRegister(mod)); |
1438 } else { | 1445 } else { |
1439 LModI* mod = new(zone()) LModI(UseRegister(left), | 1446 LModI* mod = new(zone()) LModI(UseRegister(left), |
1440 UseRegister(right), | 1447 UseRegister(right), |
1441 TempRegister(), | 1448 TempRegister(), |
1442 FixedTemp(f20), | 1449 FixedTemp(f20), |
1443 FixedTemp(f22)); | 1450 FixedTemp(f22)); |
1444 LInstruction* result = DefineAsRegister(mod); | 1451 LInstruction* result = DefineAsRegister(mod); |
1445 return (right->CanBeZero() || | 1452 return (right->CanBeZero() || |
1446 (left->RangeCanInclude(kMinInt) && | 1453 (left->RangeCanInclude(kMinInt) && |
1447 right->RangeCanInclude(-1)) || | 1454 right->RangeCanInclude(-1)) || |
1448 instr->CheckFlag(HValue::kBailoutOnMinusZero)) | 1455 instr->CheckFlag(HValue::kBailoutOnMinusZero)) |
1449 ? AssignEnvironment(result) | 1456 ? AssignEnvironment(result) |
1450 : result; | 1457 : result; |
1451 } | 1458 } |
1452 } else if (instr->representation().IsSmiOrTagged()) { | 1459 } else if (instr->representation().IsTagged()) { |
1453 return DoArithmeticT(Token::MOD, instr); | 1460 return DoArithmeticT(Token::MOD, instr); |
1454 } else { | 1461 } else { |
1455 ASSERT(instr->representation().IsDouble()); | 1462 ASSERT(instr->representation().IsDouble()); |
1456 // We call a C function for double modulo. It can't trigger a GC. We need | 1463 // We call a C function for double modulo. It can't trigger a GC. We need |
1457 // to use fixed result register for the call. | 1464 // to use fixed result register for the call. |
1458 // TODO(fschneider): Allow any register as input registers. | 1465 // TODO(fschneider): Allow any register as input registers. |
1459 LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD, | 1466 LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD, |
1460 UseFixedDouble(left, f2), | 1467 UseFixedDouble(left, f2), |
1461 UseFixedDouble(right, f4)); | 1468 UseFixedDouble(right, f4)); |
1462 return MarkAsCall(DefineFixedDouble(mod, f2), instr); | 1469 return MarkAsCall(DefineFixedDouble(mod, f2), instr); |
1463 } | 1470 } |
1464 } | 1471 } |
1465 | 1472 |
1466 | 1473 |
1467 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1474 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
1468 if (instr->representation().IsInteger32()) { | 1475 if (instr->representation().IsSmiOrInteger32()) { |
1469 ASSERT(instr->left()->representation().IsInteger32()); | 1476 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1470 ASSERT(instr->right()->representation().IsInteger32()); | 1477 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1471 LOperand* left; | 1478 LOperand* left; |
1472 LOperand* right = UseOrConstant(instr->BetterRightOperand()); | 1479 LOperand* right = UseOrConstant(instr->BetterRightOperand()); |
1473 LOperand* temp = NULL; | 1480 LOperand* temp = NULL; |
1474 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) && | 1481 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) && |
1475 (instr->CheckFlag(HValue::kCanOverflow) || | 1482 (instr->CheckFlag(HValue::kCanOverflow) || |
1476 !right->IsConstantOperand())) { | 1483 !right->IsConstantOperand())) { |
1477 left = UseRegister(instr->BetterLeftOperand()); | 1484 left = UseRegister(instr->BetterLeftOperand()); |
1478 temp = TempRegister(); | 1485 temp = TempRegister(); |
1479 } else { | 1486 } else { |
1480 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1487 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
(...skipping 22 matching lines...) Expand all Loading... |
1503 } | 1510 } |
1504 } | 1511 } |
1505 return DoArithmeticD(Token::MUL, instr); | 1512 return DoArithmeticD(Token::MUL, instr); |
1506 } else { | 1513 } else { |
1507 return DoArithmeticT(Token::MUL, instr); | 1514 return DoArithmeticT(Token::MUL, instr); |
1508 } | 1515 } |
1509 } | 1516 } |
1510 | 1517 |
1511 | 1518 |
1512 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1519 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
1513 if (instr->representation().IsInteger32()) { | 1520 if (instr->representation().IsSmiOrInteger32()) { |
1514 ASSERT(instr->left()->representation().IsInteger32()); | 1521 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1515 ASSERT(instr->right()->representation().IsInteger32()); | 1522 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1516 LOperand* left = UseRegisterAtStart(instr->left()); | 1523 LOperand* left = UseRegisterAtStart(instr->left()); |
1517 LOperand* right = UseOrConstantAtStart(instr->right()); | 1524 LOperand* right = UseOrConstantAtStart(instr->right()); |
1518 LSubI* sub = new(zone()) LSubI(left, right); | 1525 LSubI* sub = new(zone()) LSubI(left, right); |
1519 LInstruction* result = DefineAsRegister(sub); | 1526 LInstruction* result = DefineAsRegister(sub); |
1520 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1527 if (instr->CheckFlag(HValue::kCanOverflow)) { |
1521 result = AssignEnvironment(result); | 1528 result = AssignEnvironment(result); |
1522 } | 1529 } |
1523 return result; | 1530 return result; |
1524 } else if (instr->representation().IsDouble()) { | 1531 } else if (instr->representation().IsDouble()) { |
1525 return DoArithmeticD(Token::SUB, instr); | 1532 return DoArithmeticD(Token::SUB, instr); |
1526 } else { | 1533 } else { |
1527 return DoArithmeticT(Token::SUB, instr); | 1534 return DoArithmeticT(Token::SUB, instr); |
1528 } | 1535 } |
1529 } | 1536 } |
1530 | 1537 |
1531 | 1538 |
1532 LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) { | 1539 LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) { |
1533 LOperand* multiplier_op = UseRegisterAtStart(mul->left()); | 1540 LOperand* multiplier_op = UseRegisterAtStart(mul->left()); |
1534 LOperand* multiplicand_op = UseRegisterAtStart(mul->right()); | 1541 LOperand* multiplicand_op = UseRegisterAtStart(mul->right()); |
1535 LOperand* addend_op = UseRegisterAtStart(addend); | 1542 LOperand* addend_op = UseRegisterAtStart(addend); |
1536 return DefineSameAsFirst(new(zone()) LMultiplyAddD(addend_op, multiplier_op, | 1543 return DefineSameAsFirst(new(zone()) LMultiplyAddD(addend_op, multiplier_op, |
1537 multiplicand_op)); | 1544 multiplicand_op)); |
1538 } | 1545 } |
1539 | 1546 |
1540 | 1547 |
1541 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { | 1548 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { |
1542 if (instr->representation().IsInteger32()) { | 1549 if (instr->representation().IsSmiOrInteger32()) { |
1543 ASSERT(instr->left()->representation().IsInteger32()); | 1550 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1544 ASSERT(instr->right()->representation().IsInteger32()); | 1551 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1545 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1552 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1546 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1553 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); |
1547 LAddI* add = new(zone()) LAddI(left, right); | 1554 LAddI* add = new(zone()) LAddI(left, right); |
1548 LInstruction* result = DefineAsRegister(add); | 1555 LInstruction* result = DefineAsRegister(add); |
1549 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1556 if (instr->CheckFlag(HValue::kCanOverflow)) { |
1550 result = AssignEnvironment(result); | 1557 result = AssignEnvironment(result); |
1551 } | 1558 } |
1552 return result; | 1559 return result; |
1553 } else if (instr->representation().IsDouble()) { | 1560 } else if (instr->representation().IsDouble()) { |
1554 if (kArchVariant == kMips32r2) { | 1561 if (kArchVariant == kMips32r2) { |
1555 if (instr->left()->IsMul()) | 1562 if (instr->left()->IsMul()) |
1556 return DoMultiplyAdd(HMul::cast(instr->left()), instr->right()); | 1563 return DoMultiplyAdd(HMul::cast(instr->left()), instr->right()); |
1557 | 1564 |
1558 if (instr->right()->IsMul()) { | 1565 if (instr->right()->IsMul()) { |
1559 ASSERT(!instr->left()->IsMul()); | 1566 ASSERT(!instr->left()->IsMul()); |
1560 return DoMultiplyAdd(HMul::cast(instr->right()), instr->left()); | 1567 return DoMultiplyAdd(HMul::cast(instr->right()), instr->left()); |
1561 } | 1568 } |
1562 } | 1569 } |
1563 return DoArithmeticD(Token::ADD, instr); | 1570 return DoArithmeticD(Token::ADD, instr); |
1564 } else { | 1571 } else { |
1565 ASSERT(instr->representation().IsSmiOrTagged()); | 1572 ASSERT(instr->representation().IsTagged()); |
1566 return DoArithmeticT(Token::ADD, instr); | 1573 return DoArithmeticT(Token::ADD, instr); |
1567 } | 1574 } |
1568 } | 1575 } |
1569 | 1576 |
1570 | 1577 |
1571 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1578 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
1572 LOperand* left = NULL; | 1579 LOperand* left = NULL; |
1573 LOperand* right = NULL; | 1580 LOperand* right = NULL; |
1574 if (instr->representation().IsInteger32()) { | 1581 if (instr->representation().IsSmiOrInteger32()) { |
1575 ASSERT(instr->left()->representation().IsInteger32()); | 1582 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1576 ASSERT(instr->right()->representation().IsInteger32()); | 1583 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1577 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1584 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1578 right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1585 right = UseOrConstantAtStart(instr->BetterRightOperand()); |
1579 } else { | 1586 } else { |
1580 ASSERT(instr->representation().IsDouble()); | 1587 ASSERT(instr->representation().IsDouble()); |
1581 ASSERT(instr->left()->representation().IsDouble()); | 1588 ASSERT(instr->left()->representation().IsDouble()); |
1582 ASSERT(instr->right()->representation().IsDouble()); | 1589 ASSERT(instr->right()->representation().IsDouble()); |
1583 left = UseRegisterAtStart(instr->left()); | 1590 left = UseRegisterAtStart(instr->left()); |
1584 right = UseRegisterAtStart(instr->right()); | 1591 right = UseRegisterAtStart(instr->right()); |
1585 } | 1592 } |
1586 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); | 1593 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1645 | 1652 |
1646 | 1653 |
1647 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( | 1654 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( |
1648 HCompareObjectEqAndBranch* instr) { | 1655 HCompareObjectEqAndBranch* instr) { |
1649 LOperand* left = UseRegisterAtStart(instr->left()); | 1656 LOperand* left = UseRegisterAtStart(instr->left()); |
1650 LOperand* right = UseRegisterAtStart(instr->right()); | 1657 LOperand* right = UseRegisterAtStart(instr->right()); |
1651 return new(zone()) LCmpObjectEqAndBranch(left, right); | 1658 return new(zone()) LCmpObjectEqAndBranch(left, right); |
1652 } | 1659 } |
1653 | 1660 |
1654 | 1661 |
1655 LInstruction* LChunkBuilder::DoCompareConstantEqAndBranch( | |
1656 HCompareConstantEqAndBranch* instr) { | |
1657 return new(zone()) LCmpConstantEqAndBranch( | |
1658 UseRegisterAtStart(instr->value())); | |
1659 } | |
1660 | |
1661 | |
1662 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { | 1662 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { |
1663 ASSERT(instr->value()->representation().IsTagged()); | 1663 ASSERT(instr->value()->representation().IsTagged()); |
1664 LOperand* temp = TempRegister(); | 1664 LOperand* temp = TempRegister(); |
1665 return new(zone()) LIsObjectAndBranch(UseRegisterAtStart(instr->value()), | 1665 return new(zone()) LIsObjectAndBranch(UseRegisterAtStart(instr->value()), |
1666 temp); | 1666 temp); |
1667 } | 1667 } |
1668 | 1668 |
1669 | 1669 |
1670 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { | 1670 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { |
1671 ASSERT(instr->value()->representation().IsTagged()); | 1671 ASSERT(instr->value()->representation().IsTagged()); |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1949 | 1949 |
1950 | 1950 |
1951 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { | 1951 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { |
1952 LOperand* value = UseRegisterAtStart(instr->value()); | 1952 LOperand* value = UseRegisterAtStart(instr->value()); |
1953 LInstruction* result = new(zone()) LCheckInstanceType(value); | 1953 LInstruction* result = new(zone()) LCheckInstanceType(value); |
1954 return AssignEnvironment(result); | 1954 return AssignEnvironment(result); |
1955 } | 1955 } |
1956 | 1956 |
1957 | 1957 |
1958 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { | 1958 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { |
1959 LUnallocated* temp1 = TempRegister(); | 1959 LUnallocated* temp1 = NULL; |
1960 LOperand* temp2 = TempRegister(); | 1960 LOperand* temp2 = NULL; |
| 1961 if (!instr->CanOmitPrototypeChecks()) { |
| 1962 temp1 = TempRegister(); |
| 1963 temp2 = TempRegister(); |
| 1964 } |
1961 LCheckPrototypeMaps* result = new(zone()) LCheckPrototypeMaps(temp1, temp2); | 1965 LCheckPrototypeMaps* result = new(zone()) LCheckPrototypeMaps(temp1, temp2); |
| 1966 if (instr->CanOmitPrototypeChecks()) return result; |
1962 return AssignEnvironment(result); | 1967 return AssignEnvironment(result); |
1963 } | 1968 } |
1964 | 1969 |
1965 | 1970 |
1966 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { | 1971 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { |
1967 LOperand* value = UseRegisterAtStart(instr->value()); | 1972 LOperand* value = UseRegisterAtStart(instr->value()); |
1968 return AssignEnvironment(new(zone()) LCheckFunction(value)); | 1973 return AssignEnvironment(new(zone()) LCheckFunction(value)); |
1969 } | 1974 } |
1970 | 1975 |
1971 | 1976 |
1972 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { | 1977 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { |
1973 LOperand* value = UseRegisterAtStart(instr->value()); | 1978 LOperand* value = NULL; |
| 1979 if (!instr->CanOmitMapChecks()) value = UseRegisterAtStart(instr->value()); |
1974 LInstruction* result = new(zone()) LCheckMaps(value); | 1980 LInstruction* result = new(zone()) LCheckMaps(value); |
| 1981 if (instr->CanOmitMapChecks()) return result; |
1975 return AssignEnvironment(result); | 1982 return AssignEnvironment(result); |
1976 } | 1983 } |
1977 | 1984 |
1978 | 1985 |
1979 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { | 1986 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { |
1980 HValue* value = instr->value(); | 1987 HValue* value = instr->value(); |
1981 Representation input_rep = value->representation(); | 1988 Representation input_rep = value->representation(); |
1982 LOperand* reg = UseRegister(value); | 1989 LOperand* reg = UseRegister(value); |
1983 if (input_rep.IsDouble()) { | 1990 if (input_rep.IsDouble()) { |
1984 // Revisit this decision, here and 8 lines below. | 1991 // Revisit this decision, here and 8 lines below. |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2121 | 2128 |
2122 | 2129 |
2123 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( | 2130 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( |
2124 HLoadExternalArrayPointer* instr) { | 2131 HLoadExternalArrayPointer* instr) { |
2125 LOperand* input = UseRegisterAtStart(instr->value()); | 2132 LOperand* input = UseRegisterAtStart(instr->value()); |
2126 return DefineAsRegister(new(zone()) LLoadExternalArrayPointer(input)); | 2133 return DefineAsRegister(new(zone()) LLoadExternalArrayPointer(input)); |
2127 } | 2134 } |
2128 | 2135 |
2129 | 2136 |
2130 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 2137 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
2131 ASSERT(instr->key()->representation().IsInteger32() || | 2138 ASSERT(instr->key()->representation().IsSmiOrInteger32()); |
2132 instr->key()->representation().IsSmi()); | |
2133 ElementsKind elements_kind = instr->elements_kind(); | 2139 ElementsKind elements_kind = instr->elements_kind(); |
2134 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 2140 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
2135 LLoadKeyed* result = NULL; | 2141 LLoadKeyed* result = NULL; |
2136 | 2142 |
2137 if (!instr->is_external()) { | 2143 if (!instr->is_external()) { |
2138 LOperand* obj = NULL; | 2144 LOperand* obj = NULL; |
2139 if (instr->representation().IsDouble()) { | 2145 if (instr->representation().IsDouble()) { |
2140 obj = UseTempRegister(instr->elements()); | 2146 obj = UseTempRegister(instr->elements()); |
2141 } else { | 2147 } else { |
2142 ASSERT(instr->representation().IsSmiOrTagged()); | 2148 ASSERT(instr->representation().IsSmiOrTagged()); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2232 return MarkAsCall(new(zone()) LStoreKeyedGeneric(obj, key, val), instr); | 2238 return MarkAsCall(new(zone()) LStoreKeyedGeneric(obj, key, val), instr); |
2233 } | 2239 } |
2234 | 2240 |
2235 | 2241 |
2236 LInstruction* LChunkBuilder::DoTransitionElementsKind( | 2242 LInstruction* LChunkBuilder::DoTransitionElementsKind( |
2237 HTransitionElementsKind* instr) { | 2243 HTransitionElementsKind* instr) { |
2238 LOperand* object = UseRegister(instr->object()); | 2244 LOperand* object = UseRegister(instr->object()); |
2239 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { | 2245 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { |
2240 LOperand* new_map_reg = TempRegister(); | 2246 LOperand* new_map_reg = TempRegister(); |
2241 LTransitionElementsKind* result = | 2247 LTransitionElementsKind* result = |
2242 new(zone()) LTransitionElementsKind(object, new_map_reg, NULL); | 2248 new(zone()) LTransitionElementsKind(object, new_map_reg); |
2243 return result; | 2249 return result; |
2244 } else if (FLAG_compiled_transitions) { | 2250 } else { |
2245 LTransitionElementsKind* result = | 2251 LTransitionElementsKind* result = |
2246 new(zone()) LTransitionElementsKind(object, NULL, NULL); | 2252 new(zone()) LTransitionElementsKind(object, NULL); |
2247 return AssignPointerMap(result); | 2253 return AssignPointerMap(result); |
2248 } else { | |
2249 LOperand* object = UseFixed(instr->object(), a0); | |
2250 LOperand* fixed_object_reg = FixedTemp(a2); | |
2251 LOperand* new_map_reg = FixedTemp(a3); | |
2252 LTransitionElementsKind* result = | |
2253 new(zone()) LTransitionElementsKind(object, | |
2254 new_map_reg, | |
2255 fixed_object_reg); | |
2256 return MarkAsCall(result, instr); | |
2257 } | 2254 } |
2258 } | 2255 } |
2259 | 2256 |
2260 | 2257 |
2261 LInstruction* LChunkBuilder::DoTrapAllocationMemento( | 2258 LInstruction* LChunkBuilder::DoTrapAllocationMemento( |
2262 HTrapAllocationMemento* instr) { | 2259 HTrapAllocationMemento* instr) { |
2263 LOperand* object = UseRegister(instr->object()); | 2260 LOperand* object = UseRegister(instr->object()); |
2264 LOperand* temp = TempRegister(); | 2261 LOperand* temp = TempRegister(); |
2265 LTrapAllocationMemento* result = | 2262 LTrapAllocationMemento* result = |
2266 new(zone()) LTrapAllocationMemento(object, temp); | 2263 new(zone()) LTrapAllocationMemento(object, temp); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2563 | 2560 |
2564 | 2561 |
2565 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2562 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2566 LOperand* object = UseRegister(instr->object()); | 2563 LOperand* object = UseRegister(instr->object()); |
2567 LOperand* index = UseRegister(instr->index()); | 2564 LOperand* index = UseRegister(instr->index()); |
2568 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); | 2565 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); |
2569 } | 2566 } |
2570 | 2567 |
2571 | 2568 |
2572 } } // namespace v8::internal | 2569 } } // namespace v8::internal |
OLD | NEW |