From ccf0ab0ef6da95eae71c0dbc2c0ded0d5d674a40 Mon Sep 17 00:00:00 2001 From: kcbanner Date: Thu, 29 Dec 2022 16:41:48 -0500 Subject: cbe: use callconv(.C) for zig.g stub functions, use zig.h function for windows teb instead of syscall --- lib/std/os/windows.zig | 18 +++--------------- lib/std/zig/system/x86.zig | 4 ++-- lib/zig.h | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index efd7c805cf..268e13a379 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -1776,6 +1776,8 @@ pub fn UnlockFile( } } +extern fn zig_x86_64_windows_teb() callconv(.C) *anyopaque; + pub fn teb() *TEB { return switch (native_arch) { .x86 => asm volatile ( @@ -1784,21 +1786,7 @@ pub fn teb() *TEB { ), .x86_64 => blk: { if (builtin.zig_backend == .stage2_c) { - // TODO: __asm is not available on x64 MSVC. This is a workaround - // until an intrinsic to read the gs register is available - var thread_information: THREAD_BASIC_INFORMATION = undefined; - const result = ntdll.NtQueryInformationThread( - kernel32.GetCurrentThread(), - .ThreadBasicInformation, - &thread_information, - @sizeOf(THREAD_BASIC_INFORMATION), - null); - - if (result == .SUCCESS) { - break :blk @ptrCast(*TEB, @alignCast(@alignOf(TEB), thread_information.TebBaseAddress)); - } else { - unexpectedStatus(result) catch unreachable; - } + break :blk @ptrCast(*TEB, @alignCast(@alignOf(TEB), zig_x86_64_windows_teb())); } else { break :blk asm volatile ( \\ movq %%gs:0x30, %[ptr] diff --git a/lib/std/zig/system/x86.zig b/lib/std/zig/system/x86.zig index 9a9aa54975..634a04fb43 100644 --- a/lib/std/zig/system/x86.zig +++ b/lib/std/zig/system/x86.zig @@ -528,7 +528,7 @@ const CpuidLeaf = packed struct { edx: u32, }; -extern fn zig_x86_cpuid(leaf_id: u32, subid: u32, eax: *u32, ebx: *u32, ecx: *u32, edx: *u32) void; +extern fn zig_x86_cpuid(leaf_id: u32, subid: u32, eax: *u32, ebx: *u32, ecx: *u32, edx: *u32) callconv(.C) void; fn cpuid(leaf_id: u32, subid: u32) CpuidLeaf { // valid for both x86 and x86_64 @@ -553,7 +553,7 @@ fn cpuid(leaf_id: u32, subid: u32) CpuidLeaf { return .{ .eax = eax, .ebx = ebx, .ecx = ecx, .edx = edx }; } -extern fn zig_x86_get_xcr0() u32; +extern fn zig_x86_get_xcr0() callconv(.C) u32; // Read control register 0 (XCR0). Used to detect features such as AVX. fn getXCR0() u32 { diff --git a/lib/zig.h b/lib/zig.h index 645850aa0e..d54ad285d6 100644 --- a/lib/zig.h +++ b/lib/zig.h @@ -2349,6 +2349,20 @@ zig_msvc_atomics_128op(u128, max) /* ========================= Special Case Intrinsics ========================= */ +#if (_MSC_VER && _M_X64) || defined(__x86_64__) + +static inline void* zig_x86_64_windows_teb() { +#if _MSC_VER + return __readgsqword(0x30); +#else + void* teb; + __asm volatile(" movq %%gs:0x30, %[ptr]": [ptr]"=r"(teb)::); + return teb; +#endif +} + +#endif + #if (_MSC_VER && (_M_IX86 || _M_X64)) || defined(__i386__) || defined(__x86_64__) static inline void zig_x86_cpuid(zig_u32 leaf_id, zig_u32 subid, zig_u32* eax, zig_u32* ebx, zig_u32* ecx, zig_u32* edx) { -- cgit v1.2.3