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 1631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1642 ASSERT(right->IsRegister() || right->IsConstantOperand()); | 1642 ASSERT(right->IsRegister() || right->IsConstantOperand()); |
1643 __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); | 1643 __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); |
1644 } | 1644 } |
1645 | 1645 |
1646 if (can_overflow) { | 1646 if (can_overflow) { |
1647 DeoptimizeIf(vs, instr->environment()); | 1647 DeoptimizeIf(vs, instr->environment()); |
1648 } | 1648 } |
1649 } | 1649 } |
1650 | 1650 |
1651 | 1651 |
| 1652 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
| 1653 LOperand* left = instr->InputAt(0); |
| 1654 LOperand* right = instr->InputAt(1); |
| 1655 HMathMinMax::Operation operation = instr->hydrogen()->operation(); |
| 1656 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; |
| 1657 if (instr->hydrogen()->representation().IsInteger32()) { |
| 1658 Register left_reg = ToRegister(left); |
| 1659 Operand right_op = (right->IsRegister() || right->IsConstantOperand()) |
| 1660 ? ToOperand(right) |
| 1661 : Operand(EmitLoadRegister(right, ip)); |
| 1662 Register result_reg = ToRegister(instr->result()); |
| 1663 __ cmp(left_reg, right_op); |
| 1664 if (!result_reg.is(left_reg)) { |
| 1665 __ mov(result_reg, left_reg, LeaveCC, condition); |
| 1666 } |
| 1667 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); |
| 1668 } else { |
| 1669 ASSERT(instr->hydrogen()->representation().IsDouble()); |
| 1670 DoubleRegister left_reg = ToDoubleRegister(left); |
| 1671 DoubleRegister right_reg = ToDoubleRegister(right); |
| 1672 DoubleRegister result_reg = ToDoubleRegister(instr->result()); |
| 1673 Label check_nan_left, check_zero, return_left, return_right, done; |
| 1674 __ VFPCompareAndSetFlags(left_reg, right_reg); |
| 1675 __ b(vs, &check_nan_left); |
| 1676 __ b(eq, &check_zero); |
| 1677 __ b(condition, &return_left); |
| 1678 __ b(al, &return_right); |
| 1679 |
| 1680 __ bind(&check_zero); |
| 1681 __ VFPCompareAndSetFlags(left_reg, 0.0); |
| 1682 __ b(ne, &return_left); // left == right != 0. |
| 1683 // At this point, both left and right are either 0 or -0. |
| 1684 if (operation == HMathMinMax::kMathMin) { |
| 1685 // We could use a single 'vorr' instruction here if we had NEON support. |
| 1686 __ vneg(left_reg, left_reg); |
| 1687 __ vsub(result_reg, left_reg, right_reg); |
| 1688 __ vneg(result_reg, result_reg); |
| 1689 } else { |
| 1690 // Since we operate on +0 and/or -0, vadd and vand have the same effect; |
| 1691 // the decision for vadd is easy because vand is a NEON instruction. |
| 1692 __ vadd(result_reg, left_reg, right_reg); |
| 1693 } |
| 1694 __ b(al, &done); |
| 1695 |
| 1696 __ bind(&check_nan_left); |
| 1697 __ VFPCompareAndSetFlags(left_reg, left_reg); |
| 1698 __ b(vs, &return_left); // left == NaN. |
| 1699 __ bind(&return_right); |
| 1700 if (!right_reg.is(result_reg)) { |
| 1701 __ vmov(result_reg, right_reg); |
| 1702 } |
| 1703 __ b(al, &done); |
| 1704 |
| 1705 __ bind(&return_left); |
| 1706 if (!left_reg.is(result_reg)) { |
| 1707 __ vmov(result_reg, left_reg); |
| 1708 } |
| 1709 __ bind(&done); |
| 1710 } |
| 1711 } |
| 1712 |
| 1713 |
1652 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 1714 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { |
1653 DoubleRegister left = ToDoubleRegister(instr->InputAt(0)); | 1715 DoubleRegister left = ToDoubleRegister(instr->InputAt(0)); |
1654 DoubleRegister right = ToDoubleRegister(instr->InputAt(1)); | 1716 DoubleRegister right = ToDoubleRegister(instr->InputAt(1)); |
1655 DoubleRegister result = ToDoubleRegister(instr->result()); | 1717 DoubleRegister result = ToDoubleRegister(instr->result()); |
1656 switch (instr->op()) { | 1718 switch (instr->op()) { |
1657 case Token::ADD: | 1719 case Token::ADD: |
1658 __ vadd(result, left, right); | 1720 __ vadd(result, left, right); |
1659 break; | 1721 break; |
1660 case Token::SUB: | 1722 case Token::SUB: |
1661 __ vsub(result, left, right); | 1723 __ vsub(result, left, right); |
(...skipping 3802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5464 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 5526 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
5465 __ ldr(result, FieldMemOperand(scratch, | 5527 __ ldr(result, FieldMemOperand(scratch, |
5466 FixedArray::kHeaderSize - kPointerSize)); | 5528 FixedArray::kHeaderSize - kPointerSize)); |
5467 __ bind(&done); | 5529 __ bind(&done); |
5468 } | 5530 } |
5469 | 5531 |
5470 | 5532 |
5471 #undef __ | 5533 #undef __ |
5472 | 5534 |
5473 } } // namespace v8::internal | 5535 } } // namespace v8::internal |
OLD | NEW |