http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51840

Timo Kreuzer <timo.kreuzer at reactos dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timo.kreuzer at reactos dot
                   |                            |org

--- Comment #3 from Timo Kreuzer <timo.kreuzer at reactos dot org> 2012-09-05 
21:39:56 UTC ---
I support this enhancement request with additional explanation.

The documentation for asm goto in the online docs for gcc 4.7.1 contain an
example using a jump table. This is done by creating the jump table inside the
asm statement, using ".pushsection" and ".popsection" directives to move the
actual jump table data into a dedicated section.

This does not work on x86 PE targets.

2 possible workarounds come to mind:
a) Using explicit sections, like ".section bla; ... ;.section .text;"
But this has limitations, since you cannot use it in a function that will go to
a different section than the .text section, something pretty common for driver
code, where initialization code is put in ".INIT" and pageable code is put in
".PAGE". For my usage scenario (exception handling for reactos) this approach
will not work.

b) Use C-style jump tables. "static void *jmp_table[] = {&&label1, &&label2};"
This has also the advantage that it integrates better with the rest of the C
code and allows to reuse the jump tables in C code.

Sadly solution b) is broken.

Here's an example:

int
example1(int param)
{
    int value = 0;

    if (param > 2)
        asm goto ("movl %0, %%ecx\n\tjmp %l[label1]\n" : : "i"(&&label1) :
"ecx" : label1);

    value = 1;

    if (param > 1)
        asm goto ("movl %0, %%ecx\n\tjmp %l[label1]\n" : : "i"(&&label1) :
"ecx" : label1);

    value = 2;

label1:
    return value;
}


The compiler output looks like this (cleaned up):

_example1:
    movl    4(%esp), %edx
    cmpl    $2, %edx
    jle    L2
    movl $L3, %ecx
    jmp L4
L2:
    movl    $2, %eax
    cmpl    $1, %edx
    jle    L3
    movl $L3, %ecx
    jmp L6
    ret
L4:
    movl    $0, %eax
    ret
L6:
    movl    $1, %eax
L3:
    rep
    ret


The 2 jmp instructions jump to L4 and L6, while both mov instructions point
to L3. A jump from the asm goto to L3 would result in broken behaviour.

Using asm goto with C style jump tables causes the compiler to generate code
pathes that are incompatible with a jump to the static address of the label, as
stored in the jump table.

When a simple goto can correctly jump to addresses in static tables, then asm
goto should be able to do that as well.
There should also not be a big performance penalty for that, since the compiler
can simple move whatever is now put in the individual pathes to the place
before the asm goto is emitted.

Reply via email to