| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/constant_propagator.h" | 8 #include "vm/constant_propagator.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1559 op->set_can_overflow(can_overflow); | 1559 op->set_can_overflow(can_overflow); |
| 1560 if (is_truncating) { | 1560 if (is_truncating) { |
| 1561 op->mark_truncating(); | 1561 op->mark_truncating(); |
| 1562 } | 1562 } |
| 1563 | 1563 |
| 1564 ASSERT(op->representation() == representation); | 1564 ASSERT(op->representation() == representation); |
| 1565 return op; | 1565 return op; |
| 1566 } | 1566 } |
| 1567 | 1567 |
| 1568 | 1568 |
| 1569 static bool IsRepresentable(const Integer& value, Representation rep) { |
| 1570 switch (rep) { |
| 1571 case kTagged: // Smi case. |
| 1572 return value.IsSmi(); |
| 1573 |
| 1574 case kUnboxedInt32: |
| 1575 if (value.IsSmi() || value.IsMint()) { |
| 1576 return Utils::IsInt(32, value.AsInt64Value()); |
| 1577 } |
| 1578 return false; |
| 1579 |
| 1580 case kUnboxedMint: |
| 1581 return value.IsSmi() || value.IsMint(); |
| 1582 |
| 1583 case kUnboxedUint32: // Only truncating Uint32 arithmetic is supported. |
| 1584 default: |
| 1585 UNREACHABLE(); |
| 1586 } |
| 1587 |
| 1588 return false; |
| 1589 } |
| 1590 |
| 1591 |
| 1569 RawInteger* BinaryIntegerOpInstr::Evaluate(const Integer& left, | 1592 RawInteger* BinaryIntegerOpInstr::Evaluate(const Integer& left, |
| 1570 const Integer& right) const { | 1593 const Integer& right) const { |
| 1571 Integer& result = Integer::Handle(); | 1594 Integer& result = Integer::Handle(); |
| 1572 | 1595 |
| 1573 switch (op_kind()) { | 1596 switch (op_kind()) { |
| 1574 case Token::kTRUNCDIV: | 1597 case Token::kTRUNCDIV: |
| 1575 case Token::kMOD: | 1598 case Token::kMOD: |
| 1576 // Check right value for zero. | 1599 // Check right value for zero. |
| 1577 if (right.AsInt64Value() == 0) { | 1600 if (right.AsInt64Value() == 0) { |
| 1578 break; // Will throw. | 1601 break; // Will throw. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1600 break; | 1623 break; |
| 1601 default: | 1624 default: |
| 1602 UNREACHABLE(); | 1625 UNREACHABLE(); |
| 1603 } | 1626 } |
| 1604 | 1627 |
| 1605 if (!result.IsNull()) { | 1628 if (!result.IsNull()) { |
| 1606 if (is_truncating()) { | 1629 if (is_truncating()) { |
| 1607 int64_t truncated = result.AsTruncatedInt64Value(); | 1630 int64_t truncated = result.AsTruncatedInt64Value(); |
| 1608 truncated &= RepresentationMask(representation()); | 1631 truncated &= RepresentationMask(representation()); |
| 1609 result = Integer::New(truncated); | 1632 result = Integer::New(truncated); |
| 1633 ASSERT(IsRepresentable(result, representation())); |
| 1634 } else if (!IsRepresentable(result, representation())) { |
| 1635 // If this operation is not truncating it would deoptimize on overflow. |
| 1636 // Check that we match this behavior and don't produce a value that is |
| 1637 // larger than something this operation can produce. We could have |
| 1638 // specialized instructions that use this value under this assumption. |
| 1639 return Integer::null(); |
| 1610 } | 1640 } |
| 1611 result ^= result.CheckAndCanonicalize(NULL); | 1641 result ^= result.CheckAndCanonicalize(NULL); |
| 1612 } | 1642 } |
| 1613 | 1643 |
| 1614 return result.raw(); | 1644 return result.raw(); |
| 1615 } | 1645 } |
| 1616 | 1646 |
| 1617 | 1647 |
| 1618 Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) { | 1648 Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) { |
| 1619 // If both operands are constants evaluate this expression. Might | 1649 // If both operands are constants evaluate this expression. Might |
| (...skipping 1870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3490 case Token::kTRUNCDIV: return 0; | 3520 case Token::kTRUNCDIV: return 0; |
| 3491 case Token::kMOD: return 1; | 3521 case Token::kMOD: return 1; |
| 3492 default: UNIMPLEMENTED(); return -1; | 3522 default: UNIMPLEMENTED(); return -1; |
| 3493 } | 3523 } |
| 3494 } | 3524 } |
| 3495 | 3525 |
| 3496 | 3526 |
| 3497 #undef __ | 3527 #undef __ |
| 3498 | 3528 |
| 3499 } // namespace dart | 3529 } // namespace dart |
| OLD | NEW |