avr-gcc-list
[Top][All Lists]
Advanced

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

Re: [avr-gcc-list] Function pointers on > 128 KiB devices, how to?


From: Dale Whitfield
Subject: Re: [avr-gcc-list] Function pointers on > 128 KiB devices, how to?
Date: Wed, 20 Jan 2010 17:54:18 +0200
User-agent: Mutt/1.5.20 (2009-06-14)

Hi Joerg                                         >@2010.01.20_15:53:55_+0200

This will create an explicit trampoline. The rest of your code would
remain the same. I've used this technique in a slightly different way
previously. Caution: Compiled and inspected but not tested/simulated! 

#define JMP_TABLE_ENTRY(x)      __asm__ __volatile__ ("jmp "#x)

void jumptable_fn(void) __attribute__ ((naked));
void jumptable_fn(void) {
        JMP_TABLE_ENTRY(foo);
        JMP_TABLE_ENTRY(bar);
        JMP_TABLE_ENTRY(mumble);
}

fptr jumptable[] __attribute__((progmem)) = {
        jumptable_fn+0, // foo
        jumptable_fn+4, // bar,
        jumptable_fn+8, // mumble,
};

An advanced use for this is to allow creation of a 'jump table' that can
call functions that are not all of type fptr, ie. void fn(void).

> 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 mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
> 

-- 

Regards

Dale





reply via email to

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