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_bitfield_unsigned_read(srcp
,
88 exp
= ctf_bitfield_signed_read(srcp
, src_class
->exp
);
89 sign
= ctf_bitfield_unsigned_read(srcp
, src_class
->sign
);
91 sign
= ctf_bitfield_unsigned_read(srcp
, src_class
->sign
);
92 exp
= ctf_bitfield_signed_read(srcp
, src_class
->exp
);
93 mantissa
= ctf_bitfield_unsigned_read(srcp
,
97 if (dest
->byte_order
== LITTLE_ENDIAN
) {
98 ctf_bitfield_unsigned_write(destp
, dest_class
->mantissa
,
100 ctf_bitfield_signed_write(destp
, dest_class
->exp
, exp
);
101 ctf_bitfield_unsigned_write(destp
, dest_class
->sign
, sign
);
103 ctf_bitfield_unsigned_write(destp
, dest_class
->sign
, sign
);
104 ctf_bitfield_signed_write(destp
, dest_class
->exp
, exp
);
105 ctf_bitfield_unsigned_write(destp
, dest_class
->mantissa
,
110 void ctf_float_copy(struct stream_pos
*dest
, struct stream_pos
*src
,
111 const struct type_class_float
*float_class
)
113 align_pos(src
, float_class
->p
.alignment
);
114 align_pos(dest
, float_class
->p
.alignment
);
115 _ctf_float_copy(dest
, float_class
, src
, float_class
);
118 double ctf_double_read(struct stream_pos
*srcp
,
119 const struct type_class_float
*float_class
)
121 union doubleIEEE754 u
;
122 struct ctf_float
*dest_class
= float_type_new(NULL
,
124 sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
,
126 __alignof__(double));
127 struct stream_pos destp
;
129 align_pos(srcp
, float_class
->p
.alignment
);
130 init_pos(&destp
, &u
.bits
);
131 _ctf_float_copy(&destp
, dest_class
, srcp
, float_class
);
132 float_type_free(dest_class
);
136 void ctf_double_write(struct stream_pos
*destp
,
137 const struct type_class_float
*float_class
,
140 union doubleIEEE754 u
;
141 struct ctf_float
*src_class
= float_type_new(NULL
,
143 sizeof(double) * CHAR_BIT
- DBL_MANT_DIG
,
145 __alignof__(double));
146 struct stream_pos srcp
;
149 align_pos(destp
, float_class
->p
.alignment
);
150 init_pos(&srcp
, &u
.bits
);
151 _ctf_float_copy(destp
, float_class
, &srcp
, src_class
);
152 float_type_free(src_class
);
155 long double ctf_ldouble_read(struct stream_pos
*srcp
,
156 const struct type_class_float
*float_class
)
158 union ldoubleIEEE754 u
;
159 struct ctf_float
*dest_class
= float_type_new(NULL
,
161 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
,
163 __alignof__(long double));
164 struct stream_pos destp
;
166 align_pos(srcp
, float_class
->p
.alignment
);
167 init_pos(&destp
, &u
.bits
);
168 _ctf_float_copy(&destp
, dest_class
, srcp
, float_class
);
169 float_type_free(dest_class
);
173 void ctf_ldouble_write(struct stream_pos
*destp
,
174 const struct type_class_float
*float_class
,
177 union ldoubleIEEE754 u
;
178 struct ctf_float
*src_class
= float_type_new(NULL
,
180 sizeof(long double) * CHAR_BIT
- LDBL_MANT_DIG
,
182 __alignof__(long double));
183 struct stream_pos srcp
;
186 align_pos(destp
, float_class
->p
.alignment
);
187 init_pos(&srcp
, &u
.bits
);
188 _ctf_float_copy(destp
, float_class
, &srcp
, src_class
);
189 float_type_free(src_class
);
This page took 0.034974 seconds and 6 git commands to generate.