[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-gcc-list] Function pointers on > 128 KiB devices, how to?
From: |
Joerg Wunsch |
Subject: |
[avr-gcc-list] Function pointers on > 128 KiB devices, how to? |
Date: |
Wed, 20 Jan 2010 14:53:55 +0100 |
User-agent: |
Mutt/1.5.20 (2009-06-14) |
When porting a larger application to a 256 KiB device, we stumbled
across our function pointers and jump tables. Consider the
following code:
#include <stdint.h>
#include <avr/pgmspace.h>
void foo(void);
void bar(void);
void mumble(void);
typedef void (*fptr) (void);
fptr jumptable[] __attribute__((progmem)) = {
foo,
bar,
mumble,
};
volatile uint32_t i, j, k;
void
foo(void)
{
for (uint8_t x = 0; x < 200; x++) {
i = j * 5 + k * 7;
j = i + 32412341243;
k = i & 0x12345678ull;
}
for (uint8_t x = 0; x < 200; x++) {
i = j * 5 + k * 7;
j = i + 32412341243;
k = i & 0x12345678ull;
}
}
void
mumble(void)
{
for (uint8_t x = 0; x < 200; x++) {
i = j * 5 + k * 7;
j = i + 32412341243;
k = i & 0x12345678ull;
}
for (uint8_t x = 0; x < 200; x++) {
i = j * 5 + k * 7;
j = i + 32412341243;
k = i & 0x12345678ull;
}
}
void
bar(void)
{
for (uint8_t x = 0; x < 200; x++) {
i = j * 5 + k * 7;
j = i + 32412341243;
k = i & 0x12345678ull;
}
}
int
main(int argc, char **argv)
{
fptr f;
if (argc < sizeof jumptable / sizeof jumptable[0]) {
f = (fptr)pgm_read_word(jumptable[argc]);
f();
}
return 0;
}
...compiled with (thoroughly pessimized to generate large amounts of
code):
avr-gcc -O3 -funroll-loops --param max-peeled-insns=1000000 \
--param max-completely-peel-times=1000000 \
--param max-unrolled-insns=1000000 \
--param=max-completely-peeled-insns=1000000 \
--param max-average-unrolled-insns=1000000 \
-mmcu=atmega2560 -std=c99 -g -o foo.elf foo.c
This yields:
/tmp/cc1QZqci.o: In function `foo':
/tmp/foo.c:20: warning: internal error: out of range error
Trying to replace the pgm_read_word() by a pgm_read_dword_far() just
adds more warnings about casting pointers/integers of different size,
but doesn't help for the initial "out of range" error anyway.
Is there any option at all to use function pointers for a device which
supports code sizes > 128 KiB? I (incorrectly) assumed these were
replaced by trampoline pointers, but apparently, they aren't.
Any ideas welcome, possibly including quick&dirty inline asm hacks to
generate the indirect call.
--
cheers, J"org .-.-. --... ...-- -.. . DL8DTL
http://www.sax.de/~joerg/ NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
- [avr-gcc-list] Function pointers on > 128 KiB devices, how to?,
Joerg Wunsch <=