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 |