Version 8 (modified by Kptrs, on Jul 12, 2009 at 6:09:39 AM) (diff)

Floating Point Support

RTEMS provides software and hardware floating-point support. However, there are some issues to beware of when building RTEMS and when building your applications.

This page has been written from a SPARC BSP perspective, so some things here may not be generally applicable. And it has been initially written by an experienced RTEMS user, but not by an actual RTEMS developer, so this is not definitive and there could be misunderstandings here. Feel free to improve this page.

Task/Thread? Support


The presence or absence of the {{{RTEMS_FLOATING_POINT</code> attribute in the call to {{{rtems_task_create()</code> determines whether or not the task is floating-point enabled.

From the RTEMS C User's Guide:

Creating a task with the RTEMS_FLOATING_POINT attribute flag results in additional memory being allocated for the TCB to store the state of the numeric coprocessor during task switches. This additional memory is NOT allocated for RTEMS_NO_FLOATING_POINT tasks. Saving and restoring the context of a RTEMS_FLOATING_POINT task takes longer than that of a RTEMS_NO_FLOATING_POINT task because of the relatively large amount of time required for the numeric coprocessor to save or restore its computational state.


If the supported processor type does not have hardware floating capabilities or a standard numeric coprocessor, RTEMS will not provide built-in support for hardware floating point on that processor. In this case, all tasks are considered RTEMS_NO_FLOATING_POINT whether created as RTEMS_FLOATING_POINT or RTEMS_NO_FLOATING_POINT tasks. A floating point emulation software library must be utilized for floating point operations.

On some processors, it is possible to disable the floating point unit dynamically. If this capability is supported by the target processor, then RTEMS will utilize this capability to enable the floating point unit only for tasks which are created with the RTEMS_FLOATING_POINT attribute. The consequence of a RTEMS_NO_FLOATING_POINT task attempting to access the floating point unit is CPU dependent but will generally result in an exception condition.

RTEMS Init Task

The RTEMS Init task is not floating point by default (has {{{RTEMS_DEFAULT_ATTRIBUTES</code>). It can be made floating point by #defining {{{ CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT</code> before including {{{confdefs.h</code>


All POSIX threads are floating point, if either software or hardware floating point is defined to be available at the time of compilation of the RTEMS libraries (see more below). From pthreadcreate.c:


  • Currently all POSIX threads are floating point if the hardware
  • supports it. */

is_fp = true;


is_fp = false;


{{{is_fp</code> is then used in a call to {{{_Thread_Initialize</code>, similar to the ITRON code segment below.


All ITRON tasks are floating point, if either software or hardware floating point is defined to be available at the time of compilation of the RTEMS libraries (see more below). From cre_tsk.c:

status = _Thread_Initialize(

&_ITRON_Task_Information, the_thread, NULL, pk_ctsk->stksz,


TRUE, /* XXX - All tasks FP (if the HW supports it) for now */




core_priority, TRUE, /* preemptible */ THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE, NULL, /* no budget algorithm callout */ 0, name


RTEMS Library Support

Throughout the RTEMS kernel, actions are taken to support floating point, if either software or hardware floating point is defined to be available at the time of compilation of the RTEMS libraries. For example, from {{{threaddispatch.c</code> (edited here for simplification):

    if ( executing->fp_context != NULL )
      _Context_Save_fp( &executing->fp_context );

    _Context_Switch( &executing->Registers, &heir->Registers );

    if ( executing->fp_context != NULL )
      _Context_Restore_fp( &executing->fp_context );

If floating point is defined as available, and if the executing task has a floating point context, then that context will be saved and restored in context switches. But where do these definitions of floating point support come from? Read on.

BSP/cpukit Support

Technically I should probably call this "cpukit support" rather than "BSP support." However, since often someone looking into a board port needs to at least look at the CPU support, and possibly adjust it, I am considering the cpukit as part of the "greater BSP".

The definitions controlling floating point support for the RTEMS kernel are found in a CPU-dependent header file in the RTEMS source tree, typically {{{cpukit/score/cpu/<cpu name>/rtems/score/cpu.h</code>.

For example, for the {{{sparc</code> CPU:

 *  Does the CPU have hardware floating point?
 *  If TRUE, then the FLOATING_POINT task attribute is supported.
 *  If FALSE, then the FLOATING_POINT task attribute is ignored.

#if ( SPARC_HAS_FPU == 1 )

For more details about this precompiler definition and others related to floating point specializations, read the comments in any {{{cpu.h</code> file, and (even more informative) the file in the RTEMS source tree {{{doc/porting/taskcontext.t</code>, which gets built into a nice document somewhere if you build the docs, but is readable as-is.

Most CPUs are really a CPU family, some members of which have hardware floating point and some do not. Thus, in the example above, the definition of SPARC_HAS_FPU</code> comes from another header file that specifies the different members of the CPU family, typically {{{cpukit/score/cpu/<cpu name>/rtems/score/<cpu name>.h</code>. For eample, for the {{{sparc

#if defined(_SOFT_FLOAT) #define SPARC_HAS_FPU 0 #else #define SPARC_HAS_FPU 1 #endif

In theory, the determination of whether the CPU has a hardware FPU should be made based on knowledge of which CPU is involved. In practice, the determination is commonly made based on a definition set by the compiler based on compiler command line arguments such as -msoft-float (in the example above, if that compiler option is provided, then the SPARC cross-compiler automatically sets the preprocessor definition {{{_SOFT_FLOAT</code>). <big>This is often a mistake,</big> because there are other reasons for telling the compiler to use software floating point besides absence of a hardware FPU (see below).

In addition to the preprocessor definitions for floating point settings, the BSP must provide the actual functions for various operations such as saving and restoring the floating point context, since they are CPU dependent. These are typically found in {{{cpukit/score/cpu/<cpu name>/cpu_asm.S</code>.

Compiler Support

This is specific to GCC cross-compilers, since those are the compilers generally expected for RTEMS, and are the ones I have experience using with RTEMS.

In general, a GCC cross-compiler has command line options for specifying what member of a CPU family for which to specialize the object code, as well as command line options to enable use of specific CPU features/accessories, such as a hardware FPU. Typically, the specific CPU has an option like {{{-mcpu=<cpu_type></code> with several supported CPU types. Also typically, there is an option such as {{{-msoft-float</code> to tell GCC to use software floating point subroutines (generally in some compiler-provided library) rather than generating hardware FPU instructions and using hardware FPU registers.

This raises a problem. Unfortunately, GCC versions since 3.4 or so and up to at least 4.3.3 (I think) will sometimes use registers in a hardware floating point unit as temporary storage, even for integer variables. There is some indication that maybe using an optimization level less than 3 avoids this, though it is not obvious that any of the documented level 3 optimizations have anything to do with this, and that might be CPU-dependent.

From the perspective of the RTEMS kernel, this means that even tasks that are not floating point might try to access hardware FPU registers thanks to compiler tricks. Even worse, the kernel code itself (which does not use floating point) might be "unknowingly" compiled to use floating point registers!