[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.
mega_256x_binutils.patch
Description: Text Data
mega_256x_gcc.patch
Description: Text Data
- [avr-libc-dev] [PATCH] Alpha version: True support for atmega256x in binutils and gcc,
Björn Haase <=