C/C++ and Fortran

 View Only

Inline asm: inputs -- to "b" or not to "b"

By Archive User posted Fri May 18, 2012 02:16 PM

  

Originally posted by: billo


In a previous post I showed how to use the operand syntax of inline asm to eliminate the need for explicit loads and stores in the asm code. I wound up with an asm like this...
 
asm ( "addi %0,%0, 88   \n"
                : "+r"(x)
                : );
 
However, there is a subtle problem with this code that is often overlooked (including by myself) -- the dreaded r0 problem. Certain instructions on Power have special semantics when one of the register input operands is r0. For example, in the case of addi, if the second operand is r0, it will use the literal zero instead of the contents of r0. However, because you are using a compiler to do the allocation of registers, there is every chance in an asm like this that the compiler will choose r0 for the operand %0. If that happens it will typically result in a segmentation violation at run time (if, for instance, if the addi was being used to calculate an address).
 
To avoid this problem when using an instruction for which one of its operands has special meaning for r0, use "b" as the operand constraint instead of "r". This tells the compiler not to use r0. NOTE: there would be no practical way for the compiler to deduce this automatically, as it would have to be able to parse every possible assembly instruction to determine if there were such an instruction used. The corrected example is as follows:

asm ( "addi %0,%0, 88   \n"
                : "+b"(x)
                : );

The "b" constraint is not needed for instructions that aren't sensitive to the use of r0 as an input. For instance, adde, addc, addic, and related instructions don't need the "b" constraint. If you don't need to use "b" it's best not to, as that gives the compiler a little more freedom in choosing registers, which might ultimately result in faster code (for example, by avoiding a register spill).

Till next time... Bill
0 comments
0 views

Permalink