| ... | ... | @@ -1660,19 +1660,26 @@ pub const Value = extern union { |
| 1660 | 1660 | if (ty.isAnyFloat()) { |
| 1661 | 1661 | return floatAdd(lhs, rhs, ty, arena); |
| 1662 | 1662 | } |
| 1663 | | const result = try intAdd(lhs, rhs, arena); |
| 1664 | 1663 | |
| 1665 | | const max = try ty.maxInt(arena, target); |
| 1666 | | if (compare(result, .gt, max, ty)) { |
| 1667 | | @panic("TODO comptime wrapping integer addition"); |
| 1668 | | } |
| 1664 | const info = ty.intInfo(target); |
| 1669 | 1665 | |
| 1670 | | const min = try ty.minInt(arena, target); |
| 1671 | | if (compare(result, .lt, min, ty)) { |
| 1672 | | @panic("TODO comptime wrapping integer addition"); |
| 1673 | | } |
| 1666 | var lhs_space: Value.BigIntSpace = undefined; |
| 1667 | var rhs_space: Value.BigIntSpace = undefined; |
| 1668 | const lhs_bigint = lhs.toBigInt(&lhs_space); |
| 1669 | const rhs_bigint = rhs.toBigInt(&rhs_space); |
| 1670 | const limbs = try arena.alloc( |
| 1671 | std.math.big.Limb, |
| 1672 | std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, |
| 1673 | ); |
| 1674 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 1675 | result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| 1676 | const result_limbs = result_bigint.limbs[0..result_bigint.len]; |
| 1674 | 1677 | |
| 1675 | | return result; |
| 1678 | if (result_bigint.positive) { |
| 1679 | return Value.Tag.int_big_positive.create(arena, result_limbs); |
| 1680 | } else { |
| 1681 | return Value.Tag.int_big_negative.create(arena, result_limbs); |
| 1682 | } |
| 1676 | 1683 | } |
| 1677 | 1684 | |
| 1678 | 1685 | /// Supports integers only; asserts neither operand is undefined. |
| ... | ... | @@ -1714,19 +1721,27 @@ pub const Value = extern union { |
| 1714 | 1721 | if (ty.isAnyFloat()) { |
| 1715 | 1722 | return floatSub(lhs, rhs, ty, arena); |
| 1716 | 1723 | } |
| 1717 | | const result = try intSub(lhs, rhs, arena); |
| 1718 | 1724 | |
| 1719 | | const max = try ty.maxInt(arena, target); |
| 1720 | | if (compare(result, .gt, max, ty)) { |
| 1721 | | @panic("TODO comptime wrapping integer subtraction"); |
| 1722 | | } |
| 1725 | const info = ty.intInfo(target); |
| 1723 | 1726 | |
| 1724 | | const min = try ty.minInt(arena, target); |
| 1725 | | if (compare(result, .lt, min, ty)) { |
| 1726 | | @panic("TODO comptime wrapping integer subtraction"); |
| 1727 | var lhs_space: Value.BigIntSpace = undefined; |
| 1728 | var rhs_space: Value.BigIntSpace = undefined; |
| 1729 | const lhs_bigint = lhs.toBigInt(&lhs_space); |
| 1730 | const rhs_bigint = rhs.toBigInt(&rhs_space); |
| 1731 | const limbs = try arena.alloc( |
| 1732 | std.math.big.Limb, |
| 1733 | std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, |
| 1734 | ); |
| 1735 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 1736 | result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| 1737 | const result_limbs = result_bigint.limbs[0..result_bigint.len]; |
| 1738 | |
| 1739 | if (result_bigint.positive) { |
| 1740 | return Value.Tag.int_big_positive.create(arena, result_limbs); |
| 1741 | } else { |
| 1742 | return Value.Tag.int_big_negative.create(arena, result_limbs); |
| 1727 | 1743 | } |
| 1728 | 1744 | |
| 1729 | | return result; |
| 1730 | 1745 | } |
| 1731 | 1746 | |
| 1732 | 1747 | /// Supports integers only; asserts neither operand is undefined. |