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

Side by Side Diff: src/arm/lithium-codegen-arm.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 1325 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 // it gets implemented. 1336 // it gets implemented.
1337 __ mul(scratch, result, ip); 1337 __ mul(scratch, result, ip);
1338 __ sub(remainder, dividend, scratch); 1338 __ sub(remainder, dividend, scratch);
1339 } 1339 }
1340 } 1340 }
1341 } 1341 }
1342 1342
1343 1343
1344 void LCodeGen::DoDivI(LDivI* instr) { 1344 void LCodeGen::DoDivI(LDivI* instr) {
1345 if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) { 1345 if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) {
1346 const Register dividend = ToRegister(instr->left()); 1346 Register dividend = ToRegister(instr->left());
1347 const Register result = ToRegister(instr->result()); 1347 HDiv* hdiv = instr->hydrogen();
1348 int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant(); 1348 int32_t divisor = hdiv->right()->GetInteger32Constant();
1349 int32_t test_value = 0; 1349 Register result = ToRegister(instr->result());
1350 int32_t power = 0; 1350 ASSERT(!result.is(dividend));
1351 1351
1352 if (divisor > 0) { 1352 // Check for (0 / -x) that will produce negative zero.
1353 test_value = divisor - 1; 1353 if (hdiv->left()->RangeCanInclude(0) && divisor < 0 &&
1354 power = WhichPowerOf2(divisor); 1354 hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1355 __ cmp(dividend, Operand::Zero());
1356 DeoptimizeIf(eq, instr->environment());
1357 }
1358 // Check for (kMinInt / -1).
1359 if (hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1 &&
1360 hdiv->CheckFlag(HValue::kCanOverflow)) {
1361 __ cmp(dividend, Operand(kMinInt));
1362 DeoptimizeIf(eq, instr->environment());
1363 }
1364 // Deoptimize if remainder will not be 0.
1365 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1366 Abs(divisor) != 1) {
1367 __ tst(dividend, Operand(Abs(divisor) - 1));
1368 DeoptimizeIf(ne, instr->environment());
1369 }
1370 if (divisor == -1) { // Nice shortcut, not needed for correctness.
1371 __ rsb(result, dividend, Operand(0));
1372 return;
1373 }
1374 int32_t shift = WhichPowerOf2(Abs(divisor));
1375 if (shift == 0) {
1376 __ mov(result, dividend);
1377 } else if (shift == 1) {
1378 __ add(result, dividend, Operand(dividend, LSR, 31));
1355 } else { 1379 } else {
1356 // Check for (0 / -x) that will produce negative zero. 1380 __ mov(result, Operand(dividend, ASR, 31));
1357 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1381 __ mov(result, Operand(result, LSR, 32 - shift));
1358 __ cmp(dividend, Operand::Zero()); 1382 __ add(result, result, dividend);
Benedikt Meurer 2014/02/18 09:43:30 Same as for a64.
1359 DeoptimizeIf(eq, instr->environment());
1360 }
1361 // Check for (kMinInt / -1).
1362 if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1363 __ cmp(dividend, Operand(kMinInt));
1364 DeoptimizeIf(eq, instr->environment());
1365 }
1366 test_value = - divisor - 1;
1367 power = WhichPowerOf2(-divisor);
1368 } 1383 }
1369 1384 if (shift > 0) __ mov(result, Operand(result, ASR, shift));
1370 if (test_value != 0) { 1385 if (divisor < 0) __ rsb(result, result, Operand(0));
1371 if (instr->hydrogen()->CheckFlag(
1372 HInstruction::kAllUsesTruncatingToInt32)) {
1373 __ sub(result, dividend, Operand::Zero(), SetCC);
1374 __ rsb(result, result, Operand::Zero(), LeaveCC, lt);
1375 __ mov(result, Operand(result, ASR, power));
1376 if (divisor > 0) __ rsb(result, result, Operand::Zero(), LeaveCC, lt);
1377 if (divisor < 0) __ rsb(result, result, Operand::Zero(), LeaveCC, gt);
1378 return; // Don't fall through to "__ rsb" below.
1379 } else {
1380 // Deoptimize if remainder is not 0.
1381 __ tst(dividend, Operand(test_value));
1382 DeoptimizeIf(ne, instr->environment());
1383 __ mov(result, Operand(dividend, ASR, power));
1384 if (divisor < 0) __ rsb(result, result, Operand(0));
1385 }
1386 } else {
1387 if (divisor < 0) {
1388 __ rsb(result, dividend, Operand(0));
1389 } else {
1390 __ Move(result, dividend);
1391 }
1392 }
1393
1394 return; 1386 return;
1395 } 1387 }
1396 1388
1397 const Register left = ToRegister(instr->left()); 1389 const Register left = ToRegister(instr->left());
1398 const Register right = ToRegister(instr->right()); 1390 const Register right = ToRegister(instr->right());
1399 const Register result = ToRegister(instr->result()); 1391 const Register result = ToRegister(instr->result());
1400 1392
1401 // Check for x / 0. 1393 // Check for x / 0.
1402 if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) { 1394 if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
1403 __ cmp(right, Operand::Zero()); 1395 __ cmp(right, Operand::Zero());
(...skipping 4340 matching lines...) Expand 10 before | Expand all | Expand 10 after
5744 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5736 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5745 __ ldr(result, FieldMemOperand(scratch, 5737 __ ldr(result, FieldMemOperand(scratch,
5746 FixedArray::kHeaderSize - kPointerSize)); 5738 FixedArray::kHeaderSize - kPointerSize));
5747 __ bind(&done); 5739 __ bind(&done);
5748 } 5740 }
5749 5741
5750 5742
5751 #undef __ 5743 #undef __
5752 5744
5753 } } // namespace v8::internal 5745 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698