zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

divmodei4.zig (2047B) - Raw


      1 const std = @import("std");
      2 const builtin = @import("builtin");
      3 const common = @import("common.zig");
      4 const udivmod = @import("udivmodei4.zig").divmod;
      5 
      6 comptime {
      7     @export(&__divei4, .{ .name = "__divei4", .linkage = common.linkage, .visibility = common.visibility });
      8     @export(&__modei4, .{ .name = "__modei4", .linkage = common.linkage, .visibility = common.visibility });
      9 }
     10 
     11 const endian = builtin.cpu.arch.endian();
     12 
     13 inline fn limb(x: []u32, i: usize) *u32 {
     14     return if (endian == .little) &x[i] else &x[x.len - 1 - i];
     15 }
     16 
     17 inline fn neg(x: []u32) void {
     18     var ov: u1 = 1;
     19     for (0..x.len) |limb_index| {
     20         const l = limb(x, limb_index);
     21         l.*, ov = @addWithOverflow(~l.*, ov);
     22     }
     23 }
     24 
     25 /// Mutates the arguments!
     26 fn divmod(q: ?[]u32, r: ?[]u32, u: []u32, v: []u32) !void {
     27     const u_sign: i32 = @bitCast(u[u.len - 1]);
     28     const v_sign: i32 = @bitCast(v[v.len - 1]);
     29     if (u_sign < 0) neg(u);
     30     if (v_sign < 0) neg(v);
     31     try @call(.always_inline, udivmod, .{ q, r, u, v });
     32     if (q) |x| if (u_sign ^ v_sign < 0) neg(x);
     33     if (r) |x| if (u_sign < 0) neg(x);
     34 }
     35 
     36 pub fn __divei4(q_p: [*]u8, u_p: [*]u8, v_p: [*]u8, bits: usize) callconv(.c) void {
     37     @setRuntimeSafety(common.test_safety);
     38     const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
     39     const q: []u32 = @ptrCast(@alignCast(q_p[0..byte_size]));
     40     const u: []u32 = @ptrCast(@alignCast(u_p[0..byte_size]));
     41     const v: []u32 = @ptrCast(@alignCast(v_p[0..byte_size]));
     42     @call(.always_inline, divmod, .{ q, null, u, v }) catch unreachable;
     43 }
     44 
     45 pub fn __modei4(r_p: [*]u8, u_p: [*]u8, v_p: [*]u8, bits: usize) callconv(.c) void {
     46     @setRuntimeSafety(common.test_safety);
     47     const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
     48     const r: []u32 = @ptrCast(@alignCast(r_p[0..byte_size]));
     49     const u: []u32 = @ptrCast(@alignCast(u_p[0..byte_size]));
     50     const v: []u32 = @ptrCast(@alignCast(v_p[0..byte_size]));
     51     @call(.always_inline, divmod, .{ null, r, u, v }) catch unreachable;
     52 }