avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-libc-dev] Fwd: [PATCH gnu binutils] add linker relaxation support f


From: Björn Haase
Subject: [avr-libc-dev] Fwd: [PATCH gnu binutils] add linker relaxation support for avr
Date: Tue, 28 Feb 2006 06:25:00 +0100
User-agent: KMail/1.7.1

Hi,

FYI, here is a patch for the binutils that I now consider to be final. I 
myself am using it already for production code. 

With this patch, gcc could be used with the switch sequence
-ffunction-sections -Wl,--relax -Wl,--gc-sections
. The linker then will replace call/jmp instructions with the shorter variants 
rcall/rjmp if possible. The linker will then also replace 
#  rcall/call function
#  ret
by
#  rjmp/jmp function
#  ret
or even only
# rjmp/jmp function
if the ret could no longer be reached. My tests showed that all of this is 
good for about 5% improvement for the code density for a 16k device.

I think, that with this patch also the -fdata-sections switch of gcc should be 
functional. This part of the patch, however, is not completely tested.

Yours,

Bjoern.

----------  Forwarded Message  ----------

Subject: [PATCH] add linker relaxation support for avr port rev. 6
Date: Dienstag, 28. Februar 2006 06:14
From: Björn Haase <address@hidden>
To: address@hidden

Hello,

this is now the sixth (and hopefully acceptable) version of the linker
relaxation patch for avr. The remaining problem with the last patch were two
new failures for the gas testsuite. With this patch the gas testsuite no
longer exhibits regressions.

In total this patch incorporates the following changes:

GAS:

In order to make relaxation work, we need to make gas generate relocs instead
of fixups at various places. The issue is that all the relative instruction
offsets no longer must be calculated at assembly time but at linke time.
For this purpose the patch disables the fixups for all of the program-space
relative relocs by setting linkrelax to the value 1.

Because there was no way to find out from the object file itself if it is
suitable for relaxing or not, It is necessary to avoid that ld attempts to
run relaxing optimization on old object files. In order to guarantee this,
I have introduced a new flag bit in the e_flag portion of the elf header.
Bits 0-3 have the same meaning (new define symbol EF_AVR_LINKRELAX_PREPARED).

In order to be able to leave the fixup for the higher two bytes of 32 bit
values to the linker, I have changed the present workaround. Before my change
gas internally made use of negated BFD enum values for these higher bytes.
I replaced this by adding proper new relocs to bfd and the elf files
(BFD_RELOC_AVR_MS8_LDI and R_AVR_MS8_LDI as well as the negated variants) for
the most significant byte of 32 bit values.

BFD:

I first had to implement a couple of changes in bfd for supporting the new
relocs for the most significant bytes.

Three functions for implementing linker relaxation support are now new.
 Before the relaxation machine starts, it is checked that the bfd has the
EF_AVR_LINKRELAX_PREPARED flag set in the elf header so that we could safely
continue to link old object files.

In the ".jumptables" and ".vectors" sections only a reduced relaxation
 machine runs: Jumps and Calls are replaced by the shorter variants without
 changing the relative addresses.

In elf32-avr.c I then have introduced a new global variable determinating the
wrap-around value of the avr program memory space. This value is presently
initialized with a value signalizing that no wraparound could occur, but if
it is filled one day with the correct value, the relaxation machine will make
use of the wrap-around shortcuts for jumps.
Since this is interesting only for targets with 16k and 32k of program
 memory, I thought about adding a target-specific options for ld
(-muse-16k-wraparound-jumps) or (-muse-32k-wraparound-jumps).

If this patch happens to be inside the source tree one day, I plan to prepare
a follow up patch that incorporates this addition.

LD:

In order to fix the --gc-sections bug I have added the required KEEP()
statements in the linker script for avr.
The contents of .data* , .rodata and .rodata* are now also linked into
the .data output section so that gcc could be used with the -fdata-sections
switch.

Yours,

Bjoern.

2006-02-28  Bjoern Haase  <address@hidden>

        * include/elf/avr.h:

        R_AVR_MS8_LDI,R_AVR_MS8_LDI_NEG: Add.
        EF_AVR_LINKRELAX_PREPARED: Add.

        * bfd/elf32-avr.c:

        avr_reloc_map:
        insert BFD_RELOC_AVR_MS8_LDI and R_AVR_MS8_LDI
        bfd_elf_avr_final_write_processing:
        set EF_AVR_LINKRELAX_PREPARED in e_flags field.
        elf32_avr_relax_section: add.
        elf32_avr_relax_delete_bytes: add.
        elf32_avr_get_relocated_section_contents: add.
        avr_pc_wrap_around: add.
        avr_relative_distance_considering_wrap_around: add.
        avr_final_link_relocate: Handle negative int8t_t immediate for R_AVR_LDI

        * gas/config/tc-avr.c:

        avr_mod_hash_value: Add.
        md_apply_fix, exp_mod:
        Use BFD_RELOC_HH8_LDI and BFD_RELOC_MS8_LDI for hlo8() and hhi8()
        md_begin:
        set linkrelax variable to 1, use avr_mod_hash_value instead of int
        avr_ldi_expression: use avr_mod_hash_value instead of (int)
        tc_gen_reloc:
        handle substractions of symbols, if possible do fixups, abort otherwise

        * gas/config/tc-avr.h:
        TC_LINKRELAX_FIXUP, TC_VALIDATE_FIX, tc_fix_adjustable: add.

        * bfd/bfd-in2.h: Add BFD_RELOC_AVR_MS8_LDI and BFD_RELOC_AVR_LDI_NEG
        * bfd/libbfd.h: Ditto.
        * bfd/reloc.c: Ditto.

        * ld/scripttempl/avr.sc:
        add *(.jumptables) *(.lowtext), add KEEP() directives
        add *(.data*) *(.rodata) and *(.rodata*) and *(.bss*) to .data and .bss
        output sections.

-------------------------------------------------------

Attachment: avr_linkrelax_patch.rev6
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]