diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2024-02-29 17:19:27 +0100 |
---|---|---|
committer | Georg-Johann Lay <avr@gjlay.de> | 2024-02-29 20:39:58 +0100 |
commit | cda3836161834c5f21f264885891fe4d0ce90da1 (patch) | |
tree | 50bff4f80befdac6abd0350a0655088055ec4ccf /gcc/config/avr/avr.opt | |
parent | 02ca9d3f0c5d2b0255df28f021834dd67ad79bc2 (diff) | |
download | gcc-cda3836161834c5f21f264885891fe4d0ce90da1.zip gcc-cda3836161834c5f21f264885891fe4d0ce90da1.tar.gz gcc-cda3836161834c5f21f264885891fe4d0ce90da1.tar.bz2 |
AVR: target/114100 - Better indirect accesses for reduced Tiny
The Reduced Tiny core does not support indirect addressing with offset,
which basically means that every indirect memory access with a size
of more than one byte is effectively POST_INC or PRE_DEC. The lack of
that addressing mode is currently handled by pretending to support it,
and then let the insn printers add and subtract again offsets as needed.
For example, the following C code
int vars[10];
void inc_var2 (void) {
++vars[2];
}
is compiled to:
ldi r30,lo8(vars) ; 14 [c=4 l=2] *movhi/4
ldi r31,hi8(vars)
subi r30,lo8(-(4)) ; 15 [c=8 l=6] *movhi/2
sbci r31,hi8(-(4))
ld r20,Z+
ld r21,Z
subi r30,lo8((4+1))
sbci r31,hi8((4+1))
subi r20,-1 ; 16 [c=4 l=2] *addhi3_clobber/1
sbci r21,-1
subi r30,lo8(-(4+1)) ; 17 [c=4 l=4] *movhi/3
sbci r31,hi8(-(4+1))
st Z,r21
st -Z,r20
where the code could be -- and with this patch actually is -- like
ldi r30,lo8(vars+4) ; 28 [c=4 l=2] *movhi/4
ldi r31,hi8(vars+4)
ld r20,Z+ ; 17 [c=8 l=2] *movhi/2
ld r21,Z+
subi r20,-1 ; 19 [c=4 l=2] *addhi3_clobber/1
sbci r21,-1
st -Z,r21 ; 30 [c=4 l=2] *movhi/3
st -Z,r20
This is achieved in two steps:
- A post-reload split into "real" instructions during .split2.
- A new avr-specific mini pass .avr-fuse-add that runs before
RTL peephole and that tries to combine the generated pointer
additions into memory accesses to form POST_INC or PRE_DEC.
gcc/
PR target/114100
* doc/invoke.texi (AVR Options) <-mfuse-add>: Document.
* config/avr/avr.opt (-mfuse-add=): New target option.
* common/config/avr/avr-common.cc (avr_option_optimization_table)
[OPT_LEVELS_1_PLUS]: Set -mfuse-add=1.
[OPT_LEVELS_2_PLUS]: Set -mfuse-add=2.
* config/avr/avr-passes.def (avr_pass_fuse_add): Insert new pass.
* config/avr/avr-protos.h (avr_split_tiny_move)
(make_avr_pass_fuse_add): New protos.
* config/avr/avr.md [AVR_TINY]: New post-reload splitter uses
avr_split_tiny_move to split indirect memory accesses.
(gen_move_clobbercc): New define_expand helper.
* config/avr/avr.cc (avr_pass_data_fuse_add): New pass data.
(avr_pass_fuse_add): New class from rtl_opt_pass.
(make_avr_pass_fuse_add, avr_split_tiny_move): New functions.
(reg_seen_between_p, emit_move_ccc, emit_move_ccc_after): New functions.
(avr_legitimate_address_p) [AVR_TINY]: Don't restrict offsets
of PLUS addressing for AVR_TINY.
(avr_regno_mode_code_ok_for_base_p) [AVR_TINY]: Ignore -mstrict-X.
(avr_out_plus_1) [AVR_TINY]: Tweak ++Y and --Y.
(avr_mode_code_base_reg_class) [AVR_TINY]: Always return POINTER_REGS.
Diffstat (limited to 'gcc/config/avr/avr.opt')
-rw-r--r-- | gcc/config/avr/avr.opt | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt index 76530fd..ea35b7d 100644 --- a/gcc/config/avr/avr.opt +++ b/gcc/config/avr/avr.opt @@ -107,6 +107,14 @@ msp8 Target RejectNegative Var(avr_sp8) Init(0) The device has no SPH special function register. This option will be overridden by the compiler driver with the correct setting if presence/absence of SPH can be deduced from -mmcu=MCU. +mfuse-add +Target Alias(mfuse-add=, 1, 0) Optimization +Split register additions from load/store instructions. Most useful on Reduced Tiny. + +mfuse-add= +Target Joined RejectNegative UInteger Var(avr_fuse_add) Init(0) Optimization IntegerRange(0, 3) +Split register additions from load/store instructions. Most useful on Reduced Tiny. + Waddr-space-convert Warning C Var(avr_warn_addr_space_convert) Init(0) Warn if the address space of an address is changed. |