1 /* Floating point routines for GDB, the GNU debugger.
3 Copyright (C) 2017 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "floatformat.h"
25 #include "target-float.h"
28 /* Helper routines operating on binary floating-point data. */
32 /* Convert the byte-stream ADDR, interpreted as floating-point format FMT,
33 to an integer value (rounding towards zero). */
35 floatformat_to_longest (const struct floatformat
*fmt
, const gdb_byte
*addr
)
38 floatformat_to_doublest (fmt
, addr
, &d
);
42 /* Convert signed integer VAL to a target floating-number of format FMT
43 and store it as byte-stream ADDR. */
45 floatformat_from_longest (const struct floatformat
*fmt
, gdb_byte
*addr
,
48 DOUBLEST d
= (DOUBLEST
) val
;
49 floatformat_from_doublest (fmt
, &d
, addr
);
52 /* Convert unsigned integer VAL to a target floating-number of format FMT
53 and store it as byte-stream ADDR. */
55 floatformat_from_ulongest (const struct floatformat
*fmt
, gdb_byte
*addr
,
58 DOUBLEST d
= (DOUBLEST
) val
;
59 floatformat_from_doublest (fmt
, &d
, addr
);
62 /* Convert a floating-point number of format FROM_FMT from the target
63 byte-stream FROM to a floating-point number of format TO_FMT, and
64 store it to the target byte-stream TO. */
66 floatformat_convert (const gdb_byte
*from
, const struct floatformat
*from_fmt
,
67 gdb_byte
*to
, const struct floatformat
*to_fmt
)
69 if (from_fmt
== to_fmt
)
71 /* The floating-point formats match, so we simply copy the data. */
72 memcpy (to
, from
, floatformat_totalsize_bytes (to_fmt
));
76 /* The floating-point formats don't match. The best we can do
77 (apart from simulating the target FPU) is converting to the
78 widest floating-point type supported by the host, and then
79 again to the desired type. */
82 floatformat_to_doublest (from_fmt
, from
, &d
);
83 floatformat_from_doublest (to_fmt
, &d
, to
);
87 /* Perform the binary operation indicated by OPCODE, using as operands the
88 target byte streams X and Y, interpreted as floating-point numbers of
89 formats FMT_X and FMT_Y, respectively. Convert the result to format
90 FMT_RES and store it into the byte-stream RES. */
92 floatformat_binop (enum exp_opcode op
,
93 const struct floatformat
*fmt_x
, const gdb_byte
*x
,
94 const struct floatformat
*fmt_y
, const gdb_byte
*y
,
95 const struct floatformat
*fmt_result
, gdb_byte
*result
)
97 DOUBLEST v1
, v2
, v
= 0;
99 floatformat_to_doublest (fmt_x
, x
, &v1
);
100 floatformat_to_doublest (fmt_y
, y
, &v2
);
124 error (_("Cannot perform exponentiation: %s"),
125 safe_strerror (errno
));
129 v
= v1
< v2
? v1
: v2
;
133 v
= v1
> v2
? v1
: v2
;
137 error (_("Integer-only operation on floating point number."));
141 floatformat_from_doublest (fmt_result
, &v
, result
);
144 /* Compare the two target byte streams X and Y, interpreted as floating-point
145 numbers of formats FMT_X and FMT_Y, respectively. Return zero if X and Y
146 are equal, -1 if X is less than Y, and 1 otherwise. */
148 floatformat_compare (const struct floatformat
*fmt_x
, const gdb_byte
*x
,
149 const struct floatformat
*fmt_y
, const gdb_byte
*y
)
153 floatformat_to_doublest (fmt_x
, x
, &v1
);
154 floatformat_to_doublest (fmt_y
, y
, &v2
);
164 /* Typed floating-point routines. These routines operate on floating-point
165 values in target format, represented by a byte buffer interpreted as a
166 "struct type", which may be either a binary or decimal floating-point
167 type (TYPE_CODE_FLT or TYPE_CODE_DECFLOAT). */
169 /* Return whether the byte-stream ADDR holds a valid value of
170 floating-point type TYPE. */
172 target_float_is_valid (const gdb_byte
*addr
, const struct type
*type
)
174 if (TYPE_CODE (type
) == TYPE_CODE_FLT
)
175 return floatformat_is_valid (floatformat_from_type (type
), addr
);
177 if (TYPE_CODE (type
) == TYPE_CODE_DECFLOAT
)
180 gdb_assert_not_reached ("unexpected type code");
183 /* Return whether the byte-stream ADDR, interpreted as floating-point
184 type TYPE, is numerically equal to zero (of either sign). */
186 target_float_is_zero (const gdb_byte
*addr
, const struct type
*type
)
188 if (TYPE_CODE (type
) == TYPE_CODE_FLT
)
189 return (floatformat_classify (floatformat_from_type (type
), addr
)
192 if (TYPE_CODE (type
) == TYPE_CODE_DECFLOAT
)
193 return decimal_is_zero (addr
, TYPE_LENGTH (type
),
194 gdbarch_byte_order (get_type_arch (type
)));
196 gdb_assert_not_reached ("unexpected type code");
199 /* Convert the byte-stream ADDR, interpreted as floating-point type TYPE,
200 to a string, optionally using the print format FORMAT. */
202 target_float_to_string (const gdb_byte
*addr
, const struct type
*type
,
205 if (TYPE_CODE (type
) == TYPE_CODE_FLT
)
206 return floatformat_to_string (floatformat_from_type (type
), addr
, format
);
208 if (TYPE_CODE (type
) == TYPE_CODE_DECFLOAT
)
209 return decimal_to_string (addr
, TYPE_LENGTH (type
),
210 gdbarch_byte_order (get_type_arch (type
)),
213 gdb_assert_not_reached ("unexpected type code");
216 /* Parse string STRING into a target floating-number of type TYPE and
217 store it as byte-stream ADDR. Return whether parsing succeeded. */
219 target_float_from_string (gdb_byte
*addr
, const struct type
*type
,
220 const std::string
&string
)
222 /* Ensure possible padding bytes in the target buffer are zeroed out. */
223 memset (addr
, 0, TYPE_LENGTH (type
));
225 if (TYPE_CODE (type
) == TYPE_CODE_FLT
)
226 return floatformat_from_string (floatformat_from_type (type
), addr
,
229 if (TYPE_CODE (type
) == TYPE_CODE_DECFLOAT
)
230 return decimal_from_string (addr
, TYPE_LENGTH (type
),
231 gdbarch_byte_order (get_type_arch (type
)),
234 gdb_assert_not_reached ("unexpected type code");
237 /* Convert the byte-stream ADDR, interpreted as floating-point type TYPE,
238 to an integer value (rounding towards zero). */
240 target_float_to_longest (const gdb_byte
*addr
, const struct type
*type
)
242 if (TYPE_CODE (type
) == TYPE_CODE_FLT
)
243 return floatformat_to_longest (floatformat_from_type (type
), addr
);
245 if (TYPE_CODE (type
) == TYPE_CODE_DECFLOAT
)
246 return decimal_to_longest (addr
, TYPE_LENGTH (type
),
247 gdbarch_byte_order (get_type_arch (type
)));
249 gdb_assert_not_reached ("unexpected type code");
252 /* Convert signed integer VAL to a target floating-number of type TYPE
253 and store it as byte-stream ADDR. */
255 target_float_from_longest (gdb_byte
*addr
, const struct type
*type
,
258 /* Ensure possible padding bytes in the target buffer are zeroed out. */
259 memset (addr
, 0, TYPE_LENGTH (type
));
261 if (TYPE_CODE (type
) == TYPE_CODE_FLT
)
263 floatformat_from_longest (floatformat_from_type (type
), addr
, val
);
267 if (TYPE_CODE (type
) == TYPE_CODE_DECFLOAT
)
269 decimal_from_longest (val
, addr
, TYPE_LENGTH (type
),
270 gdbarch_byte_order (get_type_arch (type
)));
274 gdb_assert_not_reached ("unexpected type code");
277 /* Convert unsigned integer VAL to a target floating-number of type TYPE
278 and store it as byte-stream ADDR. */
280 target_float_from_ulongest (gdb_byte
*addr
, const struct type
*type
,
283 /* Ensure possible padding bytes in the target buffer are zeroed out. */
284 memset (addr
, 0, TYPE_LENGTH (type
));
286 if (TYPE_CODE (type
) == TYPE_CODE_FLT
)
288 floatformat_from_ulongest (floatformat_from_type (type
), addr
, val
);
292 if (TYPE_CODE (type
) == TYPE_CODE_DECFLOAT
)
294 decimal_from_ulongest (val
, addr
, TYPE_LENGTH (type
),
295 gdbarch_byte_order (get_type_arch (type
)));
299 gdb_assert_not_reached ("unexpected type code");
302 /* Convert a floating-point number of type FROM_TYPE from the target
303 byte-stream FROM to a floating-point number of type TO_TYPE, and
304 store it to the target byte-stream TO. */
306 target_float_convert (const gdb_byte
*from
, const struct type
*from_type
,
307 gdb_byte
*to
, const struct type
*to_type
)
309 /* Ensure possible padding bytes in the target buffer are zeroed out. */
310 memset (to
, 0, TYPE_LENGTH (to_type
));
312 /* Use direct conversion routines if we have them. */
314 if (TYPE_CODE (from_type
) == TYPE_CODE_FLT
315 && TYPE_CODE (to_type
) == TYPE_CODE_FLT
)
317 floatformat_convert (from
, floatformat_from_type (from_type
),
318 to
, floatformat_from_type (to_type
));
322 if (TYPE_CODE (from_type
) == TYPE_CODE_DECFLOAT
323 && TYPE_CODE (to_type
) == TYPE_CODE_DECFLOAT
)
325 decimal_convert (from
, TYPE_LENGTH (from_type
),
326 gdbarch_byte_order (get_type_arch (from_type
)),
327 to
, TYPE_LENGTH (to_type
),
328 gdbarch_byte_order (get_type_arch (to_type
)));
332 /* We cannot directly convert between binary and decimal floating-point
333 types, so go via an intermediary string. */
335 if ((TYPE_CODE (from_type
) == TYPE_CODE_FLT
336 && TYPE_CODE (to_type
) == TYPE_CODE_DECFLOAT
)
337 || (TYPE_CODE (from_type
) == TYPE_CODE_DECFLOAT
338 && TYPE_CODE (to_type
) == TYPE_CODE_FLT
))
340 std::string str
= target_float_to_string (from
, from_type
);
341 target_float_from_string (to
, to_type
, str
);
345 gdb_assert_not_reached ("unexpected type code");
348 /* Perform the binary operation indicated by OPCODE, using as operands the
349 target byte streams X and Y, interpreted as floating-point numbers of
350 types TYPE_X and TYPE_Y, respectively. Convert the result to type
351 TYPE_RES and store it into the byte-stream RES.
353 The three types must either be all binary floating-point types, or else
354 all decimal floating-point types. Binary and decimal floating-point
355 types cannot be mixed within a single operation. */
357 target_float_binop (enum exp_opcode opcode
,
358 const gdb_byte
*x
, const struct type
*type_x
,
359 const gdb_byte
*y
, const struct type
*type_y
,
360 gdb_byte
*res
, const struct type
*type_res
)
362 /* Ensure possible padding bytes in the target buffer are zeroed out. */
363 memset (res
, 0, TYPE_LENGTH (type_res
));
365 if (TYPE_CODE (type_res
) == TYPE_CODE_FLT
)
367 gdb_assert (TYPE_CODE (type_x
) == TYPE_CODE_FLT
);
368 gdb_assert (TYPE_CODE (type_y
) == TYPE_CODE_FLT
);
369 return floatformat_binop (opcode
,
370 floatformat_from_type (type_x
), x
,
371 floatformat_from_type (type_y
), y
,
372 floatformat_from_type (type_res
), res
);
375 if (TYPE_CODE (type_res
) == TYPE_CODE_DECFLOAT
)
377 gdb_assert (TYPE_CODE (type_x
) == TYPE_CODE_DECFLOAT
);
378 gdb_assert (TYPE_CODE (type_y
) == TYPE_CODE_DECFLOAT
);
379 return decimal_binop (opcode
,
380 x
, TYPE_LENGTH (type_x
),
381 gdbarch_byte_order (get_type_arch (type_x
)),
382 y
, TYPE_LENGTH (type_y
),
383 gdbarch_byte_order (get_type_arch (type_y
)),
384 res
, TYPE_LENGTH (type_res
),
385 gdbarch_byte_order (get_type_arch (type_res
)));
388 gdb_assert_not_reached ("unexpected type code");
391 /* Compare the two target byte streams X and Y, interpreted as floating-point
392 numbers of types TYPE_X and TYPE_Y, respectively. Return zero if X and Y
393 are equal, -1 if X is less than Y, and 1 otherwise.
395 The two types must either both be binary floating-point types, or else
396 both be decimal floating-point types. Binary and decimal floating-point
397 types cannot compared directly against each other. */
399 target_float_compare (const gdb_byte
*x
, const struct type
*type_x
,
400 const gdb_byte
*y
, const struct type
*type_y
)
402 if (TYPE_CODE (type_x
) == TYPE_CODE_FLT
)
404 gdb_assert (TYPE_CODE (type_y
) == TYPE_CODE_FLT
);
405 return floatformat_compare (floatformat_from_type (type_x
), x
,
406 floatformat_from_type (type_y
), y
);
409 if (TYPE_CODE (type_x
) == TYPE_CODE_DECFLOAT
)
411 gdb_assert (TYPE_CODE (type_y
) == TYPE_CODE_DECFLOAT
);
412 return decimal_compare (x
, TYPE_LENGTH (type_x
),
413 gdbarch_byte_order (get_type_arch (type_x
)),
414 y
, TYPE_LENGTH (type_y
),
415 gdbarch_byte_order (get_type_arch (type_y
)));
418 gdb_assert_not_reached ("unexpected type code");
This page took 0.053974 seconds and 5 git commands to generate.