Keil™, An ARM® Company

RealView Compiler User's Guide

About intrinsics

3.1.1. About intrinsics

C and C++ are suited to a wide variety of tasks but do not provide inbuilt support for specific areas of application, for example, Digital Signal Processing (DSP).

Within a given application domain, there is usually a range of domain-specific operations that need to be performed frequently. Often, however, these operations cannot be efficiently implemented in C or C++. A typical example is the saturated add of two 32-bit signed two’s complement integers, commonly used in DSP programming. Example 3.1 shows its implementation in C.

Example 3.1. C implementation of saturated add operation

#include <limits.h>

int L_add(const int a, const int b)
{
    int c;

    c = a + b;
    if (((a ^ b) & INT_MIN) == 0)
    {
        if ((c ^ a) & INT_MIN)
        {
            c = (a < 0) ? INT_MIN : INT_MAX;
        }
    }
    return c;
}

Intrinsic functions provide a way of easily incorporating domain-specific operations in C and C++ source code without resorting to complex implementations, for example, in embedded assembler or inline assembler. An intrinsic function has the appearance of a function call in C or C++, but is replaced during compilation by a specific sequence of low-level instructions. When implemented using an intrinsic, for example, the saturated add function of Example 3.1 has the form:

#include <dspfns.h>    /* Include ETSI intrinsics */
...
int a, b, result;
...
result = L_add(a, b);  /* Saturated add of a and b */

The use of intrinsics offers several performance benefits:

  • The low-level instructions substituted for an intrinsic might be more efficient than corresponding implementations in C or C++, resulting in both reduced instruction and cycle counts. To implement the intrinsic, the compiler automatically generates the best sequence of instructions for the specified target architecture. For example, the L_add intrinsic maps directly to the ARM v5TE assembly language instruction qadd:

    QADD r0, r0, r1    /* Assuming r0 = a, r1 = b on entry */
    
  • An intrinsic never makes unnecessary function calls, so function call overhead is minimized. These performance benefits can be significant for real-time processing applications. Care needs to be taken when using intrinsics, however, because their use can decrease code portability.

Copyright © 2007 ARM Limited. All rights reserved.ARM DUI 0375A