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(
21012101
21022102/// This is a workaround for the C backend until zig has the ability to put
21032103/// C code in inline assembly.
2104extern fn zig_thumb_windows_teb() callconv(.c) *anyopaque;
2105extern fn zig_aarch64_windows_teb() callconv(.c) *anyopaque;
21042106extern fn zig_x86_windows_teb() callconv(.c) *anyopaque;
21052107extern fn zig_x86_64_windows_teb() callconv(.c) *anyopaque;
21062108
21072109pub fn teb() *TEB {
21082110 return switch (native_arch) {
2109 .x86 => blk: {
2110 if (builtin.zig_backend == .stage2_c) {
2111 break :blk @ptrCast(@alignCast(zig_x86_windows_teb()));
2112 } else {
2113 break :blk asm (
2114 \\ movl %%fs:0x18, %[ptr]
2115 : [ptr] "=r" (-> *TEB),
2116 );
2117 }
2118 },
2119 .x86_64 => blk: {
2120 if (builtin.zig_backend == .stage2_c) {
2121 break :blk @ptrCast(@alignCast(zig_x86_64_windows_teb()));
2122 } else {
2123 break :blk asm (
2124 \\ movq %%gs:0x30, %[ptr]
2125 : [ptr] "=r" (-> *TEB),
2126 );
2127 }
2128 },
2129 .thumb => asm (
2130 \\ mrc p15, 0, %[ptr], c13, c0, 2
2131 : [ptr] "=r" (-> *TEB),
2132 ),
2133 .aarch64 => asm (
2134 \\ mov %[ptr], x18
2135 : [ptr] "=r" (-> *TEB),
2136 ),
2111 .thumb => if (builtin.zig_backend == .stage2_c)
2112 @ptrCast(@alignCast(zig_thumb_windows_teb()))
2113 else
2114 asm (
2115 \\ mrc p15, 0, %[ptr], c13, c0, 2
2116 : [ptr] "=r" (-> *TEB),
2117 ),
2118 .aarch64 => if (builtin.zig_backend == .stage2_c)
2119 @ptrCast(@alignCast(zig_aarch64_windows_teb()))
2120 else
2121 asm (
2122 \\ mov %[ptr], x18
2123 : [ptr] "=r" (-> *TEB),
2124 ),
2125 .x86 => if (builtin.zig_backend == .stage2_c)
2126 @ptrCast(@alignCast(zig_x86_windows_teb()))
2127 else
2128 asm (
2129 \\ movl %%fs:0x18, %[ptr]
2130 : [ptr] "=r" (-> *TEB),
2131 ),
2132 .x86_64 => if (builtin.zig_backend == .stage2_c)
2133 @ptrCast(@alignCast(zig_x86_64_windows_teb()))
2134 else
2135 asm (
2136 \\ movq %%gs:0x30, %[ptr]
2137 : [ptr] "=r" (-> *TEB),
2138 ),
21372139 else => @compileError("unsupported arch"),
21382140 };
21392141}
lib/zig.h+37-13
......@@ -3926,28 +3926,52 @@ static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 a
39263926
39273927/* ======================== 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) {
3932#if _MSC_VER
3933 return (void*)__readgsqword(0x30);
3934#else
3935 void* teb;
3936 __asm volatile(" movq %%gs:0x30, %[ptr]": [ptr]"=r"(teb)::);
3931static inline void* zig_thumb_windows_teb(void) {
3932 void* teb = 0;
3933#if defined(_MSC_VER)
3934 teb = (void*)_MoveFromCoprocessor(15, 0, 13, 0, 2);
3935#elif defined(__GNUC__)
3936 __asm__ ("mrc p15, 0, %[ptr], c13, c0, 2" : [ptr] "=r" (teb));
3937#endif
39373938 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));
39383949#endif
3950 return teb;
39393951}
39403952
3941#elif (_MSC_VER && _M_IX86) || defined(__i386__) || defined(__X86__)
3953#elif defined(_M_IX86) || defined(__i386__)
39423954
39433955static inline void* zig_x86_windows_teb(void) {
3944#if _MSC_VER
3945 return (void*)__readfsdword(0x18);
3946#else
3947 void* teb;
3948 __asm volatile(" movl %%fs:0x18, %[ptr]": [ptr]"=r"(teb)::);
3956 void* teb = 0;
3957#if defined(_MSC_VER)
3958 teb = (void*)__readfsdword(0x18);
3959#elif defined(__GNUC__)
3960 __asm__ ("movl %%fs:0x18, %[ptr]" : [ptr] "=r" (teb));
3961#endif
39493962 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));
39503973#endif
3974 return teb;
39513975}
39523976
39533977#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
39263926
39273927/* ======================== 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) {
3932#if _MSC_VER
3933 return (void*)__readgsqword(0x30);
3934#else
3935 void* teb;
3936 __asm volatile(" movq %%gs:0x30, %[ptr]": [ptr]"=r"(teb)::);
3931static inline void* zig_thumb_windows_teb(void) {
3932 void* teb = 0;
3933#if defined(_MSC_VER)
3934 teb = (void*)_MoveFromCoprocessor(15, 0, 13, 0, 2);
3935#elif defined(__GNUC__)
3936 __asm__ ("mrc p15, 0, %[ptr], c13, c0, 2" : [ptr] "=r" (teb));
3937#endif
39373938 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));
39383949#endif
3950 return teb;
39393951}
39403952
3941#elif (_MSC_VER && _M_IX86) || defined(__i386__) || defined(__X86__)
3953#elif defined(_M_IX86) || defined(__i386__)
39423954
39433955static inline void* zig_x86_windows_teb(void) {
3944#if _MSC_VER
3945 return (void*)__readfsdword(0x18);
3946#else
3947 void* teb;
3948 __asm volatile(" movl %%fs:0x18, %[ptr]": [ptr]"=r"(teb)::);
3956 void* teb = 0;
3957#if defined(_MSC_VER)
3958 teb = (void*)__readfsdword(0x18);
3959#elif defined(__GNUC__)
3960 __asm__ ("movl %%fs:0x18, %[ptr]" : [ptr] "=r" (teb));
3961#endif
39493962 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));
39503973#endif
3974 return teb;
39513975}
39523976
39533977#endif