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

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

[avr-libc-dev] [PATCH] Alpha version: True support for atmega256x in bin


From: Björn Haase
Subject: [avr-libc-dev] [PATCH] Alpha version: True support for atmega256x in binutils and gcc
Date: Mon, 1 May 2006 00:22:39 +0200
User-agent: KMail/1.7.1

Hi,

I am getting closer to a true solution for the atmega256x issue. The good news
is that the most difficult problem is IMO now solved. The patches still will 
need some testing, but I don't see any serious difficulty any more.

The key difficulty did not consist in the larger PC and in it's influence 
on the stack frame layout. The difficulty was that the gcc back-end used 
indirect jumps at quite a number of places and the jump targets were of
course restricted by the 16 bit pointer size.

Solving the issue by promoting the pointers to 4 bytes would have been an
approach that would have required substantial changes and would introduce 
*much* overhead.
When continuing to work with 2-Byte pointers, however, one needed to teach
the linker to add a jump stub every time that the following conditions are 
met:

1.) The object code references some PM instruction address with one of the
    relocs that is limited to 16 bits (i.e. AVR_16_PM or one of the 
    various AVR_8_LDI_XX_PM relocs).
2.) The destination of this reference is beyond the 128k boundary that could
    be accessed.

Such a situation could show up when gcc starts using tablejumps (e.g. for 
large case/switch sequences) and always when using function-pointers.
Now the linker detects these cases, inserts a far jump to the destination in
the lower 128k and bends the 16-Bit relocs to point towards this "jump stub"
instruction instead of pointing to the unreachable final destination.

So, as long as the code is in the lower memory area, there is no change in
efficiency. When the destination turns out to be > 128k, there will be one
additional "hop" in order to reach the target.

In order to distinguish the different devices, I now have added a new avr6
family. Note that we would probably be having a problem only when variables 
are passed on the stack. So one might not find it out immediately if the wrong 
library is used!

The required changes to gcc are fairly minor. The best thing is, that for gcc 
we are having almost no difference between the avr5 and avr6 architecture 
except for the different frame offsets.

The last thing to add complete support would be to add support for the new
devices to avr-libc. Mainly this would require the addition of the new 
avr6 family and of course the header files for the new devices.
Unfortunately, I am not too familiar with the new build machine, and I
did not succeed so far to boot-strap avr-libc from the cvs state. I could try 
next week. Maybe somebody would be meanwhile willing to help by adding 
support for the avr6 to avr-libc.?

The attached patches are against current head of gcc and binutils. They still
have "alpha" status and they definitively need some testing on real HW 
projects, once avr-libc support is there.

Have fun,

Bjoern.


Summary of the changes to the binutils:

The template used for implementing the linker stubs for avr was the hppa
target. The difference here is, that we are having only one single
stub section that is created at the very beginning in the linker emulation
template. The placement of this stub section is controlled by it's name that
is included in the scripttemplate. It will be linked right after the 
section used for initializing the contents of the .data section.

In order to implement this, it was necessary to add support for a derived
linker hash table and an additional stub hash table.

avr-ld now is aware of new target specific options (documented in the
avr-ld --help output):

The two options

 --no-call-ret-replacement
 --pmem-wrap-around

control the linker relaxation optimizations. When defining 
--pm-wrap-around=16k,
the linker now tries to shorten jumps from absolute 14k to absolute 1k by 
using
the fact that the PC wraps around when using a shorter relative jump.
This is, IMO, useful only for the 16k and 32k devices. 

When using --no-stubs, the linker will not generate the jump stubs even when
using an avr6 device.

By use of the --debug-stubs and --debug-relax switches one could activate
debugging printout to stdout that is meant to be used when debugging avr-ld 
itself. It's not meant to be used by the user, but documented never the less.


Yours,

Bjoern.


Change log for the binutils part:

