The Arm® Compiler toolchain supports an interface to the status word in the floating-point environment. This interface is provided as function
__ieee_status() and it is generally the most efficient function to use for modifying the status word for VFP.
NoteThe Arm Compiler toolchain does not support floating-point exception trapping for AArch64 targets.
__ieee_status() is defined in fenv.h.
The function prototype for
NoteThis function requires a floating-point model that supports exceptions. In Arm Compiler 6 this is disabled by default, and can be enabled by the armclang command-line option
__ieee_status() modifies the writable
parts of the status word according to the parameters, and returns the previous value of the
The writable bits are modified by setting them to:
new = (old & ~mask) ^ flags;
Four different operations can be performed on each bit of the status word, depending on the corresponding bits in mask and flags.
Table 5-2 Status word bit modification
|Bit of mask||Bit of flags||Effect|
|1||0||Set to 0|
|1||1||Set to 1|
The layout of the status word as seen by
__ieee_status() is as follows:
Figure 5-2 IEEE status word layout
The fields in the status word are as follows:
Bits 0 to 4 (values
0x10, respectively) are the sticky flags, or cumulative flags, for each exception. The sticky flag for an exception is set to 1 whenever that exception happens and is not trapped. Sticky flags are never cleared by the system, only by the user. The mapping of exceptions to bits is:
- Bit 0 (
0x01) is for the Invalid Operation exception
- Bit 1 (
0x02) is for the Divide by Zero exception.
- Bit 2 (
0x04) is for the Overflow exception.
- Bit 3 (
0x08) is for the Underflow exception.
- Bit 4 (
0x10) is for the Inexact Result exception.
- Bit 0 (
- Bits 8 to 12 (values
0x1000) are the exception masks. These control whether each exception is trapped or not. If a bit is set to 1, the corresponding exception is trapped. If a bit is set to 0, the corresponding exception sets its sticky flag and returns a plausible result.
- Bits 16 to 18, and bits 20 and 21, are used by VFP
hardware to control the VFP vector capability. The
__ieee_status()call does not let you modify these bits.
Bits 22 and 23 control the rounding mode. See the following table.
Table 5-3 Rounding mode control
Bits Rounding mode
Round to nearest
Round toward zero
NoteThe relevant libraries are selected by default in Arm Compiler 6. For more information, see the armclang command-line option
Bit 24 enables FZ (Flush to Zero) mode if it is set. In FZ mode, denormals are forced to zero to speed up processing because denormals can be difficult to work with and slow down floating-point systems. Setting this bit reduces accuracy but might increase speed.
- The FZ bit in the IEEE status word is not supported by any of the fplib variants. This means that switching between flushing to zero and not flushing to zero is not possible with any variant of fplib at runtime. However, flushing to zero or not flushing to zero can be set at compile time as a result of the library you choose to build with.
- Some functions are not provided in hardware. They exist only in the software floating-point libraries. So these functions cannot support the FZ mode, even when you are compiling for a hardware VFP architecture. As a result, behavior of the floating-point libraries is not consistent across all functions when you change the FZ mode dynamically.
- Bit 27 indicates that saturation has occurred in an Advanced SIMD
saturating integer operation. This is accessible through the
- Bits marked R are reserved. They cannot be written to by the
__ieee_status()call, and you must ignore anything you find in them.
In addition to defining the
__ieee_status() call itself, fenv.h also
defines the following constants to be used for the arguments:
#define FE_IEEE_FLUSHZERO (0x01000000) #define FE_IEEE_ROUND_TONEAREST (0x00000000) #define FE_IEEE_ROUND_UPWARD (0x00400000) #define FE_IEEE_ROUND_DOWNWARD (0x00800000) #define FE_IEEE_ROUND_TOWARDZERO (0x00C00000) #define FE_IEEE_ROUND_MASK (0x00C00000) #define FE_IEEE_MASK_INVALID (0x00000100) #define FE_IEEE_MASK_DIVBYZERO (0x00000200) #define FE_IEEE_MASK_OVERFLOW (0x00000400) #define FE_IEEE_MASK_UNDERFLOW (0x00000800) #define FE_IEEE_MASK_INEXACT (0x00001000) #define FE_IEEE_MASK_ALL_EXCEPT (0x00001F00) #define FE_IEEE_INVALID (0x00000001) #define FE_IEEE_DIVBYZERO (0x00000002) #define FE_IEEE_OVERFLOW (0x00000004) #define FE_IEEE_UNDERFLOW (0x00000008) #define FE_IEEE_INEXACT (0x00000010) #define FE_IEEE_ALL_EXCEPT (0x0000001F)
For example, to set the rounding mode to round down, you would call:
To trap the Invalid Operation exception and untrap all other exceptions:
To untrap the Inexact Result exception:
To clear the Underflow sticky flag: