| author | |
| committer | |
| log | ccf0ab0ef6da95eae71c0dbc2c0ded0d5d674a40 |
| tree | 9462718b2a43264a5634e97db8983e11151141f0 |
| parent | 9c70315854735ab9ecd572e327f41ea547033f09 |
3 files changed, 19 insertions(+), 17 deletions(-)
lib/std/os/windows.zig+3-15| ... | ... | @@ -1776,6 +1776,8 @@ pub fn UnlockFile( |
| 1776 | 1776 | } |
| 1777 | 1777 | } |
| 1778 | 1778 | |
| 1779 | extern fn zig_x86_64_windows_teb() callconv(.C) *anyopaque; | |
| 1780 | ||
| 1779 | 1781 | pub fn teb() *TEB { |
| 1780 | 1782 | return switch (native_arch) { |
| 1781 | 1783 | .x86 => asm volatile ( |
| ... | ... | @@ -1784,21 +1786,7 @@ pub fn teb() *TEB { |
| 1784 | 1786 | ), |
| 1785 | 1787 | .x86_64 => blk: { |
| 1786 | 1788 | if (builtin.zig_backend == .stage2_c) { |
| 1787 | // TODO: __asm is not available on x64 MSVC. This is a workaround | |
| 1788 | // until an intrinsic to read the gs register is available | |
| 1789 | var thread_information: THREAD_BASIC_INFORMATION = undefined; | |
| 1790 | const result = ntdll.NtQueryInformationThread( | |
| 1791 | kernel32.GetCurrentThread(), | |
| 1792 | .ThreadBasicInformation, | |
| 1793 | &thread_information, | |
| 1794 | @sizeOf(THREAD_BASIC_INFORMATION), | |
| 1795 | null); | |
| 1796 | ||
| 1797 | if (result == .SUCCESS) { | |
| 1798 | break :blk @ptrCast(*TEB, @alignCast(@alignOf(TEB), thread_information.TebBaseAddress)); | |
| 1799 | } else { | |
| 1800 | unexpectedStatus(result) catch unreachable; | |
| 1801 | } | |
| 1789 | break :blk @ptrCast(*TEB, @alignCast(@alignOf(TEB), zig_x86_64_windows_teb())); | |
| 1802 | 1790 | } else { |
| 1803 | 1791 | break :blk asm volatile ( |
| 1804 | 1792 | \\ movq %%gs:0x30, %[ptr] |
lib/std/zig/system/x86.zig+2-2| ... | ... | @@ -528,7 +528,7 @@ const CpuidLeaf = packed struct { |
| 528 | 528 | edx: u32, |
| 529 | 529 | }; |
| 530 | 530 | |
| 531 | extern fn zig_x86_cpuid(leaf_id: u32, subid: u32, eax: *u32, ebx: *u32, ecx: *u32, edx: *u32) void; | |
| 531 | extern fn zig_x86_cpuid(leaf_id: u32, subid: u32, eax: *u32, ebx: *u32, ecx: *u32, edx: *u32) callconv(.C) void; | |
| 532 | 532 | |
| 533 | 533 | fn cpuid(leaf_id: u32, subid: u32) CpuidLeaf { |
| 534 | 534 | // valid for both x86 and x86_64 |
| ... | ... | @@ -553,7 +553,7 @@ fn cpuid(leaf_id: u32, subid: u32) CpuidLeaf { |
| 553 | 553 | return .{ .eax = eax, .ebx = ebx, .ecx = ecx, .edx = edx }; |
| 554 | 554 | } |
| 555 | 555 | |
| 556 | extern fn zig_x86_get_xcr0() u32; | |
| 556 | extern fn zig_x86_get_xcr0() callconv(.C) u32; | |
| 557 | 557 | |
| 558 | 558 | // Read control register 0 (XCR0). Used to detect features such as AVX. |
| 559 | 559 | fn getXCR0() u32 { |
lib/zig.h+14| ... | ... | @@ -2349,6 +2349,20 @@ zig_msvc_atomics_128op(u128, max) |
| 2349 | 2349 | |
| 2350 | 2350 | /* ========================= Special Case Intrinsics ========================= */ |
| 2351 | 2351 | |
| 2352 | #if (_MSC_VER && _M_X64) || defined(__x86_64__) | |
| 2353 | ||
| 2354 | static inline void* zig_x86_64_windows_teb() { | |
| 2355 | #if _MSC_VER | |
| 2356 | return __readgsqword(0x30); | |
| 2357 | #else | |
| 2358 | void* teb; | |
| 2359 | __asm volatile(" movq %%gs:0x30, %[ptr]": [ptr]"=r"(teb)::); | |
| 2360 | return teb; | |
| 2361 | #endif | |
| 2362 | } | |
| 2363 | ||
| 2364 | #endif | |
| 2365 | ||
| 2352 | 2366 | #if (_MSC_VER && (_M_IX86 || _M_X64)) || defined(__i386__) || defined(__x86_64__) |
| 2353 | 2367 | |
| 2354 | 2368 | 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) { |