1 //===-lib/fp_extend.h - low precision -> high precision conversion -*- C
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 // Set source and destination setting
12 //===----------------------------------------------------------------------===//
14 #ifndef FP_EXTEND_HEADER
15 #define FP_EXTEND_HEADER
19 #if defined SRC_SINGLE
21 typedef uint32_t src_rep_t
;
22 #define SRC_REP_C UINT32_C
23 static const int srcBits
= sizeof(src_t
) * CHAR_BIT
;
24 static const int srcSigFracBits
= 23;
25 // -1 accounts for the sign bit.
26 // srcBits - srcSigFracBits - 1
27 static const int srcExpBits
= 8;
28 #define src_rep_t_clz clzsi
30 #elif defined SRC_DOUBLE
32 typedef uint64_t src_rep_t
;
33 #define SRC_REP_C UINT64_C
34 static const int srcBits
= sizeof(src_t
) * CHAR_BIT
;
35 static const int srcSigFracBits
= 52;
36 // -1 accounts for the sign bit.
37 // srcBits - srcSigFracBits - 1
38 static const int srcExpBits
= 11;
40 static inline int src_rep_t_clz_impl(src_rep_t a
) { return __builtin_clzll(a
); }
41 #define src_rep_t_clz src_rep_t_clz_impl
44 typedef xf_float src_t
;
45 typedef __uint128_t src_rep_t
;
46 #define SRC_REP_C (__uint128_t)
47 // sign bit, exponent and significand occupy the lower 80 bits.
48 static const int srcBits
= 80;
49 static const int srcSigFracBits
= 63;
50 // -1 accounts for the sign bit.
51 // -1 accounts for the explicitly stored integer bit.
52 // srcBits - srcSigFracBits - 1 - 1
53 static const int srcExpBits
= 15;
55 #elif defined SRC_HALF
56 #ifdef COMPILER_RT_HAS_FLOAT16
57 typedef _Float16 src_t
;
59 typedef uint16_t src_t
;
61 typedef uint16_t src_rep_t
;
62 #define SRC_REP_C UINT16_C
63 static const int srcBits
= sizeof(src_t
) * CHAR_BIT
;
64 static const int srcSigFracBits
= 10;
65 // -1 accounts for the sign bit.
66 // srcBits - srcSigFracBits - 1
67 static const int srcExpBits
= 5;
69 static inline int src_rep_t_clz_impl(src_rep_t a
) {
70 return __builtin_clz(a
) - 16;
73 #define src_rep_t_clz src_rep_t_clz_impl
75 #elif defined SRC_BFLOAT16
76 #ifdef COMPILER_RT_HAS_BFLOAT16
79 typedef uint16_t src_t
;
81 typedef uint16_t src_rep_t
;
82 #define SRC_REP_C UINT16_C
83 static const int srcBits
= sizeof(src_t
) * CHAR_BIT
;
84 static const int srcSigFracBits
= 7;
85 // -1 accounts for the sign bit.
86 // srcBits - srcSigFracBits - 1
87 static const int srcExpBits
= 8;
88 #define src_rep_t_clz __builtin_clz
91 #error Source should be half, single, or double precision!
92 #endif // end source precision
94 #if defined DST_SINGLE
96 typedef uint32_t dst_rep_t
;
97 #define DST_REP_C UINT32_C
98 static const int dstBits
= sizeof(dst_t
) * CHAR_BIT
;
99 static const int dstSigFracBits
= 23;
100 // -1 accounts for the sign bit.
101 // dstBits - dstSigFracBits - 1
102 static const int dstExpBits
= 8;
104 #elif defined DST_DOUBLE
105 typedef double dst_t
;
106 typedef uint64_t dst_rep_t
;
107 #define DST_REP_C UINT64_C
108 static const int dstBits
= sizeof(dst_t
) * CHAR_BIT
;
109 static const int dstSigFracBits
= 52;
110 // -1 accounts for the sign bit.
111 // dstBits - dstSigFracBits - 1
112 static const int dstExpBits
= 11;
114 #elif defined DST_QUAD
115 typedef tf_float dst_t
;
116 typedef __uint128_t dst_rep_t
;
117 #define DST_REP_C (__uint128_t)
118 static const int dstBits
= sizeof(dst_t
) * CHAR_BIT
;
119 static const int dstSigFracBits
= 112;
120 // -1 accounts for the sign bit.
121 // dstBits - dstSigFracBits - 1
122 static const int dstExpBits
= 15;
125 #error Destination should be single, double, or quad precision!
126 #endif // end destination precision
128 // End of specialization parameters.
130 // TODO: These helper routines should be placed into fp_lib.h
131 // Currently they depend on macros/constants defined above.
133 static inline src_rep_t
extract_sign_from_src(src_rep_t x
) {
134 const src_rep_t srcSignMask
= SRC_REP_C(1) << (srcBits
- 1);
135 return (x
& srcSignMask
) >> (srcBits
- 1);
138 static inline src_rep_t
extract_exp_from_src(src_rep_t x
) {
139 const int srcSigBits
= srcBits
- 1 - srcExpBits
;
140 const src_rep_t srcExpMask
= ((SRC_REP_C(1) << srcExpBits
) - 1) << srcSigBits
;
141 return (x
& srcExpMask
) >> srcSigBits
;
144 static inline src_rep_t
extract_sig_frac_from_src(src_rep_t x
) {
145 const src_rep_t srcSigFracMask
= (SRC_REP_C(1) << srcSigFracBits
) - 1;
146 return x
& srcSigFracMask
;
150 static inline int clz_in_sig_frac(src_rep_t sigFrac
) {
151 const int skip
= 1 + srcExpBits
;
152 return src_rep_t_clz(sigFrac
) - skip
;
156 static inline dst_rep_t
construct_dst_rep(dst_rep_t sign
, dst_rep_t exp
, dst_rep_t sigFrac
) {
157 return (sign
<< (dstBits
- 1)) | (exp
<< (dstBits
- 1 - dstExpBits
)) | sigFrac
;
160 // Two helper routines for conversion to and from the representation of
161 // floating-point data as integer values follow.
163 static inline src_rep_t
srcToRep(src_t x
) {
171 static inline dst_t
dstFromRep(dst_rep_t x
) {
178 // End helper routines. Conversion implementation follows.
180 #endif // FP_EXTEND_HEADER