1 /* Decimal floating point support for GDB.
3 Copyright 2007, 2008, 2009 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
, gdb_byte
*to
)
42 #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_LITTLE
44 #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG
47 if (gdbarch_byte_order (current_gdbarch
) == OPPOSITE_BYTE_ORDER
)
48 for (i
= 0; i
< len
; i
++)
49 to
[i
] = from
[len
- i
- 1];
51 for (i
= 0; i
< len
; i
++)
57 /* Helper function to get the appropriate libdecnumber context for each size
60 set_decnumber_context (decContext
*ctx
, int len
)
65 decContextDefault (ctx
, DEC_INIT_DECIMAL32
);
68 decContextDefault (ctx
, DEC_INIT_DECIMAL64
);
71 decContextDefault (ctx
, DEC_INIT_DECIMAL128
);
78 /* Check for errors signaled in the decimal context structure. */
80 decimal_check_errors (decContext
*ctx
)
82 /* An error here could be a division by zero, an overflow, an underflow or
83 an invalid operation (from the DEC_Errors constant in decContext.h).
84 Since GDB doesn't complain about division by zero, overflow or underflow
85 errors for binary floating, we won't complain about them for decimal
87 if (ctx
->status
& DEC_IEEE_854_Invalid_operation
)
89 /* Leave only the error bits in the status flags. */
90 ctx
->status
&= DEC_IEEE_854_Invalid_operation
;
91 error (_("Cannot perform operation: %s"), decContextStatusToString (ctx
));
95 /* Helper function to convert from libdecnumber's appropriate representation
96 for computation to each size of decimal float. */
98 decimal_from_number (const decNumber
*from
, gdb_byte
*to
, int len
)
102 set_decnumber_context (&set
, len
);
107 decimal32FromNumber ((decimal32
*) to
, from
, &set
);
110 decimal64FromNumber ((decimal64
*) to
, from
, &set
);
113 decimal128FromNumber ((decimal128
*) to
, from
, &set
);
118 /* Helper function to convert each size of decimal float to libdecnumber's
119 appropriate representation for computation. */
121 decimal_to_number (const gdb_byte
*from
, int len
, decNumber
*to
)
126 decimal32ToNumber ((decimal32
*) from
, to
);
129 decimal64ToNumber ((decimal64
*) from
, to
);
132 decimal128ToNumber ((decimal128
*) from
, to
);
135 error (_("Unknown decimal floating point type.\n"));
140 /* Convert decimal type to its string representation. LEN is the length
141 of the decimal type, 4 bytes for decimal32, 8 bytes for decimal64 and
142 16 bytes for decimal128. */
144 decimal_to_string (const gdb_byte
*decbytes
, int len
, char *s
)
148 match_endianness (decbytes
, len
, dec
);
153 decimal32ToString ((decimal32
*) dec
, s
);
156 decimal64ToString ((decimal64
*) dec
, s
);
159 decimal128ToString ((decimal128
*) dec
, s
);
162 error (_("Unknown decimal floating point type."));
167 /* Convert the string form of a decimal value to its decimal representation.
168 LEN is the length of the decimal type, 4 bytes for decimal32, 8 bytes for
169 decimal64 and 16 bytes for decimal128. */
171 decimal_from_string (gdb_byte
*decbytes
, int len
, const char *string
)
176 set_decnumber_context (&set
, len
);
181 decimal32FromString ((decimal32
*) dec
, string
, &set
);
184 decimal64FromString ((decimal64
*) dec
, string
, &set
);
187 decimal128FromString ((decimal128
*) dec
, string
, &set
);
190 error (_("Unknown decimal floating point type."));
194 match_endianness (dec
, len
, decbytes
);
196 /* Check for errors in the DFP operation. */
197 decimal_check_errors (&set
);
202 /* Converts a value of an integral type to a decimal float of
203 specified LEN bytes. */
205 decimal_from_integral (struct value
*from
, gdb_byte
*to
, int len
)
212 type
= check_typedef (value_type (from
));
214 if (TYPE_LENGTH (type
) > 4)
215 /* libdecnumber can convert only 32-bit integers. */
216 error (_("Conversion of large integer to a decimal floating type is not supported."));
218 l
= value_as_long (from
);
220 if (TYPE_UNSIGNED (type
))
221 decNumberFromUInt32 (&number
, (unsigned int) l
);
223 decNumberFromInt32 (&number
, (int) l
);
225 decimal_from_number (&number
, dec
, len
);
226 match_endianness (dec
, len
, to
);
229 /* Converts a value of a float type to a decimal float of
232 This is an ugly way to do the conversion, but libdecnumber does
233 not offer a direct way to do it. */
235 decimal_from_floating (struct value
*from
, gdb_byte
*to
, int len
)
239 buffer
= xstrprintf ("%.30" DOUBLEST_PRINT_FORMAT
, value_as_double (from
));
241 decimal_from_string (to
, len
, buffer
);
246 /* Converts a decimal float of LEN bytes to a double value. */
248 decimal_to_doublest (const gdb_byte
*from
, int len
)
250 char buffer
[MAX_DECIMAL_STRING
];
252 /* This is an ugly way to do the conversion, but libdecnumber does
253 not offer a direct way to do it. */
254 decimal_to_string (from
, len
, buffer
);
255 return strtod (buffer
, NULL
);
258 /* Check if operands have the same size and convert them to the
259 biggest of the two if necessary. */
261 promote_decimal (gdb_byte
*x
, int len_x
, gdb_byte
*y
, int len_y
)
268 decimal_to_number (x
, len_x
, &number
);
269 decimal_from_number (&number
, x
, len_y
);
272 else if (len_x
> len_y
)
274 decimal_to_number (y
, len_y
, &number
);
275 decimal_from_number (&number
, y
, len_x
);
284 /* Perform operation OP with operands X and Y and store value in RESULT.
285 If LEN_X and LEN_Y are not equal, RESULT will have the size of the biggest
286 of the two, and LEN_RESULT will be set accordingly. */
288 decimal_binop (enum exp_opcode op
, const gdb_byte
*x
, int len_x
,
289 const gdb_byte
*y
, int len_y
, gdb_byte
*result
, int *len_result
)
292 decNumber number1
, number2
, number3
;
293 gdb_byte dec1
[16], dec2
[16], dec3
[16];
295 match_endianness (x
, len_x
, dec1
);
296 match_endianness (y
, len_y
, dec2
);
298 *len_result
= promote_decimal (dec1
, len_x
, dec2
, len_y
);
300 /* Both operands are of size *len_result from now on. */
302 decimal_to_number (dec1
, *len_result
, &number1
);
303 decimal_to_number (dec2
, *len_result
, &number2
);
305 set_decnumber_context (&set
, *len_result
);
310 decNumberAdd (&number3
, &number1
, &number2
, &set
);
313 decNumberSubtract (&number3
, &number1
, &number2
, &set
);
316 decNumberMultiply (&number3
, &number1
, &number2
, &set
);
319 decNumberDivide (&number3
, &number1
, &number2
, &set
);
322 decNumberPower (&number3
, &number1
, &number2
, &set
);
325 internal_error (__FILE__
, __LINE__
,
326 _("Unknown decimal floating point operation."));
330 /* Check for errors in the DFP operation. */
331 decimal_check_errors (&set
);
333 decimal_from_number (&number3
, dec3
, *len_result
);
335 match_endianness (dec3
, *len_result
, result
);
338 /* Returns true if X (which is LEN bytes wide) is the number zero. */
340 decimal_is_zero (const gdb_byte
*x
, int len
)
345 match_endianness (x
, len
, dec
);
346 decimal_to_number (dec
, len
, &number
);
348 return decNumberIsZero (&number
);
351 /* Compares two numbers numerically. If X is less than Y then the return value
352 will be -1. If they are equal, then the return value will be 0. If X is
353 greater than the Y then the return value will be 1. */
355 decimal_compare (const gdb_byte
*x
, int len_x
, const gdb_byte
*y
, int len_y
)
357 decNumber number1
, number2
, result
;
359 gdb_byte dec1
[16], dec2
[16];
362 match_endianness (x
, len_x
, dec1
);
363 match_endianness (y
, len_y
, dec2
);
365 len_result
= promote_decimal (dec1
, len_x
, dec2
, len_y
);
367 decimal_to_number (dec1
, len_result
, &number1
);
368 decimal_to_number (dec2
, len_result
, &number2
);
370 set_decnumber_context (&set
, len_result
);
372 decNumberCompare (&result
, &number1
, &number2
, &set
);
374 /* Check for errors in the DFP operation. */
375 decimal_check_errors (&set
);
377 if (decNumberIsNaN (&result
))
378 error (_("Comparison with an invalid number (NaN)."));
379 else if (decNumberIsZero (&result
))
381 else if (decNumberIsNegative (&result
))
387 /* Convert a decimal value from a decimal type with LEN_FROM bytes to a
388 decimal type with LEN_TO bytes. */
390 decimal_convert (const gdb_byte
*from
, int len_from
, gdb_byte
*to
,
396 match_endianness (from
, len_from
, dec
);
398 decimal_to_number (dec
, len_from
, &number
);
399 decimal_from_number (&number
, dec
, len_to
);
401 match_endianness (dec
, len_to
, to
);