3.3 Inline assembly with Arm® Compiler 6

Inline assembly in Arm® Compiler 6 must be written in GNU assembly syntax. Inline assembly in Arm Compiler 5 is written in armasm syntax. If you have inline assembly written in armasm syntax, you must modify this to use GNU assembly syntax.

In Arm Compiler 5:

  • You can use C variable names directly inside inline assembly statements.
  • You do not have direct access to physical registers. You must use C or C++ variables names as operands, and the compiler maps them to physical register. You must set the value of these variables before you read them within an inline assembly statement.
  • If you use register names in inline assembly code, they are treated as C or C++ variables. They do not necessarily relate to the physical register of the same name. If the register name is not declared as a C or C++ variable, the compiler generates a warning.

In Arm Compiler 6:

  • You cannot use C or C++ variable names directly inside inline assembly statements. You can map the physical registers to C or C++ variable names using operand mapping and constraints.
  • You have direct access to physical registers. There is no need to set the value of the registers before you read them within inline assembly statements.
  • If you use register names in inline assembly code, they are the physical register of the same name.

In Arm Compiler 6 you cannot use C variable names directly within inline assembly. However, the GNU assembly syntax in Arm Compiler 6 provides a way for mapping input and output operands to C variable names.

Arm Compiler 5 optimizes inline assembly, but Arm Compiler 6 emits it exactly as written.

For more information on writing inline assembly using __asm in armclang, see __asm.

For more information on GNU assembly syntax, see 5.2 Overview of differences between armasm and GNU syntax assembly code.

Inline assembly example in Arm® Compiler 5

The example below shows inline assembly code in Arm Compiler 5.

foo.c: 

int add(int i, int j)
{
    int res;
    __asm
    (
      "ADD res, i, j \t\n"
      "SUB res, i, res \t\n"
    );
    return res;
}

The example below shows an alternative syntax for inline assembly code in Arm Compiler 5.

foo.c: 

int add(int i, int j)
{
    int res;
    __asm
    {
        ADD   res, i, j 
        SUB   res, i, res
    }
    return res;
}

Compile foo.c using armcc:

armcc foo.c -c -S -o foo.s

Arm Compiler 5 converts the example inline assembly code to:

foo.s: 

add PROC 
        ADD r1,r0,r1
        SUB r0,r0,r1
        BX  lr
        ENDP

Inline assembly example in Arm® Compiler 6

The example below shows the equivalent inline assembly code in Arm Compiler 6.

foo.c: 

int add(int i, int j)
{
  int res = 0;
  __asm 
  (
    "ADD %[result], %[input_i], %[input_j] \t\n"
    "SUB %[result], %[input_i], %[result]  \t\n"
    : [result] "=&r" (res)
    : [input_i] "r" (i), [input_j] "r" (j)
  );
  return res;
}

Compile foo.c using armclang with optimization level -O1:

armclang foo.c --target=arm-arm-none-eabi -march=armv8-a -O1 -c -S -o foo.s

Arm Compiler 6 converts the example inline assembly code to:

foo.s: 

add:  
        .fnstart
@ BB#0:
        @APP
        add r2,r0,r1
        sub r2,r0,r2
        @NO_APP
        mov r0,r2
        bx  lr

Note:

Arm Compiler 6 supports inline assembly using the __asm or asm keywords. However the asm keyword is accepted only when:

  • Used within C++ language source files.
  • Used within C language source files without strict ISO C Standard compliance. For example, asm is accepted when using -std=gnu11.
Non-ConfidentialPDF file icon PDF version100068_0609_00_en
Copyright © 2014–2017 Arm Limited (or its affiliates). All rights reserved.