authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-24 17:53:54-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-01-24 17:53:54-05:00
logcb9d00e1af365d5722ff7795aff1e74e78c3aa65
tree10ee072503d3efa8b6a845d4fa2f978095a4a04b
parentdfcedfdca0b1e26d8a735327fe8e42d7887b21b2
parent4888f9d7e1296565cb1c16e1750773e00a1e52b4
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #14402 from kcbanner/cbe_x86_fixes

CBE: x86 support and MSVC ABI fixes

13 files changed, 197 insertions(+), 50 deletions(-)

ci/x86_64-windows-debug.ps1+9-6
...@@ -67,14 +67,16 @@ Write-Output "Testing Autodocs..."...@@ -67,14 +67,16 @@ Write-Output "Testing Autodocs..."
67 -fno-emit-bin67 -fno-emit-bin
68CheckLastExitCode68CheckLastExitCode
6969
70Write-Output "Build behavior tests using the C backend..."70Write-Output "Build x86_64-windows-msvc behavior tests using the C backend..."
71& "stage3-debug\bin\zig.exe" test `71& "stage3-debug\bin\zig.exe" test `
72 ..\test\behavior.zig `72 ..\test\behavior.zig `
73 --zig-lib-dir "$ZIG_LIB_DIR" `73 --zig-lib-dir "$ZIG_LIB_DIR" `
74 -I..\test `74 -I..\test `
75 -I..\lib `75 -I..\lib `
76 -ofmt=c `76 -ofmt=c `
77 -femit-bin="test_behavior.c"77 -femit-bin="test-x86_64-windows-msvc.c" `
78 --test-no-exec `
79 -target x86_64-windows-msvc
78CheckLastExitCode80CheckLastExitCode
7981
80& "stage3-debug\bin\zig.exe" build-obj `82& "stage3-debug\bin\zig.exe" build-obj `
...@@ -83,8 +85,9 @@ CheckLastExitCode...@@ -83,8 +85,9 @@ CheckLastExitCode
83 -ofmt=c `85 -ofmt=c `
84 -OReleaseSmall `86 -OReleaseSmall `
85 --name compiler_rt `87 --name compiler_rt `
86 -femit-bin="compiler_rt.c" `88 -femit-bin="compiler_rt-x86_64-windows-msvc.c" `
87 --pkg-begin build_options config.zig --pkg-end89 --pkg-begin build_options config.zig --pkg-end `
90 -target x86_64-windows-msvc
88CheckLastExitCode91CheckLastExitCode
8992
90Import-Module "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"93Import-Module "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
...@@ -96,8 +99,8 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E...@@ -96,8 +99,8 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E
96CheckLastExitCode99CheckLastExitCode
97100
98Write-Output "Build and run behavior tests with msvc..."101Write-Output "Build and run behavior tests with msvc..."
99& cl.exe -I..\lib test_behavior.c compiler_rt.c /W3 /Z7 -link -nologo -debug -subsystem:console -entry:wWinMainCRTStartup kernel32.lib ntdll.lib vcruntime.lib libucrt.lib102& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console -entry:wWinMainCRTStartup kernel32.lib ntdll.lib vcruntime.lib libucrt.lib
100CheckLastExitCode103CheckLastExitCode
101104
102& .\test_behavior.exe105& .\test-x86_64-windows-msvc.exe
103CheckLastExitCode106CheckLastExitCode
ci/x86_64-windows-release.ps1+9-6
...@@ -67,14 +67,16 @@ Write-Output "Testing Autodocs..."...@@ -67,14 +67,16 @@ Write-Output "Testing Autodocs..."
67 -fno-emit-bin67 -fno-emit-bin
68CheckLastExitCode68CheckLastExitCode
6969
70Write-Output "Build behavior tests using the C backend..."70Write-Output "Build x86_64-windows-msvc behavior tests using the C backend..."
71& "stage3-release\bin\zig.exe" test `71& "stage3-release\bin\zig.exe" test `
72 ..\test\behavior.zig `72 ..\test\behavior.zig `
73 --zig-lib-dir "$ZIG_LIB_DIR" `73 --zig-lib-dir "$ZIG_LIB_DIR" `
74 -I..\test `74 -I..\test `
75 -I..\lib `75 -I..\lib `
76 -ofmt=c `76 -ofmt=c `
77 -femit-bin="test_behavior.c"77 -femit-bin="test-x86_64-windows-msvc.c" `
78 --test-no-exec `
79 -target x86_64-windows-msvc
78CheckLastExitCode80CheckLastExitCode
7981
80& "stage3-release\bin\zig.exe" build-obj `82& "stage3-release\bin\zig.exe" build-obj `
...@@ -83,8 +85,9 @@ CheckLastExitCode...@@ -83,8 +85,9 @@ CheckLastExitCode
83 -ofmt=c `85 -ofmt=c `
84 -OReleaseSmall `86 -OReleaseSmall `
85 --name compiler_rt `87 --name compiler_rt `
86 -femit-bin="compiler_rt.c" `88 -femit-bin="compiler_rt-x86_64-windows-msvc.c" `
87 --pkg-begin build_options config.zig --pkg-end89 --pkg-begin build_options config.zig --pkg-end `
90 -target x86_64-windows-msvc
88CheckLastExitCode91CheckLastExitCode
8992
90Import-Module "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"93Import-Module "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
...@@ -96,8 +99,8 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E...@@ -96,8 +99,8 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E
96CheckLastExitCode99CheckLastExitCode
97100
98Write-Output "Build and run behavior tests with msvc..."101Write-Output "Build and run behavior tests with msvc..."
99& cl.exe -I..\lib test_behavior.c compiler_rt.c /W3 /Z7 -link -nologo -debug -subsystem:console -entry:wWinMainCRTStartup kernel32.lib ntdll.lib vcruntime.lib libucrt.lib102& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console -entry:wWinMainCRTStartup kernel32.lib ntdll.lib vcruntime.lib libucrt.lib
100CheckLastExitCode103CheckLastExitCode
101104
102& .\test_behavior.exe105& .\test-x86_64-windows-msvc.exe
103CheckLastExitCode106CheckLastExitCode
lib/compiler_rt/aulldiv.zig+1-1
...@@ -7,7 +7,7 @@ const common = @import("common.zig");...@@ -7,7 +7,7 @@ const common = @import("common.zig");
7pub const panic = common.panic;7pub const panic = common.panic;
88
9comptime {9comptime {
10 if (arch == .x86 and abi == .msvc) {10 if (arch == .x86 and abi == .msvc and builtin.zig_backend != .stage2_c) {
11 // Don't let LLVM apply the stdcall name mangling on those MSVC builtins11 // Don't let LLVM apply the stdcall name mangling on those MSVC builtins
12 @export(_alldiv, .{ .name = "\x01__alldiv", .linkage = common.linkage, .visibility = common.visibility });12 @export(_alldiv, .{ .name = "\x01__alldiv", .linkage = common.linkage, .visibility = common.visibility });
13 @export(_aulldiv, .{ .name = "\x01__aulldiv", .linkage = common.linkage, .visibility = common.visibility });13 @export(_aulldiv, .{ .name = "\x01__aulldiv", .linkage = common.linkage, .visibility = common.visibility });
lib/compiler_rt/aullrem.zig+1-1
...@@ -7,7 +7,7 @@ const common = @import("common.zig");...@@ -7,7 +7,7 @@ const common = @import("common.zig");
7pub const panic = common.panic;7pub const panic = common.panic;
88
9comptime {9comptime {
10 if (arch == .x86 and abi == .msvc) {10 if (arch == .x86 and abi == .msvc and builtin.zig_backend != .stage2_c) {
11 // Don't let LLVM apply the stdcall name mangling on those MSVC builtins11 // Don't let LLVM apply the stdcall name mangling on those MSVC builtins
12 @export(_allrem, .{ .name = "\x01__allrem", .linkage = common.linkage, .visibility = common.visibility });12 @export(_allrem, .{ .name = "\x01__allrem", .linkage = common.linkage, .visibility = common.visibility });
13 @export(_aullrem, .{ .name = "\x01__aullrem", .linkage = common.linkage, .visibility = common.visibility });13 @export(_aullrem, .{ .name = "\x01__aullrem", .linkage = common.linkage, .visibility = common.visibility });
lib/std/os/windows.zig+11-4
...@@ -1804,14 +1804,21 @@ pub fn UnlockFile(...@@ -1804,14 +1804,21 @@ pub fn UnlockFile(
18041804
1805/// This is a workaround for the C backend until zig has the ability to put1805/// This is a workaround for the C backend until zig has the ability to put
1806/// C code in inline assembly.1806/// C code in inline assembly.
1807extern fn zig_x86_windows_teb() callconv(.C) *anyopaque;
1807extern fn zig_x86_64_windows_teb() callconv(.C) *anyopaque;1808extern fn zig_x86_64_windows_teb() callconv(.C) *anyopaque;
18081809
1809pub fn teb() *TEB {1810pub fn teb() *TEB {
1810 return switch (native_arch) {1811 return switch (native_arch) {
1811 .x86 => asm volatile (1812 .x86 => blk: {
1812 \\ movl %%fs:0x18, %[ptr]1813 if (builtin.zig_backend == .stage2_c) {
1813 : [ptr] "=r" (-> *TEB),1814 break :blk @ptrCast(*TEB, @alignCast(@alignOf(TEB), zig_x86_windows_teb()));
1814 ),1815 } else {
1816 break :blk asm volatile (
1817 \\ movl %%fs:0x18, %[ptr]
1818 : [ptr] "=r" (-> *TEB),
1819 );
1820 }
1821 },
1815 .x86_64 => blk: {1822 .x86_64 => blk: {
1816 if (builtin.zig_backend == .stage2_c) {1823 if (builtin.zig_backend == .stage2_c) {
1817 break :blk @ptrCast(*TEB, @alignCast(@alignOf(TEB), zig_x86_64_windows_teb()));1824 break :blk @ptrCast(*TEB, @alignCast(@alignOf(TEB), zig_x86_64_windows_teb()));
lib/std/start_windows_tls.zig+2-4
...@@ -7,14 +7,12 @@ export var _tls_end: u8 linksection(".tls$ZZZ") = 0;...@@ -7,14 +7,12 @@ export var _tls_end: u8 linksection(".tls$ZZZ") = 0;
7export var __xl_a: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLA") = null;7export var __xl_a: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLA") = null;
8export var __xl_z: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLZ") = null;8export var __xl_z: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLZ") = null;
99
10const tls_array: u32 = 0x2c;
10comptime {11comptime {
11 if (builtin.target.cpu.arch == .x86) {12 if (builtin.target.cpu.arch == .x86) {
12 // The __tls_array is the offset of the ThreadLocalStoragePointer field13 // The __tls_array is the offset of the ThreadLocalStoragePointer field
13 // in the TEB block whose base address held in the %fs segment.14 // in the TEB block whose base address held in the %fs segment.
14 asm (15 @export(tls_array, .{ .name = "_tls_array" });
15 \\ .global __tls_array
16 \\ __tls_array = 0x2C
17 );
18 }16 }
19}17}
2018
lib/std/target.zig+1-1
...@@ -1821,7 +1821,7 @@ pub const Target = struct {...@@ -1821,7 +1821,7 @@ pub const Target = struct {
1821 .wasm64,1821 .wasm64,
1822 => 8,1822 => 8,
18231823
1824 .x86 => return switch (target.os.tag) {1824 .x86 => if (target.ofmt == .c) 16 else return switch (target.os.tag) {
1825 .windows, .uefi => 8,1825 .windows, .uefi => 8,
1826 else => 4,1826 else => 4,
1827 },1827 },
lib/zig.h+86-22
...@@ -52,15 +52,20 @@ typedef char bool;...@@ -52,15 +52,20 @@ typedef char bool;
5252
53#if _MSC_VER53#if _MSC_VER
54#define zig_const_arr54#define zig_const_arr
55#define zig_callconv(c) __##c
55#else56#else
56#define zig_const_arr static const57#define zig_const_arr static const
58#define zig_callconv(c) __attribute__((c))
57#endif59#endif
5860
59#if zig_has_attribute(naked) || defined(zig_gnuc)61#if zig_has_attribute(naked) || defined(zig_gnuc)
62#define zig_naked_decl __attribute__((naked))
60#define zig_naked __attribute__((naked))63#define zig_naked __attribute__((naked))
61#elif defined(_MSC_VER)64#elif defined(_MSC_VER)
65#define zig_naked_decl
62#define zig_naked __declspec(naked)66#define zig_naked __declspec(naked)
63#else67#else
68#define zig_naked_decl zig_naked_unavailable
64#define zig_naked zig_naked_unavailable69#define zig_naked zig_naked_unavailable
65#endif70#endif
6671
...@@ -111,8 +116,13 @@ typedef char bool;...@@ -111,8 +116,13 @@ typedef char bool;
111#if zig_has_attribute(alias)116#if zig_has_attribute(alias)
112#define zig_export(sig, symbol, name) zig_extern sig __attribute__((alias(symbol)))117#define zig_export(sig, symbol, name) zig_extern sig __attribute__((alias(symbol)))
113#elif _MSC_VER118#elif _MSC_VER
119#if _M_X64
114#define zig_export(sig, symbol, name) sig;\120#define zig_export(sig, symbol, name) sig;\
115 __pragma(comment(linker, "/alternatename:" name "=" symbol ))121 __pragma(comment(linker, "/alternatename:" name "=" symbol ))
122#else /*_M_X64 */
123#define zig_export(sig, symbol, name) sig;\
124 __pragma(comment(linker, "/alternatename:_" name "=_" symbol ))
125#endif /*_M_X64 */
116#else126#else
117#define zig_export(sig, symbol, name) __asm(name " = " symbol)127#define zig_export(sig, symbol, name) __asm(name " = " symbol)
118#endif128#endif
...@@ -220,7 +230,12 @@ typedef char bool;...@@ -220,7 +230,12 @@ typedef char bool;
220#define zig_atomicrmw_max(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_max_, type)(obj, arg)230#define zig_atomicrmw_max(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_max_, type)(obj, arg)
221#define zig_atomic_store(obj, arg, order, type) zig_expand_concat(zig_msvc_atomic_store_, type)(obj, arg)231#define zig_atomic_store(obj, arg, order, type) zig_expand_concat(zig_msvc_atomic_store_, type)(obj, arg)
222#define zig_atomic_load(obj, order, type) zig_expand_concat(zig_msvc_atomic_load_, type)(obj)232#define zig_atomic_load(obj, order, type) zig_expand_concat(zig_msvc_atomic_load_, type)(obj)
233#if _M_X64
223#define zig_fence(order) __faststorefence()234#define zig_fence(order) __faststorefence()
235#else
236#define zig_fence(order) zig_msvc_atomic_barrier()
237#endif
238
224// TODO: _MSC_VER && (_M_ARM || _M_ARM64)239// TODO: _MSC_VER && (_M_ARM || _M_ARM64)
225#else240#else
226#define memory_order_relaxed 0241#define memory_order_relaxed 0
...@@ -1214,8 +1229,14 @@ typedef struct { zig_align(16) zig_i64 hi; zig_u64 lo; } zig_i128;...@@ -1214,8 +1229,14 @@ typedef struct { zig_align(16) zig_i64 hi; zig_u64 lo; } zig_i128;
12141229
1215#define zig_as_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) })1230#define zig_as_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) })
1216#define zig_as_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) })1231#define zig_as_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) })
1232
1233#if _MSC_VER
1217#define zig_as_constant_u128(hi, lo) { .h##i = (hi), .l##o = (lo) }1234#define zig_as_constant_u128(hi, lo) { .h##i = (hi), .l##o = (lo) }
1218#define zig_as_constant_i128(hi, lo) { .h##i = (hi), .l##o = (lo) }1235#define zig_as_constant_i128(hi, lo) { .h##i = (hi), .l##o = (lo) }
1236#else
1237#define zig_as_constant_u128(hi, lo) zig_as_u128(hi, lo)
1238#define zig_as_constant_i128(hi, lo) zig_as_i128(hi, lo)
1239#endif
1219#define zig_hi_u128(val) ((val).hi)1240#define zig_hi_u128(val) ((val).hi)
1220#define zig_lo_u128(val) ((val).lo)1241#define zig_lo_u128(val) ((val).lo)
1221#define zig_hi_i128(val) ((val).hi)1242#define zig_hi_i128(val) ((val).hi)
...@@ -1344,13 +1365,13 @@ static inline zig_u128 zig_shr_u128(zig_u128 lhs, zig_u8 rhs) {...@@ -1344,13 +1365,13 @@ static inline zig_u128 zig_shr_u128(zig_u128 lhs, zig_u8 rhs) {
13441365
1345static inline zig_u128 zig_shl_u128(zig_u128 lhs, zig_u8 rhs) {1366static inline zig_u128 zig_shl_u128(zig_u128 lhs, zig_u8 rhs) {
1346 if (rhs == zig_as_u8(0)) return lhs;1367 if (rhs == zig_as_u8(0)) return lhs;
1347 if (rhs >= zig_as_u8(64)) return (zig_u128){ .hi = lhs.lo << rhs, .lo = zig_minInt_u64 };1368 if (rhs >= zig_as_u8(64)) return (zig_u128){ .hi = lhs.lo << (rhs - zig_as_u8(64)), .lo = zig_minInt_u64 };
1348 return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (zig_as_u8(64) - rhs), .lo = lhs.lo << rhs };1369 return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (zig_as_u8(64) - rhs), .lo = lhs.lo << rhs };
1349}1370}
13501371
1351static inline zig_i128 zig_shl_i128(zig_i128 lhs, zig_u8 rhs) {1372static inline zig_i128 zig_shl_i128(zig_i128 lhs, zig_u8 rhs) {
1352 if (rhs == zig_as_u8(0)) return lhs;1373 if (rhs == zig_as_u8(0)) return lhs;
1353 if (rhs >= zig_as_u8(64)) return (zig_i128){ .hi = lhs.lo << rhs, .lo = zig_minInt_u64 };1374 if (rhs >= zig_as_u8(64)) return (zig_i128){ .hi = lhs.lo << (rhs - zig_as_u8(64)), .lo = zig_minInt_u64 };
1354 return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (zig_as_u8(64) - rhs), .lo = lhs.lo << rhs };1375 return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (zig_as_u8(64) - rhs), .lo = lhs.lo << rhs };
1355}1376}
13561377
...@@ -1379,6 +1400,10 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {...@@ -1379,6 +1400,10 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {
1379}1400}
13801401
1381zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs);1402zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs);
1403static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
1404 return zig_bitcast_u128(__multi3(zig_bitcast_i128(lhs), zig_bitcast_i128(rhs)));
1405}
1406
1382static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {1407static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
1383 return __multi3(lhs, rhs);1408 return __multi3(lhs, rhs);
1384}1409}
...@@ -1474,17 +1499,6 @@ static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {...@@ -1474,17 +1499,6 @@ static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1474 return zig_wrap_i128(zig_bitcast_i128(zig_sub_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);1499 return zig_wrap_i128(zig_bitcast_i128(zig_sub_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);
1475}1500}
14761501
1477#if _MSC_VER
1478static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
1479 zig_u64 lo_carry;
1480 zig_u64 lo = _umul128(lhs.lo, rhs.lo, &lo_carry);
1481 zig_u64 hi = lhs.hi * rhs.lo + lhs.lo * rhs.hi + lo_carry;
1482 return zig_as_u128(hi, lo);
1483}
1484#else
1485static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs); // TODO
1486#endif
1487
1488static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {1502static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1489 return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits);1503 return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits);
1490}1504}
...@@ -1857,10 +1871,13 @@ typedef zig_i32 zig_f32;...@@ -1857,10 +1871,13 @@ typedef zig_i32 zig_f32;
1857#define zig_bitSizeOf_f64 641871#define zig_bitSizeOf_f64 64
1858#define zig_libc_name_f64(name) name1872#define zig_libc_name_f64(name) name
1859#if _MSC_VER1873#if _MSC_VER
1874#ifdef ZIG_TARGET_ABI_MSVC
1875#define zig_bitSizeOf_c_longdouble 64
1876#endif
1860#define zig_as_special_constant_f64(sign, name, arg, repr) sign zig_as_f64(zig_msvc_flt_##name, )1877#define zig_as_special_constant_f64(sign, name, arg, repr) sign zig_as_f64(zig_msvc_flt_##name, )
1861#else1878#else /* _MSC_VER */
1862#define zig_as_special_constant_f64(sign, name, arg, repr) zig_as_special_f64(sign, name, arg, repr)1879#define zig_as_special_constant_f64(sign, name, arg, repr) zig_as_special_f64(sign, name, arg, repr)
1863#endif1880#endif /* _MSC_VER */
1864#if FLT_MANT_DIG == 531881#if FLT_MANT_DIG == 53
1865typedef float zig_f64;1882typedef float zig_f64;
1866#define zig_as_f64(fp, repr) fp##f1883#define zig_as_f64(fp, repr) fp##f
...@@ -1962,16 +1979,32 @@ typedef zig_i128 zig_f128;...@@ -1962,16 +1979,32 @@ typedef zig_i128 zig_f128;
1962#endif1979#endif
19631980
1964#define zig_has_c_longdouble 11981#define zig_has_c_longdouble 1
1982
1983#ifdef ZIG_TARGET_ABI_MSVC
1984#define zig_libc_name_c_longdouble(name) name
1985#else
1965#define zig_libc_name_c_longdouble(name) name##l1986#define zig_libc_name_c_longdouble(name) name##l
1987#endif
1988
1966#define zig_as_special_constant_c_longdouble(sign, name, arg, repr) zig_as_special_c_longdouble(sign, name, arg, repr)1989#define zig_as_special_constant_c_longdouble(sign, name, arg, repr) zig_as_special_c_longdouble(sign, name, arg, repr)
1967#ifdef zig_bitSizeOf_c_longdouble1990#ifdef zig_bitSizeOf_c_longdouble
1991
1992#ifdef ZIG_TARGET_ABI_MSVC
1993typedef double zig_c_longdouble;
1994#undef zig_bitSizeOf_c_longdouble
1995#define zig_bitSizeOf_c_longdouble 64
1996#define zig_as_c_longdouble(fp, repr) fp
1997#else
1968typedef long double zig_c_longdouble;1998typedef long double zig_c_longdouble;
1969#define zig_as_c_longdouble(fp, repr) fp##l1999#define zig_as_c_longdouble(fp, repr) fp##l
1970#else2000#endif
2001
2002#else /* zig_bitSizeOf_c_longdouble */
2003
1971#undef zig_has_c_longdouble2004#undef zig_has_c_longdouble
2005#define zig_has_c_longdouble 0
1972#define zig_bitSizeOf_c_longdouble 802006#define zig_bitSizeOf_c_longdouble 80
1973#define zig_compiler_rt_abbrev_c_longdouble zig_compiler_rt_abbrev_f802007#define zig_compiler_rt_abbrev_c_longdouble zig_compiler_rt_abbrev_f80
1974#define zig_has_c_longdouble 0
1975#define zig_repr_c_longdouble i1282008#define zig_repr_c_longdouble i128
1976typedef zig_i128 zig_c_longdouble;2009typedef zig_i128 zig_c_longdouble;
1977#define zig_as_c_longdouble(fp, repr) repr2010#define zig_as_c_longdouble(fp, repr) repr
...@@ -1979,19 +2012,26 @@ typedef zig_i128 zig_c_longdouble;...@@ -1979,19 +2012,26 @@ typedef zig_i128 zig_c_longdouble;
1979#define zig_as_special_c_longdouble(sign, name, arg, repr) repr2012#define zig_as_special_c_longdouble(sign, name, arg, repr) repr
1980#undef zig_as_special_constant_c_longdouble2013#undef zig_as_special_constant_c_longdouble
1981#define zig_as_special_constant_c_longdouble(sign, name, arg, repr) repr2014#define zig_as_special_constant_c_longdouble(sign, name, arg, repr) repr
1982#endif2015
2016#endif /* zig_bitSizeOf_c_longdouble */
19832017
1984#if !zig_has_float_builtins2018#if !zig_has_float_builtins
1985#define zig_float_from_repr(Type, ReprType) \2019#define zig_float_from_repr(Type, ReprType) \
1986 static inline zig_##Type zig_float_from_repr_##Type(zig_##ReprType repr) { \2020 static inline zig_##Type zig_float_from_repr_##Type(zig_##ReprType repr) { \
1987 return *((zig_##Type*)&repr); \2021 return *((zig_##Type*)&repr); \
1988 }2022 }
2023
1989zig_float_from_repr(f16, u16)2024zig_float_from_repr(f16, u16)
1990zig_float_from_repr(f32, u32)2025zig_float_from_repr(f32, u32)
1991zig_float_from_repr(f64, u64)2026zig_float_from_repr(f64, u64)
1992zig_float_from_repr(f80, u128)2027zig_float_from_repr(f80, u128)
1993zig_float_from_repr(f128, u128)2028zig_float_from_repr(f128, u128)
2029#if zig_bitSizeOf_c_longdouble == 80
1994zig_float_from_repr(c_longdouble, u128)2030zig_float_from_repr(c_longdouble, u128)
2031#else
2032#define zig_expand_float_from_repr(Type, ReprType) zig_float_from_repr(Type, ReprType)
2033zig_expand_float_from_repr(c_longdouble, zig_expand_concat(u, zig_bitSizeOf_c_longdouble))
2034#endif
1995#endif2035#endif
19962036
1997#define zig_cast_f16 (zig_f16)2037#define zig_cast_f16 (zig_f16)
...@@ -2218,8 +2258,11 @@ zig_msvc_atomics(u16, 16)...@@ -2218,8 +2258,11 @@ zig_msvc_atomics(u16, 16)
2218zig_msvc_atomics(i16, 16)2258zig_msvc_atomics(i16, 16)
2219zig_msvc_atomics(u32, )2259zig_msvc_atomics(u32, )
2220zig_msvc_atomics(i32, )2260zig_msvc_atomics(i32, )
2261
2262#if _M_X64
2221zig_msvc_atomics(u64, 64)2263zig_msvc_atomics(u64, 64)
2222zig_msvc_atomics(i64, 64)2264zig_msvc_atomics(i64, 64)
2265#endif
22232266
2224#define zig_msvc_flt_atomics(Type, ReprType, suffix) \2267#define zig_msvc_flt_atomics(Type, ReprType, suffix) \
2225 static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \2268 static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \
...@@ -2259,9 +2302,18 @@ zig_msvc_atomics(i64, 64)...@@ -2259,9 +2302,18 @@ zig_msvc_atomics(i64, 64)
2259 }2302 }
22602303
2261zig_msvc_flt_atomics(f32, u32, )2304zig_msvc_flt_atomics(f32, u32, )
2305#if _M_X64
2262zig_msvc_flt_atomics(f64, u64, 64)2306zig_msvc_flt_atomics(f64, u64, 64)
2307#endif
22632308
2264#if _M_IX862309#if _M_IX86
2310static inline void zig_msvc_atomic_barrier() {
2311 zig_i32 barrier;
2312 __asm {
2313 xchg barrier, eax
2314 }
2315}
2316
2265static inline void* zig_msvc_atomicrmw_xchg_p32(void** obj, zig_u32* arg) {2317static inline void* zig_msvc_atomicrmw_xchg_p32(void** obj, zig_u32* arg) {
2266 return _InterlockedExchangePointer(obj, arg);2318 return _InterlockedExchangePointer(obj, arg);
2267}2319}
...@@ -2270,7 +2322,7 @@ static inline void zig_msvc_atomic_store_p32(void** obj, zig_u32* arg) {...@@ -2270,7 +2322,7 @@ static inline void zig_msvc_atomic_store_p32(void** obj, zig_u32* arg) {
2270 _InterlockedExchangePointer(obj, arg);2322 _InterlockedExchangePointer(obj, arg);
2271}2323}
22722324
2273static inline void* zig_msvc_atomic_load_p32(void** obj, zig_u32* arg) {2325static inline void* zig_msvc_atomic_load_p32(void** obj) {
2274 return (void*)_InterlockedOr((void*)obj, 0);2326 return (void*)_InterlockedOr((void*)obj, 0);
2275}2327}
22762328
...@@ -2283,7 +2335,7 @@ static inline bool zig_msvc_cmpxchg_p32(void** obj, void** expected, void* desir...@@ -2283,7 +2335,7 @@ static inline bool zig_msvc_cmpxchg_p32(void** obj, void** expected, void* desir
2283 }2335 }
2284 return exchanged;2336 return exchanged;
2285}2337}
2286#else2338#else /* _M_IX86 */
2287static inline void* zig_msvc_atomicrmw_xchg_p64(void** obj, zig_u64* arg) {2339static inline void* zig_msvc_atomicrmw_xchg_p64(void** obj, zig_u64* arg) {
2288 return _InterlockedExchangePointer(obj, arg);2340 return _InterlockedExchangePointer(obj, arg);
2289}2341}
...@@ -2305,7 +2357,6 @@ static inline bool zig_msvc_cmpxchg_p64(void** obj, void** expected, void* desir...@@ -2305,7 +2357,6 @@ static inline bool zig_msvc_cmpxchg_p64(void** obj, void** expected, void* desir
2305 }2357 }
2306 return exchanged;2358 return exchanged;
2307}2359}
2308#endif
23092360
2310static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expected, zig_u128 desired) {2361static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expected, zig_u128 desired) {
2311 return _InterlockedCompareExchange128((zig_i64 volatile*)obj, desired.hi, desired.lo, (zig_i64*)expected);2362 return _InterlockedCompareExchange128((zig_i64 volatile*)obj, desired.hi, desired.lo, (zig_i64*)expected);
...@@ -2350,6 +2401,7 @@ zig_msvc_atomics_128op(u128, and)...@@ -2350,6 +2401,7 @@ zig_msvc_atomics_128op(u128, and)
2350zig_msvc_atomics_128op(u128, nand)2401zig_msvc_atomics_128op(u128, nand)
2351zig_msvc_atomics_128op(u128, min)2402zig_msvc_atomics_128op(u128, min)
2352zig_msvc_atomics_128op(u128, max)2403zig_msvc_atomics_128op(u128, max)
2404#endif /* _M_IX86 */
23532405
2354#endif /* _MSC_VER && (_M_IX86 || _M_X64) */2406#endif /* _MSC_VER && (_M_IX86 || _M_X64) */
23552407
...@@ -2359,7 +2411,7 @@ zig_msvc_atomics_128op(u128, max)...@@ -2359,7 +2411,7 @@ zig_msvc_atomics_128op(u128, max)
23592411
2360static inline void* zig_x86_64_windows_teb(void) {2412static inline void* zig_x86_64_windows_teb(void) {
2361#if _MSC_VER2413#if _MSC_VER
2362 return __readgsqword(0x30);2414 return (void*)__readgsqword(0x30);
2363#else2415#else
2364 void* teb;2416 void* teb;
2365 __asm volatile(" movq %%gs:0x30, %[ptr]": [ptr]"=r"(teb)::);2417 __asm volatile(" movq %%gs:0x30, %[ptr]": [ptr]"=r"(teb)::);
...@@ -2367,6 +2419,18 @@ static inline void* zig_x86_64_windows_teb(void) {...@@ -2367,6 +2419,18 @@ static inline void* zig_x86_64_windows_teb(void) {
2367#endif2419#endif
2368}2420}
23692421
2422#elif (_MSC_VER && _M_IX86) || defined(__i386__) || defined(__X86__)
2423
2424static inline void* zig_x86_windows_teb(void) {
2425#if _MSC_VER
2426 return (void*)__readfsdword(0x18);
2427#else
2428 void* teb;
2429 __asm volatile(" movl %%fs:0x18, %[ptr]": [ptr]"=r"(teb)::);
2430 return teb;
2431#endif
2432}
2433
2370#endif2434#endif
23712435
2372#if (_MSC_VER && (_M_IX86 || _M_X64)) || defined(__i386__) || defined(__x86_64__)2436#if (_MSC_VER && (_M_IX86 || _M_X64)) || defined(__i386__) || defined(__x86_64__)
src/codegen/c.zig+23-2
...@@ -1459,7 +1459,12 @@ pub const DeclGen = struct {...@@ -1459,7 +1459,12 @@ pub const DeclGen = struct {
14591459
1460 fn renderFunctionSignature(dg: *DeclGen, w: anytype, kind: TypedefKind, export_index: u32) !void {1460 fn renderFunctionSignature(dg: *DeclGen, w: anytype, kind: TypedefKind, export_index: u32) !void {
1461 const fn_info = dg.decl.ty.fnInfo();1461 const fn_info = dg.decl.ty.fnInfo();
1462 if (fn_info.cc == .Naked) try w.writeAll("zig_naked ");1462 if (fn_info.cc == .Naked) {
1463 switch (kind) {
1464 .Forward => try w.writeAll("zig_naked_decl "),
1465 .Complete => try w.writeAll("zig_naked "),
1466 }
1467 }
1463 if (dg.decl.val.castTag(.function)) |func_payload|1468 if (dg.decl.val.castTag(.function)) |func_payload|
1464 if (func_payload.data.is_cold) try w.writeAll("zig_cold ");1469 if (func_payload.data.is_cold) try w.writeAll("zig_cold ");
14651470
...@@ -1469,6 +1474,13 @@ pub const DeclGen = struct {...@@ -1469,6 +1474,13 @@ pub const DeclGen = struct {
14691474
1470 try dg.renderType(w, ret_ty, kind);1475 try dg.renderType(w, ret_ty, kind);
1471 try w.writeByte(' ');1476 try w.writeByte(' ');
1477
1478 if (toCallingConvention(fn_info.cc)) |call_conv| {
1479 try w.print("zig_callconv({s}) ", .{call_conv});
1480 }
1481
1482 if (fn_info.alignment > 0 and kind == .Complete) try w.print(" zig_align_fn({})", .{fn_info.alignment});
1483
1472 try dg.renderDeclName(w, dg.decl_index, export_index);1484 try dg.renderDeclName(w, dg.decl_index, export_index);
1473 try w.writeByte('(');1485 try w.writeByte('(');
14741486
...@@ -1488,7 +1500,7 @@ pub const DeclGen = struct {...@@ -1488,7 +1500,7 @@ pub const DeclGen = struct {
1488 try dg.renderType(w, Type.void, kind);1500 try dg.renderType(w, Type.void, kind);
1489 }1501 }
1490 try w.writeByte(')');1502 try w.writeByte(')');
1491 if (fn_info.alignment > 0) try w.print(" zig_align_fn({})", .{fn_info.alignment});1503 if (fn_info.alignment > 0 and kind == .Forward) try w.print(" zig_align_fn({})", .{fn_info.alignment});
1492 }1504 }
14931505
1494 fn renderPtrToFnTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1506 fn renderPtrToFnTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
...@@ -7035,6 +7047,15 @@ fn writeMemoryOrder(w: anytype, order: std.builtin.AtomicOrder) !void {...@@ -7035,6 +7047,15 @@ fn writeMemoryOrder(w: anytype, order: std.builtin.AtomicOrder) !void {
7035 return w.writeAll(toMemoryOrder(order));7047 return w.writeAll(toMemoryOrder(order));
7036}7048}
70377049
7050fn toCallingConvention(call_conv: std.builtin.CallingConvention) ?[]const u8 {
7051 return switch (call_conv) {
7052 .Stdcall => "stdcall",
7053 .Fastcall => "fastcall",
7054 .Vectorcall => "vectorcall",
7055 else => null,
7056 };
7057}
7058
7038fn toAtomicRmwSuffix(order: std.builtin.AtomicRmwOp) []const u8 {7059fn toAtomicRmwSuffix(order: std.builtin.AtomicRmwOp) []const u8 {
7039 return switch (order) {7060 return switch (order) {
7040 .Xchg => "xchg",7061 .Xchg => "xchg",
src/link/C.zig+14-2
...@@ -231,6 +231,13 @@ pub fn flush(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void...@@ -231,6 +231,13 @@ pub fn flush(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void
231 return self.flushModule(comp, prog_node);231 return self.flushModule(comp, prog_node);
232}232}
233233
234fn abiDefine(comp: *Compilation) ?[]const u8 {
235 return switch (comp.getTarget().abi) {
236 .msvc => "#define ZIG_TARGET_ABI_MSVC\n",
237 else => null,
238 };
239}
240
234pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void {241pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void {
235 const tracy = trace(@src());242 const tracy = trace(@src());
236 defer tracy.end();243 defer tracy.end();
...@@ -248,9 +255,14 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)...@@ -248,9 +255,14 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
248 var f: Flush = .{};255 var f: Flush = .{};
249 defer f.deinit(gpa);256 defer f.deinit(gpa);
250257
251 // Covers zig.h, typedef, and asm.258 const abi_define = abiDefine(comp);
252 try f.all_buffers.ensureUnusedCapacity(gpa, 2);259
260 // Covers defines, zig.h, typedef, and asm.
261 var buf_count: usize = 2;
262 if (abi_define != null) buf_count += 1;
263 try f.all_buffers.ensureUnusedCapacity(gpa, buf_count);
253264
265 if (abi_define) |buf| f.appendBufAssumeCapacity(buf);
254 f.appendBufAssumeCapacity(zig_h);266 f.appendBufAssumeCapacity(zig_h);
255267
256 const typedef_index = f.all_buffers.items.len;268 const typedef_index = f.all_buffers.items.len;
stage1/zig1.wasm
Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ
test/behavior/align.zig+12-1
...@@ -104,7 +104,18 @@ test "alignment and size of structs with 128-bit fields" {...@@ -104,7 +104,18 @@ test "alignment and size of structs with 128-bit fields" {
104 .u129_size = 24,104 .u129_size = 24,
105 },105 },
106106
107 .x86 => switch (builtin.os.tag) {107 .x86 => if (builtin.object_format == .c) .{
108 .a_align = 16,
109 .a_size = 16,
110
111 .b_align = 16,
112 .b_size = 32,
113
114 .u128_align = 16,
115 .u128_size = 16,
116 .u129_align = 16,
117 .u129_size = 32,
118 } else switch (builtin.os.tag) {
108 .windows => .{119 .windows => .{
109 .a_align = 8,120 .a_align = 8,
110 .a_size = 16,121 .a_size = 16,
test/behavior/int128.zig+28
...@@ -84,3 +84,31 @@ test "truncate int128" {...@@ -84,3 +84,31 @@ test "truncate int128" {
84 try expect(@truncate(i128, buff) == maxInt(i128));84 try expect(@truncate(i128, buff) == maxInt(i128));
85 }85 }
86}86}
87
88test "shift int128" {
89 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
90 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
91 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
92 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
93 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
94
95 const types = .{ u128, i128 };
96 inline for (types) |t| {
97 try testShlTrunc(t, 0x8, 123);
98 comptime try testShlTrunc(t, 0x8, 123);
99
100 try testShlTrunc(t, 0x40000000_00000000, 64);
101 comptime try testShlTrunc(t, 0x40000000_00000000, 64);
102
103 try testShlTrunc(t, 0x01000000_00000000_00000000, 38);
104 comptime try testShlTrunc(t, 0x01000000_00000000_00000000, 38);
105
106 try testShlTrunc(t, 0x00000008_00000000_00000000_00000000, 27);
107 comptime try testShlTrunc(t, 0x00000008_00000000_00000000_00000000, 27);
108 }
109}
110
111fn testShlTrunc(comptime Type: type, x: Type, rhs: u7) !void {
112 const shifted = x << rhs;
113 try expect(shifted == @as(Type, 0x40000000_00000000_00000000_00000000));
114}