| ... | @@ -1677,22 +1677,8 @@ pub const Value = extern union { | ... | @@ -1677,22 +1677,8 @@ pub const Value = extern union { |
| 1677 | @panic("TODO implement i64 Value clz"); | 1677 | @panic("TODO implement i64 Value clz"); |
| 1678 | }, | 1678 | }, |
| 1679 | .int_big_positive => { | 1679 | .int_big_positive => { |
| 1680 | // TODO: move this code into std lib big ints | | |
| 1681 | const bigint = val.castTag(.int_big_positive).?.asBigInt(); | 1680 | const bigint = val.castTag(.int_big_positive).?.asBigInt(); |
| 1682 | // Limbs are stored in little-endian order but we need | 1681 | return bigint.clz(ty_bits); |
| 1683 | // to iterate big-endian. | | |
| 1684 | var total_limb_lz: u64 = 0; | | |
| 1685 | var i: usize = bigint.limbs.len; | | |
| 1686 | const bits_per_limb = @sizeOf(std.math.big.Limb) * 8; | | |
| 1687 | while (i != 0) { | | |
| 1688 | i -= 1; | | |
| 1689 | const limb = bigint.limbs[i]; | | |
| 1690 | const this_limb_lz = @clz(limb); | | |
| 1691 | total_limb_lz += this_limb_lz; | | |
| 1692 | if (this_limb_lz != bits_per_limb) break; | | |
| 1693 | } | | |
| 1694 | const total_limb_bits = bigint.limbs.len * bits_per_limb; | | |
| 1695 | return total_limb_lz + ty_bits - total_limb_bits; | | |
| 1696 | }, | 1682 | }, |
| 1697 | .int_big_negative => { | 1683 | .int_big_negative => { |
| 1698 | @panic("TODO implement int_big_negative Value clz"); | 1684 | @panic("TODO implement int_big_negative Value clz"); |
| ... | @@ -1703,6 +1689,12 @@ pub const Value = extern union { | ... | @@ -1703,6 +1689,12 @@ pub const Value = extern union { |
| 1703 | return ty_bits; | 1689 | return ty_bits; |
| 1704 | }, | 1690 | }, |
| 1705 | | 1691 | |
| | 1692 | .lazy_align, .lazy_size => { |
| | 1693 | var bigint_buf: BigIntSpace = undefined; |
| | 1694 | const bigint = val.toBigIntAdvanced(&bigint_buf, target, null) catch unreachable; |
| | 1695 | return bigint.clz(ty_bits); |
| | 1696 | }, |
| | 1697 | |
| 1706 | else => unreachable, | 1698 | else => unreachable, |
| 1707 | } | 1699 | } |
| 1708 | } | 1700 | } |
| ... | @@ -1721,16 +1713,8 @@ pub const Value = extern union { | ... | @@ -1721,16 +1713,8 @@ pub const Value = extern union { |
| 1721 | @panic("TODO implement i64 Value ctz"); | 1713 | @panic("TODO implement i64 Value ctz"); |
| 1722 | }, | 1714 | }, |
| 1723 | .int_big_positive => { | 1715 | .int_big_positive => { |
| 1724 | // TODO: move this code into std lib big ints | | |
| 1725 | const bigint = val.castTag(.int_big_positive).?.asBigInt(); | 1716 | const bigint = val.castTag(.int_big_positive).?.asBigInt(); |
| 1726 | // Limbs are stored in little-endian order. | 1717 | return bigint.ctz(); |
| 1727 | var result: u64 = 0; | | |
| 1728 | for (bigint.limbs) |limb| { | | |
| 1729 | const limb_tz = @ctz(limb); | | |
| 1730 | result += limb_tz; | | |
| 1731 | if (limb_tz != @sizeOf(std.math.big.Limb) * 8) break; | | |
| 1732 | } | | |
| 1733 | return result; | | |
| 1734 | }, | 1718 | }, |
| 1735 | .int_big_negative => { | 1719 | .int_big_negative => { |
| 1736 | @panic("TODO implement int_big_negative Value ctz"); | 1720 | @panic("TODO implement int_big_negative Value ctz"); |
| ... | @@ -1741,6 +1725,12 @@ pub const Value = extern union { | ... | @@ -1741,6 +1725,12 @@ pub const Value = extern union { |
| 1741 | return ty_bits; | 1725 | return ty_bits; |
| 1742 | }, | 1726 | }, |
| 1743 | | 1727 | |
| | 1728 | .lazy_align, .lazy_size => { |
| | 1729 | var bigint_buf: BigIntSpace = undefined; |
| | 1730 | const bigint = val.toBigIntAdvanced(&bigint_buf, target, null) catch unreachable; |
| | 1731 | return bigint.ctz(); |
| | 1732 | }, |
| | 1733 | |
| 1744 | else => unreachable, | 1734 | else => unreachable, |
| 1745 | } | 1735 | } |
| 1746 | } | 1736 | } |