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 1403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1414 __ vmla(addend, multiplier, multiplicand); | 1414 __ vmla(addend, multiplier, multiplicand); |
1415 } | 1415 } |
1416 | 1416 |
1417 | 1417 |
1418 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { | 1418 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { |
1419 const Register result = ToRegister(instr->result()); | 1419 const Register result = ToRegister(instr->result()); |
1420 const Register left = ToRegister(instr->left()); | 1420 const Register left = ToRegister(instr->left()); |
1421 const Register remainder = ToRegister(instr->temp()); | 1421 const Register remainder = ToRegister(instr->temp()); |
1422 const Register scratch = scratch0(); | 1422 const Register scratch = scratch0(); |
1423 | 1423 |
1424 // We only optimize this for division by constants, because the standard | 1424 if (!CpuFeatures::IsSupported(SUDIV)) { |
1425 // integer division routine is usually slower than transitionning to VFP. | 1425 // If the CPU doesn't support sdiv instruction, we only optimize when we |
1426 // This could be optimized on processors with SDIV available. | 1426 // have magic numbers for the divisor. The standard integer division routine |
1427 ASSERT(instr->right()->IsConstantOperand()); | 1427 // is usually slower than transitionning to VFP. |
1428 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right())); | 1428 ASSERT(instr->right()->IsConstantOperand()); |
1429 if (divisor < 0) { | 1429 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right())); |
1430 __ cmp(left, Operand(0)); | 1430 ASSERT(LChunkBuilder::HasMagicNumberForDivisor(divisor)); |
| 1431 if (divisor < 0) { |
| 1432 __ cmp(left, Operand(0)); |
| 1433 DeoptimizeIf(eq, instr->environment()); |
| 1434 } |
| 1435 EmitSignedIntegerDivisionByConstant(result, |
| 1436 left, |
| 1437 divisor, |
| 1438 remainder, |
| 1439 scratch, |
| 1440 instr->environment()); |
| 1441 // We performed a truncating division. Correct the result if necessary. |
| 1442 __ cmp(remainder, Operand(0)); |
| 1443 __ teq(remainder, Operand(divisor), ne); |
| 1444 __ sub(result, result, Operand(1), LeaveCC, mi); |
| 1445 } else { |
| 1446 CpuFeatures::Scope scope(SUDIV); |
| 1447 const Register right = ToRegister(instr->right()); |
| 1448 |
| 1449 // Check for x / 0. |
| 1450 __ cmp(right, Operand(0)); |
1431 DeoptimizeIf(eq, instr->environment()); | 1451 DeoptimizeIf(eq, instr->environment()); |
| 1452 |
| 1453 // Check for (kMinInt / -1). |
| 1454 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 1455 Label left_not_min_int; |
| 1456 __ cmp(left, Operand(kMinInt)); |
| 1457 __ b(ne, &left_not_min_int); |
| 1458 __ cmp(right, Operand(-1)); |
| 1459 DeoptimizeIf(eq, instr->environment()); |
| 1460 __ bind(&left_not_min_int); |
| 1461 } |
| 1462 |
| 1463 // Check for (0 / -x) that will produce negative zero. |
| 1464 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1465 __ cmp(right, Operand(0)); |
| 1466 __ cmp(left, Operand(0), mi); |
| 1467 // "right" can't be null because the code would have already been |
| 1468 // deoptimized. The Z flag is set only if (right < 0) and (left == 0). |
| 1469 // In this case we need to deoptimize to produce a -0. |
| 1470 DeoptimizeIf(eq, instr->environment()); |
| 1471 } |
| 1472 |
| 1473 Label done; |
| 1474 __ sdiv(result, left, right); |
| 1475 // If both operands have the same sign then we are done. |
| 1476 __ eor(remainder, left, Operand(right), SetCC); |
| 1477 __ b(pl, &done); |
| 1478 |
| 1479 // Check if the result needs to be corrected. |
| 1480 __ mls(remainder, result, right, left); |
| 1481 __ cmp(remainder, Operand(0)); |
| 1482 __ sub(result, result, Operand(1), LeaveCC, ne); |
| 1483 |
| 1484 __ bind(&done); |
1432 } | 1485 } |
1433 EmitSignedIntegerDivisionByConstant(result, | |
1434 left, | |
1435 divisor, | |
1436 remainder, | |
1437 scratch, | |
1438 instr->environment()); | |
1439 // We operated a truncating division. Correct the result if necessary. | |
1440 __ cmp(remainder, Operand(0)); | |
1441 __ teq(remainder, Operand(divisor), ne); | |
1442 __ sub(result, result, Operand(1), LeaveCC, mi); | |
1443 } | 1486 } |
1444 | 1487 |
1445 | 1488 |
1446 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, | 1489 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, |
1447 LOperand* left_argument, | 1490 LOperand* left_argument, |
1448 LOperand* right_argument, | 1491 LOperand* right_argument, |
1449 Token::Value op) { | 1492 Token::Value op) { |
1450 CpuFeatures::Scope vfp_scope(VFP2); | 1493 CpuFeatures::Scope vfp_scope(VFP2); |
1451 Register left = ToRegister(left_argument); | 1494 Register left = ToRegister(left_argument); |
1452 Register right = ToRegister(right_argument); | 1495 Register right = ToRegister(right_argument); |
(...skipping 4577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6030 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 6073 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
6031 __ ldr(result, FieldMemOperand(scratch, | 6074 __ ldr(result, FieldMemOperand(scratch, |
6032 FixedArray::kHeaderSize - kPointerSize)); | 6075 FixedArray::kHeaderSize - kPointerSize)); |
6033 __ bind(&done); | 6076 __ bind(&done); |
6034 } | 6077 } |
6035 | 6078 |
6036 | 6079 |
6037 #undef __ | 6080 #undef __ |
6038 | 6081 |
6039 } } // namespace v8::internal | 6082 } } // namespace v8::internal |
OLD | NEW |