Chromium Code Reviews| 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 1320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1331 __ vmla(addend, multiplier, multiplicand); | 1331 __ vmla(addend, multiplier, multiplicand); |
| 1332 } | 1332 } |
| 1333 | 1333 |
| 1334 | 1334 |
| 1335 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { | 1335 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { |
| 1336 const Register result = ToRegister(instr->result()); | 1336 const Register result = ToRegister(instr->result()); |
| 1337 const Register left = ToRegister(instr->left()); | 1337 const Register left = ToRegister(instr->left()); |
| 1338 const Register remainder = ToRegister(instr->temp()); | 1338 const Register remainder = ToRegister(instr->temp()); |
| 1339 const Register scratch = scratch0(); | 1339 const Register scratch = scratch0(); |
| 1340 | 1340 |
| 1341 // We only optimize this for division by constants, because the standard | 1341 if (instr->right()->IsConstantOperand()) { |
|
danno
2012/11/27 22:17:20
Can you please make sure the comment about "divisi
| |
| 1342 // integer division routine is usually slower than transitionning to VFP. | 1342 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right())); |
| 1343 // This could be optimized on processors with SDIV available. | 1343 if (LChunkBuilder::HasMagicNumberForDivisor(divisor)) { |
| 1344 ASSERT(instr->right()->IsConstantOperand()); | 1344 if (divisor < 0) { |
| 1345 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right())); | 1345 __ cmp(left, Operand(0)); |
| 1346 if (divisor < 0) { | 1346 DeoptimizeIf(eq, instr->environment()); |
| 1347 __ cmp(left, Operand(0)); | 1347 } |
| 1348 EmitSignedIntegerDivisionByConstant(result, | |
| 1349 left, | |
| 1350 divisor, | |
| 1351 remainder, | |
| 1352 scratch, | |
| 1353 instr->environment()); | |
| 1354 } else { | |
| 1355 // This point should never be reached if the CPU doesn't support SUDIV. | |
| 1356 ASSERT(CpuFeatures::IsSupported(SUDIV)); | |
| 1357 CpuFeatures::Scope scope(SUDIV); | |
| 1358 | |
| 1359 __ mov(scratch, ToOperand(instr->right())); | |
| 1360 __ sdiv(result, left, scratch); | |
|
danno
2012/11/27 22:17:20
from here to the sub(result, result, ....) the cod
| |
| 1361 __ mls(remainder, result, scratch, left); | |
| 1362 } | |
| 1363 | |
| 1364 // We performed a truncating division. Correct the result if necessary. | |
|
danno
2012/11/27 22:17:20
Why is it safe to omit the x/0, kMinInt/-1 and -0
| |
| 1365 __ cmp(remainder, Operand(0)); | |
| 1366 __ teq(remainder, Operand(divisor), ne); | |
| 1367 __ sub(result, result, Operand(1), LeaveCC, mi); | |
| 1368 } else { | |
| 1369 // This point should never be reached if the CPU doesn't support SUDIV. | |
| 1370 ASSERT(CpuFeatures::IsSupported(SUDIV)); | |
| 1371 CpuFeatures::Scope scope(SUDIV); | |
| 1372 | |
| 1373 const Register right = ToRegister(instr->right()); | |
| 1374 | |
| 1375 // Check for x / 0. | |
| 1376 __ cmp(right, Operand(0)); | |
| 1348 DeoptimizeIf(eq, instr->environment()); | 1377 DeoptimizeIf(eq, instr->environment()); |
| 1378 | |
| 1379 // Check for (kMinInt / -1). | |
| 1380 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | |
| 1381 Label left_not_min_int; | |
| 1382 __ cmp(left, Operand(kMinInt)); | |
| 1383 __ b(ne, &left_not_min_int); | |
| 1384 __ cmp(right, Operand(-1)); | |
| 1385 DeoptimizeIf(eq, instr->environment()); | |
| 1386 __ bind(&left_not_min_int); | |
| 1387 } | |
| 1388 | |
| 1389 // Check for (0 / -x) that will produce negative zero. | |
| 1390 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
| 1391 __ cmp(right, Operand(0)); | |
| 1392 __ cmp(left, Operand(0), mi); | |
| 1393 // "right" can't be null because the code would have already been | |
| 1394 // deoptimized. The Z flag is set only if (right < 0) and (left == 0). | |
| 1395 // In this case we need to deoptimize to produce a -0. | |
| 1396 DeoptimizeIf(eq, instr->environment()); | |
| 1397 } | |
| 1398 | |
| 1399 __ sdiv(result, left, right); | |
| 1400 __ mls(remainder, result, right, left); | |
| 1401 | |
| 1402 // We performed a truncating division. Correct the result if necessary. | |
| 1403 __ cmp(remainder, Operand(0)); | |
| 1404 __ teq(remainder, Operand(right), ne); | |
| 1405 __ sub(result, result, Operand(1), LeaveCC, mi); | |
| 1349 } | 1406 } |
| 1350 EmitSignedIntegerDivisionByConstant(result, | |
| 1351 left, | |
| 1352 divisor, | |
| 1353 remainder, | |
| 1354 scratch, | |
| 1355 instr->environment()); | |
| 1356 // We operated a truncating division. Correct the result if necessary. | |
| 1357 __ cmp(remainder, Operand(0)); | |
| 1358 __ teq(remainder, Operand(divisor), ne); | |
| 1359 __ sub(result, result, Operand(1), LeaveCC, mi); | |
| 1360 } | 1407 } |
| 1361 | 1408 |
| 1362 | 1409 |
| 1363 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, | 1410 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, |
| 1364 LOperand* left_argument, | 1411 LOperand* left_argument, |
| 1365 LOperand* right_argument, | 1412 LOperand* right_argument, |
| 1366 Token::Value op) { | 1413 Token::Value op) { |
| 1367 Register left = ToRegister(left_argument); | 1414 Register left = ToRegister(left_argument); |
| 1368 Register right = ToRegister(right_argument); | 1415 Register right = ToRegister(right_argument); |
| 1369 | 1416 |
| (...skipping 4402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5772 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 5819 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 5773 __ ldr(result, FieldMemOperand(scratch, | 5820 __ ldr(result, FieldMemOperand(scratch, |
| 5774 FixedArray::kHeaderSize - kPointerSize)); | 5821 FixedArray::kHeaderSize - kPointerSize)); |
| 5775 __ bind(&done); | 5822 __ bind(&done); |
| 5776 } | 5823 } |
| 5777 | 5824 |
| 5778 | 5825 |
| 5779 #undef __ | 5826 #undef __ |
| 5780 | 5827 |
| 5781 } } // namespace v8::internal | 5828 } } // namespace v8::internal |
| OLD | NEW |