zig.h: Improve portability of zig_*_windows_teb() helpers.

* Make it work for thumb and aarch64.
* Clean up std.os.windows.teb() a bit.

I also updated stage1/zig.h since the changes are backwards-compatible and are
necessary due to the std.os.windows changes that call the newly-added functions.
This commit is contained in:
Alex Rønne Petersen 2024-11-03 13:36:11 +01:00
parent 814a41b48f
commit 6b2c8fc688
3 changed files with 108 additions and 58 deletions

View File

@ -2101,39 +2101,41 @@ pub fn UnlockFile(
/// This is a workaround for the C backend until zig has the ability to put /// This is a workaround for the C backend until zig has the ability to put
/// C code in inline assembly. /// C code in inline assembly.
extern fn zig_thumb_windows_teb() callconv(.c) *anyopaque;
extern fn zig_aarch64_windows_teb() callconv(.c) *anyopaque;
extern fn zig_x86_windows_teb() callconv(.c) *anyopaque; extern fn zig_x86_windows_teb() callconv(.c) *anyopaque;
extern fn zig_x86_64_windows_teb() callconv(.c) *anyopaque; extern fn zig_x86_64_windows_teb() callconv(.c) *anyopaque;
pub fn teb() *TEB { pub fn teb() *TEB {
return switch (native_arch) { return switch (native_arch) {
.x86 => blk: { .thumb => if (builtin.zig_backend == .stage2_c)
if (builtin.zig_backend == .stage2_c) { @ptrCast(@alignCast(zig_thumb_windows_teb()))
break :blk @ptrCast(@alignCast(zig_x86_windows_teb())); else
} else { asm (
break :blk asm ( \\ mrc p15, 0, %[ptr], c13, c0, 2
\\ movl %%fs:0x18, %[ptr] : [ptr] "=r" (-> *TEB),
: [ptr] "=r" (-> *TEB), ),
); .aarch64 => if (builtin.zig_backend == .stage2_c)
} @ptrCast(@alignCast(zig_aarch64_windows_teb()))
}, else
.x86_64 => blk: { asm (
if (builtin.zig_backend == .stage2_c) { \\ mov %[ptr], x18
break :blk @ptrCast(@alignCast(zig_x86_64_windows_teb())); : [ptr] "=r" (-> *TEB),
} else { ),
break :blk asm ( .x86 => if (builtin.zig_backend == .stage2_c)
\\ movq %%gs:0x30, %[ptr] @ptrCast(@alignCast(zig_x86_windows_teb()))
: [ptr] "=r" (-> *TEB), else
); asm (
} \\ movl %%fs:0x18, %[ptr]
}, : [ptr] "=r" (-> *TEB),
.thumb => asm ( ),
\\ mrc p15, 0, %[ptr], c13, c0, 2 .x86_64 => if (builtin.zig_backend == .stage2_c)
: [ptr] "=r" (-> *TEB), @ptrCast(@alignCast(zig_x86_64_windows_teb()))
), else
.aarch64 => asm ( asm (
\\ mov %[ptr], x18 \\ movq %%gs:0x30, %[ptr]
: [ptr] "=r" (-> *TEB), : [ptr] "=r" (-> *TEB),
), ),
else => @compileError("unsupported arch"), else => @compileError("unsupported arch"),
}; };
} }

View File

@ -3926,28 +3926,52 @@ static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 a
/* ======================== Special Case Intrinsics ========================= */ /* ======================== Special Case Intrinsics ========================= */
#if (_MSC_VER && _M_X64) || defined(__x86_64__) #if defined(_M_ARM) || defined(__thumb__)
static inline void* zig_x86_64_windows_teb(void) { static inline void* zig_thumb_windows_teb(void) {
#if _MSC_VER void* teb = 0;
return (void*)__readgsqword(0x30); #if defined(_MSC_VER)
#else teb = (void*)_MoveFromCoprocessor(15, 0, 13, 0, 2);
void* teb; #elif defined(__GNUC__)
__asm volatile(" movq %%gs:0x30, %[ptr]": [ptr]"=r"(teb)::); __asm__ ("mrc p15, 0, %[ptr], c13, c0, 2" : [ptr] "=r" (teb));
return teb;
#endif #endif
return teb;
} }
#elif (_MSC_VER && _M_IX86) || defined(__i386__) || defined(__X86__) #elif defined(_M_ARM64) || defined(__arch64__)
static inline void* zig_aarch64_windows_teb(void) {
void* teb = 0;
#if defined(_MSC_VER)
teb = (void*)__readx18qword(0x0);
#elif defined(__GNUC__)
__asm__ ("mov %[ptr], x18" : [ptr] "=r" (teb));
#endif
return teb;
}
#elif defined(_M_IX86) || defined(__i386__)
static inline void* zig_x86_windows_teb(void) { static inline void* zig_x86_windows_teb(void) {
#if _MSC_VER void* teb = 0;
return (void*)__readfsdword(0x18); #if defined(_MSC_VER)
#else teb = (void*)__readfsdword(0x18);
void* teb; #elif defined(__GNUC__)
__asm volatile(" movl %%fs:0x18, %[ptr]": [ptr]"=r"(teb)::); __asm__ ("movl %%fs:0x18, %[ptr]" : [ptr] "=r" (teb));
return teb;
#endif #endif
return teb;
}
#elif defined(_M_X64) || defined(__x86_64__)
static inline void* zig_x86_64_windows_teb(void) {
void* teb = 0;
#if defined(_MSC_VER)
teb = (void*)__readgsqword(0x30);
#elif defined(__GNUC__)
__asm__ ("movq %%gs:0x30, %[ptr]" : [ptr] "=r" (teb));
#endif
return teb;
} }
#endif #endif

View File

@ -3926,28 +3926,52 @@ static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 a
/* ======================== Special Case Intrinsics ========================= */ /* ======================== Special Case Intrinsics ========================= */
#if (_MSC_VER && _M_X64) || defined(__x86_64__) #if defined(_M_ARM) || defined(__thumb__)
static inline void* zig_x86_64_windows_teb(void) { static inline void* zig_thumb_windows_teb(void) {
#if _MSC_VER void* teb = 0;
return (void*)__readgsqword(0x30); #if defined(_MSC_VER)
#else teb = (void*)_MoveFromCoprocessor(15, 0, 13, 0, 2);
void* teb; #elif defined(__GNUC__)
__asm volatile(" movq %%gs:0x30, %[ptr]": [ptr]"=r"(teb)::); __asm__ ("mrc p15, 0, %[ptr], c13, c0, 2" : [ptr] "=r" (teb));
return teb;
#endif #endif
return teb;
} }
#elif (_MSC_VER && _M_IX86) || defined(__i386__) || defined(__X86__) #elif defined(_M_ARM64) || defined(__arch64__)
static inline void* zig_aarch64_windows_teb(void) {
void* teb = 0;
#if defined(_MSC_VER)
teb = (void*)__readx18qword(0x0);
#elif defined(__GNUC__)
__asm__ ("mov %[ptr], x18" : [ptr] "=r" (teb));
#endif
return teb;
}
#elif defined(_M_IX86) || defined(__i386__)
static inline void* zig_x86_windows_teb(void) { static inline void* zig_x86_windows_teb(void) {
#if _MSC_VER void* teb = 0;
return (void*)__readfsdword(0x18); #if defined(_MSC_VER)
#else teb = (void*)__readfsdword(0x18);
void* teb; #elif defined(__GNUC__)
__asm volatile(" movl %%fs:0x18, %[ptr]": [ptr]"=r"(teb)::); __asm__ ("movl %%fs:0x18, %[ptr]" : [ptr] "=r" (teb));
return teb;
#endif #endif
return teb;
}
#elif defined(_M_X64) || defined(__x86_64__)
static inline void* zig_x86_64_windows_teb(void) {
void* teb = 0;
#if defined(_MSC_VER)
teb = (void*)__readgsqword(0x30);
#elif defined(__GNUC__)
__asm__ ("movq %%gs:0x30, %[ptr]" : [ptr] "=r" (teb));
#endif
return teb;
} }
#endif #endif