Target FP: Add binop and compare routines to target-float.{c,h}
[deliverable/binutils-gdb.git] / gdb / dfp.c
CommitLineData
9b913628
TJB
1/* Decimal floating point support for GDB.
2
61baf725 3 Copyright (C) 2007-2017 Free Software Foundation, Inc.
9b913628
TJB
4
5 This file is part of GDB.
6
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.
11
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.
16
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/>. */
19
20#include "defs.h"
4ef30785 21#include "expression.h"
4ef30785 22#include "dfp.h"
9b913628
TJB
23
24/* The order of the following headers is important for making sure
25 decNumber structure is large enough to hold decimal128 digits. */
26
27#include "dpd/decimal128.h"
28#include "dpd/decimal64.h"
29#include "dpd/decimal32.h"
30
3b4b2f16
UW
31/* When using decimal128, this is the maximum string length + 1
32 (value comes from libdecnumber's DECIMAL128_String constant). */
33#define MAX_DECIMAL_STRING 43
34
9b913628
TJB
35/* In GDB, we are using an array of gdb_byte to represent decimal values.
36 They are stored in host byte order. This routine does the conversion if
37 the target byte order is different. */
38static void
e17a4113
UW
39match_endianness (const gdb_byte *from, int len, enum bfd_endian byte_order,
40 gdb_byte *to)
9b913628
TJB
41{
42 int i;
43
44#if WORDS_BIGENDIAN
45#define OPPOSITE_BYTE_ORDER BFD_ENDIAN_LITTLE
46#else
47#define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG
48#endif
49
e17a4113 50 if (byte_order == OPPOSITE_BYTE_ORDER)
9b913628
TJB
51 for (i = 0; i < len; i++)
52 to[i] = from[len - i - 1];
53 else
54 for (i = 0; i < len; i++)
55 to[i] = from[i];
56
57 return;
58}
59
4ef30785
TJB
60/* Helper function to get the appropriate libdecnumber context for each size
61 of decimal float. */
62static void
63set_decnumber_context (decContext *ctx, int len)
64{
65 switch (len)
66 {
67 case 4:
68 decContextDefault (ctx, DEC_INIT_DECIMAL32);
69 break;
70 case 8:
71 decContextDefault (ctx, DEC_INIT_DECIMAL64);
72 break;
73 case 16:
74 decContextDefault (ctx, DEC_INIT_DECIMAL128);
75 break;
76 }
77
78 ctx->traps = 0;
79}
80
81/* Check for errors signaled in the decimal context structure. */
82static void
83decimal_check_errors (decContext *ctx)
84{
85 /* An error here could be a division by zero, an overflow, an underflow or
86 an invalid operation (from the DEC_Errors constant in decContext.h).
87 Since GDB doesn't complain about division by zero, overflow or underflow
88 errors for binary floating, we won't complain about them for decimal
89 floating either. */
90 if (ctx->status & DEC_IEEE_854_Invalid_operation)
91 {
92 /* Leave only the error bits in the status flags. */
93 ctx->status &= DEC_IEEE_854_Invalid_operation;
3e43a32a
MS
94 error (_("Cannot perform operation: %s"),
95 decContextStatusToString (ctx));
4ef30785
TJB
96 }
97}
98
99/* Helper function to convert from libdecnumber's appropriate representation
100 for computation to each size of decimal float. */
101static void
102decimal_from_number (const decNumber *from, gdb_byte *to, int len)
103{
104 decContext set;
105
106 set_decnumber_context (&set, len);
107
108 switch (len)
109 {
110 case 4:
111 decimal32FromNumber ((decimal32 *) to, from, &set);
112 break;
113 case 8:
114 decimal64FromNumber ((decimal64 *) to, from, &set);
115 break;
116 case 16:
117 decimal128FromNumber ((decimal128 *) to, from, &set);
118 break;
119 }
120}
121
122/* Helper function to convert each size of decimal float to libdecnumber's
123 appropriate representation for computation. */
124static void
125decimal_to_number (const gdb_byte *from, int len, decNumber *to)
126{
127 switch (len)
128 {
129 case 4:
130 decimal32ToNumber ((decimal32 *) from, to);
131 break;
132 case 8:
133 decimal64ToNumber ((decimal64 *) from, to);
134 break;
135 case 16:
136 decimal128ToNumber ((decimal128 *) from, to);
137 break;
138 default:
b37520b6 139 error (_("Unknown decimal floating point type."));
4ef30785
TJB
140 break;
141 }
142}
143
9b913628
TJB
144/* Convert decimal type to its string representation. LEN is the length
145 of the decimal type, 4 bytes for decimal32, 8 bytes for decimal64 and
146 16 bytes for decimal128. */
3b4b2f16 147std::string
e17a4113 148decimal_to_string (const gdb_byte *decbytes, int len,
16e812b2 149 enum bfd_endian byte_order, const char *format)
9b913628
TJB
150{
151 gdb_byte dec[16];
152
e17a4113 153 match_endianness (decbytes, len, byte_order, dec);
4ef30785 154
16e812b2
UW
155 if (format != nullptr)
156 {
157 /* We don't handle format strings (yet). If the host printf supports
158 decimal floating point types, just use this. Otherwise, fall back
159 to printing the number while ignoring the format string. */
160#if defined (PRINTF_HAS_DECFLOAT)
161 /* FIXME: This makes unwarranted assumptions about the host ABI! */
162 return string_printf (format, dec);
163#endif
164 }
165
3b4b2f16
UW
166 std::string result;
167 result.resize (MAX_DECIMAL_STRING);
168
9b913628
TJB
169 switch (len)
170 {
171 case 4:
3b4b2f16 172 decimal32ToString ((decimal32 *) dec, &result[0]);
9b913628
TJB
173 break;
174 case 8:
3b4b2f16 175 decimal64ToString ((decimal64 *) dec, &result[0]);
9b913628
TJB
176 break;
177 case 16:
3b4b2f16 178 decimal128ToString ((decimal128 *) dec, &result[0]);
9b913628
TJB
179 break;
180 default:
a4ae0ca1 181 error (_("Unknown decimal floating point type."));
9b913628
TJB
182 break;
183 }
3b4b2f16
UW
184
185 return result;
9b913628
TJB
186}
187
188/* Convert the string form of a decimal value to its decimal representation.
189 LEN is the length of the decimal type, 4 bytes for decimal32, 8 bytes for
190 decimal64 and 16 bytes for decimal128. */
3b4b2f16 191bool
e17a4113 192decimal_from_string (gdb_byte *decbytes, int len, enum bfd_endian byte_order,
09a7c6aa 193 const std::string &string)
9b913628
TJB
194{
195 decContext set;
196 gdb_byte dec[16];
197
4ef30785
TJB
198 set_decnumber_context (&set, len);
199
9b913628
TJB
200 switch (len)
201 {
202 case 4:
3b4b2f16 203 decimal32FromString ((decimal32 *) dec, string.c_str (), &set);
9b913628
TJB
204 break;
205 case 8:
3b4b2f16 206 decimal64FromString ((decimal64 *) dec, string.c_str (), &set);
9b913628
TJB
207 break;
208 case 16:
3b4b2f16 209 decimal128FromString ((decimal128 *) dec, string.c_str (), &set);
9b913628
TJB
210 break;
211 default:
a4ae0ca1 212 error (_("Unknown decimal floating point type."));
9b913628
TJB
213 break;
214 }
215
e17a4113 216 match_endianness (dec, len, byte_order, decbytes);
9b913628 217
4ef30785
TJB
218 /* Check for errors in the DFP operation. */
219 decimal_check_errors (&set);
220
3b4b2f16 221 return true;
9b913628 222}
4ef30785 223
3b4b2f16 224/* Converts a LONGEST to a decimal float of specified LEN bytes. */
4ef30785 225void
3b4b2f16
UW
226decimal_from_longest (LONGEST from,
227 gdb_byte *to, int len, enum bfd_endian byte_order)
4ef30785 228{
4ef30785
TJB
229 gdb_byte dec[16];
230 decNumber number;
3b4b2f16
UW
231 if ((int32_t) from != from)
232 /* libdecnumber can convert only 32-bit integers. */
233 error (_("Conversion of large integer to a "
234 "decimal floating type is not supported."));
4ef30785 235
3b4b2f16 236 decNumberFromInt32 (&number, (int32_t) from);
4ef30785 237
3b4b2f16
UW
238 decimal_from_number (&number, dec, len);
239 match_endianness (dec, len, byte_order, to);
240}
241
242/* Converts a ULONGEST to a decimal float of specified LEN bytes. */
243void
244decimal_from_ulongest (ULONGEST from,
245 gdb_byte *to, int len, enum bfd_endian byte_order)
246{
247 gdb_byte dec[16];
248 decNumber number;
249
250 if ((uint32_t) from != from)
4ef30785 251 /* libdecnumber can convert only 32-bit integers. */
3e43a32a
MS
252 error (_("Conversion of large integer to a "
253 "decimal floating type is not supported."));
4ef30785 254
3b4b2f16 255 decNumberFromUInt32 (&number, (uint32_t) from);
4ef30785
TJB
256
257 decimal_from_number (&number, dec, len);
e17a4113 258 match_endianness (dec, len, byte_order, to);
4ef30785
TJB
259}
260
3b4b2f16
UW
261/* Converts a decimal float of LEN bytes to a LONGEST. */
262LONGEST
263decimal_to_longest (const gdb_byte *from, int len, enum bfd_endian byte_order)
264{
265 /* libdecnumber has a function to convert from decimal to integer, but
266 it doesn't work when the decimal number has a fractional part. */
267 std::string str = decimal_to_string (from, len, byte_order);
268 return strtoll (str.c_str (), NULL, 10);
269}
270
4ef30785
TJB
271/* Converts a value of a float type to a decimal float of
272 specified LEN bytes.
273
274 This is an ugly way to do the conversion, but libdecnumber does
275 not offer a direct way to do it. */
276void
3b4b2f16 277decimal_from_doublest (DOUBLEST from,
e17a4113 278 gdb_byte *to, int len, enum bfd_endian byte_order)
4ef30785 279{
3b4b2f16
UW
280 std::string str = string_printf ("%.30" DOUBLEST_PRINT_FORMAT, from);
281 decimal_from_string (to, len, byte_order, str);
4ef30785
TJB
282}
283
284/* Converts a decimal float of LEN bytes to a double value. */
285DOUBLEST
e17a4113 286decimal_to_doublest (const gdb_byte *from, int len, enum bfd_endian byte_order)
4ef30785 287{
4ef30785
TJB
288 /* This is an ugly way to do the conversion, but libdecnumber does
289 not offer a direct way to do it. */
3b4b2f16
UW
290 std::string str = decimal_to_string (from, len, byte_order);
291 return strtod (str.c_str (), NULL);
4ef30785
TJB
292}
293
289bd67a 294/* Perform operation OP with operands X and Y with sizes LEN_X and LEN_Y
e17a4113
UW
295 and byte orders BYTE_ORDER_X and BYTE_ORDER_Y, and store value in
296 RESULT with size LEN_RESULT and byte order BYTE_ORDER_RESULT. */
4ef30785 297void
e17a4113
UW
298decimal_binop (enum exp_opcode op,
299 const gdb_byte *x, int len_x, enum bfd_endian byte_order_x,
300 const gdb_byte *y, int len_y, enum bfd_endian byte_order_y,
301 gdb_byte *result, int len_result,
302 enum bfd_endian byte_order_result)
4ef30785
TJB
303{
304 decContext set;
305 decNumber number1, number2, number3;
306 gdb_byte dec1[16], dec2[16], dec3[16];
307
e17a4113
UW
308 match_endianness (x, len_x, byte_order_x, dec1);
309 match_endianness (y, len_y, byte_order_y, dec2);
4ef30785 310
289bd67a
UW
311 decimal_to_number (dec1, len_x, &number1);
312 decimal_to_number (dec2, len_y, &number2);
4ef30785 313
289bd67a 314 set_decnumber_context (&set, len_result);
4ef30785
TJB
315
316 switch (op)
317 {
318 case BINOP_ADD:
319 decNumberAdd (&number3, &number1, &number2, &set);
320 break;
321 case BINOP_SUB:
322 decNumberSubtract (&number3, &number1, &number2, &set);
323 break;
324 case BINOP_MUL:
325 decNumberMultiply (&number3, &number1, &number2, &set);
326 break;
327 case BINOP_DIV:
328 decNumberDivide (&number3, &number1, &number2, &set);
329 break;
330 case BINOP_EXP:
331 decNumberPower (&number3, &number1, &number2, &set);
332 break;
66c02b9e
UW
333 default:
334 error (_("Operation not valid for decimal floating point number."));
4ef30785
TJB
335 break;
336 }
337
338 /* Check for errors in the DFP operation. */
339 decimal_check_errors (&set);
340
289bd67a 341 decimal_from_number (&number3, dec3, len_result);
4ef30785 342
e17a4113 343 match_endianness (dec3, len_result, byte_order_result, result);
4ef30785
TJB
344}
345
346/* Returns true if X (which is LEN bytes wide) is the number zero. */
347int
e17a4113 348decimal_is_zero (const gdb_byte *x, int len, enum bfd_endian byte_order)
4ef30785
TJB
349{
350 decNumber number;
351 gdb_byte dec[16];
352
e17a4113 353 match_endianness (x, len, byte_order, dec);
4ef30785
TJB
354 decimal_to_number (dec, len, &number);
355
356 return decNumberIsZero (&number);
357}
358
359/* Compares two numbers numerically. If X is less than Y then the return value
360 will be -1. If they are equal, then the return value will be 0. If X is
361 greater than the Y then the return value will be 1. */
362int
e17a4113
UW
363decimal_compare (const gdb_byte *x, int len_x, enum bfd_endian byte_order_x,
364 const gdb_byte *y, int len_y, enum bfd_endian byte_order_y)
4ef30785
TJB
365{
366 decNumber number1, number2, result;
367 decContext set;
368 gdb_byte dec1[16], dec2[16];
369 int len_result;
370
e17a4113
UW
371 match_endianness (x, len_x, byte_order_x, dec1);
372 match_endianness (y, len_y, byte_order_y, dec2);
4ef30785 373
289bd67a
UW
374 decimal_to_number (dec1, len_x, &number1);
375 decimal_to_number (dec2, len_y, &number2);
4ef30785 376
289bd67a
UW
377 /* Perform the comparison in the larger of the two sizes. */
378 len_result = len_x > len_y ? len_x : len_y;
4ef30785
TJB
379 set_decnumber_context (&set, len_result);
380
381 decNumberCompare (&result, &number1, &number2, &set);
382
383 /* Check for errors in the DFP operation. */
384 decimal_check_errors (&set);
385
386 if (decNumberIsNaN (&result))
387 error (_("Comparison with an invalid number (NaN)."));
388 else if (decNumberIsZero (&result))
389 return 0;
390 else if (decNumberIsNegative (&result))
391 return -1;
392 else
393 return 1;
394}
395
396/* Convert a decimal value from a decimal type with LEN_FROM bytes to a
397 decimal type with LEN_TO bytes. */
398void
e17a4113
UW
399decimal_convert (const gdb_byte *from, int len_from,
400 enum bfd_endian byte_order_from, gdb_byte *to, int len_to,
401 enum bfd_endian byte_order_to)
4ef30785
TJB
402{
403 decNumber number;
cd0b43b1
JM
404 gdb_byte dec[16];
405
e17a4113 406 match_endianness (from, len_from, byte_order_from, dec);
cd0b43b1
JM
407
408 decimal_to_number (dec, len_from, &number);
409 decimal_from_number (&number, dec, len_to);
4ef30785 410
e17a4113 411 match_endianness (dec, len_to, byte_order_to, to);
4ef30785 412}
This page took 0.817574 seconds and 4 git commands to generate.