| 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 751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 } | 762 } |
| 763 | 763 |
| 764 | 764 |
| 765 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 765 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
| 766 return AssignEnvironment(new(zone()) LDeoptimize); | 766 return AssignEnvironment(new(zone()) LDeoptimize); |
| 767 } | 767 } |
| 768 | 768 |
| 769 | 769 |
| 770 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 770 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
| 771 HBitwiseBinaryOperation* instr) { | 771 HBitwiseBinaryOperation* instr) { |
| 772 if (instr->representation().IsSmiOrTagged()) { | 772 if (instr->representation().IsTagged()) { |
| 773 ASSERT(instr->left()->representation().IsSmiOrTagged()); | 773 ASSERT(instr->left()->representation().IsSmiOrTagged()); |
| 774 ASSERT(instr->right()->representation().IsSmiOrTagged()); | 774 ASSERT(instr->right()->representation().IsSmiOrTagged()); |
| 775 | 775 |
| 776 LOperand* context = UseFixed(instr->context(), esi); | 776 LOperand* context = UseFixed(instr->context(), esi); |
| 777 LOperand* left = UseFixed(instr->left(), edx); | 777 LOperand* left = UseFixed(instr->left(), edx); |
| 778 LOperand* right = UseFixed(instr->right(), eax); | 778 LOperand* right = UseFixed(instr->right(), eax); |
| 779 LArithmeticT* result = new(zone()) LArithmeticT(op, context, left, right); | 779 LArithmeticT* result = new(zone()) LArithmeticT(op, context, left, right); |
| 780 return MarkAsCall(DefineFixed(result, eax), instr); | 780 return MarkAsCall(DefineFixed(result, eax), instr); |
| 781 } | 781 } |
| 782 | 782 |
| 783 ASSERT(instr->representation().IsInteger32()); | 783 ASSERT(instr->representation().IsSmiOrInteger32()); |
| 784 ASSERT(instr->left()->representation().IsInteger32()); | 784 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 785 ASSERT(instr->right()->representation().IsInteger32()); | 785 ASSERT(instr->right()->representation().IsInteger32()); |
| 786 LOperand* left = UseRegisterAtStart(instr->left()); | 786 LOperand* left = UseRegisterAtStart(instr->left()); |
| 787 | 787 |
| 788 HValue* right_value = instr->right(); | 788 HValue* right_value = instr->right(); |
| 789 LOperand* right = NULL; | 789 LOperand* right = NULL; |
| 790 int constant_value = 0; | 790 int constant_value = 0; |
| 791 if (right_value->IsConstant()) { | 791 if (right_value->IsConstant()) { |
| 792 HConstant* constant = HConstant::cast(right_value); | 792 HConstant* constant = HConstant::cast(right_value); |
| 793 right = chunk_->DefineConstantOperand(constant); | 793 right = chunk_->DefineConstantOperand(constant); |
| 794 constant_value = constant->Integer32Value() & 0x1f; | 794 constant_value = constant->Integer32Value() & 0x1f; |
| 795 } else { | 795 } else { |
| 796 right = UseFixed(right_value, ecx); | 796 right = UseFixed(right_value, ecx); |
| 797 } | 797 } |
| 798 | 798 |
| 799 // Shift operations can only deoptimize if we do a logical shift by 0 and | 799 // Shift operations can only deoptimize if we do a logical shift by 0 and the |
| 800 // the result cannot be truncated to int32. | 800 // result cannot be truncated to int32. |
| 801 bool does_deopt = false; | 801 bool does_deopt = false; |
| 802 if (op == Token::SHR && constant_value == 0) { | 802 if (op == Token::SHR && constant_value == 0) { |
| 803 if (FLAG_opt_safe_uint32_operations) { | 803 if (FLAG_opt_safe_uint32_operations) { |
| 804 does_deopt = !instr->CheckFlag(HInstruction::kUint32); | 804 does_deopt = !instr->CheckFlag(HInstruction::kUint32); |
| 805 } else { | 805 } else { |
| 806 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { | 806 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { |
| 807 if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) { | 807 if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) { |
| 808 does_deopt = true; | 808 does_deopt = true; |
| 809 break; | 809 break; |
| 810 } | 810 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 833 | 833 |
| 834 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 834 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 835 HArithmeticBinaryOperation* instr) { | 835 HArithmeticBinaryOperation* instr) { |
| 836 ASSERT(op == Token::ADD || | 836 ASSERT(op == Token::ADD || |
| 837 op == Token::DIV || | 837 op == Token::DIV || |
| 838 op == Token::MOD || | 838 op == Token::MOD || |
| 839 op == Token::MUL || | 839 op == Token::MUL || |
| 840 op == Token::SUB); | 840 op == Token::SUB); |
| 841 HValue* left = instr->left(); | 841 HValue* left = instr->left(); |
| 842 HValue* right = instr->right(); | 842 HValue* right = instr->right(); |
| 843 ASSERT(left->representation().IsSmiOrTagged()); | 843 ASSERT(left->representation().IsTagged()); |
| 844 ASSERT(right->representation().IsSmiOrTagged()); | 844 ASSERT(right->representation().IsTagged()); |
| 845 LOperand* context = UseFixed(instr->context(), esi); | 845 LOperand* context = UseFixed(instr->context(), esi); |
| 846 LOperand* left_operand = UseFixed(left, edx); | 846 LOperand* left_operand = UseFixed(left, edx); |
| 847 LOperand* right_operand = UseFixed(right, eax); | 847 LOperand* right_operand = UseFixed(right, eax); |
| 848 LArithmeticT* result = | 848 LArithmeticT* result = |
| 849 new(zone()) LArithmeticT(op, context, left_operand, right_operand); | 849 new(zone()) LArithmeticT(op, context, left_operand, right_operand); |
| 850 return MarkAsCall(DefineFixed(result, eax), instr); | 850 return MarkAsCall(DefineFixed(result, eax), instr); |
| 851 } | 851 } |
| 852 | 852 |
| 853 | 853 |
| 854 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 854 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1376 return DoShift(Token::SAR, instr); | 1376 return DoShift(Token::SAR, instr); |
| 1377 } | 1377 } |
| 1378 | 1378 |
| 1379 | 1379 |
| 1380 LInstruction* LChunkBuilder::DoShl(HShl* instr) { | 1380 LInstruction* LChunkBuilder::DoShl(HShl* instr) { |
| 1381 return DoShift(Token::SHL, instr); | 1381 return DoShift(Token::SHL, instr); |
| 1382 } | 1382 } |
| 1383 | 1383 |
| 1384 | 1384 |
| 1385 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { | 1385 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { |
| 1386 if (instr->representation().IsInteger32()) { | 1386 if (instr->representation().IsSmiOrInteger32()) { |
| 1387 ASSERT(instr->left()->representation().IsInteger32()); | 1387 ASSERT(instr->left()->representation().IsSmiOrInteger32()); |
| 1388 ASSERT(instr->right()->representation().IsInteger32()); | 1388 ASSERT(instr->right()->representation().Equals( |
| 1389 instr->left()->representation())); |
| 1389 | 1390 |
| 1390 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1391 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1391 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1392 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); |
| 1392 return DefineSameAsFirst(new(zone()) LBitI(left, right)); | 1393 return DefineSameAsFirst(new(zone()) LBitI(left, right)); |
| 1393 } else { | 1394 } else { |
| 1394 ASSERT(instr->representation().IsSmiOrTagged()); | 1395 ASSERT(instr->representation().IsSmiOrTagged()); |
| 1395 ASSERT(instr->left()->representation().IsSmiOrTagged()); | 1396 ASSERT(instr->left()->representation().IsSmiOrTagged()); |
| 1396 ASSERT(instr->right()->representation().IsSmiOrTagged()); | 1397 ASSERT(instr->right()->representation().IsSmiOrTagged()); |
| 1397 | 1398 |
| 1398 LOperand* context = UseFixed(instr->context(), esi); | 1399 LOperand* context = UseFixed(instr->context(), esi); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1411 if (instr->HasNoUses()) return NULL; | 1412 if (instr->HasNoUses()) return NULL; |
| 1412 LOperand* input = UseRegisterAtStart(instr->value()); | 1413 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1413 LBitNotI* result = new(zone()) LBitNotI(input); | 1414 LBitNotI* result = new(zone()) LBitNotI(input); |
| 1414 return DefineSameAsFirst(result); | 1415 return DefineSameAsFirst(result); |
| 1415 } | 1416 } |
| 1416 | 1417 |
| 1417 | 1418 |
| 1418 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1419 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
| 1419 if (instr->representation().IsDouble()) { | 1420 if (instr->representation().IsDouble()) { |
| 1420 return DoArithmeticD(Token::DIV, instr); | 1421 return DoArithmeticD(Token::DIV, instr); |
| 1421 } else if (instr->representation().IsInteger32()) { | 1422 } else if (instr->representation().IsSmiOrInteger32()) { |
| 1423 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1424 ASSERT(instr->right()->representation().IsInteger32()); |
| 1422 if (instr->HasPowerOf2Divisor()) { | 1425 if (instr->HasPowerOf2Divisor()) { |
| 1423 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); | 1426 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); |
| 1424 LOperand* value = UseRegisterAtStart(instr->left()); | 1427 LOperand* value = UseRegisterAtStart(instr->left()); |
| 1425 LDivI* div = | 1428 LDivI* div = |
| 1426 new(zone()) LDivI(value, UseOrConstant(instr->right()), NULL); | 1429 new(zone()) LDivI(value, UseOrConstant(instr->right()), NULL); |
| 1427 return AssignEnvironment(DefineSameAsFirst(div)); | 1430 return AssignEnvironment(DefineSameAsFirst(div)); |
| 1428 } | 1431 } |
| 1429 // The temporary operand is necessary to ensure that right is not allocated | 1432 // The temporary operand is necessary to ensure that right is not allocated |
| 1430 // into edx. | 1433 // into edx. |
| 1431 LOperand* temp = FixedTemp(edx); | 1434 LOperand* temp = FixedTemp(edx); |
| 1432 LOperand* dividend = UseFixed(instr->left(), eax); | 1435 LOperand* dividend = UseFixed(instr->left(), eax); |
| 1433 LOperand* divisor = UseRegister(instr->right()); | 1436 LOperand* divisor = UseRegister(instr->right()); |
| 1434 LDivI* result = new(zone()) LDivI(dividend, divisor, temp); | 1437 LDivI* result = new(zone()) LDivI(dividend, divisor, temp); |
| 1435 return AssignEnvironment(DefineFixed(result, eax)); | 1438 return AssignEnvironment(DefineFixed(result, eax)); |
| 1436 } else { | 1439 } else { |
| 1437 ASSERT(instr->representation().IsSmiOrTagged()); | 1440 ASSERT(instr->representation().IsTagged()); |
| 1438 return DoArithmeticT(Token::DIV, instr); | 1441 return DoArithmeticT(Token::DIV, instr); |
| 1439 } | 1442 } |
| 1440 } | 1443 } |
| 1441 | 1444 |
| 1442 | 1445 |
| 1443 HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue* dividend) { | 1446 HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue* dividend) { |
| 1444 // A value with an integer representation does not need to be transformed. | 1447 // A value with an integer representation does not need to be transformed. |
| 1445 if (dividend->representation().IsInteger32()) { | 1448 if (dividend->representation().IsInteger32()) { |
| 1446 return dividend; | 1449 return dividend; |
| 1447 // A change from an integer32 can be replaced by the integer32 value. | 1450 // A change from an integer32 can be replaced by the integer32 value. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 LOperand* dividend = UseFixed(instr->left(), eax); | 1507 LOperand* dividend = UseFixed(instr->left(), eax); |
| 1505 LOperand* temp = TempRegister(); | 1508 LOperand* temp = TempRegister(); |
| 1506 LInstruction* result = DefineFixed( | 1509 LInstruction* result = DefineFixed( |
| 1507 new(zone()) LMathFloorOfDiv(dividend, divisor, temp), edx); | 1510 new(zone()) LMathFloorOfDiv(dividend, divisor, temp), edx); |
| 1508 return divisor_si < 0 ? AssignEnvironment(result) : result; | 1511 return divisor_si < 0 ? AssignEnvironment(result) : result; |
| 1509 } | 1512 } |
| 1510 } | 1513 } |
| 1511 | 1514 |
| 1512 | 1515 |
| 1513 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1516 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1514 if (instr->representation().IsInteger32()) { | 1517 if (instr->representation().IsSmiOrInteger32()) { |
| 1515 ASSERT(instr->left()->representation().IsInteger32()); | 1518 ASSERT(instr->left()->representation().IsSmiOrInteger32()); |
| 1516 ASSERT(instr->right()->representation().IsInteger32()); | 1519 ASSERT(instr->right()->representation().Equals( |
| 1520 instr->left()->representation())); |
| 1517 | 1521 |
| 1518 LInstruction* result; | 1522 LInstruction* result; |
| 1519 if (instr->HasPowerOf2Divisor()) { | 1523 if (instr->HasPowerOf2Divisor()) { |
| 1520 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); | 1524 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); |
| 1521 LOperand* value = UseRegisterAtStart(instr->left()); | 1525 LOperand* value = UseRegisterAtStart(instr->left()); |
| 1522 LModI* mod = | 1526 LModI* mod = |
| 1523 new(zone()) LModI(value, UseOrConstant(instr->right()), NULL); | 1527 new(zone()) LModI(value, UseOrConstant(instr->right()), NULL); |
| 1524 result = DefineSameAsFirst(mod); | 1528 result = DefineSameAsFirst(mod); |
| 1525 } else { | 1529 } else { |
| 1526 // The temporary operand is necessary to ensure that right is | 1530 // The temporary operand is necessary to ensure that right is |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1546 // TODO(fschneider): Allow any register as input registers. | 1550 // TODO(fschneider): Allow any register as input registers. |
| 1547 LOperand* left = UseFixedDouble(instr->left(), xmm2); | 1551 LOperand* left = UseFixedDouble(instr->left(), xmm2); |
| 1548 LOperand* right = UseFixedDouble(instr->right(), xmm1); | 1552 LOperand* right = UseFixedDouble(instr->right(), xmm1); |
| 1549 LArithmeticD* result = new(zone()) LArithmeticD(Token::MOD, left, right); | 1553 LArithmeticD* result = new(zone()) LArithmeticD(Token::MOD, left, right); |
| 1550 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); | 1554 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); |
| 1551 } | 1555 } |
| 1552 } | 1556 } |
| 1553 | 1557 |
| 1554 | 1558 |
| 1555 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1559 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 1556 if (instr->representation().IsInteger32()) { | 1560 if (instr->representation().IsSmiOrInteger32()) { |
| 1557 ASSERT(instr->left()->representation().IsInteger32()); | 1561 ASSERT((instr->BetterLeftOperand()->representation().IsSmiOrInteger32() && |
| 1558 ASSERT(instr->right()->representation().IsInteger32()); | 1562 instr->BetterRightOperand()->representation().IsInteger32()) || |
| 1563 (instr->BetterRightOperand()->representation().IsSmi() && |
| 1564 instr->BetterLeftOperand()->representation().IsInteger32())); |
| 1559 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1565 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1560 LOperand* right = UseOrConstant(instr->BetterRightOperand()); | 1566 LOperand* right = UseOrConstant(instr->BetterRightOperand()); |
| 1561 LOperand* temp = NULL; | 1567 LOperand* temp = NULL; |
| 1562 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1568 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1563 temp = TempRegister(); | 1569 temp = TempRegister(); |
| 1564 } | 1570 } |
| 1565 LMulI* mul = new(zone()) LMulI(left, right, temp); | 1571 LMulI* mul = new(zone()) LMulI(left, right, temp); |
| 1566 if (instr->CheckFlag(HValue::kCanOverflow) || | 1572 if (instr->CheckFlag(HValue::kCanOverflow) || |
| 1567 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1573 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1568 AssignEnvironment(mul); | 1574 AssignEnvironment(mul); |
| 1569 } | 1575 } |
| 1570 return DefineSameAsFirst(mul); | 1576 return DefineSameAsFirst(mul); |
| 1571 } else if (instr->representation().IsDouble()) { | 1577 } else if (instr->representation().IsDouble()) { |
| 1572 return DoArithmeticD(Token::MUL, instr); | 1578 return DoArithmeticD(Token::MUL, instr); |
| 1573 } else { | 1579 } else { |
| 1574 ASSERT(instr->representation().IsSmiOrTagged()); | 1580 ASSERT(instr->representation().IsTagged()); |
| 1575 return DoArithmeticT(Token::MUL, instr); | 1581 return DoArithmeticT(Token::MUL, instr); |
| 1576 } | 1582 } |
| 1577 } | 1583 } |
| 1578 | 1584 |
| 1579 | 1585 |
| 1580 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1586 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
| 1581 if (instr->representation().IsInteger32()) { | 1587 if (instr->representation().IsSmiOrInteger32()) { |
| 1582 ASSERT(instr->left()->representation().IsInteger32()); | 1588 ASSERT(instr->left()->representation().IsSmiOrInteger32()); |
| 1583 ASSERT(instr->right()->representation().IsInteger32()); | 1589 ASSERT(instr->right()->representation().Equals( |
| 1590 instr->left()->representation())); |
| 1584 LOperand* left = UseRegisterAtStart(instr->left()); | 1591 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1585 LOperand* right = UseOrConstantAtStart(instr->right()); | 1592 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1586 LSubI* sub = new(zone()) LSubI(left, right); | 1593 LSubI* sub = new(zone()) LSubI(left, right); |
| 1587 LInstruction* result = DefineSameAsFirst(sub); | 1594 LInstruction* result = DefineSameAsFirst(sub); |
| 1588 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1595 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 1589 result = AssignEnvironment(result); | 1596 result = AssignEnvironment(result); |
| 1590 } | 1597 } |
| 1591 return result; | 1598 return result; |
| 1592 } else if (instr->representation().IsDouble()) { | 1599 } else if (instr->representation().IsDouble()) { |
| 1593 return DoArithmeticD(Token::SUB, instr); | 1600 return DoArithmeticD(Token::SUB, instr); |
| 1594 } else { | 1601 } else { |
| 1595 ASSERT(instr->representation().IsSmiOrTagged()); | 1602 ASSERT(instr->representation().IsSmiOrTagged()); |
| 1596 return DoArithmeticT(Token::SUB, instr); | 1603 return DoArithmeticT(Token::SUB, instr); |
| 1597 } | 1604 } |
| 1598 } | 1605 } |
| 1599 | 1606 |
| 1600 | 1607 |
| 1601 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { | 1608 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { |
| 1602 if (instr->representation().IsInteger32()) { | 1609 if (instr->representation().IsSmiOrInteger32()) { |
| 1610 ASSERT(instr->left()->representation().IsSmiOrInteger32()); |
| 1611 ASSERT(instr->right()->representation().Equals( |
| 1612 instr->left()->representation())); |
| 1603 // Check to see if it would be advantageous to use an lea instruction rather | 1613 // Check to see if it would be advantageous to use an lea instruction rather |
| 1604 // than an add. This is the case when no overflow check is needed and there | 1614 // than an add. This is the case when no overflow check is needed and there |
| 1605 // are multiple uses of the add's inputs, so using a 3-register add will | 1615 // are multiple uses of the add's inputs, so using a 3-register add will |
| 1606 // preserve all input values for later uses. | 1616 // preserve all input values for later uses. |
| 1607 bool use_lea = LAddI::UseLea(instr); | 1617 bool use_lea = LAddI::UseLea(instr); |
| 1608 ASSERT(instr->left()->representation().IsInteger32()); | |
| 1609 ASSERT(instr->right()->representation().IsInteger32()); | |
| 1610 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1618 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1611 HValue* right_candidate = instr->BetterRightOperand(); | 1619 HValue* right_candidate = instr->BetterRightOperand(); |
| 1612 LOperand* right = use_lea | 1620 LOperand* right = use_lea |
| 1613 ? UseRegisterOrConstantAtStart(right_candidate) | 1621 ? UseRegisterOrConstantAtStart(right_candidate) |
| 1614 : UseOrConstantAtStart(right_candidate); | 1622 : UseOrConstantAtStart(right_candidate); |
| 1615 LAddI* add = new(zone()) LAddI(left, right); | 1623 LAddI* add = new(zone()) LAddI(left, right); |
| 1616 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); | 1624 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); |
| 1617 LInstruction* result = use_lea | 1625 LInstruction* result = use_lea |
| 1618 ? DefineAsRegister(add) | 1626 ? DefineAsRegister(add) |
| 1619 : DefineSameAsFirst(add); | 1627 : DefineSameAsFirst(add); |
| 1620 if (can_overflow) { | 1628 if (can_overflow) { |
| 1621 result = AssignEnvironment(result); | 1629 result = AssignEnvironment(result); |
| 1622 } | 1630 } |
| 1623 return result; | 1631 return result; |
| 1624 } else if (instr->representation().IsDouble()) { | 1632 } else if (instr->representation().IsDouble()) { |
| 1625 return DoArithmeticD(Token::ADD, instr); | 1633 return DoArithmeticD(Token::ADD, instr); |
| 1626 } else { | 1634 } else { |
| 1627 ASSERT(instr->representation().IsSmiOrTagged()); | 1635 ASSERT(instr->representation().IsSmiOrTagged()); |
| 1628 return DoArithmeticT(Token::ADD, instr); | 1636 return DoArithmeticT(Token::ADD, instr); |
| 1629 } | 1637 } |
| 1630 } | 1638 } |
| 1631 | 1639 |
| 1632 | 1640 |
| 1633 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1641 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
| 1634 LOperand* left = NULL; | 1642 LOperand* left = NULL; |
| 1635 LOperand* right = NULL; | 1643 LOperand* right = NULL; |
| 1636 if (instr->representation().IsInteger32()) { | 1644 if (instr->representation().IsSmiOrInteger32()) { |
| 1637 ASSERT(instr->left()->representation().IsInteger32()); | 1645 ASSERT(instr->left()->representation().IsSmiOrInteger32()); |
| 1638 ASSERT(instr->right()->representation().IsInteger32()); | 1646 ASSERT(instr->right()->representation().Equals( |
| 1647 instr->left()->representation())); |
| 1639 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1648 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1640 right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1649 right = UseOrConstantAtStart(instr->BetterRightOperand()); |
| 1641 } else { | 1650 } else { |
| 1642 ASSERT(instr->representation().IsDouble()); | 1651 ASSERT(instr->representation().IsDouble()); |
| 1643 ASSERT(instr->left()->representation().IsDouble()); | 1652 ASSERT(instr->left()->representation().IsDouble()); |
| 1644 ASSERT(instr->right()->representation().IsDouble()); | 1653 ASSERT(instr->right()->representation().IsDouble()); |
| 1645 left = UseRegisterAtStart(instr->left()); | 1654 left = UseRegisterAtStart(instr->left()); |
| 1646 right = UseRegisterAtStart(instr->right()); | 1655 right = UseRegisterAtStart(instr->right()); |
| 1647 } | 1656 } |
| 1648 LMathMinMax* minmax = new(zone()) LMathMinMax(left, right); | 1657 LMathMinMax* minmax = new(zone()) LMathMinMax(left, right); |
| (...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2230 | 2239 |
| 2231 | 2240 |
| 2232 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( | 2241 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( |
| 2233 HLoadExternalArrayPointer* instr) { | 2242 HLoadExternalArrayPointer* instr) { |
| 2234 LOperand* input = UseRegisterAtStart(instr->value()); | 2243 LOperand* input = UseRegisterAtStart(instr->value()); |
| 2235 return DefineAsRegister(new(zone()) LLoadExternalArrayPointer(input)); | 2244 return DefineAsRegister(new(zone()) LLoadExternalArrayPointer(input)); |
| 2236 } | 2245 } |
| 2237 | 2246 |
| 2238 | 2247 |
| 2239 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 2248 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
| 2240 ASSERT(instr->key()->representation().IsInteger32() || | 2249 ASSERT(instr->key()->representation().IsSmiOrInteger32()); |
| 2241 instr->key()->representation().IsSmi()); | |
| 2242 ElementsKind elements_kind = instr->elements_kind(); | 2250 ElementsKind elements_kind = instr->elements_kind(); |
| 2243 bool clobbers_key = ExternalArrayOpRequiresTemp( | 2251 bool clobbers_key = ExternalArrayOpRequiresTemp( |
| 2244 instr->key()->representation(), elements_kind); | 2252 instr->key()->representation(), elements_kind); |
| 2245 LOperand* key = clobbers_key | 2253 LOperand* key = clobbers_key |
| 2246 ? UseTempRegister(instr->key()) | 2254 ? UseTempRegister(instr->key()) |
| 2247 : UseRegisterOrConstantAtStart(instr->key()); | 2255 : UseRegisterOrConstantAtStart(instr->key()); |
| 2248 LLoadKeyed* result = NULL; | 2256 LLoadKeyed* result = NULL; |
| 2249 | 2257 |
| 2250 if (!instr->is_external()) { | 2258 if (!instr->is_external()) { |
| 2251 LOperand* obj = UseRegisterAtStart(instr->elements()); | 2259 LOperand* obj = UseRegisterAtStart(instr->elements()); |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2767 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2775 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
| 2768 LOperand* object = UseRegister(instr->object()); | 2776 LOperand* object = UseRegister(instr->object()); |
| 2769 LOperand* index = UseTempRegister(instr->index()); | 2777 LOperand* index = UseTempRegister(instr->index()); |
| 2770 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2778 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
| 2771 } | 2779 } |
| 2772 | 2780 |
| 2773 | 2781 |
| 2774 } } // namespace v8::internal | 2782 } } // namespace v8::internal |
| 2775 | 2783 |
| 2776 #endif // V8_TARGET_ARCH_IA32 | 2784 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |