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 1506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1517 LOperand* dividend = UseFixed(instr->left(), eax); | 1517 LOperand* dividend = UseFixed(instr->left(), eax); |
1518 LOperand* temp = TempRegister(); | 1518 LOperand* temp = TempRegister(); |
1519 LInstruction* result = DefineFixed( | 1519 LInstruction* result = DefineFixed( |
1520 new(zone()) LMathFloorOfDiv(dividend, divisor, temp), edx); | 1520 new(zone()) LMathFloorOfDiv(dividend, divisor, temp), edx); |
1521 return divisor_si < 0 ? AssignEnvironment(result) : result; | 1521 return divisor_si < 0 ? AssignEnvironment(result) : result; |
1522 } | 1522 } |
1523 } | 1523 } |
1524 | 1524 |
1525 | 1525 |
1526 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1526 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1527 HValue* left = instr->left(); |
| 1528 HValue* right = instr->right(); |
1527 if (instr->representation().IsInteger32()) { | 1529 if (instr->representation().IsInteger32()) { |
1528 ASSERT(instr->left()->representation().IsInteger32()); | 1530 ASSERT(left->representation().IsInteger32()); |
1529 ASSERT(instr->right()->representation().IsInteger32()); | 1531 ASSERT(right->representation().IsInteger32()); |
1530 | |
1531 LInstruction* result; | |
1532 if (instr->HasPowerOf2Divisor()) { | 1532 if (instr->HasPowerOf2Divisor()) { |
1533 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); | 1533 ASSERT(!right->CanBeZero()); |
1534 LOperand* value = UseRegisterAtStart(instr->left()); | 1534 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), |
1535 LModI* mod = | 1535 UseOrConstant(right), |
1536 new(zone()) LModI(value, UseOrConstant(instr->right()), NULL); | 1536 NULL); |
1537 result = DefineSameAsFirst(mod); | 1537 LInstruction* result = DefineSameAsFirst(mod); |
| 1538 return (left->CanBeNegative() && |
| 1539 instr->CheckFlag(HValue::kBailoutOnMinusZero)) |
| 1540 ? AssignEnvironment(result) |
| 1541 : result; |
| 1542 } else if (instr->has_fixed_right_arg()) { |
| 1543 LModI* mod = new(zone()) LModI(UseRegister(left), |
| 1544 UseRegisterAtStart(right), |
| 1545 NULL); |
| 1546 return AssignEnvironment(DefineSameAsFirst(mod)); |
1538 } else { | 1547 } else { |
1539 // The temporary operand is necessary to ensure that right is | 1548 // The temporary operand is necessary to ensure that right is not |
1540 // not allocated into edx. | 1549 // allocated into edx. |
1541 LOperand* temp = FixedTemp(edx); | 1550 LModI* mod = new(zone()) LModI(UseFixed(left, eax), |
1542 LOperand* value = UseFixed(instr->left(), eax); | 1551 UseRegister(right), |
1543 LOperand* divisor = UseRegister(instr->right()); | 1552 FixedTemp(edx)); |
1544 LModI* mod = new(zone()) LModI(value, divisor, temp); | 1553 LInstruction* result = DefineFixed(mod, edx); |
1545 result = DefineFixed(mod, edx); | 1554 return (right->CanBeZero() || |
| 1555 (left->RangeCanInclude(kMinInt) && |
| 1556 right->RangeCanInclude(-1) && |
| 1557 instr->CheckFlag(HValue::kBailoutOnMinusZero)) || |
| 1558 (left->CanBeNegative() && |
| 1559 instr->CanBeZero() && |
| 1560 instr->CheckFlag(HValue::kBailoutOnMinusZero))) |
| 1561 ? AssignEnvironment(result) |
| 1562 : result; |
1546 } | 1563 } |
1547 | |
1548 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || | |
1549 instr->CheckFlag(HValue::kCanBeDivByZero) || | |
1550 instr->CheckFlag(HValue::kCanOverflow)) | |
1551 ? AssignEnvironment(result) | |
1552 : result; | |
1553 } else if (instr->representation().IsSmiOrTagged()) { | 1564 } else if (instr->representation().IsSmiOrTagged()) { |
1554 return DoArithmeticT(Token::MOD, instr); | 1565 return DoArithmeticT(Token::MOD, instr); |
1555 } else { | 1566 } else { |
1556 ASSERT(instr->representation().IsDouble()); | 1567 ASSERT(instr->representation().IsDouble()); |
1557 // We call a C function for double modulo. It can't trigger a GC. | 1568 // We call a C function for double modulo. It can't trigger a GC. We need |
1558 // We need to use fixed result register for the call. | 1569 // to use fixed result register for the call. |
1559 // TODO(fschneider): Allow any register as input registers. | 1570 // TODO(fschneider): Allow any register as input registers. |
1560 LOperand* left = UseFixedDouble(instr->left(), xmm2); | 1571 LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD, |
1561 LOperand* right = UseFixedDouble(instr->right(), xmm1); | 1572 UseFixedDouble(left, xmm2), |
1562 LArithmeticD* result = new(zone()) LArithmeticD(Token::MOD, left, right); | 1573 UseFixedDouble(right, xmm1)); |
1563 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); | 1574 return MarkAsCall(DefineFixedDouble(mod, xmm1), instr); |
1564 } | 1575 } |
1565 } | 1576 } |
1566 | 1577 |
1567 | 1578 |
1568 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1579 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
1569 if (instr->representation().IsInteger32()) { | 1580 if (instr->representation().IsInteger32()) { |
1570 ASSERT(instr->left()->representation().IsInteger32()); | 1581 ASSERT(instr->left()->representation().IsInteger32()); |
1571 ASSERT(instr->right()->representation().IsInteger32()); | 1582 ASSERT(instr->right()->representation().IsInteger32()); |
1572 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1583 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1573 LOperand* right = UseOrConstant(instr->BetterRightOperand()); | 1584 LOperand* right = UseOrConstant(instr->BetterRightOperand()); |
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2781 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2792 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2782 LOperand* object = UseRegister(instr->object()); | 2793 LOperand* object = UseRegister(instr->object()); |
2783 LOperand* index = UseTempRegister(instr->index()); | 2794 LOperand* index = UseTempRegister(instr->index()); |
2784 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2795 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
2785 } | 2796 } |
2786 | 2797 |
2787 | 2798 |
2788 } } // namespace v8::internal | 2799 } } // namespace v8::internal |
2789 | 2800 |
2790 #endif // V8_TARGET_ARCH_IA32 | 2801 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |