This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.

Erik


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]