https://gcc.gnu.org/g:172785c36dae189fdae68900cb455fad9d9659f2

commit r17-758-g172785c36dae189fdae68900cb455fad9d9659f2
Author: Georg-Johann Lay <[email protected]>
Date:   Sun May 24 22:12:31 2026 +0200

    AVR: ad target/121343 - Let __load_<size> insns use hard-reg constraints.
    
    Insns that generate transparent __load_<size> calls can be simplified
    using hard-reg constraints instead of explicit hard registers.
    This handles __flash loads of 3-byte and 4-byte integral, floating point
    and fixed-point values on devices without LPMx instruction.
    
            PR target/121343
    gcc/
            * config/avr/avr.md (load_<mode>_libgcc): Rewrite to use
            a hard-reg constraint for operand 0.
            (gen_load<mode>_libgcc): Remove expander.
            (mov<mode>): No more special handling needed for sources that
            satisfy avr_load_libgcc_p.

Diff:
---
 gcc/config/avr/avr.md | 39 ++++++++++-----------------------------
 1 file changed, 10 insertions(+), 29 deletions(-)

diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 71a97a1c4a70..2110f36febf5 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -546,33 +546,18 @@
 ;;========================================================================
 ;; Move stuff around
 
-;; Expand helper for mov<mode>.
-(define_expand "gen_load<mode>_libgcc"
-  [(set (match_dup 3)
-        (match_dup 2))
-   (set (reg:MOVMODE 22)
-        (match_operand:MOVMODE 1 "memory_operand"))
-   (set (match_operand:MOVMODE 0 "register_operand")
-        (reg:MOVMODE 22))]
-  "avr_load_libgcc_p (operands[1])"
-  {
-    operands[3] = gen_rtx_REG (HImode, REG_Z);
-    operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
-    operands[1] = replace_equiv_address (operands[1], operands[3]);
-    set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
-  })
-
-;; "load_qi_libgcc"
-;; "load_hi_libgcc"
+;; On devices without LPMx, __flash values > 2 bytes
+;; are loaded with libgcc's __load_<size>.
+;; Must be prior to the mov<mode> insns.
+;; "load_qi_libgcc" (unused)
+;; "load_hi_libgcc" (unused)
 ;; "load_psi_libgcc"
 ;; "load_si_libgcc"
 ;; "load_sf_libgcc"
 (define_insn_and_split "load_<mode>_libgcc"
-  [(set (reg:MOVMODE 22)
-        (match_operand:MOVMODE 0 "memory_operand" "m"))]
-  "avr_load_libgcc_p (operands[0])
-   && REG_P (XEXP (operands[0], 0))
-   && REG_Z == REGNO (XEXP (operands[0], 0))"
+  [(set (match_operand:MOVMODE 0 "register_operand" "={r22}")
+        (match_operand:MOVMODE 1 "memory_operand"     "m"))]
+  "avr_load_libgcc_p (operands[1])"
   "#"
   "&& reload_completed"
   [(scratch)]
@@ -823,12 +808,8 @@
         DONE;
       }
 
-    if (avr_load_libgcc_p (src))
-      {
-        // For the small devices, do loads per libgcc call.
-        emit_insn (gen_gen_load<mode>_libgcc (dest, src));
-        DONE;
-      }
+    // The avr_load_libgcc_p (src) insns are handled above by
+    // "load_<mode>_libgcc".  They look like ordinary move insns.
   })
 
 ;;========================================================================

Reply via email to