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

Side by Side Diff: src/mips/lithium-mips.cc

Issue 192743006: MIPS: Reland "Handle non-power-of-2 divisors in division-like operations". (Closed) Base URL: https://github.com/v8/v8.git@gbl
Patch Set: Created 6 years, 9 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
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 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 if (instr->representation().IsSmiOrInteger32()) { 1259 if (instr->representation().IsSmiOrInteger32()) {
1260 return DoDivI(instr); 1260 return DoDivI(instr);
1261 } else if (instr->representation().IsDouble()) { 1261 } else if (instr->representation().IsDouble()) {
1262 return DoArithmeticD(Token::DIV, instr); 1262 return DoArithmeticD(Token::DIV, instr);
1263 } else { 1263 } else {
1264 return DoArithmeticT(Token::DIV, instr); 1264 return DoArithmeticT(Token::DIV, instr);
1265 } 1265 }
1266 } 1266 }
1267 1267
1268 1268
1269 bool LChunkBuilder::HasMagicNumberForDivisor(int32_t divisor) { 1269 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
1270 uint32_t divisor_abs = abs(divisor); 1270 LOperand* dividend = UseRegisterAtStart(instr->left());
1271 // Dividing by 0 or powers of 2 is easy. 1271 int32_t divisor = instr->right()->GetInteger32Constant();
1272 if (divisor == 0 || IsPowerOf2(divisor_abs)) return true; 1272 LInstruction* result =
1273 1273 DefineSameAsFirst(
1274 // We have magic numbers for a few specific divisors. 1274 new(zone()) LFlooringDivByPowerOf2I(dividend, divisor));
1275 // Details and proofs can be found in: 1275 bool can_deopt =
1276 // - Hacker's Delight, Henry S. Warren, Jr. 1276 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1277 // - The PowerPC Compiler Writer's Guide 1277 (instr->left()->RangeCanInclude(kMinInt) && divisor == -1);
1278 // and probably many others. 1278 return can_deopt ? AssignEnvironment(result) : result;
1279 //
1280 // We handle
1281 // <divisor with magic numbers> * <power of 2>
1282 // but not
1283 // <divisor with magic numbers> * <other divisor with magic numbers>
1284 int32_t power_of_2_factor =
1285 CompilerIntrinsics::CountTrailingZeros(divisor_abs);
1286 DivMagicNumbers magic_numbers =
1287 DivMagicNumberFor(divisor_abs >> power_of_2_factor);
1288 return magic_numbers.M != InvalidDivMagicNumber.M;
1289 } 1279 }
1290 1280
1291 1281
1292 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { 1282 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
1283 ASSERT(instr->representation().IsInteger32());
1284 ASSERT(instr->left()->representation().Equals(instr->representation()));
1285 ASSERT(instr->right()->representation().Equals(instr->representation()));
1293 LOperand* dividend = UseRegister(instr->left()); 1286 LOperand* dividend = UseRegister(instr->left());
1294 LOperand* divisor = UseOrConstant(instr->right()); 1287 int32_t divisor = instr->right()->GetInteger32Constant();
1295 LOperand* remainder = TempRegister();
1296 LInstruction* result = 1288 LInstruction* result =
1297 DefineAsRegister( 1289 DefineAsRegister(new(zone()) LFlooringDivByConstI(dividend, divisor));
1298 new(zone()) LFlooringDivByConstI(dividend, divisor, remainder)); 1290 bool can_deopt =
1299 return AssignEnvironment(result); 1291 divisor == 0 ||
1292 (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
1293 instr->left()->RangeCanInclude(0) && divisor < 0);
1294 return can_deopt ? AssignEnvironment(result) : result;
1300 } 1295 }
1301 1296
1302 1297
1303 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { 1298 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1304 if (instr->right()->IsConstant()) { 1299 if (instr->RightIsPowerOf2()) {
1300 return DoFlooringDivByPowerOf2I(instr);
1301 } else if (instr->right()->IsConstant()) {
1305 return DoFlooringDivByConstI(instr); 1302 return DoFlooringDivByConstI(instr);
1306 } else { 1303 } else {
1307 HValue* right = instr->right(); 1304 HValue* right = instr->right();
1308 LOperand* dividend = UseRegister(instr->left()); 1305 LOperand* dividend = UseRegister(instr->left());
1309 LOperand* divisor = UseRegisterOrConstant(right); 1306 LOperand* divisor = UseRegisterOrConstant(right);
1310 LOperand* remainder = TempRegister(); 1307 LOperand* remainder = TempRegister();
1311 return AssignEnvironment(DefineAsRegister( 1308 return AssignEnvironment(DefineAsRegister(
1312 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); 1309 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder)));
1313 } 1310 }
1314 } 1311 }
(...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2447 2444
2448 2445
2449 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2446 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2450 LOperand* object = UseRegister(instr->object()); 2447 LOperand* object = UseRegister(instr->object());
2451 LOperand* index = UseRegister(instr->index()); 2448 LOperand* index = UseRegister(instr->index());
2452 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); 2449 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index));
2453 } 2450 }
2454 2451
2455 2452
2456 } } // namespace v8::internal 2453 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698