1//===-lib/fp_extend.h - low precision -> high precision conversion -*- C
2//-*-===//
3//
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
7//
8//===----------------------------------------------------------------------===//
9//
10// Set source and destination setting
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef FP_EXTEND_HEADER
15#define FP_EXTEND_HEADER
16
17#include "int_lib.h"
18
19#if defined SRC_SINGLE
20typedef float src_t;
21typedef uint32_t src_rep_t;
22#define SRC_REP_C UINT32_C
23static const int srcBits = sizeof(src_t) * CHAR_BIT;
24static const int srcSigFracBits = 23;
25// -1 accounts for the sign bit.
26// srcBits - srcSigFracBits - 1
27static const int srcExpBits = 8;
28#define src_rep_t_clz clzsi
29
30#elif defined SRC_DOUBLE
31typedef double src_t;
32typedef uint64_t src_rep_t;
33#define SRC_REP_C UINT64_C
34static const int srcBits = sizeof(src_t) * CHAR_BIT;
35static const int srcSigFracBits = 52;
36// -1 accounts for the sign bit.
37// srcBits - srcSigFracBits - 1
38static const int srcExpBits = 11;
39
40static 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
42
43#elif defined SRC_80
44typedef xf_float src_t;
45typedef __uint128_t src_rep_t;
46#define SRC_REP_C (__uint128_t)
47// sign bit, exponent and significand occupy the lower 80 bits.
48static const int srcBits = 80;
49static 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
53static const int srcExpBits = 15;
54
55#elif defined SRC_HALF
56#ifdef COMPILER_RT_HAS_FLOAT16
57typedef _Float16 src_t;
58#else
59typedef uint16_t src_t;
60#endif
61typedef uint16_t src_rep_t;
62#define SRC_REP_C UINT16_C
63static const int srcBits = sizeof(src_t) * CHAR_BIT;
64static const int srcSigFracBits = 10;
65// -1 accounts for the sign bit.
66// srcBits - srcSigFracBits - 1
67static const int srcExpBits = 5;
68
69static inline int src_rep_t_clz_impl(src_rep_t a) {
70 return __builtin_clz(a) - 16;
71}
72
73#define src_rep_t_clz src_rep_t_clz_impl
74
75#elif defined SRC_BFLOAT16
76#ifdef COMPILER_RT_HAS_BFLOAT16
77typedef __bf16 src_t;
78#else
79typedef uint16_t src_t;
80#endif
81typedef uint16_t src_rep_t;
82#define SRC_REP_C UINT16_C
83static const int srcBits = sizeof(src_t) * CHAR_BIT;
84static const int srcSigFracBits = 7;
85// -1 accounts for the sign bit.
86// srcBits - srcSigFracBits - 1
87static const int srcExpBits = 8;
88#define src_rep_t_clz __builtin_clz
89
90#else
91#error Source should be half, single, or double precision!
92#endif // end source precision
93
94#if defined DST_SINGLE
95typedef float dst_t;
96typedef uint32_t dst_rep_t;
97#define DST_REP_C UINT32_C
98static const int dstBits = sizeof(dst_t) * CHAR_BIT;
99static const int dstSigFracBits = 23;
100// -1 accounts for the sign bit.
101// dstBits - dstSigFracBits - 1
102static const int dstExpBits = 8;
103
104#elif defined DST_DOUBLE
105typedef double dst_t;
106typedef uint64_t dst_rep_t;
107#define DST_REP_C UINT64_C
108static const int dstBits = sizeof(dst_t) * CHAR_BIT;
109static const int dstSigFracBits = 52;
110// -1 accounts for the sign bit.
111// dstBits - dstSigFracBits - 1
112static const int dstExpBits = 11;
113
114#elif defined DST_QUAD
115typedef tf_float dst_t;
116typedef __uint128_t dst_rep_t;
117#define DST_REP_C (__uint128_t)
118static const int dstBits = sizeof(dst_t) * CHAR_BIT;
119static const int dstSigFracBits = 112;
120// -1 accounts for the sign bit.
121// dstBits - dstSigFracBits - 1
122static const int dstExpBits = 15;
123
124#else
125#error Destination should be single, double, or quad precision!
126#endif // end destination precision
127
128// End of specialization parameters.
129
130// TODO: These helper routines should be placed into fp_lib.h
131// Currently they depend on macros/constants defined above.
132
133static 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);
136}
137
138static 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;
142}
143
144static 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;
147}
148
149#ifdef src_rep_t_clz
150static inline int clz_in_sig_frac(src_rep_t sigFrac) {
151 const int skip = 1 + srcExpBits;
152 return src_rep_t_clz(sigFrac) - skip;
153}
154#endif
155
156static 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;
158}
159
160// Two helper routines for conversion to and from the representation of
161// floating-point data as integer values follow.
162
163static inline src_rep_t srcToRep(src_t x) {
164 const union {
165 src_t f;
166 src_rep_t i;
167 } rep = {.f = x};
168 return rep.i;
169}
170
171static inline dst_t dstFromRep(dst_rep_t x) {
172 const union {
173 dst_t f;
174 dst_rep_t i;
175 } rep = {.i = x};
176 return rep.f;
177}
178// End helper routines. Conversion implementation follows.
179
180#endif // FP_EXTEND_HEADER
181

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of compiler-rt/lib/builtins/fp_extend.h