authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-03 13:36:11+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-04 11:59:38+01:00
log6b2c8fc6886cdf251146aa3674e87f6ca3111e24
treec50ecbbf8651c996e79299cee58cea55e225fe05
parent814a41b48f157fff1f48c4a14e92142d1e6e5748

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.

3 files changed, 104 insertions(+), 54 deletions(-)

lib/std/os/windows.zig+30-28
...@@ -2101,39 +2101,41 @@ pub fn UnlockFile(...@@ -2101,39 +2101,41 @@ pub fn UnlockFile(
21012101
2102/// This is a workaround for the C backend until zig has the ability to put2102/// This is a workaround for the C backend until zig has the ability to put
2103/// C code in inline assembly.2103/// C code in inline assembly.
2104extern fn zig_thumb_windows_teb() callconv(.c) *anyopaque;
2105extern fn zig_aarch64_windows_teb() callconv(.c) *anyopaque;
2104extern fn zig_x86_windows_teb() callconv(.c) *anyopaque;2106extern fn zig_x86_windows_teb() callconv(.c) *anyopaque;
2105extern fn zig_x86_64_windows_teb() callconv(.c) *anyopaque;2107extern fn zig_x86_64_windows_teb() callconv(.c) *anyopaque;
21062108
2107pub fn teb() *TEB {2109pub fn teb() *TEB {
2108 return switch (native_arch) {2110 return switch (native_arch) {
2109 .x86 => blk: {2111 .thumb => if (builtin.zig_backend == .stage2_c)
2110 if (builtin.zig_backend == .stage2_c) {2112 @ptrCast(@alignCast(zig_thumb_windows_teb()))
2111 break :blk @ptrCast(@alignCast(zig_x86_windows_teb()));2113 else
2112 } else {2114 asm (
2113 break :blk asm (2115 \\ mrc p15, 0, %[ptr], c13, c0, 2
2114 \\ movl %%fs:0x18, %[ptr]2116 : [ptr] "=r" (-> *TEB),
2115 : [ptr] "=r" (-> *TEB),2117 ),
2116 );2118 .aarch64 => if (builtin.zig_backend == .stage2_c)
2117 }2119 @ptrCast(@alignCast(zig_aarch64_windows_teb()))
2118 },2120 else
2119 .x86_64 => blk: {2121 asm (
2120 if (builtin.zig_backend == .stage2_c) {2122 \\ mov %[ptr], x18
2121 break :blk @ptrCast(@alignCast(zig_x86_64_windows_teb()));2123 : [ptr] "=r" (-> *TEB),
2122 } else {2124 ),
2123 break :blk asm (2125 .x86 => if (builtin.zig_backend == .stage2_c)
2124 \\ movq %%gs:0x30, %[ptr]2126 @ptrCast(@alignCast(zig_x86_windows_teb()))
2125 : [ptr] "=r" (-> *TEB),2127 else
2126 );2128 asm (
2127 }2129 \\ movl %%fs:0x18, %[ptr]
2128 },2130 : [ptr] "=r" (-> *TEB),
2129 .thumb => asm (2131 ),
2130 \\ mrc p15, 0, %[ptr], c13, c0, 22132 .x86_64 => if (builtin.zig_backend == .stage2_c)
2131 : [ptr] "=r" (-> *TEB),2133 @ptrCast(@alignCast(zig_x86_64_windows_teb()))
2132 ),2134 else
2133 .aarch64 => asm (2135 asm (
2134 \\ mov %[ptr], x182136 \\ movq %%gs:0x30, %[ptr]
2135 : [ptr] "=r" (-> *TEB),2137 : [ptr] "=r" (-> *TEB),
2136 ),2138 ),
2137 else => @compileError("unsupported arch"),2139 else => @compileError("unsupported arch"),
2138 };2140 };
2139}2141}
lib/zig.h+37-13
...@@ -3926,28 +3926,52 @@ static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 a...@@ -3926,28 +3926,52 @@ static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 a
39263926
3927/* ======================== Special Case Intrinsics ========================= */3927/* ======================== Special Case Intrinsics ========================= */
39283928
3929#if (_MSC_VER && _M_X64) || defined(__x86_64__)3929#if defined(_M_ARM) || defined(__thumb__)
39303930
3931static inline void* zig_x86_64_windows_teb(void) {3931static inline void* zig_thumb_windows_teb(void) {
3932#if _MSC_VER3932 void* teb = 0;
3933 return (void*)__readgsqword(0x30);3933#if defined(_MSC_VER)
3934#else3934 teb = (void*)_MoveFromCoprocessor(15, 0, 13, 0, 2);
3935 void* teb;3935#elif defined(__GNUC__)
3936 __asm volatile(" movq %%gs:0x30, %[ptr]": [ptr]"=r"(teb)::);3936 __asm__ ("mrc p15, 0, %[ptr], c13, c0, 2" : [ptr] "=r" (teb));
3937#endif
3937 return teb;3938 return teb;
3939}
3940
3941#elif defined(_M_ARM64) || defined(__arch64__)
3942
3943static inline void* zig_aarch64_windows_teb(void) {
3944 void* teb = 0;
3945#if defined(_MSC_VER)
3946 teb = (void*)__readx18qword(0x0);
3947#elif defined(__GNUC__)
3948 __asm__ ("mov %[ptr], x18" : [ptr] "=r" (teb));
3938#endif3949#endif
3950 return teb;
3939}3951}
39403952
3941#elif (_MSC_VER && _M_IX86) || defined(__i386__) || defined(__X86__)3953#elif defined(_M_IX86) || defined(__i386__)
39423954
3943static inline void* zig_x86_windows_teb(void) {3955static inline void* zig_x86_windows_teb(void) {
3944#if _MSC_VER3956 void* teb = 0;
3945 return (void*)__readfsdword(0x18);3957#if defined(_MSC_VER)
3946#else3958 teb = (void*)__readfsdword(0x18);
3947 void* teb;3959#elif defined(__GNUC__)
3948 __asm volatile(" movl %%fs:0x18, %[ptr]": [ptr]"=r"(teb)::);3960 __asm__ ("movl %%fs:0x18, %[ptr]" : [ptr] "=r" (teb));
3961#endif
3949 return teb;3962 return teb;
3963}
3964
3965#elif defined(_M_X64) || defined(__x86_64__)
3966
3967static inline void* zig_x86_64_windows_teb(void) {
3968 void* teb = 0;
3969#if defined(_MSC_VER)
3970 teb = (void*)__readgsqword(0x30);
3971#elif defined(__GNUC__)
3972 __asm__ ("movq %%gs:0x30, %[ptr]" : [ptr] "=r" (teb));
3950#endif3973#endif
3974 return teb;
3951}3975}
39523976
3953#endif3977#endif
stage1/zig.h+37-13
...@@ -3926,28 +3926,52 @@ static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 a...@@ -3926,28 +3926,52 @@ static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 a
39263926
3927/* ======================== Special Case Intrinsics ========================= */3927/* ======================== Special Case Intrinsics ========================= */
39283928
3929#if (_MSC_VER && _M_X64) || defined(__x86_64__)3929#if defined(_M_ARM) || defined(__thumb__)
39303930
3931static inline void* zig_x86_64_windows_teb(void) {3931static inline void* zig_thumb_windows_teb(void) {
3932#if _MSC_VER3932 void* teb = 0;
3933 return (void*)__readgsqword(0x30);3933#if defined(_MSC_VER)
3934#else3934 teb = (void*)_MoveFromCoprocessor(15, 0, 13, 0, 2);
3935 void* teb;3935#elif defined(__GNUC__)
3936 __asm volatile(" movq %%gs:0x30, %[ptr]": [ptr]"=r"(teb)::);3936 __asm__ ("mrc p15, 0, %[ptr], c13, c0, 2" : [ptr] "=r" (teb));
3937#endif
3937 return teb;3938 return teb;
3939}
3940
3941#elif defined(_M_ARM64) || defined(__arch64__)
3942
3943static inline void* zig_aarch64_windows_teb(void) {
3944 void* teb = 0;
3945#if defined(_MSC_VER)
3946 teb = (void*)__readx18qword(0x0);
3947#elif defined(__GNUC__)
3948 __asm__ ("mov %[ptr], x18" : [ptr] "=r" (teb));
3938#endif3949#endif
3950 return teb;
3939}3951}
39403952
3941#elif (_MSC_VER && _M_IX86) || defined(__i386__) || defined(__X86__)3953#elif defined(_M_IX86) || defined(__i386__)
39423954
3943static inline void* zig_x86_windows_teb(void) {3955static inline void* zig_x86_windows_teb(void) {
3944#if _MSC_VER3956 void* teb = 0;
3945 return (void*)__readfsdword(0x18);3957#if defined(_MSC_VER)
3946#else3958 teb = (void*)__readfsdword(0x18);
3947 void* teb;3959#elif defined(__GNUC__)
3948 __asm volatile(" movl %%fs:0x18, %[ptr]": [ptr]"=r"(teb)::);3960 __asm__ ("movl %%fs:0x18, %[ptr]" : [ptr] "=r" (teb));
3961#endif
3949 return teb;3962 return teb;
3963}
3964
3965#elif defined(_M_X64) || defined(__x86_64__)
3966
3967static inline void* zig_x86_64_windows_teb(void) {
3968 void* teb = 0;
3969#if defined(_MSC_VER)
3970 teb = (void*)__readgsqword(0x30);
3971#elif defined(__GNUC__)
3972 __asm__ ("movq %%gs:0x30, %[ptr]" : [ptr] "=r" (teb));
3950#endif3973#endif
3974 return teb;
3951}3975}
39523976
3953#endif3977#endif