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 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1243 } else { | 1243 } else { |
1244 return DoArithmeticT(instr->op(), instr); | 1244 return DoArithmeticT(instr->op(), instr); |
1245 } | 1245 } |
1246 } | 1246 } |
1247 | 1247 |
1248 | 1248 |
1249 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1249 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
1250 if (instr->representation().IsSmiOrInteger32()) { | 1250 if (instr->representation().IsSmiOrInteger32()) { |
1251 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1251 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1252 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1252 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1253 if (instr->HasPowerOf2Divisor()) { | 1253 if (instr->RightIsPowerOf2()) { |
1254 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); | 1254 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); |
1255 LOperand* value = UseRegisterAtStart(instr->left()); | 1255 LOperand* value = UseRegisterAtStart(instr->left()); |
1256 LDivI* div = new(zone()) LDivI(value, UseConstant(instr->right()), NULL); | 1256 LDivI* div = new(zone()) LDivI(value, UseConstant(instr->right()), NULL); |
1257 return AssignEnvironment(DefineAsRegister(div)); | 1257 return AssignEnvironment(DefineAsRegister(div)); |
1258 } | 1258 } |
1259 LOperand* dividend = UseRegister(instr->left()); | 1259 LOperand* dividend = UseRegister(instr->left()); |
1260 LOperand* divisor = UseRegister(instr->right()); | 1260 LOperand* divisor = UseRegister(instr->right()); |
1261 LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4); | 1261 LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4); |
1262 LDivI* div = new(zone()) LDivI(dividend, divisor, temp); | 1262 LDivI* div = new(zone()) LDivI(dividend, divisor, temp); |
1263 return AssignEnvironment(DefineAsRegister(div)); | 1263 return AssignEnvironment(DefineAsRegister(div)); |
(...skipping 25 matching lines...) Expand all Loading... |
1289 int32_t power_of_2_factor = | 1289 int32_t power_of_2_factor = |
1290 CompilerIntrinsics::CountTrailingZeros(divisor_abs); | 1290 CompilerIntrinsics::CountTrailingZeros(divisor_abs); |
1291 DivMagicNumbers magic_numbers = | 1291 DivMagicNumbers magic_numbers = |
1292 DivMagicNumberFor(divisor_abs >> power_of_2_factor); | 1292 DivMagicNumberFor(divisor_abs >> power_of_2_factor); |
1293 if (magic_numbers.M != InvalidDivMagicNumber.M) return true; | 1293 if (magic_numbers.M != InvalidDivMagicNumber.M) return true; |
1294 | 1294 |
1295 return false; | 1295 return false; |
1296 } | 1296 } |
1297 | 1297 |
1298 | 1298 |
1299 HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) { | |
1300 if (CpuFeatures::IsSupported(SUDIV)) { | |
1301 // A value with an integer representation does not need to be transformed. | |
1302 if (divisor->representation().IsInteger32()) { | |
1303 return divisor; | |
1304 // A change from an integer32 can be replaced by the integer32 value. | |
1305 } else if (divisor->IsChange() && | |
1306 HChange::cast(divisor)->from().IsInteger32()) { | |
1307 return HChange::cast(divisor)->value(); | |
1308 } | |
1309 } | |
1310 | |
1311 if (divisor->IsConstant() && HConstant::cast(divisor)->HasInteger32Value()) { | |
1312 HConstant* constant_val = HConstant::cast(divisor); | |
1313 int32_t int32_val = constant_val->Integer32Value(); | |
1314 if (LChunkBuilder::HasMagicNumberForDivisor(int32_val) || | |
1315 CpuFeatures::IsSupported(SUDIV)) { | |
1316 return constant_val->CopyToRepresentation(Representation::Integer32(), | |
1317 divisor->block()->zone()); | |
1318 } | |
1319 } | |
1320 | |
1321 return NULL; | |
1322 } | |
1323 | |
1324 | |
1325 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { | 1299 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
| 1300 // LMathFloorOfDiv can only handle a subset of divisors, so fall |
| 1301 // back to a flooring division in all other cases. |
1326 HValue* right = instr->right(); | 1302 HValue* right = instr->right(); |
| 1303 if (!right->IsInteger32Constant() || |
| 1304 (!CpuFeatures::IsSupported(SUDIV) && |
| 1305 !HasMagicNumberForDivisor(HConstant::cast(right)->Integer32Value()))) { |
| 1306 LOperand* dividend = UseRegister(instr->left()); |
| 1307 LOperand* divisor = UseRegister(right); |
| 1308 LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4); |
| 1309 LDivI* div = new(zone()) LDivI(dividend, divisor, temp); |
| 1310 return AssignEnvironment(DefineAsRegister(div)); |
| 1311 } |
| 1312 |
1327 LOperand* dividend = UseRegister(instr->left()); | 1313 LOperand* dividend = UseRegister(instr->left()); |
1328 LOperand* divisor = CpuFeatures::IsSupported(SUDIV) | 1314 LOperand* divisor = CpuFeatures::IsSupported(SUDIV) |
1329 ? UseRegister(right) | 1315 ? UseRegister(right) |
1330 : UseOrConstant(right); | 1316 : UseOrConstant(right); |
1331 LOperand* remainder = TempRegister(); | 1317 LOperand* remainder = TempRegister(); |
1332 ASSERT(CpuFeatures::IsSupported(SUDIV) || | |
1333 (right->IsConstant() && | |
1334 HConstant::cast(right)->HasInteger32Value() && | |
1335 HasMagicNumberForDivisor(HConstant::cast(right)->Integer32Value()))); | |
1336 return AssignEnvironment(DefineAsRegister( | 1318 return AssignEnvironment(DefineAsRegister( |
1337 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); | 1319 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); |
1338 } | 1320 } |
1339 | 1321 |
1340 | 1322 |
1341 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1323 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
1342 HValue* left = instr->left(); | 1324 HValue* left = instr->left(); |
1343 HValue* right = instr->right(); | 1325 HValue* right = instr->right(); |
1344 if (instr->representation().IsSmiOrInteger32()) { | 1326 if (instr->representation().IsSmiOrInteger32()) { |
1345 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1327 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1346 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1328 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1347 if (instr->HasPowerOf2Divisor()) { | 1329 if (instr->RightIsPowerOf2()) { |
1348 ASSERT(!right->CanBeZero()); | 1330 ASSERT(!right->CanBeZero()); |
1349 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), | 1331 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), |
1350 UseConstant(right)); | 1332 UseConstant(right)); |
1351 LInstruction* result = DefineAsRegister(mod); | 1333 LInstruction* result = DefineAsRegister(mod); |
1352 return (left->CanBeNegative() && | 1334 return (left->CanBeNegative() && |
1353 instr->CheckFlag(HValue::kBailoutOnMinusZero)) | 1335 instr->CheckFlag(HValue::kBailoutOnMinusZero)) |
1354 ? AssignEnvironment(result) | 1336 ? AssignEnvironment(result) |
1355 : result; | 1337 : result; |
1356 } else if (CpuFeatures::IsSupported(SUDIV)) { | 1338 } else if (CpuFeatures::IsSupported(SUDIV)) { |
1357 LModI* mod = new(zone()) LModI(UseRegister(left), | 1339 LModI* mod = new(zone()) LModI(UseRegister(left), |
(...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2529 } | 2511 } |
2530 | 2512 |
2531 | 2513 |
2532 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2514 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2533 LOperand* object = UseRegister(instr->object()); | 2515 LOperand* object = UseRegister(instr->object()); |
2534 LOperand* index = UseRegister(instr->index()); | 2516 LOperand* index = UseRegister(instr->index()); |
2535 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); | 2517 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); |
2536 } | 2518 } |
2537 | 2519 |
2538 } } // namespace v8::internal | 2520 } } // namespace v8::internal |
OLD | NEW |