]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
AVR: ad target/121343 - Let __load_<size> insns use hard-reg constraints.
authorGeorg-Johann Lay <avr@gjlay.de>
Sun, 24 May 2026 20:12:31 +0000 (22:12 +0200)
committerGeorg-Johann Lay <avr@gjlay.de>
Mon, 25 May 2026 17:05:41 +0000 (19:05 +0200)
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.

gcc/config/avr/avr.md

index 71a97a1c4a70d4088234623f3e399fece305cd70..2110f36febf5a58a3c9fcf64ddcb7ccfaa21b702 100644 (file)
 ;;========================================================================
 ;; 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)]
         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.
   })
 
 ;;========================================================================