OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/cpu-profiler.h" | 9 #include "src/cpu-profiler.h" |
10 #include "src/hydrogen-osr.h" | 10 #include "src/hydrogen-osr.h" |
(...skipping 1473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1484 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, left, Operand(zero_reg)); | 1484 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, left, Operand(zero_reg)); |
1485 } | 1485 } |
1486 | 1486 |
1487 switch (constant) { | 1487 switch (constant) { |
1488 case -1: | 1488 case -1: |
1489 if (overflow) { | 1489 if (overflow) { |
1490 __ SubuAndCheckForOverflow(result, zero_reg, left, scratch); | 1490 __ SubuAndCheckForOverflow(result, zero_reg, left, scratch); |
1491 DeoptimizeIf(gt, instr, Deoptimizer::kOverflow, scratch, | 1491 DeoptimizeIf(gt, instr, Deoptimizer::kOverflow, scratch, |
1492 Operand(kMaxInt)); | 1492 Operand(kMaxInt)); |
1493 } else { | 1493 } else { |
1494 __ Dsubu(result, zero_reg, left); | 1494 __ Subu(result, zero_reg, left); |
1495 } | 1495 } |
1496 break; | 1496 break; |
1497 case 0: | 1497 case 0: |
1498 if (bailout_on_minus_zero) { | 1498 if (bailout_on_minus_zero) { |
1499 // If left is strictly negative and the constant is null, the | 1499 // If left is strictly negative and the constant is null, the |
1500 // result is -0. Deoptimize if required, otherwise return 0. | 1500 // result is -0. Deoptimize if required, otherwise return 0. |
1501 DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero, left, | 1501 DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero, left, |
1502 Operand(zero_reg)); | 1502 Operand(zero_reg)); |
1503 } | 1503 } |
1504 __ mov(result, zero_reg); | 1504 __ mov(result, zero_reg); |
1505 break; | 1505 break; |
1506 case 1: | 1506 case 1: |
1507 // Nothing to do. | 1507 // Nothing to do. |
1508 __ Move(result, left); | 1508 __ Move(result, left); |
1509 break; | 1509 break; |
1510 default: | 1510 default: |
1511 // Multiplying by powers of two and powers of two plus or minus | 1511 // Multiplying by powers of two and powers of two plus or minus |
1512 // one can be done faster with shifted operands. | 1512 // one can be done faster with shifted operands. |
1513 // For other constants we emit standard code. | 1513 // For other constants we emit standard code. |
1514 int32_t mask = constant >> 31; | 1514 int32_t mask = constant >> 31; |
1515 uint32_t constant_abs = (constant + mask) ^ mask; | 1515 uint32_t constant_abs = (constant + mask) ^ mask; |
1516 | 1516 |
1517 if (base::bits::IsPowerOfTwo32(constant_abs)) { | 1517 if (base::bits::IsPowerOfTwo32(constant_abs)) { |
1518 int32_t shift = WhichPowerOf2(constant_abs); | 1518 int32_t shift = WhichPowerOf2(constant_abs); |
1519 __ dsll(result, left, shift); | 1519 __ sll(result, left, shift); |
1520 // Correct the sign of the result if the constant is negative. | 1520 // Correct the sign of the result if the constant is negative. |
1521 if (constant < 0) __ Dsubu(result, zero_reg, result); | 1521 if (constant < 0) __ Subu(result, zero_reg, result); |
1522 } else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) { | 1522 } else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) { |
1523 int32_t shift = WhichPowerOf2(constant_abs - 1); | 1523 int32_t shift = WhichPowerOf2(constant_abs - 1); |
1524 __ dsll(scratch, left, shift); | 1524 __ sll(scratch, left, shift); |
1525 __ Daddu(result, scratch, left); | 1525 __ addu(result, scratch, left); |
1526 // Correct the sign of the result if the constant is negative. | 1526 // Correct the sign of the result if the constant is negative. |
1527 if (constant < 0) __ Dsubu(result, zero_reg, result); | 1527 if (constant < 0) __ Dsubu(result, zero_reg, result); |
1528 } else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) { | 1528 } else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) { |
1529 int32_t shift = WhichPowerOf2(constant_abs + 1); | 1529 int32_t shift = WhichPowerOf2(constant_abs + 1); |
1530 __ dsll(scratch, left, shift); | 1530 __ sll(scratch, left, shift); |
1531 __ Dsubu(result, scratch, left); | 1531 __ Subu(result, scratch, left); |
1532 // Correct the sign of the result if the constant is negative. | 1532 // Correct the sign of the result if the constant is negative. |
1533 if (constant < 0) __ Dsubu(result, zero_reg, result); | 1533 if (constant < 0) __ Dsubu(result, zero_reg, result); |
1534 } else { | 1534 } else { |
1535 // Generate standard code. | 1535 // Generate standard code. |
1536 __ li(at, constant); | 1536 __ li(at, constant); |
1537 __ Dmul(result, left, at); | 1537 __ Mul(result, left, at); |
1538 } | 1538 } |
1539 } | 1539 } |
1540 | 1540 |
1541 } else { | 1541 } else { |
1542 DCHECK(right_op->IsRegister()); | 1542 DCHECK(right_op->IsRegister()); |
1543 Register right = ToRegister(right_op); | 1543 Register right = ToRegister(right_op); |
1544 | 1544 |
1545 if (overflow) { | 1545 if (overflow) { |
1546 // hi:lo = left * right. | 1546 // hi:lo = left * right. |
1547 if (instr->hydrogen()->representation().IsSmi()) { | 1547 if (instr->hydrogen()->representation().IsSmi()) { |
1548 __ Dmulh(result, left, right); | 1548 __ Dmulh(result, left, right); |
1549 } else { | 1549 } else { |
1550 __ Dmul(result, left, right); | 1550 __ Dmul(result, left, right); |
1551 } | 1551 } |
1552 __ dsra32(scratch, result, 0); | 1552 __ dsra32(scratch, result, 0); |
1553 __ sra(at, result, 31); | 1553 __ sra(at, result, 31); |
1554 if (instr->hydrogen()->representation().IsSmi()) { | 1554 if (instr->hydrogen()->representation().IsSmi()) { |
1555 __ SmiTag(result); | 1555 __ SmiTag(result); |
1556 } | 1556 } |
1557 DeoptimizeIf(ne, instr, Deoptimizer::kOverflow, scratch, Operand(at)); | 1557 DeoptimizeIf(ne, instr, Deoptimizer::kOverflow, scratch, Operand(at)); |
1558 } else { | 1558 } else { |
1559 if (instr->hydrogen()->representation().IsSmi()) { | 1559 if (instr->hydrogen()->representation().IsSmi()) { |
1560 __ SmiUntag(result, left); | 1560 __ SmiUntag(result, left); |
1561 __ Dmul(result, result, right); | 1561 __ mul(result, result, right); |
1562 } else { | 1562 } else { |
1563 __ Dmul(result, left, right); | 1563 __ mul(result, left, right); |
1564 } | 1564 } |
1565 } | 1565 } |
1566 | 1566 |
1567 if (bailout_on_minus_zero) { | 1567 if (bailout_on_minus_zero) { |
1568 Label done; | 1568 Label done; |
1569 __ Xor(at, left, right); | 1569 __ Xor(at, left, right); |
1570 __ Branch(&done, ge, at, Operand(zero_reg)); | 1570 __ Branch(&done, ge, at, Operand(zero_reg)); |
1571 // Bail out if the result is minus zero. | 1571 // Bail out if the result is minus zero. |
1572 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, result, | 1572 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, result, |
1573 Operand(zero_reg)); | 1573 Operand(zero_reg)); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1699 | 1699 |
1700 void LCodeGen::DoSubI(LSubI* instr) { | 1700 void LCodeGen::DoSubI(LSubI* instr) { |
1701 LOperand* left = instr->left(); | 1701 LOperand* left = instr->left(); |
1702 LOperand* right = instr->right(); | 1702 LOperand* right = instr->right(); |
1703 LOperand* result = instr->result(); | 1703 LOperand* result = instr->result(); |
1704 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1704 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
1705 | 1705 |
1706 if (!can_overflow) { | 1706 if (!can_overflow) { |
1707 if (right->IsStackSlot()) { | 1707 if (right->IsStackSlot()) { |
1708 Register right_reg = EmitLoadRegister(right, at); | 1708 Register right_reg = EmitLoadRegister(right, at); |
1709 __ Dsubu(ToRegister(result), ToRegister(left), Operand(right_reg)); | 1709 __ Subu(ToRegister(result), ToRegister(left), Operand(right_reg)); |
1710 } else { | 1710 } else { |
1711 DCHECK(right->IsRegister() || right->IsConstantOperand()); | 1711 DCHECK(right->IsRegister() || right->IsConstantOperand()); |
1712 __ Dsubu(ToRegister(result), ToRegister(left), ToOperand(right)); | 1712 __ Subu(ToRegister(result), ToRegister(left), ToOperand(right)); |
1713 } | 1713 } |
1714 } else { // can_overflow. | 1714 } else { // can_overflow. |
1715 Register overflow = scratch0(); | 1715 Register overflow = scratch0(); |
1716 Register scratch = scratch1(); | 1716 Register scratch = scratch1(); |
1717 if (right->IsStackSlot() || right->IsConstantOperand()) { | 1717 if (right->IsStackSlot() || right->IsConstantOperand()) { |
1718 Register right_reg = EmitLoadRegister(right, scratch); | 1718 Register right_reg = EmitLoadRegister(right, scratch); |
1719 __ SubuAndCheckForOverflow(ToRegister(result), | 1719 __ SubuAndCheckForOverflow(ToRegister(result), |
1720 ToRegister(left), | 1720 ToRegister(left), |
1721 right_reg, | 1721 right_reg, |
1722 overflow); // Reg at also used as scratch. | 1722 overflow); // Reg at also used as scratch. |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1897 | 1897 |
1898 void LCodeGen::DoAddI(LAddI* instr) { | 1898 void LCodeGen::DoAddI(LAddI* instr) { |
1899 LOperand* left = instr->left(); | 1899 LOperand* left = instr->left(); |
1900 LOperand* right = instr->right(); | 1900 LOperand* right = instr->right(); |
1901 LOperand* result = instr->result(); | 1901 LOperand* result = instr->result(); |
1902 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1902 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
1903 | 1903 |
1904 if (!can_overflow) { | 1904 if (!can_overflow) { |
1905 if (right->IsStackSlot()) { | 1905 if (right->IsStackSlot()) { |
1906 Register right_reg = EmitLoadRegister(right, at); | 1906 Register right_reg = EmitLoadRegister(right, at); |
1907 __ Daddu(ToRegister(result), ToRegister(left), Operand(right_reg)); | 1907 __ Addu(ToRegister(result), ToRegister(left), Operand(right_reg)); |
1908 } else { | 1908 } else { |
1909 DCHECK(right->IsRegister() || right->IsConstantOperand()); | 1909 DCHECK(right->IsRegister() || right->IsConstantOperand()); |
1910 __ Daddu(ToRegister(result), ToRegister(left), ToOperand(right)); | 1910 __ Addu(ToRegister(result), ToRegister(left), ToOperand(right)); |
1911 } | 1911 } |
1912 } else { // can_overflow. | 1912 } else { // can_overflow. |
1913 Register overflow = scratch0(); | 1913 Register overflow = scratch0(); |
1914 Register scratch = scratch1(); | 1914 Register scratch = scratch1(); |
1915 if (right->IsStackSlot() || | 1915 if (right->IsStackSlot() || |
1916 right->IsConstantOperand()) { | 1916 right->IsConstantOperand()) { |
1917 Register right_reg = EmitLoadRegister(right, scratch); | 1917 Register right_reg = EmitLoadRegister(right, scratch); |
1918 __ AdduAndCheckForOverflow(ToRegister(result), | 1918 __ AdduAndCheckForOverflow(ToRegister(result), |
1919 ToRegister(left), | 1919 ToRegister(left), |
1920 right_reg, | 1920 right_reg, |
(...skipping 4201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6122 __ li(at, scope_info); | 6122 __ li(at, scope_info); |
6123 __ Push(at, ToRegister(instr->function())); | 6123 __ Push(at, ToRegister(instr->function())); |
6124 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6124 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
6125 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6125 RecordSafepoint(Safepoint::kNoLazyDeopt); |
6126 } | 6126 } |
6127 | 6127 |
6128 | 6128 |
6129 #undef __ | 6129 #undef __ |
6130 | 6130 |
6131 } } // namespace v8::internal | 6131 } } // namespace v8::internal |
OLD | NEW |