2.4.5. Float vs. double

On C2000 devices without FPU64 hardware support, there is significant overhead when application compiled for EABI performs operations on double types.

In EABI, the double type is mapped to 64-bit double-precision floating point. Refer to Application Binary Interface (ABI) for details. An application compiled for EABI (--abi=eabi) can introduce double precision floating point operations in the following ways:

  1. Explicit use of the double type. Avoid using the double type unless the additional accuracy/range is required by the application.

  2. Implicitly via floating point constants. Use the f suffix when the constant can be treated as a single precision floating point constant.

    Floating point constants without the f suffix are treated as double-precision by the compiler. This behavior is mandated by the C standard. This can lead to unexpected introduction of double precision operations in the application. Table 2.10 illustrates this inefficiency - the constant is treated as double precision, leading to conversion of x from float to double precision. The multiply is a double precision operation and the result is converted back to single precision.

    Table 2.9 Single and double-precision floating point constants

    Constant (treated as double)

    Constant with f suffix (treated as float)

    float foo1(float x)
    {
        return x * 42.2;
    }
    
    float foo2(float x)
    {
        return x * 42.2f;
    }
    
    Table 2.10 Comparison of generated assembly

    Operations performed in double precision

    Operations performed in single precision

    ||foo1||:
            ADDB      SP,#8
            MOVZ      AR4,SP
            SUBB      XAR4,#8
            MOVZ      AR6,AR4
            LCR       #||__c28xabi_ftod||
            ; call occurs [#||__c28xabi_ftod||]
            MOVZ      AR4,SP
            MOVZ      AR6,SP
            MOVL      XAR5,#$C$FL1
            SUBB      XAR4,#8
            SUBB      XAR6,#4
            MOVZ      AR4,AR4
            MOVZ      AR6,AR6
            LCR       #||__c28xabi_mpyd||
            ; call occurs [#||__c28xabi_mpyd||]
            MOVZ      AR4,SP
            SUBB      XAR4,#4
            MOVZ      AR4,AR4
            LCR       #||__c28xabi_dtof||
            ; call occurs [#||__c28xabi_dtof||]
            SUBB      SP,#8
            LRETR
            ; return occurs
    
    ||foo2||:
            MOVIZ     R1H,#16936
            MOVXI     R1H,#52429
            MPYF32    R0H,R1H,R0H
            LRETR
            ; return occurs
    
  3. Math routines such as sqrt from the C Standard Library. In COFF, since float and double are both 32-bit single precision, there is no distinction between sqrt and sqrtf. However, with EABI, sqrtf operates on a float argument, sqrt operates on double.

Detecting double precision operations

The compiler option --float_operations_allowed=32 can be used to detect if an application is inadvertently using double precision operations.

This option restricts the type of floating point operations allowed in the application. The default is all. If set to none, 32, or 64, the application is checked for operations that will be performed at runtime. For example, if --float_operations_allowed=32 is specified on the command line, the compiler issues an error if the application contains double precision operations. For details, refer to TMS320C28x Optimizing C/C++ Compiler User’s Guide.