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 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1439 ASSERT(CpuFeatures::IsSupported(SUDIV) || | 1439 ASSERT(CpuFeatures::IsSupported(SUDIV) || |
1440 (right->IsConstant() && | 1440 (right->IsConstant() && |
1441 HConstant::cast(right)->HasInteger32Value() && | 1441 HConstant::cast(right)->HasInteger32Value() && |
1442 HasMagicNumberForDivisor(HConstant::cast(right)->Integer32Value()))); | 1442 HasMagicNumberForDivisor(HConstant::cast(right)->Integer32Value()))); |
1443 return AssignEnvironment(DefineAsRegister( | 1443 return AssignEnvironment(DefineAsRegister( |
1444 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); | 1444 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); |
1445 } | 1445 } |
1446 | 1446 |
1447 | 1447 |
1448 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1448 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1449 HValue* left = instr->left(); |
| 1450 HValue* right = instr->right(); |
1449 if (instr->representation().IsInteger32()) { | 1451 if (instr->representation().IsInteger32()) { |
1450 ASSERT(instr->left()->representation().IsInteger32()); | 1452 ASSERT(left->representation().IsInteger32()); |
1451 ASSERT(instr->right()->representation().IsInteger32()); | 1453 ASSERT(right->representation().IsInteger32()); |
1452 | |
1453 LModI* mod; | |
1454 if (instr->HasPowerOf2Divisor()) { | 1454 if (instr->HasPowerOf2Divisor()) { |
1455 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); | 1455 ASSERT(!right->CanBeZero()); |
1456 LOperand* value = UseRegisterAtStart(instr->left()); | 1456 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), |
1457 mod = new(zone()) LModI(value, UseOrConstant(instr->right())); | 1457 UseOrConstant(right)); |
| 1458 LInstruction* result = DefineAsRegister(mod); |
| 1459 return (left->CanBeNegative() && |
| 1460 instr->CheckFlag(HValue::kBailoutOnMinusZero)) |
| 1461 ? AssignEnvironment(result) |
| 1462 : result; |
| 1463 } else if (instr->has_fixed_right_arg()) { |
| 1464 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), |
| 1465 UseRegisterAtStart(right)); |
| 1466 return AssignEnvironment(DefineAsRegister(mod)); |
| 1467 } else if (CpuFeatures::IsSupported(SUDIV)) { |
| 1468 LModI* mod = new(zone()) LModI(UseRegister(left), |
| 1469 UseRegister(right)); |
| 1470 LInstruction* result = DefineAsRegister(mod); |
| 1471 return (right->CanBeZero() || |
| 1472 (left->RangeCanInclude(kMinInt) && |
| 1473 right->RangeCanInclude(-1) && |
| 1474 instr->CheckFlag(HValue::kBailoutOnMinusZero)) || |
| 1475 (left->CanBeNegative() && |
| 1476 instr->CanBeZero() && |
| 1477 instr->CheckFlag(HValue::kBailoutOnMinusZero))) |
| 1478 ? AssignEnvironment(result) |
| 1479 : result; |
1458 } else { | 1480 } else { |
1459 LOperand* dividend = UseRegister(instr->left()); | 1481 LModI* mod = new(zone()) LModI(UseRegister(left), |
1460 LOperand* divisor = UseRegister(instr->right()); | 1482 UseRegister(right), |
1461 mod = new(zone()) LModI(dividend, | 1483 FixedTemp(d10), |
1462 divisor, | 1484 FixedTemp(d11)); |
1463 TempRegister(), | 1485 LInstruction* result = DefineAsRegister(mod); |
1464 FixedTemp(d10), | 1486 return (right->CanBeZero() || |
1465 FixedTemp(d11)); | 1487 (left->CanBeNegative() && |
1466 } | 1488 instr->CanBeZero() && |
1467 | 1489 instr->CheckFlag(HValue::kBailoutOnMinusZero))) |
1468 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1490 ? AssignEnvironment(result) |
1469 instr->CheckFlag(HValue::kCanBeDivByZero) || | 1491 : result; |
1470 instr->CheckFlag(HValue::kCanOverflow)) { | |
1471 return AssignEnvironment(DefineAsRegister(mod)); | |
1472 } else { | |
1473 return DefineAsRegister(mod); | |
1474 } | 1492 } |
1475 } else if (instr->representation().IsSmiOrTagged()) { | 1493 } else if (instr->representation().IsSmiOrTagged()) { |
1476 return DoArithmeticT(Token::MOD, instr); | 1494 return DoArithmeticT(Token::MOD, instr); |
1477 } else { | 1495 } else { |
1478 ASSERT(instr->representation().IsDouble()); | 1496 ASSERT(instr->representation().IsDouble()); |
1479 // We call a C function for double modulo. It can't trigger a GC. | 1497 // We call a C function for double modulo. It can't trigger a GC. We need |
1480 // We need to use fixed result register for the call. | 1498 // to use fixed result register for the call. |
1481 // TODO(fschneider): Allow any register as input registers. | 1499 // TODO(fschneider): Allow any register as input registers. |
1482 LOperand* left = UseFixedDouble(instr->left(), d1); | 1500 LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD, |
1483 LOperand* right = UseFixedDouble(instr->right(), d2); | 1501 UseFixedDouble(left, d1), |
1484 LArithmeticD* result = new(zone()) LArithmeticD(Token::MOD, left, right); | 1502 UseFixedDouble(right, d2)); |
1485 return MarkAsCall(DefineFixedDouble(result, d1), instr); | 1503 return MarkAsCall(DefineFixedDouble(mod, d1), instr); |
1486 } | 1504 } |
1487 } | 1505 } |
1488 | 1506 |
1489 | 1507 |
1490 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1508 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
1491 if (instr->representation().IsInteger32()) { | 1509 if (instr->representation().IsInteger32()) { |
1492 ASSERT(instr->left()->representation().IsInteger32()); | 1510 ASSERT(instr->left()->representation().IsInteger32()); |
1493 ASSERT(instr->right()->representation().IsInteger32()); | 1511 ASSERT(instr->right()->representation().IsInteger32()); |
1494 LOperand* left; | 1512 LOperand* left; |
1495 LOperand* right = UseOrConstant(instr->BetterRightOperand()); | 1513 LOperand* right = UseOrConstant(instr->BetterRightOperand()); |
(...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2632 | 2650 |
2633 | 2651 |
2634 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2652 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2635 LOperand* object = UseRegister(instr->object()); | 2653 LOperand* object = UseRegister(instr->object()); |
2636 LOperand* index = UseRegister(instr->index()); | 2654 LOperand* index = UseRegister(instr->index()); |
2637 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); | 2655 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); |
2638 } | 2656 } |
2639 | 2657 |
2640 | 2658 |
2641 } } // namespace v8::internal | 2659 } } // namespace v8::internal |
OLD | NEW |