Changes between Version 22 and Version 23 of TBR/UserManual/Floating_Point_Support


Ignore:
Timestamp:
Jun 27, 2020, 6:12:30 PM (2 weeks ago)
Author:
Jens Schweikhardt
Comment:

s,</code>,}}}, to fix markup.

Legend:

Unmodified
Added
Removed
Modified
  • TBR/UserManual/Floating_Point_Support

    v22 v23  
    1414
    1515
    16 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.
     16The presence or absence of the {{{RTEMS_FLOATING_POINT}}} attribute in the call to {{{rtems_task_create()}}} determines whether or not the task is floating-point enabled.
    1717
    1818From the ''RTEMS C User's Guide'':
     
    2828
    2929
    30 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>
     30The RTEMS Init task is not floating point by default (has {{{RTEMS_DEFAULT_ATTRIBUTES}}}). It can be made floating point by #defining {{{CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT}}} before including {{{confdefs.h}}}
    3131=  POSIX API  =
    3232
     
    4444  #endif
    4545
    46 {{{is_fp</code> is then used in a call to {{{_Thread_Initialize</code>, similar to the ITRON code segment below.
     46{{{is_fp}}} is then used in a call to {{{_Thread_Initialize}}}, similar to the ITRON code segment below.
    4747=  ITRON API  =
    4848
     
    7070
    7171
    72 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):
     72Throughout 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}}} (edited here for simplification):
    7373{{{
    7474 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
     
    9090Technically 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".
    9191
    92 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>.
     92The 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}}}.
    9393
    94 For example, for the {{{sparc</code> CPU:
     94For example, for the {{{sparc}}} CPU:
    9595{{{
    9696/*
     
    109109}}}
    110110
    111 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.
     111For more details about this precompiler definition and others related to floating point specializations, read the comments in any {{{cpu.h}}} file, and (even more informative) the file in the RTEMS source tree {{{doc/porting/taskcontext.t}}}, which gets built into a nice document somewhere if you build the docs, but is readable as-is.
    112112
    113 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}}}
     113Most 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}}} 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}}}. For eample, for the {{{sparc}}}
    114114
    115115 #if defined(_SOFT_FLOAT)
     
    119119 #endif
    120120
    121 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</code> (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).
     121In 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}}}). '''<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).
    122122
    123 In addition to the preprocessor definitions for floating point settings, the cpukit/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>.
     123In addition to the preprocessor definitions for floating point settings, the cpukit/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}}}.
    124124= Compiler Support =
    125125
     
    127127This 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.
    128128
    129 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.
     129In 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>}}} with several supported CPU types. Also typically, there is an option such as {{{-msoft-float}}} 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.
    130130=  Disaster Strikes  =
    131131
    132132
    133 '''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. And there is no GCC-provided option to specifically tell the compiler not to use FPU registers for integer variables, short of the {{{-msoft-float</code> (or equivalent) telling the compiler that no FPU exists at all.
     133'''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. And there is no GCC-provided option to specifically tell the compiler not to use FPU registers for integer variables, short of the {{{-msoft-float}}} (or equivalent) telling the compiler that no FPU exists at all.
    134134
    135 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! Rather than have the kernel "FPU-safe", which would be painful and less portable, the RTEMS build process uses {{{-msoft-float</code> (or equivalent) so that when compiling the RTEMS libraries, the compiler is specifically instructed not to emit FPU instructions or use FPU registers at all.
     135From 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! Rather than have the kernel "FPU-safe", which would be painful and less portable, the RTEMS build process uses {{{-msoft-float}}} (or equivalent) so that when compiling the RTEMS libraries, the compiler is specifically instructed not to emit FPU instructions or use FPU registers at all.
    136136
    137 But now, any cpukit/BSP that determines whether the CPU has hardware floating point by using a preprocessor definition automatically set by the compiler as a result of {{{-msoft-float</code> (or equivalent), as many of them currently do (RTEMS 4.8.1 release, and CVS head as of July 13, 2009), will because of this completely disable the RTEMS library floating point support. So a user application that would like to use floating point will not be able to - RTEMS will not save the floating point context, etc. In fact, RTEMS will probably not enable the floating point unit, likely resulting in "exception conditions" as noted above. All user code in this condition must also be compiled and linked with {{{-msoft-float</code> (or equivalent).
     137But now, any cpukit/BSP that determines whether the CPU has hardware floating point by using a preprocessor definition automatically set by the compiler as a result of {{{-msoft-float}}} (or equivalent), as many of them currently do (RTEMS 4.8.1 release, and CVS head as of July 13, 2009), will because of this completely disable the RTEMS library floating point support. So a user application that would like to use floating point will not be able to - RTEMS will not save the floating point context, etc. In fact, RTEMS will probably not enable the floating point unit, likely resulting in "exception conditions" as noted above. All user code in this condition must also be compiled and linked with {{{-msoft-float}}} (or equivalent).
    138138= Escaping Disaster =
    139139
     
    141141There are several options at this point:
    142142
    143  *  Just live with it, compile and link everything with {{{-msoft-float</code> (or equivalent), and do not use hardware floating point. For many BSPs, this is what will happen by default; the standard RTEMS makefile inclusions for such BSPs will automatically set {{{-msoft-float</code> (or equivalent) for user application builds. Many embedded systems can accept this.
    144  *  Do not base the setting of {{{CPU_HARDWARE_FP</code> ultimately on a compiler definition based on {{{-msoft-float</code> (or equivalent). For example, the {{{cpukit/score/cpu/sparc/rtems/score/sparc.h</code> code shown above could be changed to:
     143 *  Just live with it, compile and link everything with {{{-msoft-float}}} (or equivalent), and do not use hardware floating point. For many BSPs, this is what will happen by default; the standard RTEMS makefile inclusions for such BSPs will automatically set {{{-msoft-float}}} (or equivalent) for user application builds. Many embedded systems can accept this.
     144 *  Do not base the setting of {{{CPU_HARDWARE_FP}}} ultimately on a compiler definition based on {{{-msoft-float}}} (or equivalent). For example, the {{{cpukit/score/cpu/sparc/rtems/score/sparc.h}}} code shown above could be changed to:
    145145
    146146 <strike>#if defined(_SOFT_FLOAT)
     
    150150 <strike>#endif</strike>
    151151
    152  This would result in the RTEMS compilation not generating any floating point usage internally (since {{{-msoft-float</code> (or equivalent) is still set), but because {{{CPU_HARDWARE_FP</code> will be set TRUE, the RTEMS kernel will be built containing the code needed to support floating point tasks in user applications. The user applications do not need to have {{{-msoft-float</code> (or equivalent) applied to code used in floating point tasks. Any code that is (or might be) used in non-floating-point tasks will still need to be compiled with {{{-msoft-float</code> (or equivalent). The linker step needs that option also (to bring in the needed software floating point library code, for the RTEMS kernel even if nothing else).
     152 This would result in the RTEMS compilation not generating any floating point usage internally (since {{{-msoft-float}}} (or equivalent) is still set), but because {{{CPU_HARDWARE_FP}}} will be set TRUE, the RTEMS kernel will be built containing the code needed to support floating point tasks in user applications. The user applications do not need to have {{{-msoft-float}}} (or equivalent) applied to code used in floating point tasks. Any code that is (or might be) used in non-floating-point tasks will still need to be compiled with {{{-msoft-float}}} (or equivalent). The linker step needs that option also (to bring in the needed software floating point library code, for the RTEMS kernel even if nothing else).
    153153
    154  This can be tricky to pull off, since your standard C libraries and so on also need to have been built with {{{-msoft-float</code> (or equivalent), and for some CPUs the GCC documentation indicates that the function calling convention is different for soft- and hard-float, so that mixing the two may not be compatible. But, if your application needs a lot of floating point speed, this is worth a try. You may have to disable or override your BSP's automatic setting of {{{-msoft-float</code> (or equivalent) in your makefiles. If using the standard RTEMS makefile templates, this can be done by inserting {{{CPU_CFLAGS += -mhard-float</code>; that should appear late on the generated command lines and override the soft float. Make sure to test thoroughly for incompatibilities and proper context switches, etc.
     154 This can be tricky to pull off, since your standard C libraries and so on also need to have been built with {{{-msoft-float}}} (or equivalent), and for some CPUs the GCC documentation indicates that the function calling convention is different for soft- and hard-float, so that mixing the two may not be compatible. But, if your application needs a lot of floating point speed, this is worth a try. You may have to disable or override your BSP's automatic setting of {{{-msoft-float}}} (or equivalent) in your makefiles. If using the standard RTEMS makefile templates, this can be done by inserting {{{CPU_CFLAGS += -mhard-float}}}; that should appear late on the generated command lines and override the soft float. Make sure to test thoroughly for incompatibilities and proper context switches, etc.
    155155
    156  *  Have {{{cpu.h</code> set {{{CPU_SOFTWARE_FP TRUE</code>. A quick look through the RTEMS source code indicates that this may work to properly activate the RTEMS library support. However, I have not looked into this thoroughly, and there may be BSP-specific problems with this, such as not enabling the hardware FPU.
     156 *  Have {{{cpu.h}}} set {{{CPU_SOFTWARE_FP TRUE}}}. A quick look through the RTEMS source code indicates that this may work to properly activate the RTEMS library support. However, I have not looked into this thoroughly, and there may be BSP-specific problems with this, such as not enabling the hardware FPU.
    157157 *  Get GCC to provide a specific named optimization option to enable/disable the storage of integer variables in FPU registers. Then instead of deleting all hardware floating point, we could allow it but only for actual floating point activities. Any GCC developers out there?
    158158=  ISR Support  =
    159159
    160160
    161 The core internal RTEMS ISR handler ({{{_ISR_Handler</code>, CPU dependent, generally found in {{{cpukit/score/cpu/<cpu name>/cpu_asm.S</code>), that executes to call user ISR handlers registered via {{{rtems_interrupt_catch</code>, does not save and restore FPU registers (in most if not all CPUs). Thus, user ISR handlers should not modify FPU registers (unless you take care of them yourself).
     161The core internal RTEMS ISR handler ({{{_ISR_Handler}}}, CPU dependent, generally found in {{{cpukit/score/cpu/<cpu name>/cpu_asm.S}}}), that executes to call user ISR handlers registered via {{{rtems_interrupt_catch}}}, does not save and restore FPU registers (in most if not all CPUs). Thus, user ISR handlers should not modify FPU registers (unless you take care of them yourself).
    162162
    163 Given the current state of the GCC compilers, this means user ISR handlers need to be compiled with {{{-msoft-float</code>, so that the compiler does not emit any FPU instructions or use FPU registers as part of the handler.
     163Given the current state of the GCC compilers, this means user ISR handlers need to be compiled with {{{-msoft-float}}}, so that the compiler does not emit any FPU instructions or use FPU registers as part of the handler.
    164164
    165165= An update (Feb/2016) on using Leon2/3 FPU under RTEMS4.11 =