C/C++ and Fortran

 View Only

Inline asm: inputs and outputs

By Archive User posted Thu March 08, 2012 04:55 PM

  

Originally posted by: billo


Hi. This is the first posting in what I hope to be a continuing blog on tips and tricks for inline assembly – a.k.a. asm – which is a way of inserting assembly language into your C and C++ programs. In this blog I won’t be covering basic syntax and semantics (you can get that by consulting a DeveloperWorks article – link at the end), but rather will focus on some of the trickier aspects of using inline asm in your programs. My primary focus will be on the Power architecture. Today I’ll start with tips for input and output operands.

Imagine that, for whatever reason, you wanted to add 88 to a program variable “x” using inline asm. Knowing that Power is a load-store architecture, you might design your asm like this…..
 
 asm ("lwz  5, %0      \n"
            "addi 5, 5, 88   \n"
            "stw  5, %0      \n"
                : "+m"(x)
                :
                : "r5" );

Here we load x into a register (r5), add 88 to it, and store it back to x. We have designated x as a memory operand in the output list, as we are modifying it. We also used a “+” to indicate that we are using its original value as well as modifying it. We are also clobbering r5, as we are using that register for our calculations.
 
However, this is an overly complex asm for what we want to do. Although Power is load/store, you can rely upon the compiler’s implementation of the operands to get data into registers and to store it back. The asm can thus be re-written as this:
 
 asm ( "addi %0,%0, 88   \n"
                : "+r"(x)
                : );
 
This is improved in a number of ways:

  • Three instructions are reduced to one instruction
  • There is no need for a clobbers list
  • The loading and storing of x into and from a register is taken care of by the compiler, and can be optimized by it

Notice that we are no longer using an “m” (i.e. “memory”) operand, but are now using an “r” (for register) operand, and we are letting the compiler take care of loading it with x, and storing its value back into x. NOTE: in a subsequent blog I will discuss why it's sometimes better to use a "b" constraint -- and this is one of those times! Look at the following posting to see why:
 
Inline asm: inputs -- to "b" or not to "b"

The overall lesson here is that it is rarely necessary to use explicit loads and stores in inline asm. One exception to this would be when using the “load with reservation” and “store conditional” instructions (lwarx/stwcx). Other exceptions could be the use of load-multiple or load-with-update instructions. These will be dealt with in future blog entries.
 
A guide to inline assembly for C and C++

Till next time…. Bill
 
 
 
0 comments
1 view

Permalink