aarch64.cc has been updated to prevent emitting "symbol + offset"
for SYMBOL_SMALL_ABSOLUTE for the PECOFF target. "symbol + offset"
cannot be used in relocations for aarch64-w64-mingw32 due to
relocation requirements.

Instead, it will adjust the address by an offset with the
"add" instruction.

This approach allows addressing 4GB, instead of 1MB as it was before.
This issue has been fixed in the binutils patch series.

https://sourceware.org/pipermail/binutils/2024-August/136481.html

gcc/ChangeLog:

        * config/aarch64/aarch64.cc (aarch64_load_symref_and_add_offset):
        New.
        (aarch64_expand_mov_immediate): Use
        aarch64_load_symref_and_add_offset.
---
 gcc/config/aarch64/aarch64.cc | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 03362a975c0..3a8ecdf562b 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -4887,6 +4887,19 @@ aarch64_split_add_offset (scalar_int_mode mode, rtx 
dest, rtx src,
                      temp1, temp2, 0, false);
 }
 
+/* Load the address and apply the offset by using "add" instruction.  */
+
+static void
+aarch64_load_symref_and_add_offset (scalar_int_mode mode, rtx dest, rtx src,
+                                   poly_int64 offset)
+{
+  gcc_assert (can_create_pseudo_p ());
+  src = aarch64_force_temporary (mode, dest, src);
+  aarch64_add_offset (mode, dest, src, offset,
+                     NULL_RTX, NULL_RTX, 0, false);
+}
+
+
 /* Add DELTA to the stack pointer, marking the instructions frame-related.
    TEMP1 is available as a temporary if nonnull.  FORCE_ISA_MODE is as
    for aarch64_add_offset.  EMIT_MOVE_IMM is false if TEMP1 already
@@ -6054,10 +6067,8 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
        case SYMBOL_TINY_TLSIE:
          if (const_offset != 0)
            {
-             gcc_assert(can_create_pseudo_p ());
-             base = aarch64_force_temporary (int_mode, dest, base);
-             aarch64_add_offset (int_mode, dest, base, const_offset,
-                                 NULL_RTX, NULL_RTX, 0, false);
+             aarch64_load_symref_and_add_offset (int_mode, dest, base,
+                                                 const_offset);
              return;
            }
          /* FALLTHRU */
@@ -6068,6 +6079,13 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
        case SYMBOL_TLSLE24:
        case SYMBOL_TLSLE32:
        case SYMBOL_TLSLE48:
+         if (TARGET_PECOFF && const_offset != 0)
+           {
+             aarch64_load_symref_and_add_offset (int_mode, dest, base,
+                                                 const_offset);
+             return;
+           }
+
          aarch64_load_symref_appropriately (dest, imm, sty);
          return;
 
-- 
2.34.1

Reply via email to