const builtin = @import("builtin"); // Ported from // https://github.com/llvm/llvm-project/blob/llvmorg-9.0.0/compiler-rt/lib/builtins/muldi3.c const dwords = extern union { all: i64, s: switch (builtin.endian) { .Little => extern struct { low: u32, high: u32, }, .Big => extern struct { high: u32, low: u32, }, }, }; fn __muldsi3(a: u32, b: u32) i64 { @setRuntimeSafety(builtin.is_test); const bits_in_word_2 = @sizeOf(i32) * 8 / 2; const lower_mask = (~u32(0)) >> bits_in_word_2; var r: dwords = undefined; r.s.low = (a & lower_mask) *% (b & lower_mask); var t: u32 = r.s.low >> bits_in_word_2; r.s.low &= lower_mask; t += (a >> bits_in_word_2) *% (b & lower_mask); r.s.low +%= (t & lower_mask) << bits_in_word_2; r.s.high = t >> bits_in_word_2; t = r.s.low >> bits_in_word_2; r.s.low &= lower_mask; t +%= (b >> bits_in_word_2) *% (a & lower_mask); r.s.low +%= (t & lower_mask) << bits_in_word_2; r.s.high +%= t >> bits_in_word_2; r.s.high +%= (a >> bits_in_word_2) *% (b >> bits_in_word_2); return r.all; } pub extern fn __muldi3(a: i64, b: i64) i64 { @setRuntimeSafety(builtin.is_test); const x = dwords{ .all = a }; const y = dwords{ .all = b }; var r = dwords{ .all = __muldsi3(x.s.low, y.s.low) }; r.s.high +%= x.s.high *% y.s.low +% x.s.low *% y.s.high; return r.all; } test "import muldi3" { _ = @import("muldi3_test.zig"); }