1 /* Decimal floating point support for GDB.
3 Copyright (C) 2007-2015 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"),
93 decContextStatusToString (ctx
));
97 /* Helper function to convert from libdecnumber's appropriate representation
98 for computation to each size of decimal float. */
100 decimal_from_number (const decNumber
*from
, gdb_byte
*to
, int len
)
104 set_decnumber_context (&set
, len
);
109 decimal32FromNumber ((decimal32
*) to
, from
, &set
);
112 decimal64FromNumber ((decimal64
*) to
, from
, &set
);
115 decimal128FromNumber ((decimal128
*) to
, from
, &set
);
120 /* Helper function to convert each size of decimal float to libdecnumber's
121 appropriate representation for computation. */
123 decimal_to_number (const gdb_byte
*from
, int len
, decNumber
*to
)
128 decimal32ToNumber ((decimal32
*) from
, to
);
131 decimal64ToNumber ((decimal64
*) from
, to
);
134 decimal128ToNumber ((decimal128
*) from
, to
);
137 error (_("Unknown decimal floating point type."));
142 /* Convert decimal type to its string representation. LEN is the length
143 of the decimal type, 4 bytes for decimal32, 8 bytes for decimal64 and
144 16 bytes for decimal128. */
146 decimal_to_string (const gdb_byte
*decbytes
, int len
,
147 enum bfd_endian byte_order
, char *s
)
151 match_endianness (decbytes
, len
, byte_order
, dec
);
156 decimal32ToString ((decimal32
*) dec
, s
);
159 decimal64ToString ((decimal64
*) dec
, s
);
162 decimal128ToString ((decimal128
*) dec
, s
);
165 error (_("Unknown decimal floating point type."));
170 /* Convert the string form of a decimal value to its decimal representation.
171 LEN is the length of the decimal type, 4 bytes for decimal32, 8 bytes for
172 decimal64 and 16 bytes for decimal128. */
174 decimal_from_string (gdb_byte
*decbytes
, int len
, enum bfd_endian byte_order
,
180 set_decnumber_context (&set
, len
);
185 decimal32FromString ((decimal32
*) dec
, string
, &set
);
188 decimal64FromString ((decimal64
*) dec
, string
, &set
);
191 decimal128FromString ((decimal128
*) dec
, string
, &set
);
194 error (_("Unknown decimal floating point type."));
198 match_endianness (dec
, len
, byte_order
, decbytes
);
200 /* Check for errors in the DFP operation. */
201 decimal_check_errors (&set
);
206 /* Converts a value of an integral type to a decimal float of
207 specified LEN bytes. */
209 decimal_from_integral (struct value
*from
,
210 gdb_byte
*to
, int len
, enum bfd_endian byte_order
)
217 type
= check_typedef (value_type (from
));
219 if (TYPE_LENGTH (type
) > 4)
220 /* libdecnumber can convert only 32-bit integers. */
221 error (_("Conversion of large integer to a "
222 "decimal floating type is not supported."));
224 l
= value_as_long (from
);
226 if (TYPE_UNSIGNED (type
))
227 decNumberFromUInt32 (&number
, (unsigned int) l
);
229 decNumberFromInt32 (&number
, (int) l
);
231 decimal_from_number (&number
, dec
, len
);
232 match_endianness (dec
, len
, byte_order
, to
);
235 /* Converts a value of a float type to a decimal float of
238 This is an ugly way to do the conversion, but libdecnumber does
239 not offer a direct way to do it. */
241 decimal_from_floating (struct value
*from
,
242 gdb_byte
*to
, int len
, enum bfd_endian byte_order
)
246 buffer
= xstrprintf ("%.30" DOUBLEST_PRINT_FORMAT
, value_as_double (from
));
248 decimal_from_string (to
, len
, byte_order
, buffer
);
253 /* Converts a decimal float of LEN bytes to a double value. */
255 decimal_to_doublest (const gdb_byte
*from
, int len
, enum bfd_endian byte_order
)
257 char buffer
[MAX_DECIMAL_STRING
];
259 /* This is an ugly way to do the conversion, but libdecnumber does
260 not offer a direct way to do it. */
261 decimal_to_string (from
, len
, byte_order
, buffer
);
262 return strtod (buffer
, NULL
);
265 /* Perform operation OP with operands X and Y with sizes LEN_X and LEN_Y
266 and byte orders BYTE_ORDER_X and BYTE_ORDER_Y, and store value in
267 RESULT with size LEN_RESULT and byte order BYTE_ORDER_RESULT. */
269 decimal_binop (enum exp_opcode op
,
270 const gdb_byte
*x
, int len_x
, enum bfd_endian byte_order_x
,
271 const gdb_byte
*y
, int len_y
, enum bfd_endian byte_order_y
,
272 gdb_byte
*result
, int len_result
,
273 enum bfd_endian byte_order_result
)
276 decNumber number1
, number2
, number3
;
277 gdb_byte dec1
[16], dec2
[16], dec3
[16];
279 match_endianness (x
, len_x
, byte_order_x
, dec1
);
280 match_endianness (y
, len_y
, byte_order_y
, dec2
);
282 decimal_to_number (dec1
, len_x
, &number1
);
283 decimal_to_number (dec2
, len_y
, &number2
);
285 set_decnumber_context (&set
, len_result
);
290 decNumberAdd (&number3
, &number1
, &number2
, &set
);
293 decNumberSubtract (&number3
, &number1
, &number2
, &set
);
296 decNumberMultiply (&number3
, &number1
, &number2
, &set
);
299 decNumberDivide (&number3
, &number1
, &number2
, &set
);
302 decNumberPower (&number3
, &number1
, &number2
, &set
);
305 internal_error (__FILE__
, __LINE__
,
306 _("Unknown decimal floating point operation."));
310 /* Check for errors in the DFP operation. */
311 decimal_check_errors (&set
);
313 decimal_from_number (&number3
, dec3
, len_result
);
315 match_endianness (dec3
, len_result
, byte_order_result
, result
);
318 /* Returns true if X (which is LEN bytes wide) is the number zero. */
320 decimal_is_zero (const gdb_byte
*x
, int len
, enum bfd_endian byte_order
)
325 match_endianness (x
, len
, byte_order
, dec
);
326 decimal_to_number (dec
, len
, &number
);
328 return decNumberIsZero (&number
);
331 /* Compares two numbers numerically. If X is less than Y then the return value
332 will be -1. If they are equal, then the return value will be 0. If X is
333 greater than the Y then the return value will be 1. */
335 decimal_compare (const gdb_byte
*x
, int len_x
, enum bfd_endian byte_order_x
,
336 const gdb_byte
*y
, int len_y
, enum bfd_endian byte_order_y
)
338 decNumber number1
, number2
, result
;
340 gdb_byte dec1
[16], dec2
[16];
343 match_endianness (x
, len_x
, byte_order_x
, dec1
);
344 match_endianness (y
, len_y
, byte_order_y
, dec2
);
346 decimal_to_number (dec1
, len_x
, &number1
);
347 decimal_to_number (dec2
, len_y
, &number2
);
349 /* Perform the comparison in the larger of the two sizes. */
350 len_result
= len_x
> len_y
? len_x
: len_y
;
351 set_decnumber_context (&set
, len_result
);
353 decNumberCompare (&result
, &number1
, &number2
, &set
);
355 /* Check for errors in the DFP operation. */
356 decimal_check_errors (&set
);
358 if (decNumberIsNaN (&result
))
359 error (_("Comparison with an invalid number (NaN)."));
360 else if (decNumberIsZero (&result
))
362 else if (decNumberIsNegative (&result
))
368 /* Convert a decimal value from a decimal type with LEN_FROM bytes to a
369 decimal type with LEN_TO bytes. */
371 decimal_convert (const gdb_byte
*from
, int len_from
,
372 enum bfd_endian byte_order_from
, gdb_byte
*to
, int len_to
,
373 enum bfd_endian byte_order_to
)
378 match_endianness (from
, len_from
, byte_order_from
, dec
);
380 decimal_to_number (dec
, len_from
, &number
);
381 decimal_from_number (&number
, dec
, len_to
);
383 match_endianness (dec
, len_to
, byte_order_to
, to
);