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 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1399 __ mul(scratch, result, ip); | 1399 __ mul(scratch, result, ip); |
1400 __ sub(remainder, dividend, scratch); | 1400 __ sub(remainder, dividend, scratch); |
1401 } | 1401 } |
1402 } | 1402 } |
1403 } | 1403 } |
1404 | 1404 |
1405 | 1405 |
1406 void LCodeGen::DoDivI(LDivI* instr) { | 1406 void LCodeGen::DoDivI(LDivI* instr) { |
1407 if (instr->hydrogen()->HasPowerOf2Divisor()) { | 1407 if (instr->hydrogen()->HasPowerOf2Divisor()) { |
1408 Register dividend = ToRegister(instr->left()); | 1408 Register dividend = ToRegister(instr->left()); |
1409 int32_t divisor = | 1409 int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant(); |
1410 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); | |
1411 int32_t test_value = 0; | 1410 int32_t test_value = 0; |
1412 int32_t power = 0; | 1411 int32_t power = 0; |
1413 | 1412 |
1414 if (divisor > 0) { | 1413 if (divisor > 0) { |
1415 test_value = divisor - 1; | 1414 test_value = divisor - 1; |
1416 power = WhichPowerOf2(divisor); | 1415 power = WhichPowerOf2(divisor); |
1417 } else { | 1416 } else { |
1418 // Check for (0 / -x) that will produce negative zero. | 1417 // Check for (0 / -x) that will produce negative zero. |
1419 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1418 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1420 __ tst(dividend, Operand(dividend)); | 1419 __ tst(dividend, Operand(dividend)); |
1421 DeoptimizeIf(eq, instr->environment()); | 1420 DeoptimizeIf(eq, instr->environment()); |
1422 } | 1421 } |
1423 // Check for (kMinInt / -1). | 1422 // Check for (kMinInt / -1). |
1424 if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1423 if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
1425 __ cmp(dividend, Operand(kMinInt)); | 1424 __ cmp(dividend, Operand(kMinInt)); |
1426 DeoptimizeIf(eq, instr->environment()); | 1425 DeoptimizeIf(eq, instr->environment()); |
1427 } | 1426 } |
1428 test_value = - divisor - 1; | 1427 test_value = - divisor - 1; |
1429 power = WhichPowerOf2(-divisor); | 1428 power = WhichPowerOf2(-divisor); |
1430 } | 1429 } |
1431 | 1430 |
1432 if (test_value != 0) { | 1431 if (test_value != 0) { |
1433 // Deoptimize if remainder is not 0. | 1432 if (instr->hydrogen()->CheckFlag( |
1434 __ tst(dividend, Operand(test_value)); | 1433 HInstruction::kAllUsesTruncatingToInt32)) { |
1435 DeoptimizeIf(ne, instr->environment()); | 1434 __ cmp(dividend, Operand(0)); |
1436 __ mov(dividend, Operand(dividend, ASR, power)); | 1435 __ rsb(dividend, dividend, Operand(0), LeaveCC, lt); |
| 1436 __ mov(dividend, Operand(dividend, ASR, power)); |
| 1437 if (divisor > 0) __ rsb(dividend, dividend, Operand(0), LeaveCC, lt); |
| 1438 return; // Don't fall through to "__ rsb" below. |
| 1439 } else { |
| 1440 // Deoptimize if remainder is not 0. |
| 1441 __ tst(dividend, Operand(test_value)); |
| 1442 DeoptimizeIf(ne, instr->environment()); |
| 1443 __ mov(dividend, Operand(dividend, ASR, power)); |
| 1444 } |
1437 } | 1445 } |
1438 if (divisor < 0) __ rsb(dividend, dividend, Operand(0)); | 1446 if (divisor < 0) __ rsb(dividend, dividend, Operand(0)); |
1439 | 1447 |
1440 return; | 1448 return; |
1441 } | 1449 } |
1442 | 1450 |
1443 const Register left = ToRegister(instr->left()); | 1451 const Register left = ToRegister(instr->left()); |
1444 const Register right = ToRegister(instr->right()); | 1452 const Register right = ToRegister(instr->right()); |
1445 const Register result = ToRegister(instr->result()); | 1453 const Register result = ToRegister(instr->result()); |
1446 | 1454 |
(...skipping 20 matching lines...) Expand all Loading... |
1467 __ b(ne, &left_not_min_int); | 1475 __ b(ne, &left_not_min_int); |
1468 __ cmp(right, Operand(-1)); | 1476 __ cmp(right, Operand(-1)); |
1469 DeoptimizeIf(eq, instr->environment()); | 1477 DeoptimizeIf(eq, instr->environment()); |
1470 __ bind(&left_not_min_int); | 1478 __ bind(&left_not_min_int); |
1471 } | 1479 } |
1472 | 1480 |
1473 if (CpuFeatures::IsSupported(SUDIV)) { | 1481 if (CpuFeatures::IsSupported(SUDIV)) { |
1474 CpuFeatureScope scope(masm(), SUDIV); | 1482 CpuFeatureScope scope(masm(), SUDIV); |
1475 __ sdiv(result, left, right); | 1483 __ sdiv(result, left, right); |
1476 | 1484 |
1477 // Compute remainder and deopt if it's not zero. | 1485 if (!instr->hydrogen()->CheckFlag( |
1478 const Register remainder = scratch0(); | 1486 HInstruction::kAllUsesTruncatingToInt32)) { |
1479 __ mls(remainder, result, right, left); | 1487 // Compute remainder and deopt if it's not zero. |
1480 __ cmp(remainder, Operand::Zero()); | 1488 const Register remainder = scratch0(); |
1481 DeoptimizeIf(ne, instr->environment()); | 1489 __ mls(remainder, result, right, left); |
| 1490 __ cmp(remainder, Operand::Zero()); |
| 1491 DeoptimizeIf(ne, instr->environment()); |
| 1492 } |
1482 } else { | 1493 } else { |
1483 const DoubleRegister vleft = ToDoubleRegister(instr->temp()); | 1494 const DoubleRegister vleft = ToDoubleRegister(instr->temp()); |
1484 const DoubleRegister vright = double_scratch0(); | 1495 const DoubleRegister vright = double_scratch0(); |
1485 __ vmov(vleft.low(), left); | 1496 __ vmov(vleft.low(), left); |
1486 __ vmov(vright.low(), right); | 1497 __ vmov(vright.low(), right); |
1487 __ vcvt_f64_s32(vleft, vleft.low()); | 1498 __ vcvt_f64_s32(vleft, vleft.low()); |
1488 __ vcvt_f64_s32(vright, vright.low()); | 1499 __ vcvt_f64_s32(vright, vright.low()); |
1489 __ vdiv(vleft, vleft, vright); // vleft now contains the result. | 1500 __ vdiv(vleft, vleft, vright); // vleft now contains the result. |
1490 | |
1491 // Convert back to integer32; deopt if exact conversion is not possible. | |
1492 // Use vright as scratch register. | |
1493 __ vcvt_s32_f64(vright.low(), vleft); | 1501 __ vcvt_s32_f64(vright.low(), vleft); |
1494 __ vmov(result, vright.low()); | 1502 __ vmov(result, vright.low()); |
1495 __ vcvt_f64_s32(vright, vright.low()); | 1503 |
1496 __ VFPCompareAndSetFlags(vleft, vright); | 1504 if (!instr->hydrogen()->CheckFlag( |
1497 DeoptimizeIf(ne, instr->environment()); | 1505 HInstruction::kAllUsesTruncatingToInt32)) { |
| 1506 // Deopt if exact conversion to integer was not possible. |
| 1507 // Use vright as scratch register. |
| 1508 __ vcvt_f64_s32(vright, vright.low()); |
| 1509 __ VFPCompareAndSetFlags(vleft, vright); |
| 1510 DeoptimizeIf(ne, instr->environment()); |
| 1511 } |
1498 } | 1512 } |
1499 } | 1513 } |
1500 | 1514 |
1501 | 1515 |
1502 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { | 1516 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { |
1503 DwVfpRegister addend = ToDoubleRegister(instr->addend()); | 1517 DwVfpRegister addend = ToDoubleRegister(instr->addend()); |
1504 DwVfpRegister multiplier = ToDoubleRegister(instr->multiplier()); | 1518 DwVfpRegister multiplier = ToDoubleRegister(instr->multiplier()); |
1505 DwVfpRegister multiplicand = ToDoubleRegister(instr->multiplicand()); | 1519 DwVfpRegister multiplicand = ToDoubleRegister(instr->multiplicand()); |
1506 | 1520 |
1507 // This is computed in-place. | 1521 // This is computed in-place. |
(...skipping 4359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5867 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5881 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
5868 __ ldr(result, FieldMemOperand(scratch, | 5882 __ ldr(result, FieldMemOperand(scratch, |
5869 FixedArray::kHeaderSize - kPointerSize)); | 5883 FixedArray::kHeaderSize - kPointerSize)); |
5870 __ bind(&done); | 5884 __ bind(&done); |
5871 } | 5885 } |
5872 | 5886 |
5873 | 5887 |
5874 #undef __ | 5888 #undef __ |
5875 | 5889 |
5876 } } // namespace v8::internal | 5890 } } // namespace v8::internal |
OLD | NEW |