[Patch, avr] Relax LDS/STS to IN/OUT if symbol is in I/O address range

Sivanupandi, Pitchumani Pitchumani.Sivanupandi@atmel.com
Tue Dec 23 10:06:00 GMT 2014

> -----Original Message-----
> From: binutils-owner@sourceware.org [mailto:binutils-
> owner@sourceware.org] On Behalf Of Erik Christiansen
> Sent: Saturday, October 11, 2014 3:52 PM
> To: binutils@sourceware.org
> Subject: Re: [Patch, avr] Relax LDS/STS to IN/OUT if symbol is in I/O address
> range
> 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.

When multiple registers (which may or may not be in I/O address ranges) are 
Accessed, it increases the complexity to have optimized load/store 
(to select in/out over lds/sds).

E.g. CCP and WDT register usages in wdt_enable/disable functions in avr-libc.
We may need four branching to have optimized load/store of I/O registers.

This proposed optimization may reduce the complexity and source code size.

Vote +1 :)


More information about the Binutils mailing list