Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(464)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 166793002: Fixed and improved code for integral division. Fixed and extended tests. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: A64 fixes and cleanup Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 1435 matching lines...) Expand 10 before | Expand all | Expand 10 after
1446 } 1446 }
1447 __ idiv(right_reg); 1447 __ idiv(right_reg);
1448 __ bind(&done); 1448 __ bind(&done);
1449 } 1449 }
1450 } 1450 }
1451 1451
1452 1452
1453 void LCodeGen::DoDivI(LDivI* instr) { 1453 void LCodeGen::DoDivI(LDivI* instr) {
1454 if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) { 1454 if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) {
1455 Register dividend = ToRegister(instr->left()); 1455 Register dividend = ToRegister(instr->left());
1456 int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant(); 1456 HDiv* hdiv = instr->hydrogen();
1457 int32_t test_value = 0; 1457 int32_t divisor = hdiv->right()->GetInteger32Constant();
1458 int32_t power = 0; 1458 Register result = ToRegister(instr->result());
1459 ASSERT(!result.is(dividend));
1459 1460
1460 if (divisor > 0) { 1461 // Check for (0 / -x) that will produce negative zero.
1461 test_value = divisor - 1; 1462 if (hdiv->left()->RangeCanInclude(0) && divisor < 0 &&
1462 power = WhichPowerOf2(divisor); 1463 hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1463 } else { 1464 __ test(dividend, Operand(dividend));
1464 // Check for (0 / -x) that will produce negative zero. 1465 DeoptimizeIf(zero, instr->environment());
1465 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1466 __ test(dividend, Operand(dividend));
1467 DeoptimizeIf(zero, instr->environment());
1468 }
1469 // Check for (kMinInt / -1).
1470 if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1471 __ cmp(dividend, kMinInt);
1472 DeoptimizeIf(zero, instr->environment());
1473 }
1474 test_value = - divisor - 1;
1475 power = WhichPowerOf2(-divisor);
1476 } 1466 }
1477 1467 // Check for (kMinInt / -1).
1478 if (test_value != 0) { 1468 if (hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1 &&
1479 if (instr->hydrogen()->CheckFlag( 1469 hdiv->CheckFlag(HValue::kCanOverflow)) {
1480 HInstruction::kAllUsesTruncatingToInt32)) { 1470 __ cmp(dividend, kMinInt);
1481 Label done, negative; 1471 DeoptimizeIf(zero, instr->environment());
1482 __ cmp(dividend, 0); 1472 }
1483 __ j(less, &negative, Label::kNear); 1473 // Deoptimize if remainder will not be 0.
1484 __ sar(dividend, power); 1474 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1485 if (divisor < 0) __ neg(dividend); 1475 Abs(divisor) != 1) {
1486 __ jmp(&done, Label::kNear); 1476 __ test(dividend, Immediate(Abs(divisor) - 1));
1487
1488 __ bind(&negative);
1489 __ neg(dividend);
1490 __ sar(dividend, power);
1491 if (divisor > 0) __ neg(dividend);
1492 __ bind(&done);
1493 return; // Don't fall through to "__ neg" below.
1494 } else {
1495 // Deoptimize if remainder is not 0.
1496 __ test(dividend, Immediate(test_value));
1497 DeoptimizeIf(not_zero, instr->environment()); 1477 DeoptimizeIf(not_zero, instr->environment());
1498 __ sar(dividend, power);
1499 }
1500 } 1478 }
1501 1479 __ Move(result, dividend);
1502 if (divisor < 0) __ neg(dividend); 1480 int32_t shift = WhichPowerOf2(Abs(divisor));
1503 1481 if (shift > 0) {
1482 // The arithmetic shift is always OK, the 'if' is an optimization only.
1483 if (shift > 1) __ sar(result, 31);
1484 __ shr(result, 32 - shift);
1485 __ add(result, dividend);
1486 __ sar(result, shift);
1487 }
1488 if (divisor < 0) __ neg(result);
1504 return; 1489 return;
1505 } 1490 }
1506 1491
1507 LOperand* right = instr->right(); 1492 LOperand* right = instr->right();
1508 ASSERT(ToRegister(instr->result()).is(eax)); 1493 ASSERT(ToRegister(instr->result()).is(eax));
1509 ASSERT(ToRegister(instr->left()).is(eax)); 1494 ASSERT(ToRegister(instr->left()).is(eax));
1510 ASSERT(!ToRegister(instr->right()).is(eax)); 1495 ASSERT(!ToRegister(instr->right()).is(eax));
1511 ASSERT(!ToRegister(instr->right()).is(edx)); 1496 ASSERT(!ToRegister(instr->right()).is(edx));
1512 1497
1513 Register left_reg = eax; 1498 Register left_reg = eax;
(...skipping 4756 matching lines...) Expand 10 before | Expand all | Expand 10 after
6270 FixedArray::kHeaderSize - kPointerSize)); 6255 FixedArray::kHeaderSize - kPointerSize));
6271 __ bind(&done); 6256 __ bind(&done);
6272 } 6257 }
6273 6258
6274 6259
6275 #undef __ 6260 #undef __
6276 6261
6277 } } // namespace v8::internal 6262 } } // namespace v8::internal
6278 6263
6279 #endif // V8_TARGET_ARCH_IA32 6264 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698