This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [Patch, avr] Relax LDS/STS to IN/OUT if symbol is in I/O address range
- From: Erik Christiansen <dvalin at internode dot on dot net>
- To: binutils at sourceware dot org
- Date: Sat, 11 Oct 2014 21:21:33 +1100
- Subject: Re: [Patch, avr] Relax LDS/STS to IN/OUT if symbol is in I/O address range
- Authentication-results: sourceware.org; auth=none
- References: <20140929104545 dot GA984 at atmel dot com> <CADOs=zaSvw-8Lpg5Te1v0YE19KBh6uN8udCpsNAWuvfpL7YHbA at mail dot gmail dot com> <20140930021023 dot GA14314 at atmel dot com> <5431C74C dot 5030500 at gjlay dot de> <20141006042945 dot GA1261 at atmel dot com> <20141009103449 dot GF3842 at atmel dot com> <CADOs=zbn053kb85j7GxSAVpbyGJcjRTwF5x70H0zhFrb=UrXhw at mail dot gmail dot com>
- Reply-to: dvalin at internode dot on dot net
On 09.10.14 18:26, Denis Chertykov wrote:
> 2. You poin to a place where the linker change one jump instruction to
> another. IMHO it's predictable from the linker.
> 3. Your patch change loading/storing from memory to input/output -
> it's not so predictable from the linker.
> 4. I worry only on compatibility issues.
> 5. It's not a strong objection.
Hi Denis,
Given that AVR I/O is both memory and IO-space mapped, isn't the
shorter addressing mode very much like a linker relaxation of long
absolute jump to a shorter relative one?
Even the address offset between the two addressing modes remains
constant across the entire product range - it is the number of general
purpose registers, and so can hardly change unless the whole instruction
set changes.
And the range of I/O addressing is fixed by the number of bits available
in the opcode, not by I/O memory population, which changes between
chips.
The interchangeability is referenced in datasheets, e.g. in section
"7.3 SRAM Data Memory" for ATmega328p:
"The ATmega48PA/88PA/168PA/328P is a complex microcontroller with more
peripheral units than can be supported within the 64 locations reserved
in the Opcode for the IN and OUT instructions. For the Extended I/O
space from 0x60 - 0xFF in SRAM, only the ST/STS/STD and LD/LDS/LDD
instructions can be used."
With that inbuilt duality in mind, and to avoid the hassle of ever
having to think about the address offset, I have for the last 14 years
or more used, in private and commercial code, assembler optimisation,
which does exactly the same as the proposed linker relaxation.
IO_SFRMAX = 0x5f ; 0x5f - 0x20 = 0x3f, which is intrinsic to
SFR_OFFSET = 0x20 ; the AVR opcodes.
; Single mnemonic for both I/O address ranges. Automatically optimise I/O code.
; And the user works with only one address space. PORTC is PORTC, regardless.
.macro inp reg,addr
.if \addr > IO_SFRMAX
lds \reg,\addr
.else
in \reg, \addr - SFR_OFFSET
.endif
.endm
; Single mnemonic for both I/O address ranges. Automatically optimise I/O code.
.macro outp addr,reg
.if \addr > IO_SFRMAX
sts \addr,\reg
.else
out \addr - SFR_OFFSET,\reg
.endif
.endm
So Senthil's proposed change already has a proven track record, and its
nature is fixed by factors that Atmel would find hard to change, even if
they tried, I suggest. Neither more registers nor a larger I/O space
could be provided without changing the entire instruction set, to free
up opcode bits.
The use of ST/STS/STD and LD/LDS/LDD, where an IN/OUT would suffice, is
a missed optimisation. If it is not done in the compiler or assembler,
then LTO is the last opportunity to fix the bug, I submit.
Erik