From ec2a81a081f6c6d77de1bbeebf1d87754a4fae67 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 28 Apr 2018 22:03:07 -0400 Subject: [PATCH] fix compiler-rt ABI for x86_64 windows --- std/os/time.zig | 2 +- std/special/compiler_rt/index.zig | 21 +++++++++++++++++---- std/special/compiler_rt/udivmodti4.zig | 6 ++++++ std/special/compiler_rt/udivti3.zig | 9 +++++++-- std/special/compiler_rt/umodti3.zig | 10 ++++++++-- test/cases/eval.zig | 7 +++++++ 6 files changed, 46 insertions(+), 9 deletions(-) diff --git a/std/os/time.zig b/std/os/time.zig index e9fbf9798c..4fd2c4e924 100644 --- a/std/os/time.zig +++ b/std/os/time.zig @@ -281,7 +281,7 @@ test "os.time.Timer" { debug.assert(time_0 > 0 and time_0 < margin); const time_1 = timer.lap(); - debug.assert(time_1 > time_0); + debug.assert(time_1 >= time_0); timer.reset(); debug.assert(timer.read() < time_1); diff --git a/std/special/compiler_rt/index.zig b/std/special/compiler_rt/index.zig index 81fe1ffec1..6ef43c4fed 100644 --- a/std/special/compiler_rt/index.zig +++ b/std/special/compiler_rt/index.zig @@ -32,10 +32,6 @@ comptime { @export("__fixunstfti", @import("fixunstfti.zig").__fixunstfti, linkage); @export("__udivmoddi4", @import("udivmoddi4.zig").__udivmoddi4, linkage); - @export("__udivmodti4", @import("udivmodti4.zig").__udivmodti4, linkage); - - @export("__udivti3", @import("udivti3.zig").__udivti3, linkage); - @export("__umodti3", @import("umodti3.zig").__umodti3, linkage); @export("__udivsi3", __udivsi3, linkage); @export("__udivdi3", __udivdi3, linkage); @@ -62,9 +58,16 @@ comptime { @export("__chkstk", __chkstk, strong_linkage); @export("___chkstk_ms", ___chkstk_ms, linkage); } + @export("__udivti3", @import("udivti3.zig").__udivti3_windows_x86_64, linkage); + @export("__udivmodti4", @import("udivmodti4.zig").__udivmodti4_windows_x86_64, linkage); + @export("__umodti3", @import("umodti3.zig").__umodti3_windows_x86_64, linkage); }, else => {}, } + } else { + @export("__udivti3", @import("udivti3.zig").__udivti3, linkage); + @export("__udivmodti4", @import("udivmodti4.zig").__udivmodti4, linkage); + @export("__umodti3", @import("umodti3.zig").__umodti3, linkage); } } @@ -83,6 +86,16 @@ pub fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) noreturn } } +pub fn setXmm0(comptime T: type, value: T) void { + comptime assert(builtin.arch == builtin.Arch.x86_64); + const aligned_value: T align(16) = value; + asm volatile ( + \\movaps (%[ptr]), %%xmm0 + : + : [ptr] "r" (&aligned_value) + : "xmm0"); +} + extern fn __udivdi3(a: u64, b: u64) u64 { @setRuntimeSafety(is_test); return __udivmoddi4(a, b, null); diff --git a/std/special/compiler_rt/udivmodti4.zig b/std/special/compiler_rt/udivmodti4.zig index 196d067aef..f8fdebe4db 100644 --- a/std/special/compiler_rt/udivmodti4.zig +++ b/std/special/compiler_rt/udivmodti4.zig @@ -1,11 +1,17 @@ const udivmod = @import("udivmod.zig").udivmod; const builtin = @import("builtin"); +const compiler_rt = @import("index.zig"); pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) u128 { @setRuntimeSafety(builtin.is_test); return udivmod(u128, a, b, maybe_rem); } +pub extern fn __udivmodti4_windows_x86_64(a: &const u128, b: &const u128, maybe_rem: ?&u128) void { + @setRuntimeSafety(builtin.is_test); + compiler_rt.setXmm0(u128, udivmod(u128, *a, *b, maybe_rem)); +} + test "import udivmodti4" { _ = @import("udivmodti4_test.zig"); } diff --git a/std/special/compiler_rt/udivti3.zig b/std/special/compiler_rt/udivti3.zig index eaecbac4d2..ad0f09e733 100644 --- a/std/special/compiler_rt/udivti3.zig +++ b/std/special/compiler_rt/udivti3.zig @@ -1,7 +1,12 @@ -const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4; +const udivmodti4 = @import("udivmodti4.zig"); const builtin = @import("builtin"); pub extern fn __udivti3(a: u128, b: u128) u128 { @setRuntimeSafety(builtin.is_test); - return __udivmodti4(a, b, null); + return udivmodti4.__udivmodti4(a, b, null); +} + +pub extern fn __udivti3_windows_x86_64(a: &const u128, b: &const u128) void { + @setRuntimeSafety(builtin.is_test); + udivmodti4.__udivmodti4_windows_x86_64(a, b, null); } diff --git a/std/special/compiler_rt/umodti3.zig b/std/special/compiler_rt/umodti3.zig index 26b306efa9..3e8b80058e 100644 --- a/std/special/compiler_rt/umodti3.zig +++ b/std/special/compiler_rt/umodti3.zig @@ -1,9 +1,15 @@ -const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4; +const udivmodti4 = @import("udivmodti4.zig"); const builtin = @import("builtin"); +const compiler_rt = @import("index.zig"); pub extern fn __umodti3(a: u128, b: u128) u128 { @setRuntimeSafety(builtin.is_test); var r: u128 = undefined; - _ = __udivmodti4(a, b, &r); + _ = udivmodti4.__udivmodti4(a, b, &r); return r; } + +pub extern fn __umodti3_windows_x86_64(a: &const u128, b: &const u128) void { + @setRuntimeSafety(builtin.is_test); + compiler_rt.setXmm0(u128, __umodti3(*a, *b)); +} diff --git a/test/cases/eval.zig b/test/cases/eval.zig index e13d4340e7..364db5e152 100644 --- a/test/cases/eval.zig +++ b/test/cases/eval.zig @@ -529,3 +529,10 @@ test "comptime shlWithOverflow" { assert(ct_shifted == rt_shifted); } + +test "runtime 128 bit integer division" { + var a: u128 = 152313999999999991610955792383; + var b: u128 = 10000000000000000000; + var c = a / b; + assert(c == 15231399999); +}