Merge pull request #14402 from kcbanner/cbe_x86_fixes
CBE: x86 support and MSVC ABI fixes
This commit is contained in:
@@ -67,14 +67,16 @@ Write-Output "Testing Autodocs..."
|
||||
-fno-emit-bin
|
||||
CheckLastExitCode
|
||||
|
||||
Write-Output "Build behavior tests using the C backend..."
|
||||
Write-Output "Build x86_64-windows-msvc behavior tests using the C backend..."
|
||||
& "stage3-debug\bin\zig.exe" test `
|
||||
..\test\behavior.zig `
|
||||
--zig-lib-dir "$ZIG_LIB_DIR" `
|
||||
-I..\test `
|
||||
-I..\lib `
|
||||
-ofmt=c `
|
||||
-femit-bin="test_behavior.c"
|
||||
-femit-bin="test-x86_64-windows-msvc.c" `
|
||||
--test-no-exec `
|
||||
-target x86_64-windows-msvc
|
||||
CheckLastExitCode
|
||||
|
||||
& "stage3-debug\bin\zig.exe" build-obj `
|
||||
@@ -83,8 +85,9 @@ CheckLastExitCode
|
||||
-ofmt=c `
|
||||
-OReleaseSmall `
|
||||
--name compiler_rt `
|
||||
-femit-bin="compiler_rt.c" `
|
||||
--pkg-begin build_options config.zig --pkg-end
|
||||
-femit-bin="compiler_rt-x86_64-windows-msvc.c" `
|
||||
--pkg-begin build_options config.zig --pkg-end `
|
||||
-target x86_64-windows-msvc
|
||||
CheckLastExitCode
|
||||
|
||||
Import-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
|
||||
CheckLastExitCode
|
||||
|
||||
Write-Output "Build and run behavior tests with msvc..."
|
||||
& 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.lib
|
||||
& 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
|
||||
CheckLastExitCode
|
||||
|
||||
& .\test_behavior.exe
|
||||
& .\test-x86_64-windows-msvc.exe
|
||||
CheckLastExitCode
|
||||
|
||||
@@ -67,14 +67,16 @@ Write-Output "Testing Autodocs..."
|
||||
-fno-emit-bin
|
||||
CheckLastExitCode
|
||||
|
||||
Write-Output "Build behavior tests using the C backend..."
|
||||
Write-Output "Build x86_64-windows-msvc behavior tests using the C backend..."
|
||||
& "stage3-release\bin\zig.exe" test `
|
||||
..\test\behavior.zig `
|
||||
--zig-lib-dir "$ZIG_LIB_DIR" `
|
||||
-I..\test `
|
||||
-I..\lib `
|
||||
-ofmt=c `
|
||||
-femit-bin="test_behavior.c"
|
||||
-femit-bin="test-x86_64-windows-msvc.c" `
|
||||
--test-no-exec `
|
||||
-target x86_64-windows-msvc
|
||||
CheckLastExitCode
|
||||
|
||||
& "stage3-release\bin\zig.exe" build-obj `
|
||||
@@ -83,8 +85,9 @@ CheckLastExitCode
|
||||
-ofmt=c `
|
||||
-OReleaseSmall `
|
||||
--name compiler_rt `
|
||||
-femit-bin="compiler_rt.c" `
|
||||
--pkg-begin build_options config.zig --pkg-end
|
||||
-femit-bin="compiler_rt-x86_64-windows-msvc.c" `
|
||||
--pkg-begin build_options config.zig --pkg-end `
|
||||
-target x86_64-windows-msvc
|
||||
CheckLastExitCode
|
||||
|
||||
Import-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
|
||||
CheckLastExitCode
|
||||
|
||||
Write-Output "Build and run behavior tests with msvc..."
|
||||
& 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.lib
|
||||
& 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
|
||||
CheckLastExitCode
|
||||
|
||||
& .\test_behavior.exe
|
||||
& .\test-x86_64-windows-msvc.exe
|
||||
CheckLastExitCode
|
||||
|
||||
@@ -7,7 +7,7 @@ const common = @import("common.zig");
|
||||
pub const panic = common.panic;
|
||||
|
||||
comptime {
|
||||
if (arch == .x86 and abi == .msvc) {
|
||||
if (arch == .x86 and abi == .msvc and builtin.zig_backend != .stage2_c) {
|
||||
// Don't let LLVM apply the stdcall name mangling on those MSVC builtins
|
||||
@export(_alldiv, .{ .name = "\x01__alldiv", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(_aulldiv, .{ .name = "\x01__aulldiv", .linkage = common.linkage, .visibility = common.visibility });
|
||||
|
||||
@@ -7,7 +7,7 @@ const common = @import("common.zig");
|
||||
pub const panic = common.panic;
|
||||
|
||||
comptime {
|
||||
if (arch == .x86 and abi == .msvc) {
|
||||
if (arch == .x86 and abi == .msvc and builtin.zig_backend != .stage2_c) {
|
||||
// Don't let LLVM apply the stdcall name mangling on those MSVC builtins
|
||||
@export(_allrem, .{ .name = "\x01__allrem", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(_aullrem, .{ .name = "\x01__aullrem", .linkage = common.linkage, .visibility = common.visibility });
|
||||
|
||||
@@ -1804,14 +1804,21 @@ pub fn UnlockFile(
|
||||
|
||||
/// This is a workaround for the C backend until zig has the ability to put
|
||||
/// C code in inline assembly.
|
||||
extern fn zig_x86_windows_teb() callconv(.C) *anyopaque;
|
||||
extern fn zig_x86_64_windows_teb() callconv(.C) *anyopaque;
|
||||
|
||||
pub fn teb() *TEB {
|
||||
return switch (native_arch) {
|
||||
.x86 => asm volatile (
|
||||
\\ movl %%fs:0x18, %[ptr]
|
||||
: [ptr] "=r" (-> *TEB),
|
||||
),
|
||||
.x86 => blk: {
|
||||
if (builtin.zig_backend == .stage2_c) {
|
||||
break :blk @ptrCast(*TEB, @alignCast(@alignOf(TEB), zig_x86_windows_teb()));
|
||||
} else {
|
||||
break :blk asm volatile (
|
||||
\\ movl %%fs:0x18, %[ptr]
|
||||
: [ptr] "=r" (-> *TEB),
|
||||
);
|
||||
}
|
||||
},
|
||||
.x86_64 => blk: {
|
||||
if (builtin.zig_backend == .stage2_c) {
|
||||
break :blk @ptrCast(*TEB, @alignCast(@alignOf(TEB), zig_x86_64_windows_teb()));
|
||||
|
||||
@@ -7,14 +7,12 @@ export var _tls_end: u8 linksection(".tls$ZZZ") = 0;
|
||||
export var __xl_a: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLA") = null;
|
||||
export var __xl_z: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLZ") = null;
|
||||
|
||||
const tls_array: u32 = 0x2c;
|
||||
comptime {
|
||||
if (builtin.target.cpu.arch == .x86) {
|
||||
// The __tls_array is the offset of the ThreadLocalStoragePointer field
|
||||
// in the TEB block whose base address held in the %fs segment.
|
||||
asm (
|
||||
\\ .global __tls_array
|
||||
\\ __tls_array = 0x2C
|
||||
);
|
||||
@export(tls_array, .{ .name = "_tls_array" });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1821,7 +1821,7 @@ pub const Target = struct {
|
||||
.wasm64,
|
||||
=> 8,
|
||||
|
||||
.x86 => return switch (target.os.tag) {
|
||||
.x86 => if (target.ofmt == .c) 16 else return switch (target.os.tag) {
|
||||
.windows, .uefi => 8,
|
||||
else => 4,
|
||||
},
|
||||
|
||||
110
lib/zig.h
110
lib/zig.h
@@ -52,15 +52,20 @@ typedef char bool;
|
||||
|
||||
#if _MSC_VER
|
||||
#define zig_const_arr
|
||||
#define zig_callconv(c) __##c
|
||||
#else
|
||||
#define zig_const_arr static const
|
||||
#define zig_callconv(c) __attribute__((c))
|
||||
#endif
|
||||
|
||||
#if zig_has_attribute(naked) || defined(zig_gnuc)
|
||||
#define zig_naked_decl __attribute__((naked))
|
||||
#define zig_naked __attribute__((naked))
|
||||
#elif defined(_MSC_VER)
|
||||
#define zig_naked_decl
|
||||
#define zig_naked __declspec(naked)
|
||||
#else
|
||||
#define zig_naked_decl zig_naked_unavailable
|
||||
#define zig_naked zig_naked_unavailable
|
||||
#endif
|
||||
|
||||
@@ -111,8 +116,13 @@ typedef char bool;
|
||||
#if zig_has_attribute(alias)
|
||||
#define zig_export(sig, symbol, name) zig_extern sig __attribute__((alias(symbol)))
|
||||
#elif _MSC_VER
|
||||
#if _M_X64
|
||||
#define zig_export(sig, symbol, name) sig;\
|
||||
__pragma(comment(linker, "/alternatename:" name "=" symbol ))
|
||||
#else /*_M_X64 */
|
||||
#define zig_export(sig, symbol, name) sig;\
|
||||
__pragma(comment(linker, "/alternatename:_" name "=_" symbol ))
|
||||
#endif /*_M_X64 */
|
||||
#else
|
||||
#define zig_export(sig, symbol, name) __asm(name " = " symbol)
|
||||
#endif
|
||||
@@ -220,7 +230,12 @@ typedef char bool;
|
||||
#define zig_atomicrmw_max(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_max_, type)(obj, arg)
|
||||
#define zig_atomic_store(obj, arg, order, type) zig_expand_concat(zig_msvc_atomic_store_, type)(obj, arg)
|
||||
#define zig_atomic_load(obj, order, type) zig_expand_concat(zig_msvc_atomic_load_, type)(obj)
|
||||
#if _M_X64
|
||||
#define zig_fence(order) __faststorefence()
|
||||
#else
|
||||
#define zig_fence(order) zig_msvc_atomic_barrier()
|
||||
#endif
|
||||
|
||||
// TODO: _MSC_VER && (_M_ARM || _M_ARM64)
|
||||
#else
|
||||
#define memory_order_relaxed 0
|
||||
@@ -1214,8 +1229,14 @@ typedef struct { zig_align(16) zig_i64 hi; zig_u64 lo; } zig_i128;
|
||||
|
||||
#define zig_as_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) })
|
||||
#define zig_as_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) })
|
||||
|
||||
#if _MSC_VER
|
||||
#define zig_as_constant_u128(hi, lo) { .h##i = (hi), .l##o = (lo) }
|
||||
#define zig_as_constant_i128(hi, lo) { .h##i = (hi), .l##o = (lo) }
|
||||
#else
|
||||
#define zig_as_constant_u128(hi, lo) zig_as_u128(hi, lo)
|
||||
#define zig_as_constant_i128(hi, lo) zig_as_i128(hi, lo)
|
||||
#endif
|
||||
#define zig_hi_u128(val) ((val).hi)
|
||||
#define zig_lo_u128(val) ((val).lo)
|
||||
#define zig_hi_i128(val) ((val).hi)
|
||||
@@ -1344,13 +1365,13 @@ static inline zig_u128 zig_shr_u128(zig_u128 lhs, zig_u8 rhs) {
|
||||
|
||||
static inline zig_u128 zig_shl_u128(zig_u128 lhs, zig_u8 rhs) {
|
||||
if (rhs == zig_as_u8(0)) return lhs;
|
||||
if (rhs >= zig_as_u8(64)) return (zig_u128){ .hi = lhs.lo << rhs, .lo = zig_minInt_u64 };
|
||||
if (rhs >= zig_as_u8(64)) return (zig_u128){ .hi = lhs.lo << (rhs - zig_as_u8(64)), .lo = zig_minInt_u64 };
|
||||
return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (zig_as_u8(64) - rhs), .lo = lhs.lo << rhs };
|
||||
}
|
||||
|
||||
static inline zig_i128 zig_shl_i128(zig_i128 lhs, zig_u8 rhs) {
|
||||
if (rhs == zig_as_u8(0)) return lhs;
|
||||
if (rhs >= zig_as_u8(64)) return (zig_i128){ .hi = lhs.lo << rhs, .lo = zig_minInt_u64 };
|
||||
if (rhs >= zig_as_u8(64)) return (zig_i128){ .hi = lhs.lo << (rhs - zig_as_u8(64)), .lo = zig_minInt_u64 };
|
||||
return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (zig_as_u8(64) - rhs), .lo = lhs.lo << rhs };
|
||||
}
|
||||
|
||||
@@ -1379,6 +1400,10 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {
|
||||
}
|
||||
|
||||
zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs);
|
||||
static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
|
||||
return zig_bitcast_u128(__multi3(zig_bitcast_i128(lhs), zig_bitcast_i128(rhs)));
|
||||
}
|
||||
|
||||
static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
|
||||
return __multi3(lhs, rhs);
|
||||
}
|
||||
@@ -1474,17 +1499,6 @@ static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
|
||||
return zig_wrap_i128(zig_bitcast_i128(zig_sub_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);
|
||||
}
|
||||
|
||||
#if _MSC_VER
|
||||
static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
|
||||
zig_u64 lo_carry;
|
||||
zig_u64 lo = _umul128(lhs.lo, rhs.lo, &lo_carry);
|
||||
zig_u64 hi = lhs.hi * rhs.lo + lhs.lo * rhs.hi + lo_carry;
|
||||
return zig_as_u128(hi, lo);
|
||||
}
|
||||
#else
|
||||
static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs); // TODO
|
||||
#endif
|
||||
|
||||
static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
|
||||
return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits);
|
||||
}
|
||||
@@ -1857,10 +1871,13 @@ typedef zig_i32 zig_f32;
|
||||
#define zig_bitSizeOf_f64 64
|
||||
#define zig_libc_name_f64(name) name
|
||||
#if _MSC_VER
|
||||
#define zig_as_special_constant_f64(sign, name, arg, repr) sign zig_as_f64(zig_msvc_flt_##name, )
|
||||
#else
|
||||
#define zig_as_special_constant_f64(sign, name, arg, repr) zig_as_special_f64(sign, name, arg, repr)
|
||||
#ifdef ZIG_TARGET_ABI_MSVC
|
||||
#define zig_bitSizeOf_c_longdouble 64
|
||||
#endif
|
||||
#define zig_as_special_constant_f64(sign, name, arg, repr) sign zig_as_f64(zig_msvc_flt_##name, )
|
||||
#else /* _MSC_VER */
|
||||
#define zig_as_special_constant_f64(sign, name, arg, repr) zig_as_special_f64(sign, name, arg, repr)
|
||||
#endif /* _MSC_VER */
|
||||
#if FLT_MANT_DIG == 53
|
||||
typedef float zig_f64;
|
||||
#define zig_as_f64(fp, repr) fp##f
|
||||
@@ -1962,16 +1979,32 @@ typedef zig_i128 zig_f128;
|
||||
#endif
|
||||
|
||||
#define zig_has_c_longdouble 1
|
||||
|
||||
#ifdef ZIG_TARGET_ABI_MSVC
|
||||
#define zig_libc_name_c_longdouble(name) name
|
||||
#else
|
||||
#define zig_libc_name_c_longdouble(name) name##l
|
||||
#endif
|
||||
|
||||
#define zig_as_special_constant_c_longdouble(sign, name, arg, repr) zig_as_special_c_longdouble(sign, name, arg, repr)
|
||||
#ifdef zig_bitSizeOf_c_longdouble
|
||||
|
||||
#ifdef ZIG_TARGET_ABI_MSVC
|
||||
typedef double zig_c_longdouble;
|
||||
#undef zig_bitSizeOf_c_longdouble
|
||||
#define zig_bitSizeOf_c_longdouble 64
|
||||
#define zig_as_c_longdouble(fp, repr) fp
|
||||
#else
|
||||
typedef long double zig_c_longdouble;
|
||||
#define zig_as_c_longdouble(fp, repr) fp##l
|
||||
#else
|
||||
#endif
|
||||
|
||||
#else /* zig_bitSizeOf_c_longdouble */
|
||||
|
||||
#undef zig_has_c_longdouble
|
||||
#define zig_has_c_longdouble 0
|
||||
#define zig_bitSizeOf_c_longdouble 80
|
||||
#define zig_compiler_rt_abbrev_c_longdouble zig_compiler_rt_abbrev_f80
|
||||
#define zig_has_c_longdouble 0
|
||||
#define zig_repr_c_longdouble i128
|
||||
typedef zig_i128 zig_c_longdouble;
|
||||
#define zig_as_c_longdouble(fp, repr) repr
|
||||
@@ -1979,19 +2012,26 @@ typedef zig_i128 zig_c_longdouble;
|
||||
#define zig_as_special_c_longdouble(sign, name, arg, repr) repr
|
||||
#undef zig_as_special_constant_c_longdouble
|
||||
#define zig_as_special_constant_c_longdouble(sign, name, arg, repr) repr
|
||||
#endif
|
||||
|
||||
#endif /* zig_bitSizeOf_c_longdouble */
|
||||
|
||||
#if !zig_has_float_builtins
|
||||
#define zig_float_from_repr(Type, ReprType) \
|
||||
static inline zig_##Type zig_float_from_repr_##Type(zig_##ReprType repr) { \
|
||||
return *((zig_##Type*)&repr); \
|
||||
}
|
||||
|
||||
zig_float_from_repr(f16, u16)
|
||||
zig_float_from_repr(f32, u32)
|
||||
zig_float_from_repr(f64, u64)
|
||||
zig_float_from_repr(f80, u128)
|
||||
zig_float_from_repr(f128, u128)
|
||||
#if zig_bitSizeOf_c_longdouble == 80
|
||||
zig_float_from_repr(c_longdouble, u128)
|
||||
#else
|
||||
#define zig_expand_float_from_repr(Type, ReprType) zig_float_from_repr(Type, ReprType)
|
||||
zig_expand_float_from_repr(c_longdouble, zig_expand_concat(u, zig_bitSizeOf_c_longdouble))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define zig_cast_f16 (zig_f16)
|
||||
@@ -2218,8 +2258,11 @@ zig_msvc_atomics(u16, 16)
|
||||
zig_msvc_atomics(i16, 16)
|
||||
zig_msvc_atomics(u32, )
|
||||
zig_msvc_atomics(i32, )
|
||||
|
||||
#if _M_X64
|
||||
zig_msvc_atomics(u64, 64)
|
||||
zig_msvc_atomics(i64, 64)
|
||||
#endif
|
||||
|
||||
#define zig_msvc_flt_atomics(Type, ReprType, suffix) \
|
||||
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)
|
||||
}
|
||||
|
||||
zig_msvc_flt_atomics(f32, u32, )
|
||||
#if _M_X64
|
||||
zig_msvc_flt_atomics(f64, u64, 64)
|
||||
#endif
|
||||
|
||||
#if _M_IX86
|
||||
static inline void zig_msvc_atomic_barrier() {
|
||||
zig_i32 barrier;
|
||||
__asm {
|
||||
xchg barrier, eax
|
||||
}
|
||||
}
|
||||
|
||||
static inline void* zig_msvc_atomicrmw_xchg_p32(void** obj, zig_u32* arg) {
|
||||
return _InterlockedExchangePointer(obj, arg);
|
||||
}
|
||||
@@ -2270,7 +2322,7 @@ static inline void zig_msvc_atomic_store_p32(void** obj, zig_u32* arg) {
|
||||
_InterlockedExchangePointer(obj, arg);
|
||||
}
|
||||
|
||||
static inline void* zig_msvc_atomic_load_p32(void** obj, zig_u32* arg) {
|
||||
static inline void* zig_msvc_atomic_load_p32(void** obj) {
|
||||
return (void*)_InterlockedOr((void*)obj, 0);
|
||||
}
|
||||
|
||||
@@ -2283,7 +2335,7 @@ static inline bool zig_msvc_cmpxchg_p32(void** obj, void** expected, void* desir
|
||||
}
|
||||
return exchanged;
|
||||
}
|
||||
#else
|
||||
#else /* _M_IX86 */
|
||||
static inline void* zig_msvc_atomicrmw_xchg_p64(void** obj, zig_u64* arg) {
|
||||
return _InterlockedExchangePointer(obj, arg);
|
||||
}
|
||||
@@ -2305,7 +2357,6 @@ static inline bool zig_msvc_cmpxchg_p64(void** obj, void** expected, void* desir
|
||||
}
|
||||
return exchanged;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expected, zig_u128 desired) {
|
||||
return _InterlockedCompareExchange128((zig_i64 volatile*)obj, desired.hi, desired.lo, (zig_i64*)expected);
|
||||
@@ -2350,6 +2401,7 @@ zig_msvc_atomics_128op(u128, and)
|
||||
zig_msvc_atomics_128op(u128, nand)
|
||||
zig_msvc_atomics_128op(u128, min)
|
||||
zig_msvc_atomics_128op(u128, max)
|
||||
#endif /* _M_IX86 */
|
||||
|
||||
#endif /* _MSC_VER && (_M_IX86 || _M_X64) */
|
||||
|
||||
@@ -2359,7 +2411,7 @@ zig_msvc_atomics_128op(u128, max)
|
||||
|
||||
static inline void* zig_x86_64_windows_teb(void) {
|
||||
#if _MSC_VER
|
||||
return __readgsqword(0x30);
|
||||
return (void*)__readgsqword(0x30);
|
||||
#else
|
||||
void* teb;
|
||||
__asm volatile(" movq %%gs:0x30, %[ptr]": [ptr]"=r"(teb)::);
|
||||
@@ -2367,6 +2419,18 @@ static inline void* zig_x86_64_windows_teb(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif (_MSC_VER && _M_IX86) || defined(__i386__) || defined(__X86__)
|
||||
|
||||
static inline void* zig_x86_windows_teb(void) {
|
||||
#if _MSC_VER
|
||||
return (void*)__readfsdword(0x18);
|
||||
#else
|
||||
void* teb;
|
||||
__asm volatile(" movl %%fs:0x18, %[ptr]": [ptr]"=r"(teb)::);
|
||||
return teb;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (_MSC_VER && (_M_IX86 || _M_X64)) || defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
@@ -1459,7 +1459,12 @@ pub const DeclGen = struct {
|
||||
|
||||
fn renderFunctionSignature(dg: *DeclGen, w: anytype, kind: TypedefKind, export_index: u32) !void {
|
||||
const fn_info = dg.decl.ty.fnInfo();
|
||||
if (fn_info.cc == .Naked) try w.writeAll("zig_naked ");
|
||||
if (fn_info.cc == .Naked) {
|
||||
switch (kind) {
|
||||
.Forward => try w.writeAll("zig_naked_decl "),
|
||||
.Complete => try w.writeAll("zig_naked "),
|
||||
}
|
||||
}
|
||||
if (dg.decl.val.castTag(.function)) |func_payload|
|
||||
if (func_payload.data.is_cold) try w.writeAll("zig_cold ");
|
||||
|
||||
@@ -1469,6 +1474,13 @@ pub const DeclGen = struct {
|
||||
|
||||
try dg.renderType(w, ret_ty, kind);
|
||||
try w.writeByte(' ');
|
||||
|
||||
if (toCallingConvention(fn_info.cc)) |call_conv| {
|
||||
try w.print("zig_callconv({s}) ", .{call_conv});
|
||||
}
|
||||
|
||||
if (fn_info.alignment > 0 and kind == .Complete) try w.print(" zig_align_fn({})", .{fn_info.alignment});
|
||||
|
||||
try dg.renderDeclName(w, dg.decl_index, export_index);
|
||||
try w.writeByte('(');
|
||||
|
||||
@@ -1488,7 +1500,7 @@ pub const DeclGen = struct {
|
||||
try dg.renderType(w, Type.void, kind);
|
||||
}
|
||||
try w.writeByte(')');
|
||||
if (fn_info.alignment > 0) try w.print(" zig_align_fn({})", .{fn_info.alignment});
|
||||
if (fn_info.alignment > 0 and kind == .Forward) try w.print(" zig_align_fn({})", .{fn_info.alignment});
|
||||
}
|
||||
|
||||
fn renderPtrToFnTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
|
||||
@@ -7035,6 +7047,15 @@ fn writeMemoryOrder(w: anytype, order: std.builtin.AtomicOrder) !void {
|
||||
return w.writeAll(toMemoryOrder(order));
|
||||
}
|
||||
|
||||
fn toCallingConvention(call_conv: std.builtin.CallingConvention) ?[]const u8 {
|
||||
return switch (call_conv) {
|
||||
.Stdcall => "stdcall",
|
||||
.Fastcall => "fastcall",
|
||||
.Vectorcall => "vectorcall",
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
fn toAtomicRmwSuffix(order: std.builtin.AtomicRmwOp) []const u8 {
|
||||
return switch (order) {
|
||||
.Xchg => "xchg",
|
||||
|
||||
@@ -231,6 +231,13 @@ pub fn flush(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void
|
||||
return self.flushModule(comp, prog_node);
|
||||
}
|
||||
|
||||
fn abiDefine(comp: *Compilation) ?[]const u8 {
|
||||
return switch (comp.getTarget().abi) {
|
||||
.msvc => "#define ZIG_TARGET_ABI_MSVC\n",
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
@@ -248,9 +255,14 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
|
||||
var f: Flush = .{};
|
||||
defer f.deinit(gpa);
|
||||
|
||||
// Covers zig.h, typedef, and asm.
|
||||
try f.all_buffers.ensureUnusedCapacity(gpa, 2);
|
||||
const abi_define = abiDefine(comp);
|
||||
|
||||
// Covers defines, zig.h, typedef, and asm.
|
||||
var buf_count: usize = 2;
|
||||
if (abi_define != null) buf_count += 1;
|
||||
try f.all_buffers.ensureUnusedCapacity(gpa, buf_count);
|
||||
|
||||
if (abi_define) |buf| f.appendBufAssumeCapacity(buf);
|
||||
f.appendBufAssumeCapacity(zig_h);
|
||||
|
||||
const typedef_index = f.all_buffers.items.len;
|
||||
|
||||
BIN
stage1/zig1.wasm
BIN
stage1/zig1.wasm
Binary file not shown.
@@ -104,7 +104,18 @@ test "alignment and size of structs with 128-bit fields" {
|
||||
.u129_size = 24,
|
||||
},
|
||||
|
||||
.x86 => switch (builtin.os.tag) {
|
||||
.x86 => if (builtin.object_format == .c) .{
|
||||
.a_align = 16,
|
||||
.a_size = 16,
|
||||
|
||||
.b_align = 16,
|
||||
.b_size = 32,
|
||||
|
||||
.u128_align = 16,
|
||||
.u128_size = 16,
|
||||
.u129_align = 16,
|
||||
.u129_size = 32,
|
||||
} else switch (builtin.os.tag) {
|
||||
.windows => .{
|
||||
.a_align = 8,
|
||||
.a_size = 16,
|
||||
|
||||
@@ -84,3 +84,31 @@ test "truncate int128" {
|
||||
try expect(@truncate(i128, buff) == maxInt(i128));
|
||||
}
|
||||
}
|
||||
|
||||
test "shift int128" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
const types = .{ u128, i128 };
|
||||
inline for (types) |t| {
|
||||
try testShlTrunc(t, 0x8, 123);
|
||||
comptime try testShlTrunc(t, 0x8, 123);
|
||||
|
||||
try testShlTrunc(t, 0x40000000_00000000, 64);
|
||||
comptime try testShlTrunc(t, 0x40000000_00000000, 64);
|
||||
|
||||
try testShlTrunc(t, 0x01000000_00000000_00000000, 38);
|
||||
comptime try testShlTrunc(t, 0x01000000_00000000_00000000, 38);
|
||||
|
||||
try testShlTrunc(t, 0x00000008_00000000_00000000_00000000, 27);
|
||||
comptime try testShlTrunc(t, 0x00000008_00000000_00000000_00000000, 27);
|
||||
}
|
||||
}
|
||||
|
||||
fn testShlTrunc(comptime Type: type, x: Type, rhs: u7) !void {
|
||||
const shifted = x << rhs;
|
||||
try expect(shifted == @as(Type, 0x40000000_00000000_00000000_00000000));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user