Hello, I'm looking into adding support for ATmega256x and larger devices to the AVR port. This means that program memory addresses no longer fit in 16 bits - and I'm looking how to avoid making pointers larger.
Jumps and function calls are no problem as long as they use labels (constant addresses). Indirect jumps and calls (address in a register) are a problem. For function calls, it seems easy - generate each function in two parts, placed by linker script in different sections: - jump to function body - function body and locate the jumps below 128K (64K words), while the function body can be anywhere in the address space. If you need to take a 16-bit address of the function, simply take the address of the jump. The added runtime overhead of the jump is a small price to pay compared to making pointers 3 or 4 bytes long (instead of 2 bytes) on the AVR. But, now there is the "indirect_jump" pattern - mandatory, even though I haven't yet seen it actually used in real applications on the AVR. The question is, how to make sure that if indirect_jump ever happens to be used, its target address is guaranteed to fit in 16 bits? Where do these pointers come from? (Like function pointers come from taking the address of a function, and this may be solved as described above.) Looking at the source, I've found one use of indirect_jump so far - returning from a function with some data still on the stack. I suspect this may not work properly on the AVR anyway, because return address is stored on the stack in the wrong byte order - big endian, even though the AVR is little endian. Anything else? Thanks, Marek