On Sun, Mar 20, 2005 at 02:58:29AM +0100, Giovanni Bajo wrote: > It is possible in GNU C at least: > > int foo(int dest) > { > __label__ l1, l2, l3; > void *lb[] = { &&l1, &&l2, &&l3 }; > int x = 0; > > goto *lb[dest]; > > l1: > x += 1; > l2: > x += 1; > l3: > x += 1; > return x; > }
Thanks for explaining this. So yes, unfortunately we have to support indirect_jump properly (I was hoping it was only for something like trampolines, which can't work on the AVR anyway). I was wrong about needing two jumps - just one for each label should be enough, because switching to .text_low and back to .text doesn't disrupt the normal flow of instructions in .text. So, it's not that bad, really the same thing for indirect jumps and calls (using function pointers), each affected label needs to be output like this: .section .text_low,"ax",@progbits label: jmp 1f .text 1: This includes all global labels (visible to other object files, like function entry points), and local labels referenced by anything other than direct jumps or calls). On the other hand, branches within the same function should avoid the extra jump and go to "1:" directly. If the same label is used in both ways (direct jump/branch, and address taken), two separate labels (at the same address) should be output for both of these uses, but I'm not sure how to do this in GCC. Any suggestions? (The problem can be seen by adding something like "if (dest > 2) goto l3;" above the goto in the original example: in the assembler output, there is only one label corresponding to l3 which is both 1. referenced with pm() and 2. target of a branch for which .text_low would be out of range.) Marek