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