1 /* Decimal floating point support for GDB.
3 Copyright 2007, 2008, 2009, 2010, 2011 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/>. */
21 #include "expression.h"
26 /* The order of the following headers is important for making sure
27 decNumber structure is large enough to hold decimal128 digits. */
29 #include "dpd/decimal128.h"
30 #include "dpd/decimal64.h"
31 #include "dpd/decimal32.h"
33 /* In GDB, we are using an array of gdb_byte to represent decimal values.
34 They are stored in host byte order. This routine does the conversion if
35 the target byte order is different. */
37 match_endianness (const gdb_byte *from, int len, enum bfd_endian byte_order,
43 #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_LITTLE
45 #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG
48 if (byte_order == OPPOSITE_BYTE_ORDER)
49 for (i = 0; i < len; i++)
50 to[i] = from[len - i - 1];
52 for (i = 0; i < len; i++)
58 /* Helper function to get the appropriate libdecnumber context for each size
61 set_decnumber_context (decContext *ctx, int len)
66 decContextDefault (ctx, DEC_INIT_DECIMAL32);
69 decContextDefault (ctx, DEC_INIT_DECIMAL64);
72 decContextDefault (ctx, DEC_INIT_DECIMAL128);
79 /* Check for errors signaled in the decimal context structure. */
81 decimal_check_errors (decContext *ctx)
83 /* An error here could be a division by zero, an overflow, an underflow or
84 an invalid operation (from the DEC_Errors constant in decContext.h).
85 Since GDB doesn't complain about division by zero, overflow or underflow
86 errors for binary floating, we won't complain about them for decimal
88 if (ctx->status & DEC_IEEE_854_Invalid_operation)
90 /* Leave only the error bits in the status flags. */
91 ctx->status &= DEC_IEEE_854_Invalid_operation;
92 error (_("Cannot perform operation: %s"), decContextStatusToString (ctx));
96 /* Helper function to convert from libdecnumber's appropriate representation
97 for computation to each size of decimal float. */
99 decimal_from_number (const decNumber *from, gdb_byte *to, int len)
103 set_decnumber_context (&set, len);
108 decimal32FromNumber ((decimal32 *) to, from, &set);
111 decimal64FromNumber ((decimal64 *) to, from, &set);
114 decimal128FromNumber ((decimal128 *) to, from, &set);
119 /* Helper function to convert each size of decimal float to libdecnumber's
120 appropriate representation for computation. */
122 decimal_to_number (const gdb_byte *from, int len, decNumber *to)
127 decimal32ToNumber ((decimal32 *) from, to);
130 decimal64ToNumber ((decimal64 *) from, to);
133 decimal128ToNumber ((decimal128 *) from, to);
136 error (_("Unknown decimal floating point type.\n"));
141 /* Convert decimal type to its string representation. LEN is the length
142 of the decimal type, 4 bytes for decimal32, 8 bytes for decimal64 and
143 16 bytes for decimal128. */
145 decimal_to_string (const gdb_byte *decbytes, int len,
146 enum bfd_endian byte_order, char *s)
150 match_endianness (decbytes, len, byte_order, dec);
155 decimal32ToString ((decimal32 *) dec, s);
158 decimal64ToString ((decimal64 *) dec, s);
161 decimal128ToString ((decimal128 *) dec, s);
164 error (_("Unknown decimal floating point type."));
169 /* Convert the string form of a decimal value to its decimal representation.
170 LEN is the length of the decimal type, 4 bytes for decimal32, 8 bytes for
171 decimal64 and 16 bytes for decimal128. */
173 decimal_from_string (gdb_byte *decbytes, int len, enum bfd_endian byte_order,
179 set_decnumber_context (&set, len);
184 decimal32FromString ((decimal32 *) dec, string, &set);
187 decimal64FromString ((decimal64 *) dec, string, &set);
190 decimal128FromString ((decimal128 *) dec, string, &set);
193 error (_("Unknown decimal floating point type."));
197 match_endianness (dec, len, byte_order, decbytes);
199 /* Check for errors in the DFP operation. */
200 decimal_check_errors (&set);
205 /* Converts a value of an integral type to a decimal float of
206 specified LEN bytes. */
208 decimal_from_integral (struct value *from,
209 gdb_byte *to, int len, enum bfd_endian byte_order)
216 type = check_typedef (value_type (from));
218 if (TYPE_LENGTH (type) > 4)
219 /* libdecnumber can convert only 32-bit integers. */
220 error (_("Conversion of large integer to a decimal floating type is not supported."));
222 l = value_as_long (from);
224 if (TYPE_UNSIGNED (type))
225 decNumberFromUInt32 (&number, (unsigned int) l);
227 decNumberFromInt32 (&number, (int) l);
229 decimal_from_number (&number, dec, len);
230 match_endianness (dec, len, byte_order, to);
233 /* Converts a value of a float type to a decimal float of
236 This is an ugly way to do the conversion, but libdecnumber does
237 not offer a direct way to do it. */
239 decimal_from_floating (struct value *from,
240 gdb_byte *to, int len, enum bfd_endian byte_order)
244 buffer = xstrprintf ("%.30" DOUBLEST_PRINT_FORMAT, value_as_double (from));
246 decimal_from_string (to, len, byte_order, buffer);
251 /* Converts a decimal float of LEN bytes to a double value. */
253 decimal_to_doublest (const gdb_byte *from, int len, enum bfd_endian byte_order)
255 char buffer[MAX_DECIMAL_STRING];
257 /* This is an ugly way to do the conversion, but libdecnumber does
258 not offer a direct way to do it. */
259 decimal_to_string (from, len, byte_order, buffer);
260 return strtod (buffer, NULL);
263 /* Perform operation OP with operands X and Y with sizes LEN_X and LEN_Y
264 and byte orders BYTE_ORDER_X and BYTE_ORDER_Y, and store value in
265 RESULT with size LEN_RESULT and byte order BYTE_ORDER_RESULT. */
267 decimal_binop (enum exp_opcode op,
268 const gdb_byte *x, int len_x, enum bfd_endian byte_order_x,
269 const gdb_byte *y, int len_y, enum bfd_endian byte_order_y,
270 gdb_byte *result, int len_result,
271 enum bfd_endian byte_order_result)
274 decNumber number1, number2, number3;
275 gdb_byte dec1[16], dec2[16], dec3[16];
277 match_endianness (x, len_x, byte_order_x, dec1);
278 match_endianness (y, len_y, byte_order_y, dec2);
280 decimal_to_number (dec1, len_x, &number1);
281 decimal_to_number (dec2, len_y, &number2);
283 set_decnumber_context (&set, len_result);
288 decNumberAdd (&number3, &number1, &number2, &set);
291 decNumberSubtract (&number3, &number1, &number2, &set);
294 decNumberMultiply (&number3, &number1, &number2, &set);
297 decNumberDivide (&number3, &number1, &number2, &set);
300 decNumberPower (&number3, &number1, &number2, &set);
303 internal_error (__FILE__, __LINE__,
304 _("Unknown decimal floating point operation."));
308 /* Check for errors in the DFP operation. */
309 decimal_check_errors (&set);
311 decimal_from_number (&number3, dec3, len_result);
313 match_endianness (dec3, len_result, byte_order_result, result);
316 /* Returns true if X (which is LEN bytes wide) is the number zero. */
318 decimal_is_zero (const gdb_byte *x, int len, enum bfd_endian byte_order)
323 match_endianness (x, len, byte_order, dec);
324 decimal_to_number (dec, len, &number);
326 return decNumberIsZero (&number);
329 /* Compares two numbers numerically. If X is less than Y then the return value
330 will be -1. If they are equal, then the return value will be 0. If X is
331 greater than the Y then the return value will be 1. */
333 decimal_compare (const gdb_byte *x, int len_x, enum bfd_endian byte_order_x,
334 const gdb_byte *y, int len_y, enum bfd_endian byte_order_y)
336 decNumber number1, number2, result;
338 gdb_byte dec1[16], dec2[16];
341 match_endianness (x, len_x, byte_order_x, dec1);
342 match_endianness (y, len_y, byte_order_y, dec2);
344 decimal_to_number (dec1, len_x, &number1);
345 decimal_to_number (dec2, len_y, &number2);
347 /* Perform the comparison in the larger of the two sizes. */
348 len_result = len_x > len_y ? len_x : len_y;
349 set_decnumber_context (&set, len_result);
351 decNumberCompare (&result, &number1, &number2, &set);
353 /* Check for errors in the DFP operation. */
354 decimal_check_errors (&set);
356 if (decNumberIsNaN (&result))
357 error (_("Comparison with an invalid number (NaN)."));
358 else if (decNumberIsZero (&result))
360 else if (decNumberIsNegative (&result))
366 /* Convert a decimal value from a decimal type with LEN_FROM bytes to a
367 decimal type with LEN_TO bytes. */
369 decimal_convert (const gdb_byte *from, int len_from,
370 enum bfd_endian byte_order_from, gdb_byte *to, int len_to,
371 enum bfd_endian byte_order_to)
376 match_endianness (from, len_from, byte_order_from, dec);
378 decimal_to_number (dec, len_from, &number);
379 decimal_from_number (&number, dec, len_to);
381 match_endianness (dec, len_to, byte_order_to, to);