feature. See also
. The project being documented here (as the example) is the Zig library itself.
limb64.__shlo_limb64
fn __shlo_limb64(out_ptr: [*]u64, a_ptr: [*]const u64, shift: u16, is_signed: bool, bits: u16) callconv(.c) bool
File
Code
fn __shlo_limb64(out_ptr: [*]u64, a_ptr: [*]const u64, shift: u16, is_signed: bool, bits: u16) callconv(.c) bool {
const limb_cnt = usedLimbCount(bits);
const out = varLimbs(out_ptr, bits);
const a = constLimbs(a_ptr, bits);
assert(shift < bits);
const limb_shift = shift / 64;
const bit_shift = shift % 64;
var carry: u64 = 0;
var i: usize = 0;
while (i < limb_cnt - 1) : (i += 1) {
if (i < limb_shift) {
limbSet(out, i, 0);
} else {
const limb = limbGet(a, i - limb_shift);
limbSet(out, i, (limb << @intCast(bit_shift)) | carry);
carry = if (bit_shift != 0) (limb >> @intCast(64 - bit_shift)) else 0;
}
}
const limb = limbGet(a, i - limb_shift);
const raw_last = (limb << @intCast(bit_shift)) | carry;
carry = if (bit_shift != 0) (limb >> @intCast(64 - bit_shift)) else 0;
const last = if (bits % 64 == 0) raw_last else limbWrap(raw_last, is_signed, bits);
limbSet(out, i, last);
const sign_extend: u64 = if (is_signed and (last >> 63) == 1) ~@as(u64, 0) else 0;
const expected_carry: u64 = if (bit_shift == 0) 0 else sign_extend >> @intCast(64 - bit_shift);
var overflow = carry != expected_carry;
if (bits % 64 != 0) {
overflow = overflow or raw_last != last;
}
var j = limb_cnt - limb_shift;
while (j < limb_cnt) : (j += 1) {
overflow = overflow or limbGet(a, j) != sign_extend;
}
fixLastLimb(out_ptr, is_signed, bits);
return overflow;
}