2005-05-01  Bjoern Haase  <address@hidden> 

        * bfd/archures.c
        bfd_mach_avr6: add.
        
        * bfd/bfd-in2.h
        bfd_mach_avr6: add.
        
        * bfd/cpu-avr.c
        bfd_mach_avr6: add.
        
        * bfd/elf32-avr.h: new file
        
        * bfd/elf32-avr.c
        Add elf32-avr.h to include list.
        elf32_avr_stub_hash_entry: add.
        elf32_avr_link_hash_table: add.
        avr_link_hash_table: add.
        avr_stub_hash_entry: add.
        avr_stub_hash_lookup: add.
        stub_hash_newfunc: add.
        elf32_avr_link_hash_table_create: add.
        elf32_avr_link_hash_table_free: add.
        avr_get_stub_addr: add.
        debug_relax, debug_stubs: add.
        avr_pc_wrap_around: Change type to bfd_vma.
        avr_replace_call_ret_sequences: add.
        avr_stub_is_required_for_16_bit_reloc: add.
        avr_final_link_relocate: 
        Add linker hashtable to parameter list. Use stub addr. if necessary.
        elf32_avr_relocate_section:
        Add linker hashtable to parameter list of avr_final_link_relocate.
        bfd_elf_avr_final_write_processing:
        Add handling for bfd_mach_avr6.
        elf32_avr_object_p:
        Add support for E_AVR_MACH_AVR6.
        elf32_avr_relax_delete_bytes:
        Iterate over all sections of a bfd when adjusting relocs addends.
        elf32_avr_relax_section:
        Use avr_replace_call_ret_sequences for enabling additional optimization.
        avr_stub_name: add.
        avr_get_stub_addr: add.
        avr_get_stub_entry: add.
        avr_add_stub: add.
        avr_build_one_stub: add.
        avr_size_one_stub: add.
        elf32_avr_setup_params: add.
        elf32_avr_setup_section_lists: add.
        get_local_syms: add.
        elf32_avr_size_stubs: add.
        bfd_elf32_bfd_link_hash_table_create: add.
        bfd_elf32_bfd_link_hash_table_free: add avr6, avr2560 and avr2561
        
        * gas/config/tc-avr.c: Add "avr6"
        
        * gas/config/tc-avr.h:
        TC_VALIDATE_FIX: Don't generate fixups for PM type relocs
        
        * include/elf/avr.h
        E_AVR_MACH_AVR6: add.
        
        * ld/configure.tgt: Add avr6 to emulation list.
        
        * ld/Makefile.am, ld/Makefile.in:
        Add eavr6.o and corresponding rule.
        
        * ld/emulparams/avr6.sh: add
        
        * ld/emulparams/avrX.sh:
        TEMPLATE_NAME: Change to elf32 instead of generic.
        EXTRA_EM_FILE: add reference to new avrelf.
        
        * ld/scripttempl/avr.sc: Add ".trampolines" section.
        
        * ld/emultampl/avrelf.em: New file.


Summary of changes to gcc:

Apart of adding the new devices to the already known device list, it was only 
necessary to add a new family of devices and a new device-specific property:
the size of the pc. This one is now stored in a new variable avr_pc_size;

Moreover I have added the -fno-delete-null-pointer-checks option to the 
parameter list.

Yours,

Bjoern.


Change log for the gcc part:

        * gcc/gcc/config/avr/avr.c:
        avr_pc_size: add
        struct base_arch: add three_byte_pc to struct.
        struct base_arch_s: add new struct member and add avr6 entry.
        struct mcu_type_s: add atmega2560 and atmega2561.
        avr_override_options: set avr_pc_size to 3 if necessary.
        initial_elimination_offset: use (avr_pc_size) instead of fixed value 2.

        * gcc/gcc/config/avr/avr.h:
        CC1_SPEC: add -fno-delete-null-pointer-checks to list.
        CC1PLUS_SPEC: ditto.
        LINK_SPEC: add atmega2560 and atmega2561
        CRT_BINUTILS_SPEC: 
        add atmega2560 (crtm2560.o) and atmega2561 (crtm2561.o).

        * gcc/gcc/config/avr/t-avr:
        MULITLIB_OPTIONS: add avr6 architecture to list
        MULITLIB_DIRNAMES: ditto. 
        MULTILIB_MATCHES: add atmega2560 and atmega2561 to list.

Attachment: mega_256x_binutils.patch
Description: Text Data

Attachment: mega_256x_gcc.patch
Description: Text Data


reply via email to

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