diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-01-02 16:11:17 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-02 16:11:17 -0500 |
| commit | 4c1007fc044689b8cbc20634d73debb43df8efe1 (patch) | |
| tree | 967e4bd30091e0d28816febe1c9fea1b761b9a94 /lib/std/math/big/int.zig | |
| parent | 4172c2916684655a9742de99384be8110922ed07 (diff) | |
| parent | 23b1544f6c17dd1111ba8791189a7290581f945e (diff) | |
| download | zig-4c1007fc044689b8cbc20634d73debb43df8efe1.tar.gz zig-4c1007fc044689b8cbc20634d73debb43df8efe1.zip | |
Merge pull request #14002 from kcbanner/cbe_msvc_compatibility
CBE: MSVC-compatible code generation, and fixes to get behaviour tests passing and zig2.c building
Diffstat (limited to 'lib/std/math/big/int.zig')
| -rw-r--r-- | lib/std/math/big/int.zig | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig index 8410e25864..d222d6913b 100644 --- a/lib/std/math/big/int.zig +++ b/lib/std/math/big/int.zig @@ -1677,6 +1677,40 @@ pub const Mutable = struct { y.shiftRight(y.toConst(), norm_shift); } + /// If a is positive, this passes through to truncate. + /// If a is negative, then r is set to positive with the bit pattern ~(a - 1). + /// + /// Asserts `r` has enough storage to store the result. + /// The upper bound is `calcTwosCompLimbCount(a.len)`. + pub fn convertToTwosComplement(r: *Mutable, a: Const, signedness: Signedness, bit_count: usize) void { + if (a.positive) { + r.truncate(a, signedness, bit_count); + return; + } + + const req_limbs = calcTwosCompLimbCount(bit_count); + if (req_limbs == 0 or a.eqZero()) { + r.set(0); + return; + } + + const bit = @truncate(Log2Limb, bit_count - 1); + const signmask = @as(Limb, 1) << bit; + const mask = (signmask << 1) -% 1; + + r.addScalar(a.abs(), -1); + if (req_limbs > r.len) { + mem.set(Limb, r.limbs[r.len..req_limbs], 0); + } + + assert(r.limbs.len >= req_limbs); + r.len = req_limbs; + + llnot(r.limbs[0..r.len]); + r.limbs[r.len - 1] &= mask; + r.normalize(r.len); + } + /// Truncate an integer to a number of bits, following 2s-complement semantics. /// r may alias a. /// |
