Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I tell GCC asm that an input register is clobbered?

I'm trying to do a 64=32x32 multiply via the x86 mul instruction, but I only need the high dword of the result (the edx register). So naturally, I tried listing edx as an output register and eax as a clobbered register.

This seems natural to me, but eax is also an input register. When I try to tell GCC that eax is clobbered, it gives an error message.

__asm__("mull\t%2" : "=d"(div10) : "%a"(UINT32_C(0x1999999A)), "r"(number)
    : "cc", "rax");

If I try that, it throws this error message:

divmod10.cpp:76:91: error: can’t find a register in class ‘AREG’ while reloading
‘asm’
divmod10.cpp:76:91: error: ‘asm’ operand has impossible constraints

Omitting it compiles, but breaks the code. GCC ends up relying upon eax not being clobbered, which is incorrect:

        movl    $429496730, %eax
#APP
# 76 "divmod10.cpp" 1
        mull    %esi
# 0 "" 2
#NO_APP
        movl    %edx, %esi
#APP
# 78 "divmod10.cpp" 1
        mull    %edx
# 0 "" 2
#NO_APP

How do I do what I want?

like image 625
Myria Avatar asked Sep 29 '22 09:09

Myria


People also ask

What is a clobbered register?

A clobbered register is a register which is trashed i.e. modified in unpredictable way by inline assembler. This usually happens when you need a temp. register or use particular instruction which happens to modify some register as a by-product.

What is clobber in asm?

The clobber list is a comma-separated list of strings. Each string is the name of a register that the assembly code potentially modifies, but for which the final value is not important.

What is __ asm __ in C?

The __asm keyword invokes the inline assembler and can appear wherever a C or C++ statement is legal. It cannot appear by itself.

What is extended asm?

The asm statement allows you to include assembly instructions directly within C code. This may help you to maximize performance in time-sensitive code or to access assembly instructions that are not readily available to C programs. Note that extended asm statements must be inside a function.


1 Answers

Just make a useless temp for the output to go into and the compiler will optimize it out. For example:

__asm__("mull\t%2" : "=d"(div10), "=a"((int){0})
    : "a"(UINT32_C(0x1999999A)), "r"(number) : "cc");

That's the easiest way I know to handle clobbered inputs.

like image 62
R.. GitHub STOP HELPING ICE Avatar answered Oct 13 '22 11:10

R.. GitHub STOP HELPING ICE