summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorPeter Mitsis <peter.mitsis@windriver.com>2016-06-30 15:25:59 -0400
committerInaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>2016-07-14 17:26:09 +0000
commit7d39b40f2f5d7166042f9b4ec33d0a81c7fe9fdb (patch)
treeef42b0b7ec808725ca88b5791b6fe1f52dd7250f /doc
parentc9e2fc19299277409f4d2601087e72181fb04e5f (diff)
doc: Update floating point docs for ARM
The x86 architecture is no longer the only one that supports hardware floating point operations. Change-Id: Ib23e032f00661bab87a20872651b284580b8e7e5 Signed-off-by: Peter Mitsis <peter.mitsis@windriver.com>
Diffstat (limited to 'doc')
-rw-r--r--doc/kernel/common/common_float.rst82
1 files changed, 49 insertions, 33 deletions
diff --git a/doc/kernel/common/common_float.rst b/doc/kernel/common/common_float.rst
index c5c927824..b9250013a 100644
--- a/doc/kernel/common/common_float.rst
+++ b/doc/kernel/common/common_float.rst
@@ -4,16 +4,15 @@ Floating Point Services
#######################
.. note::
- Floating point services are currently available only for platforms
- based on the Intel x86 architecture.
+ Floating point services are currently available only for boards
+ based on the ARM Cortex-M4 or the Intel x86 architectures. The
+ services provided are architecture specific.
Concepts
********
The kernel allows an application's tasks and fibers to use floating point
registers on board configurations that support these registers.
-Threads that use the x87 FPU/MMX registers are known as "FPU users",
-while threads that use SSE registers are known as "SSE users".
.. note::
The kernel does not support the use of floating point registers by ISRs.
@@ -51,31 +50,47 @@ whenever a context switch occurs.
Shared FP registers mode
========================
-This mode is used when the application has two or more tasks or fibers
-that use floating point registers.
+This mode is used when the application has two or more threads that use
+floating point registers. Depending upon the underlying CPU architecture,
+the kernel supports one or more of the following thread sub-classes:
+
+* non-user: A thread that cannot use any floating point registers
+
+* FPU user: A thread that can use the standard floating point registers
+
+* SSE user: A thread that can use both the standard floating point registers
+ and SSE registers
The kernel initializes the floating point registers so they can be used
by any task or fiber, then saves and restores these registers during
context switches to ensure the computations performed by each FPU user
or SSE user are not impacted by the computations performed by the other users.
-A "lazy save" algorithm is used during context switching which updates the
-floating point registers only when it is absolutely necessary---for example,
-the registers are *not* saved when switching from an FPU user to a thread
-that does not use the floating point registers, and then switching back
-to the original FPU user.
-
-Every task that uses the floating point registers must provide stack space
-where the kernel can save the registers during context switches. An FPU user
-must provide 108 bytes of added stack space, above and beyond its normal
-requirements; an SSE user must provide 464 bytes of added stack space.
-
-.. note::
- A task that does *not* use the floating point registers does not need
- to provide any added stack space. A fiber does *not* need to provide any
- added stack space, regardless of whether or not it uses the floating
- point registers.
-The kernel automatically detects that a given task or fiber is using
+On the ARM Cortex-M4 architecture the kernel treats *all* tasks and fibers
+as FPU users when shared FP registers mode is enabled. This means that the
+floating point registers are saved and restored during a context switch, even
+when the associated threads are not using them. Each task and fiber must
+provide an extra 132 bytes of stack space where these register values can
+be saved.
+
+On the x86 architecture the kernel treats each task and fiber as a non-user,
+FPU user or SSE user on a case-by-case basis. A "lazy save" algorithm is used
+during context switching which updates the floating point registers only when
+it is absolutely necessary. For example, the registers are *not* saved when
+switching from an FPU user to a non-user thread, and then back to the original
+FPU user. The following table indicates the amount of additional stack space a
+thread must provide so the registers can be saved properly.
+
+=========== =============== ==========================
+Thread type FP register use Extra stack space required
+=========== =============== ==========================
+fiber any 0 bytes
+task none 0 bytes
+task FPU 108 bytes
+task SSE 464 bytes
+=========== =============== ==========================
+
+The x86 kernel automatically detects that a given task or fiber is using
the floating point registers the first time the thread accesses them.
The thread is tagged as an SSE user if the kernel has been configured
to support the SSE registers, or as an FPU user if the SSE registers are
@@ -84,12 +99,13 @@ tagged as an SSE user, or if the application wants to avoid the exception
handling overhead involved in auto-tagging threads, it is possible to
pre-tag a thread using one of the techniques listed below.
-* A task or fiber can tag itself as an FPU user or SSE user by calling
+* An x86 task or fiber can tag itself as an FPU user or SSE user by calling
:c:func:`task_float_enable()` or :c:func:`fiber_float_enable()`
once it has started executing.
-* A fiber can be tagged as an FPU user or SSE user by its creator
- when the fiber is started.
+* An x86 fiber can be tagged as an FPU user or SSE user by its creator
+ by calling :c:func:`fiber_start()` with the :c:macro:`USE_FP` or
+ :c:macro:`USE_SSE` option, respectively.
* A microkernel task can be tagged as an FPU user or SSE user by adding it
to the :c:macro:`FPU` task group or the :c:macro:`SSE` task group
@@ -100,11 +116,11 @@ pre-tag a thread using one of the techniques listed below.
by calling :c:func:`task_group_join()` does *not* tag the task
as an FPU user or SSE user.
-If a task or fiber uses the floating point registers infrequently
-it can call :c:func:`task_float_disable()` or :c:func:`fiber_float_disable()`
-to remove its tagging as an FPU user or SSE user. This eliminates the need
-for the kernel to take steps to preserve the contents of the floating point
-registers during context switches when there is no need to do so.
+If an x86 thread uses the floating point registers infrequently it can call
+:c:func:`task_float_disable()` or :c:func:`fiber_float_disable()` as
+appropriate to remove its tagging as an FPU user or SSE user. This eliminates
+the need for the kernel to take steps to preserve the contents of the floating
+point registers during context switches when there is no need to do so.
When the thread again needs to use the floating point registers it can re-tag
itself as an FPU user or SSE user using one of the techniques listed above.
@@ -133,7 +149,7 @@ sufficient added stack space for saving floating point register values
during context switches, as described above.
Use the :option:`CONFIG_SSE` configuration option to enable support for
-SSEx instructions.
+SSEx instructions (x86 only).
Example: Performing Floating Point Arithmetic
@@ -162,7 +178,7 @@ Note that no special coding is required if the kernel is properly configured.
APIs
****
-The following floating point services APIs are provided by
+The following floating point services APIs (x86 only) are provided by
:file:`microkernel.h` and by :file:`nanokernel.h`:
:c:func:`fiber_float_enable()`