| ... | @@ -825,7 +825,7 @@ pub const Mutable = struct { | ... | @@ -825,7 +825,7 @@ pub const Mutable = struct { |
| 825 | /// | 825 | /// |
| 826 | /// Asserts there is enough memory to fit the result. The upper bound Limb count is | 826 | /// Asserts there is enough memory to fit the result. The upper bound Limb count is |
| 827 | /// r is `calcTwosCompLimbCount(bit_count)`. | 827 | /// r is `calcTwosCompLimbCount(bit_count)`. |
| 828 | pub fn shiftLeftSat(r: *Mutable, a: Const, shift: usize, signedness: std.builtin.Signedness, bit_count: usize) void { | 828 | pub fn shiftLeftSat(r: *Mutable, a: Const, shift: usize, signedness: Signedness, bit_count: usize) void { |
| 829 | // Special case: When the argument is negative, but the result is supposed to be unsigned, | 829 | // Special case: When the argument is negative, but the result is supposed to be unsigned, |
| 830 | // return 0 in all cases. | 830 | // return 0 in all cases. |
| 831 | if (!a.positive and signedness == .unsigned) { | 831 | if (!a.positive and signedness == .unsigned) { |
| ... | @@ -906,6 +906,17 @@ pub const Mutable = struct { | ... | @@ -906,6 +906,17 @@ pub const Mutable = struct { |
| 906 | r.positive = a.positive; | 906 | r.positive = a.positive; |
| 907 | } | 907 | } |
| 908 | | 908 | |
| | 909 | /// r = ~a under 2s complement wrapping semantics. |
| | 910 | /// r may alias with a. |
| | 911 | /// |
| | 912 | /// Assets that r has enough limbs to store the result. The upper bound Limb count is |
| | 913 | /// r is `calcTwosCompLimbCount(bit_count)`. |
| | 914 | pub fn bitNotWrap(r: *Mutable, a: Const, signedness: Signedness, bit_count: usize) void { |
| | 915 | r.copy(a.negate()); |
| | 916 | const negative_one = Const{ .limbs = &.{1}, .positive = false }; |
| | 917 | r.addWrap(r.toConst(), negative_one, signedness, bit_count); |
| | 918 | } |
| | 919 | |
| 909 | /// r = a | b under 2s complement semantics. | 920 | /// r = a | b under 2s complement semantics. |
| 910 | /// r may alias with a or b. | 921 | /// r may alias with a or b. |
| 911 | /// | 922 | /// |
| ... | @@ -2455,7 +2466,7 @@ pub const Managed = struct { | ... | @@ -2455,7 +2466,7 @@ pub const Managed = struct { |
| 2455 | } | 2466 | } |
| 2456 | | 2467 | |
| 2457 | /// r = a <<| shift with 2s-complement saturating semantics. | 2468 | /// r = a <<| shift with 2s-complement saturating semantics. |
| 2458 | pub fn shiftLeftSat(r: *Managed, a: Managed, shift: usize, signedness: std.builtin.Signedness, bit_count: usize) !void { | 2469 | pub fn shiftLeftSat(r: *Managed, a: Managed, shift: usize, signedness: Signedness, bit_count: usize) !void { |
| 2459 | try r.ensureTwosCompCapacity(bit_count); | 2470 | try r.ensureTwosCompCapacity(bit_count); |
| 2460 | var m = r.toMutable(); | 2471 | var m = r.toMutable(); |
| 2461 | m.shiftLeftSat(a.toConst(), shift, signedness, bit_count); | 2472 | m.shiftLeftSat(a.toConst(), shift, signedness, bit_count); |
| ... | @@ -2476,6 +2487,14 @@ pub const Managed = struct { | ... | @@ -2476,6 +2487,14 @@ pub const Managed = struct { |
| 2476 | r.setMetadata(m.positive, m.len); | 2487 | r.setMetadata(m.positive, m.len); |
| 2477 | } | 2488 | } |
| 2478 | | 2489 | |
| | 2490 | /// r = ~a under 2s-complement wrapping semantics. |
| | 2491 | pub fn bitNotWrap(r: *Managed, a: Managed, signedness: Signedness, bit_count: usize) !void { |
| | 2492 | try r.ensureTwosCompCapacity(bit_count); |
| | 2493 | var m = r.toMutable(); |
| | 2494 | m.bitNotWrap(a.toConst(), signedness, bit_count); |
| | 2495 | r.setMetadata(m.positive, m.len); |
| | 2496 | } |
| | 2497 | |
| 2479 | /// r = a | b | 2498 | /// r = a | b |
| 2480 | /// | 2499 | /// |
| 2481 | /// a and b are zero-extended to the longer of a or b. | 2500 | /// a and b are zero-extended to the longer of a or b. |