| author | |
| committer | |
| log | a71bfc249d3f814d7d659fe5cf4cb582483e8938 |
| tree | 0b1b26bbb96a02eebbd05dbe9cf16fd06412d8d6 |
| parent | 52934851f2b7a5cb28a08beafa1ec1aa24a3a4cb |
This removes the compiler_rt.setXmm0 hack. Instead, for
the functions that use i128 or u128 in their parameter and
return types, we use `@Vector(2, u64)` which generates
the LLVM IR `<2 x i64>` type that matches what Clang
generates for `typedef int ti_int __attribute__ ((mode (TI)))`
when targeting Windows x86_64.9 files changed, 24 insertions(+), 31 deletions(-)
src/codegen.cpp+1-1| ... | @@ -424,7 +424,7 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) { | ... | @@ -424,7 +424,7 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) { |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | static void maybe_export_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) { | 426 | static void maybe_export_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) { |
| 427 | if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows) { | 427 | if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows && g->is_dynamic) { |
| 428 | LLVMSetDLLStorageClass(global_value, LLVMDLLExportStorageClass); | 428 | LLVMSetDLLStorageClass(global_value, LLVMDLLExportStorageClass); |
| 429 | } | 429 | } |
| 430 | } | 430 | } |
std/special/compiler_rt.zig+2-11| ... | @@ -160,6 +160,8 @@ comptime { | ... | @@ -160,6 +160,8 @@ comptime { |
| 160 | @export("__chkstk", __chkstk, strong_linkage); | 160 | @export("__chkstk", __chkstk, strong_linkage); |
| 161 | @export("___chkstk_ms", ___chkstk_ms, linkage); | 161 | @export("___chkstk_ms", ___chkstk_ms, linkage); |
| 162 | } | 162 | } |
| 163 | // The "ti" functions must use @Vector(2, u64) parameter types to adhere to the ABI | ||
| 164 | // that LLVM expects compiler-rt to have. | ||
| 163 | @export("__divti3", @import("compiler_rt/divti3.zig").__divti3_windows_x86_64, linkage); | 165 | @export("__divti3", @import("compiler_rt/divti3.zig").__divti3_windows_x86_64, linkage); |
| 164 | @export("__modti3", @import("compiler_rt/modti3.zig").__modti3_windows_x86_64, linkage); | 166 | @export("__modti3", @import("compiler_rt/modti3.zig").__modti3_windows_x86_64, linkage); |
| 165 | @export("__multi3", @import("compiler_rt/multi3.zig").__multi3_windows_x86_64, linkage); | 167 | @export("__multi3", @import("compiler_rt/multi3.zig").__multi3_windows_x86_64, linkage); |
| ... | @@ -198,17 +200,6 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn | ... | @@ -198,17 +200,6 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn |
| 198 | } | 200 | } |
| 199 | } | 201 | } |
| 200 | 202 | ||
| 201 | pub fn setXmm0(comptime T: type, value: T) void { | ||
| 202 | comptime assert(builtin.arch == builtin.Arch.x86_64); | ||
| 203 | const aligned_value: T align(16) = value; | ||
| 204 | asm volatile ( | ||
| 205 | \\movaps (%[ptr]), %%xmm0 | ||
| 206 | : | ||
| 207 | : [ptr] "r" (&aligned_value) | ||
| 208 | : "xmm0" | ||
| 209 | ); | ||
| 210 | } | ||
| 211 | |||
| 212 | extern fn __udivdi3(a: u64, b: u64) u64 { | 203 | extern fn __udivdi3(a: u64, b: u64) u64 { |
| 213 | @setRuntimeSafety(is_test); | 204 | @setRuntimeSafety(is_test); |
| 214 | return __udivmoddi4(a, b, null); | 205 | return __udivmoddi4(a, b, null); |
std/special/compiler_rt/divti3.zig+3-3| ... | @@ -16,9 +16,9 @@ pub extern fn __divti3(a: i128, b: i128) i128 { | ... | @@ -16,9 +16,9 @@ pub extern fn __divti3(a: i128, b: i128) i128 { |
| 16 | return (@bitCast(i128, r) ^ s) -% s; | 16 | return (@bitCast(i128, r) ^ s) -% s; |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | pub extern fn __divti3_windows_x86_64(a: *const i128, b: *const i128) void { | 19 | const v128 = @Vector(2, u64); |
| 20 | @setRuntimeSafety(builtin.is_test); | 20 | pub extern fn __divti3_windows_x86_64(a: v128, b: v128) v128 { |
| 21 | compiler_rt.setXmm0(i128, __divti3(a.*, b.*)); | 21 | return @bitCast(v128, @inlineCall(__divti3, @bitCast(i128, a), @bitCast(i128, b))); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | test "import divti3" { | 24 | test "import divti3" { |
std/special/compiler_rt/modti3.zig+3-3| ... | @@ -20,9 +20,9 @@ pub extern fn __modti3(a: i128, b: i128) i128 { | ... | @@ -20,9 +20,9 @@ pub extern fn __modti3(a: i128, b: i128) i128 { |
| 20 | return (@bitCast(i128, r) ^ s_a) -% s_a; // negate if s == -1 | 20 | return (@bitCast(i128, r) ^ s_a) -% s_a; // negate if s == -1 |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | pub extern fn __modti3_windows_x86_64(a: *const i128, b: *const i128) void { | 23 | const v128 = @Vector(2, u64); |
| 24 | @setRuntimeSafety(builtin.is_test); | 24 | pub extern fn __modti3_windows_x86_64(a: v128, b: v128) v128 { |
| 25 | compiler_rt.setXmm0(i128, __modti3(a.*, b.*)); | 25 | return @bitCast(v128, @inlineCall(__modti3, @bitCast(i128, a), @bitCast(i128, b))); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | test "import modti3" { | 28 | test "import modti3" { |
std/special/compiler_rt/muloti4.zig+3-3| ... | @@ -44,9 +44,9 @@ pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 { | ... | @@ -44,9 +44,9 @@ pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 { |
| 44 | return r; | 44 | return r; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | pub extern fn __muloti4_windows_x86_64(a: *const i128, b: *const i128, overflow: *c_int) void { | 47 | const v128 = @Vector(2, u64); |
| 48 | @setRuntimeSafety(builtin.is_test); | 48 | pub extern fn __muloti4_windows_x86_64(a: v128, b: v128, overflow: *c_int) v128 { |
| 49 | compiler_rt.setXmm0(i128, __muloti4(a.*, b.*, overflow)); | 49 | return @bitCast(v128, @inlineCall(__muloti4, @bitCast(i128, a), @bitCast(i128, b), overflow)); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | test "import muloti4" { | 52 | test "import muloti4" { |
std/special/compiler_rt/multi3.zig+3-3| ... | @@ -14,9 +14,9 @@ pub extern fn __multi3(a: i128, b: i128) i128 { | ... | @@ -14,9 +14,9 @@ pub extern fn __multi3(a: i128, b: i128) i128 { |
| 14 | return r.all; | 14 | return r.all; |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | pub extern fn __multi3_windows_x86_64(a: *const i128, b: *const i128) void { | 17 | const v128 = @Vector(2, u64); |
| 18 | @setRuntimeSafety(builtin.is_test); | 18 | pub extern fn __multi3_windows_x86_64(a: v128, b: v128) v128 { |
| 19 | compiler_rt.setXmm0(i128, __multi3(a.*, b.*)); | 19 | return @bitCast(v128, @inlineCall(__multi3, @bitCast(i128, a), @bitCast(i128, b))); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | fn __mulddi3(a: u64, b: u64) i128 { | 22 | fn __mulddi3(a: u64, b: u64) i128 { |
std/special/compiler_rt/udivmodti4.zig+3-2| ... | @@ -7,9 +7,10 @@ pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?*u128) u128 { | ... | @@ -7,9 +7,10 @@ pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?*u128) u128 { |
| 7 | return udivmod(u128, a, b, maybe_rem); | 7 | return udivmod(u128, a, b, maybe_rem); |
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | pub extern fn __udivmodti4_windows_x86_64(a: *const u128, b: *const u128, maybe_rem: ?*u128) void { | 10 | const v128 = @Vector(2, u64); |
| 11 | pub extern fn __udivmodti4_windows_x86_64(a: v128, b: v128, maybe_rem: ?*u128) v128 { | ||
| 11 | @setRuntimeSafety(builtin.is_test); | 12 | @setRuntimeSafety(builtin.is_test); |
| 12 | compiler_rt.setXmm0(u128, udivmod(u128, a.*, b.*, maybe_rem)); | 13 | return @bitCast(v128, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), maybe_rem)); |
| 13 | } | 14 | } |
| 14 | 15 | ||
| 15 | test "import udivmodti4" { | 16 | test "import udivmodti4" { |
std/special/compiler_rt/udivti3.zig+3-2| ... | @@ -6,7 +6,8 @@ pub extern fn __udivti3(a: u128, b: u128) u128 { | ... | @@ -6,7 +6,8 @@ pub extern fn __udivti3(a: u128, b: u128) u128 { |
| 6 | return udivmodti4.__udivmodti4(a, b, null); | 6 | return udivmodti4.__udivmodti4(a, b, null); |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | pub extern fn __udivti3_windows_x86_64(a: *const u128, b: *const u128) void { | 9 | const v128 = @Vector(2, u64); |
| 10 | pub extern fn __udivti3_windows_x86_64(a: v128, b: v128) v128 { | ||
| 10 | @setRuntimeSafety(builtin.is_test); | 11 | @setRuntimeSafety(builtin.is_test); |
| 11 | udivmodti4.__udivmodti4_windows_x86_64(a, b, null); | 12 | return udivmodti4.__udivmodti4_windows_x86_64(a, b, null); |
| 12 | } | 13 | } |
std/special/compiler_rt/umodti3.zig+3-3| ... | @@ -9,7 +9,7 @@ pub extern fn __umodti3(a: u128, b: u128) u128 { | ... | @@ -9,7 +9,7 @@ pub extern fn __umodti3(a: u128, b: u128) u128 { |
| 9 | return r; | 9 | return r; |
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | pub extern fn __umodti3_windows_x86_64(a: *const u128, b: *const u128) void { | 12 | const v128 = @Vector(2, u64); |
| 13 | @setRuntimeSafety(builtin.is_test); | 13 | pub extern fn __umodti3_windows_x86_64(a: v128, b: v128) v128 { |
| 14 | compiler_rt.setXmm0(u128, __umodti3(a.*, b.*)); | 14 | return @bitCast(v128, @inlineCall(__umodti3, @bitCast(u128, a), @bitCast(u128, b))); |
| 15 | } | 15 | } |