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

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to