Thursday, September 19, 2024
Richard Sandiford <richard.sandif...@arm.com> wrote:

> abs_hwi (const_offset) (since const_offset has HOST_WIDE_INT type).

abs_hwi has been applied.

> It might be easier to pass base and const_offset from the caller
> (aarch64_expand_mov_immediate).  We are then guaranteed that the
> offset is constant and don't need to worry about the SVE case.
> The new SYM+OFF expression can be calculated using plus_constant.

The implementation has been refactored to use plus_constant.

> I think it'd be worth asserting that the offset fits in 32 bits,
> since if by some bug the offset is larger, we'd generate silent
> wrong code (in the sense that the compiler would truncate the offset
> before the assembler sees it).

The new implementation extends offset support from 1MB to 16MB and will not
compile code with a larger offset.
A 16MB offset is sufficient for our CI, however, the offset support will be
extended to 4GB in the following patch series.

> I think the normal addition patterns can handle this, if we pass the
> result of the ~0xfffff calculation.  There should be no need for a
> dedicated pattern.

Yes, it looks like it works as expected.

> I think it'd be clearer to duplicate the gen_add_losym and avoid the
> do...while(0)

The code has been refactored to remove the use of do..while(0).

The generated code is very similar to the original implementation:
https://gcc.gnu.org/pipermail/gcc-patches/2024-September/662505.html.
The difference is that "symbol + offset" is used for cases when the offset
is less than 1MB, and only "symbol" without the offset is used when
it is greater than or equal to 1MB.

an offset < 1MB
adrp    x0, symbol+1048575
add     x0, x0, :lo12:symbol+1048575

an offset >= 1MB

adrp    x0, symbol
add     x0, x0, :lo12:symbol
add     x0, x0, 1048576
ldrb    w0, [x0, 4093]

The original implementation might be more preferable and can be extended to use
"symbol + offset" when the offset is less than 1MB. However, both options
should be fine for now to handle offsets up to 16MB.

Regards,
Evgeny


index ddaea4ab6e2..3f64182b3e4 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -2962,6 +2962,25 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
          tmp_reg = gen_reg_rtx (mode);

        emit_move_insn (tmp_reg, gen_rtx_HIGH (mode, copy_rtx (imm)));
+
+       if (TARGET_PECOFF)
+         {
+           poly_int64 offset;
+           HOST_WIDE_INT const_offset;
+           strip_offset (imm, &offset);
+
+           if (offset.is_constant (&const_offset)
+               && abs_hwi (const_offset) >= 1 << 20)
+             {
+               rtx const_int = imm;
+               const_int = XEXP (const_int, 0);
+               XEXP (const_int, 1) = GEN_INT (const_offset % (1 << 20));
+
+               emit_set_insn (tmp_reg, plus_constant (mode, tmp_reg,
+                              const_offset & ~0xfffff));
+             }
+         }
+
        emit_insn (gen_add_losym (dest, tmp_reg, imm));
        return;
       }

Reply via email to