aboutsummaryrefslogtreecommitdiff
path: root/lib/std/math
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-01-02 16:11:17 -0500
committerGitHub <noreply@github.com>2023-01-02 16:11:17 -0500
commit4c1007fc044689b8cbc20634d73debb43df8efe1 (patch)
tree967e4bd30091e0d28816febe1c9fea1b761b9a94 /lib/std/math
parent4172c2916684655a9742de99384be8110922ed07 (diff)
parent23b1544f6c17dd1111ba8791189a7290581f945e (diff)
downloadzig-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')
-rw-r--r--lib/std/math/big/int.zig34
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.
///