Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

__shlo_limb64

limb64.__shlo_limb64
fn __shlo_limb64(out_ptr: [*]u64, a_ptr: [*]const u64, shift: u16, is_signed: bool, bits: u16) callconv(.c) bool

File

lib/compiler_rt/limb64.zig:508

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;
}