This solves a leftover in 19fb46e9e8aaf10bf917266e96362fe2b4414934. Because we cannot pass a segmented memory reference to assembly, the (absolute) address was always passed in a register, preventing optimization when it could be constant, for example, in `NtCurrentTeb()`:
# -masm=att movl $48, %eax movq %gs:(%eax), %rax # -masm=intel mov eax, 48 mov rax, gs:[eax] With this commit, a constant address is allowed to be passed as a constant to inline assembly. There are two cases: 1. In AT&T syntax, there are different ways to say whether a constant is an immediate or (part of) an address. For our use, we must write the operand in its address form, using the `a` modifier: `mov %%gs:%a1, %0` 2. In Intel syntax, the `a` modifier on a constant would produce a `ds:` segment prefix, so we must not use that. On the other hand, the address form of any kind of operands is actually unified, so we enclose the operand in brackets, to indicate an address: `mov %0, gs:[%1]` `NtCurrentTeb()` now produces: # -masm=att movq %gs:48, %rax # -masm=intel mov rax, gs:[48] Signed-off-by: LIU Hao <[email protected]> --- mingw-w64-headers/include/psdk_inc/intrin-impl.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)diff --git a/mingw-w64-headers/include/psdk_inc/intrin-impl.h b/mingw-w64-headers/include/psdk_inc/intrin-impl.h
index e109c15d0..f123f9120 100644
--- a/mingw-w64-headers/include/psdk_inc/intrin-impl.h
+++ b/mingw-w64-headers/include/psdk_inc/intrin-impl.h
@@ -230,9 +230,9 @@ Parameters: (FunctionName, DataType, Segment)
#define __buildreadseg(x, y, z, a) y x(unsigned __LONG32 Offset) { \
y ret; \
- __asm__ ("mov{" a " %%" z ":(%[offset]), %[ret] | %[ret], " z ":[%[offset]]
}" \
+ __asm__ ("mov{" a " %%" z ":%a[offset], %[ret] | %[ret], " z ":[%[offset]]
}" \
: [ret] "=r" (ret) \
- : [offset] "r" (Offset) \
+ : [offset] "ir" (Offset) \
: "memory"); \
return ret; \
}
@@ -248,9 +248,9 @@ Parameters: (FunctionName, DataType, Segment)
*/
#define __buildwriteseg(x, y, z, a) void x(unsigned __LONG32 Offset, y Data)
{ \
- __asm__ volatile ("mov{" a " %[Data], %%" z ":(%[offset]) | " z ":[%[offset]],
%[Data] }" \
+ __asm__ volatile ("mov{" a " %[Data], %%" z ":%a[offset] | " z ":[%[offset]],
%[Data] }" \
: \
- : [offset] "r" (Offset), [Data] "r" (Data) \
+ : [offset] "ir" (Offset), [Data] "r" (Data) \
: "memory"); \
}
From e7e33a336853288227dde3c8e9df5bc6a86f60e9 Mon Sep 17 00:00:00 2001 From: LIU Hao <[email protected]> Date: Tue, 16 Dec 2025 19:51:21 +0800 Subject: [PATCH] headers/intrin-impl: Allow constant addresses when referencing segmented memory This solves a leftover in 19fb46e9e8aaf10bf917266e96362fe2b4414934. Because we cannot pass a segmented memory reference to assembly, the (absolute) address was always passed in a register, preventing optimization when it could be constant, for example, in `NtCurrentTeb()`: # -masm=att movl $48, %eax movq %gs:(%eax), %rax # -masm=intel mov eax, 48 mov rax, gs:[eax] With this commit, a constant address is allowed to be passed as a constant to inline assembly. There are two cases: 1. In AT&T syntax, there are different ways to say whether a constant is an immediate or (part of) an address. For our use, we must write the operand in its address form, using the `a` modifier: `mov %%gs:%a1, %0` 2. In Intel syntax, the `a` modifier on a constant would produce a `ds:` segment prefix, so we must not use that. On the other hand, the address form of any kind of operands is actually unified, so we enclose the operand in brackets, to indicate an address: `mov %0, gs:[%1]` `NtCurrentTeb()` now produces: # -masm=att movq %gs:48, %rax # -masm=intel mov rax, gs:[48] Signed-off-by: LIU Hao <[email protected]> --- mingw-w64-headers/include/psdk_inc/intrin-impl.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mingw-w64-headers/include/psdk_inc/intrin-impl.h b/mingw-w64-headers/include/psdk_inc/intrin-impl.h index e109c15d0..f123f9120 100644 --- a/mingw-w64-headers/include/psdk_inc/intrin-impl.h +++ b/mingw-w64-headers/include/psdk_inc/intrin-impl.h @@ -230,9 +230,9 @@ Parameters: (FunctionName, DataType, Segment) #define __buildreadseg(x, y, z, a) y x(unsigned __LONG32 Offset) { \ y ret; \ - __asm__ ("mov{" a " %%" z ":(%[offset]), %[ret] | %[ret], " z ":[%[offset]] }" \ + __asm__ ("mov{" a " %%" z ":%a[offset], %[ret] | %[ret], " z ":[%[offset]] }" \ : [ret] "=r" (ret) \ - : [offset] "r" (Offset) \ + : [offset] "ir" (Offset) \ : "memory"); \ return ret; \ } @@ -248,9 +248,9 @@ Parameters: (FunctionName, DataType, Segment) */ #define __buildwriteseg(x, y, z, a) void x(unsigned __LONG32 Offset, y Data) { \ - __asm__ volatile ("mov{" a " %[Data], %%" z ":(%[offset]) | " z ":[%[offset]], %[Data] }" \ + __asm__ volatile ("mov{" a " %[Data], %%" z ":%a[offset] | " z ":[%[offset]], %[Data] }" \ : \ - : [offset] "r" (Offset), [Data] "r" (Data) \ + : [offset] "ir" (Offset), [Data] "r" (Data) \ : "memory"); \ } -- 2.52.0
OpenPGP_signature.asc
Description: OpenPGP digital signature
_______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
