#include "efp_assist.h"
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <malloc.h>
#include <signal.h>
#include <sys/fault.h>
#include <fcntl.h>
#include <assert.h>
#include <kernel/macros.h>
#include <ppc/opcode.h>
#include <ppc/bookecpu.h>
#include "softfloat.h"
#include <stdio.h>
Go to the source code of this file.
Data Structures | |
struct | appenv_type |
Application environment. More... | |
Defines | |
#define | SPEFSCR_VECT_HI_EXC_MASK |
Mask of SPEFSCR high word exception flags. | |
#define | SPEFSCR_VECT_LO_EXC_MASK |
Mask of SPEFSCR low word exception flags. | |
#define | SPEFSCR_EFP_ALL_EXC_MASK |
Mask of all SPEFSCR exception flags. | |
#define | SPEFSCR_STICKY_EXC_MASK |
Mask of all SPEFSCR exception sticky bits. | |
#define | SPEFSCR_ENABLE_EXC_MASK |
Mask of all SPEFSCR exception enable bits. | |
#define | SPEFSCR_NEEDED_EXC_MASK |
Mask of all SPEFSCR exception enable bits needed for IEEE emulation. | |
#define | SPEFSCR_STICKY_EXC_SHIFT (57-42) |
Number of shifts right to bring sticky bits to the enable bits. | |
#define | NELEM(A) (sizeof(A)/sizeof(*(A))) |
Return the number of elements in the array A. | |
#define | LOADHI(V, N) __asm__ volatile ("evmergehi %0,%0,%1" : "=b" (V) : "i" (N)) |
Load the high word of register N into the 32-bit destination V. | |
#define | STOREHI(V, N) __asm__ volatile ("evmergelo %1,%0,%1" : : "b" (V), "i" (N)) |
Store the 32-bit value V into the high word of register N. | |
#define | DPRINTF(format,...) fprintf(stderr, format, ## __VA_ARGS__) |
Debugging fprintf to stderr. | |
Typedefs | |
typedef uint32_t | q31 |
Signed Fraction (Q31 format; sign plus 31 fixed-point mantissa bits). | |
typedef uint32_t | uq32 |
Unsigned Fraction (Q32 format; 32 fixed-point mantissa bits). | |
Enumerations | |
enum | ppc_xo_type { PPC_XO_evfsabs = 644, PPC_XO_evfsnabs = 645, PPC_XO_evfsneg = 646, PPC_XO_evfsadd = 640, PPC_XO_evfssub = 641, PPC_XO_evfsmul = 648, PPC_XO_evfsdiv = 649, PPC_XO_evfscmpgt = 652, PPC_XO_evfscmplt = 653, PPC_XO_evfscmpeq = 654, PPC_XO_evfststgt = 668, PPC_XO_evfststlt = 669, PPC_XO_evfststeq = 670, PPC_XO_evfscfsi = 657, PPC_XO_evfscfui = 656, PPC_XO_evfscfsf = 659, PPC_XO_evfscfuf = 658, PPC_XO_evfsctsi = 661, PPC_XO_evfsctui = 660, PPC_XO_evfsctsiz = 666, PPC_XO_evfsctuiz = 664, PPC_XO_evfsctsf = 663, PPC_XO_evfsctuf = 662, PPC_XO_efsabs = 708, PPC_XO_efsnabs = 709, PPC_XO_efsneg = 710, PPC_XO_efsadd = 704, PPC_XO_efssub = 705, PPC_XO_efsmul = 712, PPC_XO_efsdiv = 713, PPC_XO_efscmpgt = 716, PPC_XO_efscmplt = 717, PPC_XO_efscmpeq = 718, PPC_XO_efststgt = 732, PPC_XO_efststlt = 733, PPC_XO_efststeq = 734, PPC_XO_efscfsi = 721, PPC_XO_efscfui = 720, PPC_XO_efscfsf = 723, PPC_XO_efscfuf = 722, PPC_XO_efsctsi = 725, PPC_XO_efsctui = 724, PPC_XO_efsctsiz = 730, PPC_XO_efsctuiz = 728, PPC_XO_efsctsf = 727, PPC_XO_efsctuf = 726, PPC_XO_efdabs = 740, PPC_XO_efdnabs = 741, PPC_XO_efdneg = 742, PPC_XO_efdadd = 736, PPC_XO_efdsub = 737, PPC_XO_efdmul = 744, PPC_XO_efddiv = 745, PPC_XO_efdcmpgt = 748, PPC_XO_efdcmplt = 749, PPC_XO_efdcmpeq = 750, PPC_XO_efdtstgt = 764, PPC_XO_efdtstlt = 765, PPC_XO_efdtsteq = 766, PPC_XO_efdcfsi = 753, PPC_XO_efdcfui = 752, PPC_XO_efdcfsid = 739, PPC_XO_efdcfuid = 738, PPC_XO_efdcfsf = 755, PPC_XO_efdcfuf = 754, PPC_XO_efdctsi = 757, PPC_XO_efdctui = 756, PPC_XO_efdctsidz = 747, PPC_XO_efdctuidz = 746, PPC_XO_efdctsiz = 762, PPC_XO_efdctuiz = 760, PPC_XO_efdctsf = 759, PPC_XO_efdctuf = 758, PPC_XO_efdcfs = 751, PPC_XO_efscfd = 719 } |
PPC Embedded Floating Point APU Extended Opcodes. More... | |
Functions | |
int | _math_emulator (const int sigcode, void **const pdata, PPC_CPU_REGISTERS *const regs) |
IEEE 754 compliance handler. | |
Thread Local Storage (TLS) Utilities | |
static appenv_type * | getappenv (void *const *const pdata) |
Fetch the application environment from the fpuemu TLS area. | |
static run_options * | getsfenv (void *const *const pdata) |
Fetch the softfloat environment from the fpuemu TLS area. | |
float32 Utilities | |
static uint32_t | msb32 (const uint32_t v) |
Return the most significant bit of a 32-bit value. | |
static uint32_t | float32_sign (const float32 f) |
Return the sign bit of a float32. | |
static uint32_t | float32_biased_exp (const float32 f) |
Return the biased exponent of a float32. | |
static uint32_t | float32_fraction (const float32 f) |
Return the trailing significand fraction (mantissa) of a float32. | |
static flag | float32_is_neg (const float32 f) |
Test whether a float32 is negative. | |
static flag | float32_is_infnan (const float32 f) |
Test whether a float32 is an Inf or NaN. | |
float32 Functions | |
static float32 | float32_abs (const float32 f) |
Return the absolute value of a float32. | |
static flag | float32_gt (const float32 a, const float32 b, run_options *const e) |
Test if one float32 is greater than another. | |
static flag | float32_gt_quiet (const float32 a, const float32 b, run_options *const e) |
Test if one float32 is greater than another, without raising exceptions. | |
static float32 | float32_mul_pow2 (const float32 f, const int pow2) |
Multiply a float32 by a power of two. | |
float64 Utilities | |
static uint64_t | msb64 (const uint64_t v) |
Return the most significant bit of a 64-bit value. | |
static uint64_t | float64_sign (const float64 f) |
Return the sign bit of a float64. | |
static uint64_t | float64_biased_exp (const float64 f) |
Return the biased exponent of a float64. | |
static uint64_t | float64_fraction (const float64 f) |
Return the trailing significand fraction (mantissa) of a float64. | |
static flag | float64_is_neg (const float64 f) |
Test whether a float64 is negative. | |
static flag | float64_is_infnan (const float64 f) |
Test whether a float64 is an Inf or NaN. | |
float64 Functions | |
static float64 | float64_abs (const float64 f) |
Return the absolute value of a float64. | |
static flag | float64_gt (const float64 a, const float64 b, run_options *const e) |
Test if one float64 is greater than another. | |
static flag | float64_gt_quiet (const float64 a, const float64 b, run_options *const e) |
Test if one float64 is greater than another, without raising exceptions. | |
static float64 | float64_mul_pow2 (const float64 f, const int pow2) |
Multiply a float64 by a power of two. | |
static int64 | float64_to_int64_round_to_zero (const float64 f, run_options *const e) |
Convert a float64 to an int64, rounding towards zero. | |
uint32 Floating Point Conversions | |
static float32 | uint32_to_float32 (const uint32 v, run_options *const e) |
Convert a uint32 to a float32. | |
static float64 | uint32_to_float64 (const uint32 v, run_options *const e) |
Convert a uint32 to a float64. | |
static uint32 | float32_to_uint32 (const float32 f, run_options *const e) |
Convert a float32 to a uint32. | |
static uint32 | float32_to_uint32_round_to_zero (const float32 f, run_options *const e) |
Convert a float32 to a uint32, rounding towards zero. | |
static uint32 | float64_to_uint32 (const float64 f, run_options *const e) |
Convert a float64 to a uint32. | |
static uint32 | float64_to_uint32_round_to_zero (const float64 f, run_options *const e) |
Convert a float64 to a uint32, rounding towards zero. | |
uint64 Floating Point Conversions | |
static float64 | uint64_to_float64 (const uint64 v, run_options *const e) |
Convert a uint64 to a float64. | |
static uint64 | float64_to_uint64_round_to_zero (const float64 f, run_options *const e) |
Convert a float64 to a uint64, rounding towards zero. | |
q31 Floating Point Conversions | |
static float32 | q31_to_float32 (const q31 v, run_options *const e) |
Convert a q31 to a float32. | |
static float64 | q31_to_float64 (const q31 v, run_options *const e) |
Convert a q31 to a float64. | |
static q31 | float32_to_q31 (const float32 f, run_options *const e) |
Convert a float32 to a q31. | |
static q31 | float64_to_q31 (const float64 f, run_options *const e) |
Convert a float64 to a q31. | |
uq32 Floating Point Conversions | |
static float32 | uq32_to_float32 (const uq32 v, run_options *const e) |
Convert a uq32 to a float32. | |
static float64 | uq32_to_float64 (const uq32 v, run_options *const e) |
Convert a uq32 to a float64. | |
static uq32 | float32_to_uq32 (const float32 f, run_options *const e) |
Convert a float32 to a uq32. | |
static uint64 | float64_to_uq32 (const float64 f, run_options *const e) |
Convert a float64 to a uq32. | |
General Purpose Register Accessors | |
static float32 | load32 (const PPC_CPU_REGISTERS *const regs, const unsigned n) |
Fetch the 32-bit value in the low word of a register. | |
static void | store32 (PPC_CPU_REGISTERS *const regs, const unsigned n, const float32 v) |
Store a 32-bit value to the low word of a register. | |
static float32 | loadh32 (const PPC_CPU_REGISTERS *const regs, const unsigned n) |
Fetch the 32-bit value in the high word of a register. | |
static void | storeh32 (PPC_CPU_REGISTERS *const regs, const unsigned n, const float32 v) |
Store a 32-bit value in the high word of a register. | |
static float64 | load64 (const PPC_CPU_REGISTERS *const regs, const unsigned n) |
Fetch the 64-bit value in a register. | |
static void | store64 (PPC_CPU_REGISTERS *const regs, const unsigned n, const float64 v) |
Store a 64-bit value to a register. |
This module contains all of the PPC SPE specific handling for IEEE 754 compliance. The vast majority of the work is done in the single routine _math_emulator() which is usually called via the _emulator_callout()
mechanism in libc.
The basic IEEE operations for signed 32 and 64 bit integers are provided by the third party softfloat library, which is also used by the fpemu library. For symmetry with that library, this module defines a large number of related IEEE helper functions, primarily to provide support for two data types used by the PPC SPE instruction set but for which there is no softfloat library analogue: unsigned 32 and 64 bit integers, as well as both signed and unsigned 32 bit fractional types. The names of these utility functions and types have largely been chosen for symmetry with existing functions in the softfloat library.
The final group of utility functions abstracts load and store operations for the thread's general purpose registers. The lower 32 bit words of the General Purpose Registers are stored in a register save area, which will be used to restore those registers when the thread resumes after the exception has been handled. The upper 32 bit words of the General Purpose Registers (which are invisible and are unalterted by all instructions except SPE instructions) remain stored in their hardware registers. (Since this is user-mode, the usual kernel mechanics are at play in arbitrating access to this alt context, all of which is entirely transparent to the fpassist library.)
__builtin_clz()
- a single instruction on the PPC - to count leading zeroes.)Definition in file efp_assist.c.
#define DPRINTF | ( | format, | |||
... | ) | fprintf(stderr, format, ## __VA_ARGS__) |
Debugging fprintf to stderr.
Definition at line 222 of file efp_assist.c.
Referenced by _math_emulator().
#define LOADHI | ( | V, | |||
N | ) | __asm__ volatile ("evmergehi %0,%0,%1" : "=b" (V) : "i" (N)) |
Load the high word of register N into the 32-bit destination V.
* evmergehi RT,RA,RB * RT[0:31] = (RA)[0:31] * RT[32:63] = (RB)[0:31] *
RT
is left unchanged by this macro because RT
and RA
are always the same register. The low word of RT
will be loaded with the high word of RB
and is therefore the subject of an output constraint allowing the compiler to choose RT
however it sees fit, spilling as necessary; the same constraint will also result in the ultimate storage of the chosen register into the lvalue supplied by the caller.[out] | V | The lvalue in which to store the result. |
[in] | N | The number of the register from which to fetch the high word. |
Definition at line 192 of file efp_assist.c.
#define NELEM | ( | A | ) | (sizeof(A)/sizeof(*(A))) |
Return the number of elements in the array A.
Definition at line 168 of file efp_assist.c.
Referenced by _math_emulator().
#define SPEFSCR_EFP_ALL_EXC_MASK |
#define SPEFSCR_ENABLE_EXC_MASK |
Value:
(PPCBKE_APU_SPE_SPEFSCR_FINXE \ |PPCBKE_APU_SPE_SPEFSCR_FINVE \ |PPCBKE_APU_SPE_SPEFSCR_FDBZE \ |PPCBKE_APU_SPE_SPEFSCR_FUNFE \ |PPCBKE_APU_SPE_SPEFSCR_FOVFE)
Definition at line 143 of file efp_assist.c.
Referenced by _math_emulator().
#define SPEFSCR_NEEDED_EXC_MASK |
Value:
(PPCBKE_APU_SPE_SPEFSCR_FINVE \ |PPCBKE_APU_SPE_SPEFSCR_FDBZE \ |PPCBKE_APU_SPE_SPEFSCR_FUNFE \ |PPCBKE_APU_SPE_SPEFSCR_FOVFE)
Definition at line 152 of file efp_assist.c.
Referenced by _math_emulator().
#define SPEFSCR_STICKY_EXC_MASK |
Value:
(PPCBKE_APU_SPE_SPEFSCR_FINXS \ |PPCBKE_APU_SPE_SPEFSCR_FINVS \ |PPCBKE_APU_SPE_SPEFSCR_FDBZS \ |PPCBKE_APU_SPE_SPEFSCR_FUNFS \ |PPCBKE_APU_SPE_SPEFSCR_FOVFS)
Definition at line 134 of file efp_assist.c.
Referenced by _math_emulator().
#define SPEFSCR_STICKY_EXC_SHIFT (57-42) |
Number of shifts right to bring sticky bits to the enable bits.
Definition at line 160 of file efp_assist.c.
Referenced by _math_emulator().
#define SPEFSCR_VECT_HI_EXC_MASK |
Value:
(PPCBKE_APU_SPE_SPEFSCR_FXH \ |PPCBKE_APU_SPE_SPEFSCR_FGH \ |PPCBKE_APU_SPE_SPEFSCR_FINVH \ |PPCBKE_APU_SPE_SPEFSCR_FDBZH \ |PPCBKE_APU_SPE_SPEFSCR_FUNFH \ |PPCBKE_APU_SPE_SPEFSCR_FOVFH)
Definition at line 108 of file efp_assist.c.
Referenced by _math_emulator().
#define SPEFSCR_VECT_LO_EXC_MASK |
Value:
(PPCBKE_APU_SPE_SPEFSCR_FX \ |PPCBKE_APU_SPE_SPEFSCR_FG \ |PPCBKE_APU_SPE_SPEFSCR_FINV \ |PPCBKE_APU_SPE_SPEFSCR_FDBZ \ |PPCBKE_APU_SPE_SPEFSCR_FUNF \ |PPCBKE_APU_SPE_SPEFSCR_FOVF)
Definition at line 118 of file efp_assist.c.
Referenced by _math_emulator().
#define STOREHI | ( | V, | |||
N | ) | __asm__ volatile ("evmergelo %1,%0,%1" : : "b" (V), "i" (N)) |
Store the 32-bit value V into the high word of register N.
* evmergelo RT,RA,RB * RT[0:31] = (RA)[32:63] * RT[32:63] = (RB)[32:63] *
RT
is left unchanged by this macro because RT
and RB
are always the same register. The high word of RT
will be loaded with the low word of RA
. No output constraint is specified for RT
because, as stated earlier, it is assumed that the gcc code generator does not itself manipulate the high word and we are not changing the value of the low word. (Any such output constraint would then also be counterproductive, possibly spilling a register uneccesarily.)[in] | V | The value to be stored. |
[in] | N | The number of the register in which to store the high word. |
Definition at line 217 of file efp_assist.c.
Referenced by store64(), and storeh32().
typedef uint32_t q31 |
Signed Fraction (Q31 format; sign plus 31 fixed-point mantissa bits).
Definition at line 425 of file efp_assist.c.
typedef uint32_t uq32 |
Unsigned Fraction (Q32 format; 32 fixed-point mantissa bits).
Definition at line 429 of file efp_assist.c.
enum ppc_xo_type |
PPC Embedded Floating Point APU Extended Opcodes.
Definition at line 251 of file efp_assist.c.
int _math_emulator | ( | const int | sigcode, | |
void **const | pdata, | |||
PPC_CPU_REGISTERS *const | regs | |||
) |
IEEE 754 compliance handler.
This routine serves two major, somewhat independent purposes. It is primarily used as a user-mode handler for embedded floating point data and rounding exceptions raised by the hardware; it is also used as a means for the fp_status
and fenv
implementations in libm to make use of the SPEFSCR register in cooperation with the exception handling functionality.
Although the source code is quite lengthy, much of the bulk is made up of switch statements which sieve the opcode in various ways. The execution path through the routine for any given execution is intended to be as short as possible. Owing to the amount of state shared from step to step in what is essentially a sequential algorithm, it did not seem advisable to split the routine into pieces as it is conjectured that it might substantially degrade the compiler's ability to optimize the code.
FPE_NOFPU
for data, FPE_FLTRES
for rounding); the IAR pointing at the instruction causing the exception; and the remainder of the register context filled in appropriately. The high words of the GPRs and the accumulator are assumed to be in the state they were in at the time of the exception (since they can only be modified by embedded floating point instructions).kerext_debug
) to begin with a (true, non-embedded) floating point register save area, which is not otherwise used by the fpassist library and in which all registers are always set to zero. Following this is a softfloat environment, which is also unused by the fpassist library. (It is reserved for future extension and preserves an identical layout with the context used by the fpemu library. Although there is currently no functional need for compatibility, it may prove to be worthwhile if it is ever necessary to support both fpemu and fpassist simultaneously.) Next is the private context used by the fpassist library. This contains the current value of the application visible exception flags and mask.SIGFPE
should still be delivered; typically the result is not stored if a signal will be delivered (just as it would not had the fpassist library not been present.)fp_status
API and Protocolfp_setenv()
implementation in libm for SPE PPC uses a simple protocol to communicate with the fpassist library in order to cooperatively use the SPEFSCR register. It calls the _emulator_callout()
function directly, passing SIGFPE
; an IAR
of ~0U
; and a USPRG0 of either O_RDONLY
, for a read, or O_WRONLY
, for a write of the SPEFSCR. If the fpassist
library is missing, this will return non-zero (SIGFPE
) and fp_setenv()
will fall back to accessing the hardware directly. (In this case, unmasked exceptions will result in SIGFPE
delivery.) Otherwise, the value manipulated will in fact be the one from the application context allocated above.[in] | sigcode | The sigcode suggested by the caller. |
[in,out] | pdata | Pointer to pointer of TLS context save area. |
[in,out] | regs | Processor context. |
sigcode
to be delivered to the application thread (if any) ==0 | No signal required. | |
!=0 | sigcode to deliver. |
Definition at line 642 of file efp_assist.c.
References DPRINTF, float32_add(), float32_div(), float32_eq(), float32_eq_signaling(), float32_gt(), float32_gt_quiet(), float32_lt(), float32_lt_quiet(), float32_mul(), float32_sub(), float32_to_float64(), float32_to_int32(), float32_to_int32_round_to_zero(), float32_to_q31(), float32_to_uint32(), float32_to_uint32_round_to_zero(), float32_to_uq32(), float64_add(), float64_div(), float64_eq(), float64_eq_signaling(), float64_gt(), float64_gt_quiet(), float64_lt(), float64_lt_quiet(), float64_mul(), float64_sub(), float64_to_float32(), float64_to_int32(), float64_to_int32_round_to_zero(), float64_to_int64_round_to_zero(), float64_to_q31(), float64_to_uint32(), float64_to_uint32_round_to_zero(), float64_to_uint64_round_to_zero(), float64_to_uq32(), _run_options::float_exception_flags, float_flag_divbyzero, float_flag_inexact, float_flag_invalid, float_flag_overflow, float_flag_underflow, float_round_down, float_round_nearest_even, float_round_to_zero, float_round_up, _run_options::float_rounding_mode, getappenv(), getsfenv(), int32_to_float32(), int32_to_float64(), int64_to_float64(), load32(), load64(), loadh32(), NELEM, PPC_XO_efdabs, PPC_XO_efdadd, PPC_XO_efdcfs, PPC_XO_efdcfsf, PPC_XO_efdcfsi, PPC_XO_efdcfsid, PPC_XO_efdcfuf, PPC_XO_efdcfui, PPC_XO_efdcfuid, PPC_XO_efdcmpeq, PPC_XO_efdcmpgt, PPC_XO_efdcmplt, PPC_XO_efdctsf, PPC_XO_efdctsi, PPC_XO_efdctsidz, PPC_XO_efdctsiz, PPC_XO_efdctuf, PPC_XO_efdctui, PPC_XO_efdctuidz, PPC_XO_efdctuiz, PPC_XO_efddiv, PPC_XO_efdmul, PPC_XO_efdnabs, PPC_XO_efdneg, PPC_XO_efdsub, PPC_XO_efdtsteq, PPC_XO_efdtstgt, PPC_XO_efdtstlt, PPC_XO_efsabs, PPC_XO_efsadd, PPC_XO_efscfd, PPC_XO_efscfsf, PPC_XO_efscfsi, PPC_XO_efscfuf, PPC_XO_efscfui, PPC_XO_efscmpeq, PPC_XO_efscmpgt, PPC_XO_efscmplt, PPC_XO_efsctsf, PPC_XO_efsctsi, PPC_XO_efsctsiz, PPC_XO_efsctuf, PPC_XO_efsctui, PPC_XO_efsctuiz, PPC_XO_efsdiv, PPC_XO_efsmul, PPC_XO_efsnabs, PPC_XO_efsneg, PPC_XO_efssub, PPC_XO_efststeq, PPC_XO_efststgt, PPC_XO_efststlt, PPC_XO_evfsabs, PPC_XO_evfsadd, PPC_XO_evfscfsf, PPC_XO_evfscfsi, PPC_XO_evfscfuf, PPC_XO_evfscfui, PPC_XO_evfscmpeq, PPC_XO_evfscmpgt, PPC_XO_evfscmplt, PPC_XO_evfsctsf, PPC_XO_evfsctsi, PPC_XO_evfsctsiz, PPC_XO_evfsctuf, PPC_XO_evfsctui, PPC_XO_evfsctuiz, PPC_XO_evfsdiv, PPC_XO_evfsmul, PPC_XO_evfsnabs, PPC_XO_evfsneg, PPC_XO_evfssub, PPC_XO_evfststeq, PPC_XO_evfststgt, PPC_XO_evfststlt, q31_to_float32(), q31_to_float64(), softfloat_env_init(), appenv_type::spefscr, SPEFSCR_ENABLE_EXC_MASK, SPEFSCR_NEEDED_EXC_MASK, SPEFSCR_STICKY_EXC_MASK, SPEFSCR_STICKY_EXC_SHIFT, SPEFSCR_VECT_HI_EXC_MASK, SPEFSCR_VECT_LO_EXC_MASK, store32(), store64(), storeh32(), uint32_to_float32(), uint32_to_float64(), uint64_to_float64(), uq32_to_float32(), and uq32_to_float64().
Return the absolute value of a float32.
[in] | f | The value. |
f
. Definition at line 2470 of file efp_assist.c.
Referenced by float32_to_q31(), and float32_to_uq32().
static uint32_t float32_biased_exp | ( | const float32 | f | ) | [inline, static] |
Return the biased exponent of a float32.
The bias of the float32 exponent is 127. The unbiased exponent, e, is derived from the biased exponent, E, by .
[in] | f | The value. |
Definition at line 2381 of file efp_assist.c.
Referenced by float32_is_infnan(), float32_to_q31(), and float32_to_uq32().
static uint32_t float32_fraction | ( | const float32 | f | ) | [inline, static] |
Return the trailing significand fraction (mantissa) of a float32.
The trailing significand of a float32 is a 23-bit value which forms the mantissa of the floating point number.
[in] | f | The value. |
Definition at line 2404 of file efp_assist.c.
static flag float32_gt | ( | const float32 | a, | |
const float32 | b, | |||
run_options *const | e | |||
) | [inline, static] |
Test if one float32 is greater than another.
[in] | a | The first value. |
[in] | b | The second value. |
[in,out] | e | The softfloat environment. |
a
and b
. ==0 | a is not greater than b . | |
!=0 | a is greater than b . |
Definition at line 2493 of file efp_assist.c.
References float32_le(), _run_options::float_exception_flags, and float_flag_invalid.
Referenced by _math_emulator().
static flag float32_gt_quiet | ( | const float32 | a, | |
const float32 | b, | |||
run_options *const | e | |||
) | [inline, static] |
Test if one float32 is greater than another, without raising exceptions.
[in] | a | The first value. |
[in] | b | The second value. |
[in,out] | e | The softfloat environment. |
a
and b
. ==0 | a is not greater than b . | |
!=0 | a is greater than b . |
Definition at line 2521 of file efp_assist.c.
References float32_le_quiet(), _run_options::float_exception_flags, and float_flag_invalid.
Referenced by _math_emulator().
Test whether a float32 is an Inf or NaN.
[in] | f | The value. |
==0 | The value is not an Inf or NaN. | |
!=0 | The value is an Inf or NaN. |
Definition at line 2446 of file efp_assist.c.
References float32_biased_exp().
Referenced by float32_to_q31(), float32_to_uint32(), float32_to_uq32(), float64_to_q31(), float64_to_uint32(), and float64_to_uint64_round_to_zero().
Test whether a float32 is negative.
[in] | f | The value. |
==0 | The value is positive. | |
!=0 | The value is negative. |
Definition at line 2425 of file efp_assist.c.
References float32_sign().
Referenced by float32_to_q31(), float32_to_uint32(), and float32_to_uq32().
Multiply a float32 by a power of two.
Multiplies the float32 by a positive or negative power of two by adding pow2
to the biased exponent.
[in] | f | The value. |
[in] | pow2 | The power of two. |
Definition at line 2550 of file efp_assist.c.
Referenced by float32_to_q31(), float32_to_uq32(), q31_to_float32(), and uq32_to_float32().
static uint32_t float32_sign | ( | const float32 | f | ) | [inline, static] |
Return the sign bit of a float32.
[in] | f | The value. |
0 | The sign bit was zero. | |
1 | The sign bit was one. |
Definition at line 2355 of file efp_assist.c.
Referenced by float32_is_neg().
static q31 float32_to_q31 | ( | const float32 | f, | |
run_options *const | e | |||
) | [static] |
Convert a float32 to a q31.
[in] | f | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 3236 of file efp_assist.c.
References float32_abs(), float32_biased_exp(), float32_is_infnan(), float32_is_nan(), float32_is_neg(), float32_mul_pow2(), float32_to_int32(), _run_options::float_exception_flags, float_flag_invalid, and float_flag_overflow.
Referenced by _math_emulator().
static uint32 float32_to_uint32 | ( | const float32 | f, | |
run_options *const | e | |||
) | [static] |
Convert a float32 to a uint32.
[in] | f | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 2885 of file efp_assist.c.
References float32_is_infnan(), float32_is_neg(), float32_to_int64(), _run_options::float_exception_flags, float_flag_invalid, and float_flag_overflow.
Referenced by _math_emulator(), and float32_to_uint32_round_to_zero().
static uint32 float32_to_uint32_round_to_zero | ( | const float32 | f, | |
run_options *const | e | |||
) | [inline, static] |
Convert a float32 to a uint32, rounding towards zero.
[in] | f | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 2949 of file efp_assist.c.
References float32_to_uint32(), float_round_to_zero, and _run_options::float_rounding_mode.
Referenced by _math_emulator().
static uq32 float32_to_uq32 | ( | const float32 | f, | |
run_options *const | e | |||
) | [static] |
Convert a float32 to a uq32.
[in] | f | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 3431 of file efp_assist.c.
References float32_abs(), float32_biased_exp(), float32_is_infnan(), float32_is_nan(), float32_is_neg(), float32_mul_pow2(), float32_to_int64(), _run_options::float_exception_flags, float_flag_invalid, and float_flag_overflow.
Referenced by _math_emulator().
Return the absolute value of a float64.
[in] | f | The value. |
f
. Definition at line 2711 of file efp_assist.c.
Referenced by float64_to_q31(), and float64_to_uq32().
static uint64_t float64_biased_exp | ( | const float64 | f | ) | [inline, static] |
Return the biased exponent of a float64.
The bias of the float64 exponent is 1023. The unbiased exponent, e, is derived from the biased exponent, E, by .
[in] | f | The value. |
Definition at line 2622 of file efp_assist.c.
Referenced by float64_is_infnan(), float64_to_q31(), float64_to_uint64_round_to_zero(), and float64_to_uq32().
static uint64_t float64_fraction | ( | const float64 | f | ) | [inline, static] |
Return the trailing significand fraction (mantissa) of a float64.
The trailing significand of a float64 is a 52-bit value which forms the mantissa of the floating point number.
[in] | f | The value. |
Definition at line 2645 of file efp_assist.c.
static flag float64_gt | ( | const float64 | a, | |
const float64 | b, | |||
run_options *const | e | |||
) | [inline, static] |
Test if one float64 is greater than another.
[in] | a | The first value. |
[in] | b | The second value. |
[in,out] | e | The softfloat environment. |
a
and b
. ==0 | a is not greater than b . | |
!=0 | a is greater than b . |
Definition at line 2734 of file efp_assist.c.
References float64_le(), _run_options::float_exception_flags, and float_flag_invalid.
Referenced by _math_emulator().
static flag float64_gt_quiet | ( | const float64 | a, | |
const float64 | b, | |||
run_options *const | e | |||
) | [inline, static] |
Test if one float64 is greater than another, without raising exceptions.
[in] | a | The first value. |
[in] | b | The second value. |
[in,out] | e | The softfloat environment. |
a
and b
. ==0 | a is not greater than b . | |
!=0 | a is greater than b . |
Definition at line 2762 of file efp_assist.c.
References float64_le_quiet(), _run_options::float_exception_flags, and float_flag_invalid.
Referenced by _math_emulator().
Test whether a float64 is an Inf or NaN.
[in] | f | The value. |
==0 | The value is not an Inf or NaN. | |
!=0 | The value is an Inf or NaN. |
Definition at line 2687 of file efp_assist.c.
References float64_biased_exp().
Referenced by float64_to_uint64_round_to_zero(), and float64_to_uq32().
Test whether a float64 is negative.
[in] | f | The value. |
==0 | The value is positive. | |
!=0 | The value is negative. |
Definition at line 2666 of file efp_assist.c.
References float64_sign().
Referenced by float64_to_q31(), float64_to_uint32(), float64_to_uint64_round_to_zero(), and float64_to_uq32().
Multiply a float64 by a power of two.
Multiplies the float64 by a positive or negative power of two by adding pow2
to the biased exponent.
[in] | f | The value. |
[in] | pow2 | The power of two. |
Definition at line 2791 of file efp_assist.c.
Referenced by float64_to_q31(), float64_to_uint64_round_to_zero(), float64_to_uq32(), q31_to_float64(), uint64_to_float64(), and uq32_to_float64().
static uint64_t float64_sign | ( | const float64 | f | ) | [inline, static] |
Return the sign bit of a float64.
[in] | f | The value. |
0 | The sign bit was zero. | |
1 | The sign bit was one. |
Definition at line 2596 of file efp_assist.c.
References msb64().
Referenced by float64_is_neg().
static int64 float64_to_int64_round_to_zero | ( | const float64 | f, | |
run_options *const | e | |||
) | [inline, static] |
Convert a float64 to an int64, rounding towards zero.
[in] | f | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 2815 of file efp_assist.c.
References float64_to_int64(), float_round_to_zero, and _run_options::float_rounding_mode.
Referenced by _math_emulator().
static q31 float64_to_q31 | ( | const float64 | f, | |
run_options *const | e | |||
) | [static] |
Convert a float64 to a q31.
[in] | f | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 3307 of file efp_assist.c.
References float32_is_infnan(), float64_abs(), float64_biased_exp(), float64_is_nan(), float64_is_neg(), float64_mul_pow2(), float64_to_int32(), _run_options::float_exception_flags, float_flag_invalid, and float_flag_overflow.
Referenced by _math_emulator().
static uint32 float64_to_uint32 | ( | const float64 | f, | |
run_options *const | e | |||
) | [static] |
Convert a float64 to a uint32.
[in] | f | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 2971 of file efp_assist.c.
References float32_is_infnan(), float64_is_neg(), float64_to_int64(), _run_options::float_exception_flags, float_flag_invalid, and float_flag_overflow.
Referenced by _math_emulator(), and float64_to_uint32_round_to_zero().
static uint32 float64_to_uint32_round_to_zero | ( | const float64 | f, | |
run_options *const | e | |||
) | [inline, static] |
Convert a float64 to a uint32, rounding towards zero.
[in] | f | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 3035 of file efp_assist.c.
References float64_to_uint32(), float_round_to_zero, and _run_options::float_rounding_mode.
Referenced by _math_emulator().
static uint64 float64_to_uint64_round_to_zero | ( | const float64 | f, | |
run_options *const | e | |||
) | [static] |
Convert a float64 to a uint64, rounding towards zero.
[in] | f | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 3092 of file efp_assist.c.
References float32_is_infnan(), float64_biased_exp(), float64_is_infnan(), float64_is_nan(), float64_is_neg(), float64_mul_pow2(), float64_to_int64(), _run_options::float_exception_flags, float_flag_invalid, float_flag_overflow, float_round_to_zero, and _run_options::float_rounding_mode.
Referenced by _math_emulator().
static uint64 float64_to_uq32 | ( | const float64 | f, | |
run_options *const | e | |||
) | [static] |
Convert a float64 to a uq32.
[in] | f | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 3521 of file efp_assist.c.
References float64_abs(), float64_biased_exp(), float64_is_infnan(), float64_is_nan(), float64_is_neg(), float64_mul_pow2(), float64_to_int64(), _run_options::float_exception_flags, float_flag_invalid, and float_flag_overflow.
Referenced by _math_emulator().
static appenv_type * getappenv | ( | void *const *const | pdata | ) | [inline, static] |
Fetch the application environment from the fpuemu TLS area.
[in] | pdata | The fpuemu TLS data area. |
Definition at line 2288 of file efp_assist.c.
Referenced by _math_emulator().
static run_options * getsfenv | ( | void *const *const | pdata | ) | [inline, static] |
Fetch the softfloat environment from the fpuemu TLS area.
[in] | pdata | The fpuemu TLS data area. |
Definition at line 2309 of file efp_assist.c.
Referenced by _math_emulator().
static float32 load32 | ( | const PPC_CPU_REGISTERS *const | regs, | |
const unsigned | n | |||
) | [inline, static] |
Fetch the 32-bit value in the low word of a register.
[in] | regs | The low register words. |
[in] | n | The register number from which to fetch the value. |
n
. Definition at line 3619 of file efp_assist.c.
Referenced by _math_emulator().
static float64 load64 | ( | const PPC_CPU_REGISTERS *const | regs, | |
const unsigned | n | |||
) | [static] |
Fetch the 64-bit value in a register.
[in] | regs | The low register words. |
[in] | n | The register number from which to fetch the value. |
n
. Definition at line 3790 of file efp_assist.c.
References LOADHI.
Referenced by _math_emulator().
static float32 loadh32 | ( | const PPC_CPU_REGISTERS *const | regs, | |
const unsigned | n | |||
) | [static] |
Fetch the 32-bit value in the high word of a register.
regs | The low register words. (unused) | |
[in] | n | The register number from which to fetch the value. |
n
. Definition at line 3670 of file efp_assist.c.
References LOADHI.
Referenced by _math_emulator().
static uint32_t msb32 | ( | const uint32_t | v | ) | [inline, static] |
Return the most significant bit of a 32-bit value.
[in] | v | The value. |
Definition at line 2334 of file efp_assist.c.
static uint64_t msb64 | ( | const uint64_t | v | ) | [inline, static] |
Return the most significant bit of a 64-bit value.
[in] | v | The value. |
Definition at line 2575 of file efp_assist.c.
Referenced by float64_sign(), and uint64_to_float64().
static float32 q31_to_float32 | ( | const q31 | v, | |
run_options *const | e | |||
) | [inline, static] |
Convert a q31 to a float32.
[in] | v | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 3189 of file efp_assist.c.
References float32_mul_pow2(), and int32_to_float32().
Referenced by _math_emulator().
static float64 q31_to_float64 | ( | const q31 | v, | |
run_options *const | e | |||
) | [inline, static] |
Convert a q31 to a float64.
[in] | v | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 3213 of file efp_assist.c.
References float64_mul_pow2(), and int32_to_float64().
Referenced by _math_emulator().
static void store32 | ( | PPC_CPU_REGISTERS *const | regs, | |
const unsigned | n, | |||
const float32 | v | |||
) | [inline, static] |
Store a 32-bit value to the low word of a register.
[out] | regs | The low register words. |
[in] | n | The register number in which to store the value. |
[in] | v | The value to be stored. |
Definition at line 3643 of file efp_assist.c.
Referenced by _math_emulator().
static void store64 | ( | PPC_CPU_REGISTERS *const | regs, | |
const unsigned | n, | |||
const float64 | v | |||
) | [static] |
Store a 64-bit value to a register.
[out] | regs | The low register words. |
[in] | n | The register number in which to store the value. |
[in] | v | The value to be stored. |
Definition at line 3852 of file efp_assist.c.
References STOREHI.
Referenced by _math_emulator().
static void storeh32 | ( | PPC_CPU_REGISTERS *const | regs, | |
const unsigned | n, | |||
const float32 | v | |||
) | [static] |
Store a 32-bit value in the high word of a register.
[in] | regs | The low register words. (unused) |
[in] | n | The register number in which to store the value. |
[in] | v | The value to be stored. |
Definition at line 3730 of file efp_assist.c.
References STOREHI.
Referenced by _math_emulator().
static float32 uint32_to_float32 | ( | const uint32 | v, | |
run_options *const | e | |||
) | [inline, static] |
Convert a uint32 to a float32.
[in] | v | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 2844 of file efp_assist.c.
References int64_to_float32().
Referenced by _math_emulator(), and uq32_to_float32().
static float64 uint32_to_float64 | ( | const uint32 | v, | |
run_options *const | e | |||
) | [inline, static] |
Convert a uint32 to a float64.
[in] | v | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 2865 of file efp_assist.c.
References int64_to_float64().
Referenced by _math_emulator(), and uq32_to_float64().
static float64 uint64_to_float64 | ( | const uint64 | v, | |
run_options *const | e | |||
) | [inline, static] |
Convert a uint64 to a float64.
[in] | v | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 3063 of file efp_assist.c.
References float64_mul_pow2(), int64_to_float64(), and msb64().
Referenced by _math_emulator().
static float32 uq32_to_float32 | ( | const uq32 | v, | |
run_options *const | e | |||
) | [inline, static] |
Convert a uq32 to a float32.
[in] | v | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 3384 of file efp_assist.c.
References float32_mul_pow2(), and uint32_to_float32().
Referenced by _math_emulator().
static float64 uq32_to_float64 | ( | const uq32 | v, | |
run_options *const | e | |||
) | [inline, static] |
Convert a uq32 to a float64.
[in] | v | The value. |
[in,out] | e | The softfloat environment. |
Definition at line 3408 of file efp_assist.c.
References float64_mul_pow2(), and uint32_to_float64().
Referenced by _math_emulator().