Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 16082008: Increase sanity of integer division handling on ARM (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed Rodolph's comments Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1386 matching lines...) Expand 10 before | Expand all | Expand 10 after
1397 // This sequence could be replaced with 'mls' when 1397 // This sequence could be replaced with 'mls' when
1398 // it gets implemented. 1398 // it gets implemented.
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 class DeferredDivI: public LDeferredCode {
1408 public:
1409 DeferredDivI(LCodeGen* codegen, LDivI* instr)
1410 : LDeferredCode(codegen), instr_(instr) { }
1411 virtual void Generate() {
1412 codegen()->DoDeferredBinaryOpStub(instr_->pointer_map(),
1413 instr_->left(),
1414 instr_->right(),
1415 Token::DIV);
1416 }
1417 virtual LInstruction* instr() { return instr_; }
1418 private:
1419 LDivI* instr_;
1420 };
1421
1422 if (instr->hydrogen()->HasPowerOf2Divisor()) { 1407 if (instr->hydrogen()->HasPowerOf2Divisor()) {
1423 Register dividend = ToRegister(instr->left()); 1408 Register dividend = ToRegister(instr->left());
1424 int32_t divisor = 1409 int32_t divisor =
1425 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 1410 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
1426 int32_t test_value = 0; 1411 int32_t test_value = 0;
1427 int32_t power = 0; 1412 int32_t power = 0;
1428 1413
1429 if (divisor > 0) { 1414 if (divisor > 0) {
1430 test_value = divisor - 1; 1415 test_value = divisor - 1;
1431 power = WhichPowerOf2(divisor); 1416 power = WhichPowerOf2(divisor);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 // Check for (kMinInt / -1). 1463 // Check for (kMinInt / -1).
1479 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1464 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1480 Label left_not_min_int; 1465 Label left_not_min_int;
1481 __ cmp(left, Operand(kMinInt)); 1466 __ cmp(left, Operand(kMinInt));
1482 __ b(ne, &left_not_min_int); 1467 __ b(ne, &left_not_min_int);
1483 __ cmp(right, Operand(-1)); 1468 __ cmp(right, Operand(-1));
1484 DeoptimizeIf(eq, instr->environment()); 1469 DeoptimizeIf(eq, instr->environment());
1485 __ bind(&left_not_min_int); 1470 __ bind(&left_not_min_int);
1486 } 1471 }
1487 1472
1488 Label done, deoptimize; 1473 if (CpuFeatures::IsSupported(SUDIV)) {
1489 // Test for a few common cases first. 1474 CpuFeatureScope scope(masm(), SUDIV);
1490 __ cmp(right, Operand(1)); 1475 __ sdiv(result, left, right);
1491 __ mov(result, left, LeaveCC, eq);
1492 __ b(eq, &done);
1493 1476
1494 __ cmp(right, Operand(2)); 1477 // Compute remainder and deopt if it's not zero.
1495 __ tst(left, Operand(1), eq); 1478 const Register remainder = scratch0();
1496 __ mov(result, Operand(left, ASR, 1), LeaveCC, eq); 1479 __ mls(remainder, result, right, left);
1497 __ b(eq, &done); 1480 __ cmp(remainder, Operand::Zero());
1481 DeoptimizeIf(ne, instr->environment());
1482 } else {
1483 const DoubleRegister vleft = ToDoubleRegister(instr->temp());
1484 const DoubleRegister vright = double_scratch0();
1485 __ vmov(vleft.low(), left);
1486 __ vmov(vright.low(), right);
1487 __ vcvt_f64_s32(vleft, vleft.low());
1488 __ vcvt_f64_s32(vright, vright.low());
1489 __ vdiv(vleft, vleft, vright); // vleft now contains the result.
1498 1490
1499 __ cmp(right, Operand(4)); 1491 // Convert back to integer32; deopt if exact conversion is not possible.
1500 __ tst(left, Operand(3), eq); 1492 // Use vright as scratch register.
1501 __ mov(result, Operand(left, ASR, 2), LeaveCC, eq); 1493 __ vcvt_s32_f64(vright.low(), vleft);
1502 __ b(eq, &done); 1494 __ vmov(result, vright.low());
1503 1495 __ vcvt_f64_s32(vright, vright.low());
1504 // Call the stub. The numbers in r0 and r1 have 1496 __ VFPCompareAndSetFlags(vleft, vright);
1505 // to be tagged to Smis. If that is not possible, deoptimize. 1497 DeoptimizeIf(ne, instr->environment());
1506 DeferredDivI* deferred = new(zone()) DeferredDivI(this, instr); 1498 }
1507
1508 __ TrySmiTag(left, &deoptimize);
1509 __ TrySmiTag(right, &deoptimize);
1510
1511 __ b(al, deferred->entry());
1512 __ bind(deferred->exit());
1513
1514 // If the result in r0 is a Smi, untag it, else deoptimize.
1515 __ JumpIfNotSmi(result, &deoptimize);
1516 __ SmiUntag(result);
1517 __ b(&done);
1518
1519 __ bind(&deoptimize);
1520 DeoptimizeIf(al, instr->environment());
1521 __ bind(&done);
1522 } 1499 }
1523 1500
1524 1501
1525 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { 1502 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
1526 DwVfpRegister addend = ToDoubleRegister(instr->addend()); 1503 DwVfpRegister addend = ToDoubleRegister(instr->addend());
1527 DwVfpRegister multiplier = ToDoubleRegister(instr->multiplier()); 1504 DwVfpRegister multiplier = ToDoubleRegister(instr->multiplier());
1528 DwVfpRegister multiplicand = ToDoubleRegister(instr->multiplicand()); 1505 DwVfpRegister multiplicand = ToDoubleRegister(instr->multiplicand());
1529 1506
1530 // This is computed in-place. 1507 // This is computed in-place.
1531 ASSERT(addend.is(ToDoubleRegister(instr->result()))); 1508 ASSERT(addend.is(ToDoubleRegister(instr->result())));
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 // Check if the result needs to be corrected. 1587 // Check if the result needs to be corrected.
1611 __ mls(remainder, result, right, left); 1588 __ mls(remainder, result, right, left);
1612 __ cmp(remainder, Operand::Zero()); 1589 __ cmp(remainder, Operand::Zero());
1613 __ sub(result, result, Operand(1), LeaveCC, ne); 1590 __ sub(result, result, Operand(1), LeaveCC, ne);
1614 1591
1615 __ bind(&done); 1592 __ bind(&done);
1616 } 1593 }
1617 } 1594 }
1618 1595
1619 1596
1620 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map,
1621 LOperand* left_argument,
1622 LOperand* right_argument,
1623 Token::Value op) {
1624 Register left = ToRegister(left_argument);
1625 Register right = ToRegister(right_argument);
1626
1627 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles);
1628 // Move left to r1 and right to r0 for the stub call.
1629 if (left.is(r1)) {
1630 __ Move(r0, right);
1631 } else if (left.is(r0) && right.is(r1)) {
1632 __ Swap(r0, r1, r2);
1633 } else if (left.is(r0)) {
1634 ASSERT(!right.is(r1));
1635 __ mov(r1, r0);
1636 __ mov(r0, right);
1637 } else {
1638 ASSERT(!left.is(r0) && !right.is(r0));
1639 __ mov(r0, right);
1640 __ mov(r1, left);
1641 }
1642 BinaryOpStub stub(op, OVERWRITE_LEFT);
1643 __ CallStub(&stub);
1644 RecordSafepointWithRegistersAndDoubles(pointer_map,
1645 0,
1646 Safepoint::kNoLazyDeopt);
1647 // Overwrite the stored value of r0 with the result of the stub.
1648 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0);
1649 }
1650
1651
1652 void LCodeGen::DoMulI(LMulI* instr) { 1597 void LCodeGen::DoMulI(LMulI* instr) {
1653 Register scratch = scratch0(); 1598 Register scratch = scratch0();
1654 Register result = ToRegister(instr->result()); 1599 Register result = ToRegister(instr->result());
1655 // Note that result may alias left. 1600 // Note that result may alias left.
1656 Register left = ToRegister(instr->left()); 1601 Register left = ToRegister(instr->left());
1657 LOperand* right_op = instr->right(); 1602 LOperand* right_op = instr->right();
1658 1603
1659 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1604 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1660 bool bailout_on_minus_zero = 1605 bool bailout_on_minus_zero =
1661 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1606 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
(...skipping 4260 matching lines...) Expand 10 before | Expand all | Expand 10 after
5922 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5867 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5923 __ ldr(result, FieldMemOperand(scratch, 5868 __ ldr(result, FieldMemOperand(scratch,
5924 FixedArray::kHeaderSize - kPointerSize)); 5869 FixedArray::kHeaderSize - kPointerSize));
5925 __ bind(&done); 5870 __ bind(&done);
5926 } 5871 }
5927 5872
5928 5873
5929 #undef __ 5874 #undef __
5930 5875
5931 } } // namespace v8::internal 5876 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698