Inline assembly statements (IBM extension)

Under extended language levels, the compiler provides support for embedded assembly code fragments among C source statements. This extension has been implemented for use in general system programming code, and in the operating system kernel and device drivers, which were originally developed with GNU C.

The keyword asm stands for assembly code. When strict language levels are used in compilation, the C compiler treats asm as a regular identifier and reserves __asm and __asm__ as keywords.

The syntax is as follows:
Read syntax diagramSkip visual syntax diagram
asm statement syntax — statement in local scope

>>-+-asm-----+--+----------+------------------------------------>
   +-__asm---+  '-volatile-'   
   '-__asm__-'                 

>--(--code_format_string--+------------------------------------------------------+--)-><
                          '-:--+--------+--+-----------------------------------+-'      
                               '-output-'  '-:--+-------+--+-----------------+-'        
                                                '-input-'  '-:--+----------+-'          
                                                                '-clobbers-'            

input

   .-,--------------------------------------------.   
   V                                              |   
|----+----------+--constraint--(--C_expression--)-+-------------|
     '-modifier-'                                     

output

   .-,----------------------------------------.   
   V                                          |   
|----modifier--constraint--(--C_expression--)-+-----------------|

volatile
The qualifier volatile instructs the compiler to perform only minimal optimizations on the assembly block. The compiler cannot move any instructions across the implicit fences surrounding the assembly block. See Example 1 for detailed usage information.
code_format_string
The code_format_string is the source text of the asm instructions and is a string literal similar to a printf format specifier.

Operands are referred to in the %integer format, where integer refers to the sequential number of the input or output operand. See Example 1 for detailed usage information.

To increase readability, each operand can be given a symbolic name enclosed in brackets. In the assembler code section, you can refer to each operand in the %[symbolic_name] format, where the symbolic_name is referenced in the operand list. You can use any name, including existing C symbols, because the symbolic names have no relation to any C identifiers. However, no two operands in the same assembly statement can use the same symbolic name. See Example 2 for detailed usage information.

output
The output consists of zero, one or more output operands, separated by commas. Each operand consists of a constraint(C_expression) pair. The output operand must be constrained by the = or + modifier (described below), and, optionally, by an additional % or & modifier.
input
The input consists of zero, one or more input operands, separated by commas. Each operand consists of a constraint(C_expression) pair.
clobbers
clobbers is a comma-separated list of register names enclosed in double quotes. If an asm instruction updates registers that are not listed in the input or output of the asm statement, the registers must be listed as clobbered registers. The following register names are valid :
r0 to r31
General purpose registers
f0 to f31
Floating-point registers
lr
Link register
ctr
Loop count, decrement and branching register
fpscr
Floating-point status and control register
xer
Fixed-point exception register
cr0 to cr7
Condition registers. Example 3 shows a typical use of condition registers in the clobbers.
v0 to v31
Vector registers (on selected processors only)
In addition to the register names, cc and memory can also be used in the list of clobbered registers. The usage information of cc and memory is listed as follows:
cc
Add cc to the list of clobbered registers if assembler instructions can alter the condition code register.
memory

Add memory to the clobber list if assembler instructions can change a memory location in an unpredictable fashion. The memory clobber ensures that the compiler does not to move the assembler instruction across other memory references and ensures that any data that is used after the completion of the assembly statement is valid.

However, the memory clobber can result in many unnecessary reloads, reducing the benefits of hardware prefetching. Thus, the memory clobber can impose a performance penalty and should be used with caution. See Example 4 and Example 1 for the detailed usage information.

modifier
The modifier can be one of the following operators:
=
Indicates that the operand is write-only for this instruction. The previous value is discarded and replaced by output data. See Example 5 for detailed usage information.
+
Indicates that the operand is both read and written by the instruction. See Example 6 for detailed usage information.
&
Indicates that the operand may be modified before the instruction is finished using the input operands; a register that is used as input should not be reused here.
%
Declares the instruction to be commutative for this operand and the following operand. This means that the order of this operand and the next may be swapped when generating the instruction. This modifier can be used on an input or output operand, but cannot be specified on the last operand. See Example 7 for detailed usage information.
constraint
The constraint is a string literal that describes the kind of operand that is permitted, one character per constraint. The following constraints are supported:
b
Use a general register other than zero. Some instructions treat the designation of register 0 specially, and do not behave as expected if the compiler chooses r0. For these instructions, the designation of r0 does not mean that r0 is used. Instead, it means that the literal value 0 is specified. See Example 8 for detailed usage information.
c
Use the CTR register.
d
Use a floating-point register.
f
Use a floating-point register. See Example 7 for detailed usage information.
g
Use a general register, memory, or immediate operand. In the POWER® architecture, there are no instructions where a register, memory specifier, or immediate operand can be used interchangeably. However, this constraint is tolerated where it is possible to do so.
h
Use the CTR or LINK register.
i
Use an immediate integer or string literal operand.
l
Use the CTR register.
m
Use a memory operand supported by the machine. You can use this constraint for operands of the form D(R), where D is a displacement and R is a register. See Example 9 for detailed usage information.
n
Use an immediate integer.
o
Use a memory operand that is offsetable. This means that the memory operand can be addressed by adding an integer to a base address. In the POWER architecture, memory operands are always offsetable, so the constraints o and m can be used interchangeably.
r
Use a general register. See Example 5 for detailed usage information.
s
Use a string literal operand.
v
Use a vector register.
0, 1, …8, 9
A matching constraint. Allocate the same register in output as in the corresponding input.
I, J, K, L, M, N, O, P
Constant values. Fold the expression in the operand and substitute the value into the % specifier. These constraints specify a maximum value for the operand, as follows:
  • I — signed 16-bit
  • J — unsigned 16-bit shifted left 16 bits
  • K — unsigned 16-bit constant
  • L — signed 16-bit shifted left 16 bits
  • M — unsigned constant greater than 31
  • N — unsigned constant that is an exact power of 2
  • O — zero
  • P — signed whose negation is a signed 16-bit constant
C_expression

The C_expression is a C expression whose value is used as the operand for the asm instruction. Output operands must be modifiable lvalues. The C_expression must be consistent with the constraint specified on it. For example, if i is specified, the operand must be an integer constant number.

Note: If pointer expressions are used in input or output, the assembly instructions honor the ANSI aliasing rule (see Type-based aliasing for more information). This means that indirect addressing using values in pointer expression operands should be consistent with the pointer types; otherwise, you must disable the -qalias=ansi option during compilation.


Voice your opinion on getting help information Ask IBM compiler experts a technical question in the IBM XL compilers forum Reach out to us