6fd0c72ef4dc97f5ce426d8a992022edbc7c16ee
4 * Floating point read/write functions.
6 * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * Reference: ISO C99 standard 5.2.4
25 #include <babeltrace/ctf/types.h>
27 #include <float.h> /* C99 floating point definitions */
28 #include <limits.h> /* C99 limits */
32 * This library is limited to binary representation of floating point values.
33 * Sign-extension of the exponents is assumed to keep the NaN, +inf, -inf
34 * values, but this should be double-checked (TODO).
38 * Aliasing float/double and unsigned long is not strictly permitted by strict
39 * aliasing, but in practice type prunning is well supported, and this permits
40 * us to use per-word read/writes rather than per-byte.
43 #if defined(__GNUC__) || defined(__MINGW32__) || defined(_MSC_VER)
44 #define HAS_TYPE_PRUNING
49 #error "Unsupported floating point radix"
55 #ifdef HAS_TYPE_PRUNING
56 unsigned long bits
[(sizeof(double) + sizeof(unsigned long) - 1) / sizeof(unsigned long)];
58 unsigned char bits
[sizeof(double)];
62 union ldoubleIEEE754
{
64 #ifdef HAS_TYPE_PRUNING
65 unsigned long bits
[(sizeof(long double) + sizeof(unsigned long) - 1) / sizeof(unsigned long)];
67 unsigned char bits
[sizeof(long double)];
72 size_t sign_start
, exp_start
, mantissa_start
, len
;
75 void _ctf_float_copy(struct stream_pos
*destp
,
76 const struct type_class_float
*dest_class
,
77 struct stream_pos
*srcp
,
78 const struct type_class_float
*src_class
)
85 if (src
->byte_order
== LITTLE_ENDIAN
) {
86 mantissa
= ctf_uint_read(srcp
, src_class
->mantissa
);
87 exp
= ctf_int_read(srcp
, src_class
->exp
);
88 sign
= ctf_uint_read(srcp
, src_class
->sign
);
90 sign
= ctf_uint_read(srcp
, src_class
->sign
);
91 exp
= ctf_int_read(srcp
, src_class
->exp
);
92 mantissa
= ctf_uint_read(srcp
, src_class
->mantissa
);
95 if (dest
->byte_order
== LITTLE_ENDIAN
) {
96 ctf_uint_write(destp
, dest_class
->mantissa
, mantissa
);
97 ctf_int_write(destp
, dest_class
->exp
, exp
);
98 ctf_uint_write(destp
, dest_class
->sign
, sign
);
100 ctf_uint_write(destp
, dest_class
->sign
, sign
);
101 ctf_int_write(destp
, dest_class
->exp
, exp
);
102 ctf_uint_write(destp
, dest_class
->mantissa
, mantissa
);
106 void ctf_float_copy(struct stream_pos
*dest
, struct stream_pos
*src
,
107 const struct type_class_float
*float_class
)
109 align_pos(src
, float_class
->p
.alignment
);
110 align_pos(dest
, float_class
->p
.alignment
);
111 _ctf_float_copy(dest
, float_class
, src
, float_class
);
114 double ctf_double_read(struct stream_pos
*srcp
,
115 const struct type_class_float
*float_class
)
117 union doubleIEEE754 u
;
118 struct ctf_float
*dest_class
= float_type_new(NULL
,
120 sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
,
122 __alignof__(double));
123 struct stream_pos destp
;
125 align_pos(srcp
, float_class
->p
.alignment
);
126 init_pos(&destp
, &u
.bits
);
127 _ctf_float_copy(&destp
, dest_class
, srcp
, float_class
);
128 float_type_free(dest_class
);
132 void ctf_double_write(struct stream_pos
*destp
,
133 const struct type_class_float
*float_class
,
136 union doubleIEEE754 u
;
137 struct ctf_float
*src_class
= float_type_new(NULL
,
139 sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
,
141 __alignof__(double));
142 struct stream_pos srcp
;
145 align_pos(destp
, float_class
->p
.alignment
);
146 init_pos(&srcp
, &u
.bits
);
147 _ctf_float_copy(destp
, float_class
, &srcp
, src_class
);
148 float_type_free(src_class
);
151 long double ctf_ldouble_read(struct stream_pos
*srcp
,
152 const struct type_class_float
*float_class
)
154 union ldoubleIEEE754 u
;
155 struct ctf_float
*dest_class
= float_type_new(NULL
,
157 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
,
159 __alignof__(long double));
160 struct stream_pos destp
;
162 align_pos(srcp
, float_class
->p
.alignment
);
163 init_pos(&destp
, &u
.bits
);
164 _ctf_float_copy(&destp
, dest_class
, srcp
, float_class
);
165 float_type_free(dest_class
);
169 void ctf_ldouble_write(struct stream_pos
*destp
,
170 const struct type_class_float
*float_class
,
173 union ldoubleIEEE754 u
;
174 struct ctf_float
*src_class
= float_type_new(NULL
,
176 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
,
178 __alignof__(long double));
179 struct stream_pos srcp
;
182 align_pos(destp
, float_class
->p
.alignment
);
183 init_pos(&srcp
, &u
.bits
);
184 _ctf_float_copy(destp
, float_class
, &srcp
, src_class
);
185 float_type_free(src_class
);
This page took 0.049193 seconds and 4 git commands to generate.