aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2024-12-04 20:56:50 +0100
committerGeorg-Johann Lay <avr@gjlay.de>2024-12-05 11:43:54 +0100
commitf7b5527d1b48b33d8ab633c1e9dcb9883667492a (patch)
tree9f218a5beff5dffb0b0a1dbb309f82789ee6629a /gcc
parent9ae9db54631f38d66666a2080a2a26c5c5d98fa9 (diff)
downloadgcc-f7b5527d1b48b33d8ab633c1e9dcb9883667492a.zip
gcc-f7b5527d1b48b33d8ab633c1e9dcb9883667492a.tar.gz
gcc-f7b5527d1b48b33d8ab633c1e9dcb9883667492a.tar.bz2
AVR: target/64242 - Copy FP to a local reg in nonlocal_goto.
In nonlocal_goto sets, change hard_frame_pointer_rtx only after emit_stack_restore() restored SP. This is needed because SP my be stored in some frame location. gcc/ PR target/64242 * config/avr/avr.md (nonlocal_goto): Don't restore hard_frame_pointer_rtx directly, but copy it to local register, and only set hard_frame_pointer_rtx from it after emit_stack_restore().
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/avr/avr.md7
1 files changed, 6 insertions, 1 deletions
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index a68b38c..f45677a 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -421,9 +421,14 @@
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
- emit_move_insn (hard_frame_pointer_rtx, r_fp);
+ // PR64242: When r_sp is located in the frame, we must not
+ // change FP prior to reading r_sp. Hence copy r_fp to a
+ // local register (and hope that reload won't spill it).
+ rtx r_fp_reg = copy_to_reg (r_fp);
emit_stack_restore (SAVE_NONLOCAL, r_sp);
+ emit_move_insn (hard_frame_pointer_rtx, r_fp_reg);
+
emit_use (hard_frame_pointer_rtx);
emit_use (stack_pointer_rtx);