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 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1430 LOperand* dividend = UseRegisterAtStart(instr->left()); | 1430 LOperand* dividend = UseRegisterAtStart(instr->left()); |
1431 LOperand* temp = TempRegister(); | 1431 LOperand* temp = TempRegister(); |
1432 LInstruction* result = DefineAsRegister( | 1432 LInstruction* result = DefineAsRegister( |
1433 new(zone()) LMathFloorOfDiv(dividend, divisor, temp)); | 1433 new(zone()) LMathFloorOfDiv(dividend, divisor, temp)); |
1434 return divisor_si < 0 ? AssignEnvironment(result) : result; | 1434 return divisor_si < 0 ? AssignEnvironment(result) : result; |
1435 } | 1435 } |
1436 } | 1436 } |
1437 | 1437 |
1438 | 1438 |
1439 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1439 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1440 HValue* left = instr->left(); |
| 1441 HValue* right = instr->right(); |
1440 if (instr->representation().IsInteger32()) { | 1442 if (instr->representation().IsInteger32()) { |
1441 ASSERT(instr->left()->representation().IsInteger32()); | 1443 ASSERT(left->representation().IsInteger32()); |
1442 ASSERT(instr->right()->representation().IsInteger32()); | 1444 ASSERT(right->representation().IsInteger32()); |
1443 | |
1444 LInstruction* result; | |
1445 if (instr->HasPowerOf2Divisor()) { | 1445 if (instr->HasPowerOf2Divisor()) { |
1446 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); | 1446 ASSERT(!right->CanBeZero()); |
1447 LOperand* value = UseRegisterAtStart(instr->left()); | 1447 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), |
1448 LModI* mod = | 1448 UseOrConstant(right), |
1449 new(zone()) LModI(value, UseOrConstant(instr->right()), NULL); | 1449 NULL); |
1450 result = DefineSameAsFirst(mod); | 1450 LInstruction* result = DefineSameAsFirst(mod); |
| 1451 return (left->CanBeNegative() && |
| 1452 instr->CheckFlag(HValue::kBailoutOnMinusZero)) |
| 1453 ? AssignEnvironment(result) |
| 1454 : result; |
| 1455 } else if (instr->has_fixed_right_arg()) { |
| 1456 LModI* mod = new(zone()) LModI(UseRegister(left), |
| 1457 UseRegisterAtStart(right), |
| 1458 NULL); |
| 1459 return AssignEnvironment(DefineSameAsFirst(mod)); |
1451 } else { | 1460 } else { |
1452 // The temporary operand is necessary to ensure that right is not | 1461 // The temporary operand is necessary to ensure that right is not |
1453 // allocated into edx. | 1462 // allocated into edx. |
1454 LOperand* temp = FixedTemp(rdx); | 1463 LModI* mod = new(zone()) LModI(UseFixed(left, rax), |
1455 LOperand* value = UseFixed(instr->left(), rax); | 1464 UseRegister(right), |
1456 LOperand* divisor = UseRegister(instr->right()); | 1465 FixedTemp(rdx)); |
1457 LModI* mod = new(zone()) LModI(value, divisor, temp); | 1466 LInstruction* result = DefineFixed(mod, rdx); |
1458 result = DefineFixed(mod, rdx); | 1467 return (right->CanBeZero() || |
| 1468 (left->RangeCanInclude(kMinInt) && |
| 1469 right->RangeCanInclude(-1) && |
| 1470 instr->CheckFlag(HValue::kBailoutOnMinusZero)) || |
| 1471 (left->CanBeNegative() && |
| 1472 instr->CanBeZero() && |
| 1473 instr->CheckFlag(HValue::kBailoutOnMinusZero))) |
| 1474 ? AssignEnvironment(result) |
| 1475 : result; |
1459 } | 1476 } |
1460 | |
1461 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || | |
1462 instr->CheckFlag(HValue::kCanBeDivByZero) || | |
1463 instr->CheckFlag(HValue::kCanOverflow)) | |
1464 ? AssignEnvironment(result) | |
1465 : result; | |
1466 } else if (instr->representation().IsSmiOrTagged()) { | 1477 } else if (instr->representation().IsSmiOrTagged()) { |
1467 return DoArithmeticT(Token::MOD, instr); | 1478 return DoArithmeticT(Token::MOD, instr); |
1468 } else { | 1479 } else { |
1469 ASSERT(instr->representation().IsDouble()); | 1480 ASSERT(instr->representation().IsDouble()); |
1470 // We call a C function for double modulo. It can't trigger a GC. | 1481 // We call a C function for double modulo. It can't trigger a GC. We need to |
1471 // We need to use fixed result register for the call. | 1482 // use fixed result register for the call. |
1472 // TODO(fschneider): Allow any register as input registers. | 1483 // TODO(fschneider): Allow any register as input registers. |
1473 LOperand* left = UseFixedDouble(instr->left(), xmm2); | 1484 LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD, |
1474 LOperand* right = UseFixedDouble(instr->right(), xmm1); | 1485 UseFixedDouble(left, xmm2), |
1475 LArithmeticD* result = new(zone()) LArithmeticD(Token::MOD, left, right); | 1486 UseFixedDouble(right, xmm1)); |
1476 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); | 1487 return MarkAsCall(DefineFixedDouble(mod, xmm1), instr); |
1477 } | 1488 } |
1478 } | 1489 } |
1479 | 1490 |
1480 | 1491 |
1481 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1492 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
1482 if (instr->representation().IsInteger32()) { | 1493 if (instr->representation().IsInteger32()) { |
1483 ASSERT(instr->left()->representation().IsInteger32()); | 1494 ASSERT(instr->left()->representation().IsInteger32()); |
1484 ASSERT(instr->right()->representation().IsInteger32()); | 1495 ASSERT(instr->right()->representation().IsInteger32()); |
1485 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1496 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1486 LOperand* right = UseOrConstant(instr->BetterRightOperand()); | 1497 LOperand* right = UseOrConstant(instr->BetterRightOperand()); |
(...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2575 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2586 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2576 LOperand* object = UseRegister(instr->object()); | 2587 LOperand* object = UseRegister(instr->object()); |
2577 LOperand* index = UseTempRegister(instr->index()); | 2588 LOperand* index = UseTempRegister(instr->index()); |
2578 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2589 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
2579 } | 2590 } |
2580 | 2591 |
2581 | 2592 |
2582 } } // namespace v8::internal | 2593 } } // namespace v8::internal |
2583 | 2594 |
2584 #endif // V8_TARGET_ARCH_X64 | 2595 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |