xref: /freebsd/contrib/llvm-project/compiler-rt/lib/builtins/fp_trunc.h (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
10b57cec5SDimitry Andric //=== lib/fp_trunc.h - high precision -> low precision conversion *- C -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Set source and destination precision setting
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef FP_TRUNC_HEADER
140b57cec5SDimitry Andric #define FP_TRUNC_HEADER
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "int_lib.h"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric #if defined SRC_SINGLE
190b57cec5SDimitry Andric typedef float src_t;
200b57cec5SDimitry Andric typedef uint32_t src_rep_t;
210b57cec5SDimitry Andric #define SRC_REP_C UINT32_C
220b57cec5SDimitry Andric static const int srcSigBits = 23;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric #elif defined SRC_DOUBLE
250b57cec5SDimitry Andric typedef double src_t;
260b57cec5SDimitry Andric typedef uint64_t src_rep_t;
270b57cec5SDimitry Andric #define SRC_REP_C UINT64_C
280b57cec5SDimitry Andric static const int srcSigBits = 52;
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric #elif defined SRC_QUAD
310b57cec5SDimitry Andric typedef long double src_t;
320b57cec5SDimitry Andric typedef __uint128_t src_rep_t;
330b57cec5SDimitry Andric #define SRC_REP_C (__uint128_t)
340b57cec5SDimitry Andric static const int srcSigBits = 112;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric #else
370b57cec5SDimitry Andric #error Source should be double precision or quad precision!
380b57cec5SDimitry Andric #endif // end source precision
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric #if defined DST_DOUBLE
410b57cec5SDimitry Andric typedef double dst_t;
420b57cec5SDimitry Andric typedef uint64_t dst_rep_t;
430b57cec5SDimitry Andric #define DST_REP_C UINT64_C
440b57cec5SDimitry Andric static const int dstSigBits = 52;
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric #elif defined DST_SINGLE
470b57cec5SDimitry Andric typedef float dst_t;
480b57cec5SDimitry Andric typedef uint32_t dst_rep_t;
490b57cec5SDimitry Andric #define DST_REP_C UINT32_C
500b57cec5SDimitry Andric static const int dstSigBits = 23;
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric #elif defined DST_HALF
53*e8d8bef9SDimitry Andric #ifdef COMPILER_RT_HAS_FLOAT16
54*e8d8bef9SDimitry Andric typedef _Float16 dst_t;
55*e8d8bef9SDimitry Andric #else
560b57cec5SDimitry Andric typedef uint16_t dst_t;
57*e8d8bef9SDimitry Andric #endif
580b57cec5SDimitry Andric typedef uint16_t dst_rep_t;
590b57cec5SDimitry Andric #define DST_REP_C UINT16_C
600b57cec5SDimitry Andric static const int dstSigBits = 10;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric #else
630b57cec5SDimitry Andric #error Destination should be single precision or double precision!
640b57cec5SDimitry Andric #endif // end destination precision
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric // End of specialization parameters.  Two helper routines for conversion to and
670b57cec5SDimitry Andric // from the representation of floating-point data as integer values follow.
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric static __inline src_rep_t srcToRep(src_t x) {
700b57cec5SDimitry Andric   const union {
710b57cec5SDimitry Andric     src_t f;
720b57cec5SDimitry Andric     src_rep_t i;
730b57cec5SDimitry Andric   } rep = {.f = x};
740b57cec5SDimitry Andric   return rep.i;
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric static __inline dst_t dstFromRep(dst_rep_t x) {
780b57cec5SDimitry Andric   const union {
790b57cec5SDimitry Andric     dst_t f;
800b57cec5SDimitry Andric     dst_rep_t i;
810b57cec5SDimitry Andric   } rep = {.i = x};
820b57cec5SDimitry Andric   return rep.f;
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric #endif // FP_TRUNC_HEADER
86