Target FP: Add binop and compare routines to target-float.{c,h}
[external/binutils.git] / gdb / dfp.c
1 /* Decimal floating point support for GDB.
2
3    Copyright (C) 2007-2017 Free Software Foundation, Inc.
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"
21 #include "expression.h"
22 #include "dfp.h"
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
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
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.  */
38 static void
39 match_endianness (const gdb_byte *from, int len, enum bfd_endian byte_order,
40                   gdb_byte *to)
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
50   if (byte_order == OPPOSITE_BYTE_ORDER)
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
60 /* Helper function to get the appropriate libdecnumber context for each size
61    of decimal float.  */
62 static void
63 set_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.  */
82 static void
83 decimal_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;
94       error (_("Cannot perform operation: %s"),
95              decContextStatusToString (ctx));
96     }
97 }
98
99 /* Helper function to convert from libdecnumber's appropriate representation
100    for computation to each size of decimal float.  */
101 static void
102 decimal_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.  */
124 static void
125 decimal_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:
139         error (_("Unknown decimal floating point type."));
140         break;
141     }
142 }
143
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.  */
147 std::string
148 decimal_to_string (const gdb_byte *decbytes, int len,
149                    enum bfd_endian byte_order, const char *format)
150 {
151   gdb_byte dec[16];
152
153   match_endianness (decbytes, len, byte_order, dec);
154
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
166   std::string result;
167   result.resize (MAX_DECIMAL_STRING);
168
169   switch (len)
170     {
171       case 4:
172         decimal32ToString ((decimal32 *) dec, &result[0]);
173         break;
174       case 8:
175         decimal64ToString ((decimal64 *) dec, &result[0]);
176         break;
177       case 16:
178         decimal128ToString ((decimal128 *) dec, &result[0]);
179         break;
180       default:
181         error (_("Unknown decimal floating point type."));
182         break;
183     }
184
185   return result;
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.  */
191 bool
192 decimal_from_string (gdb_byte *decbytes, int len, enum bfd_endian byte_order,
193                      const std::string &string)
194 {
195   decContext set;
196   gdb_byte dec[16];
197
198   set_decnumber_context (&set, len);
199
200   switch (len)
201     {
202       case 4:
203         decimal32FromString ((decimal32 *) dec, string.c_str (), &set);
204         break;
205       case 8:
206         decimal64FromString ((decimal64 *) dec, string.c_str (), &set);
207         break;
208       case 16:
209         decimal128FromString ((decimal128 *) dec, string.c_str (), &set);
210         break;
211       default:
212         error (_("Unknown decimal floating point type."));
213         break;
214     }
215
216   match_endianness (dec, len, byte_order, decbytes);
217
218   /* Check for errors in the DFP operation.  */
219   decimal_check_errors (&set);
220
221   return true;
222 }
223
224 /* Converts a LONGEST to a decimal float of specified LEN bytes.  */
225 void
226 decimal_from_longest (LONGEST from,
227                       gdb_byte *to, int len, enum bfd_endian byte_order)
228 {
229   gdb_byte dec[16];
230   decNumber number;
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."));
235
236   decNumberFromInt32 (&number, (int32_t) from);
237
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.  */
243 void
244 decimal_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)
251     /* libdecnumber can convert only 32-bit integers.  */
252     error (_("Conversion of large integer to a "
253              "decimal floating type is not supported."));
254
255   decNumberFromUInt32 (&number, (uint32_t) from);
256
257   decimal_from_number (&number, dec, len);
258   match_endianness (dec, len, byte_order, to);
259 }
260
261 /* Converts a decimal float of LEN bytes to a LONGEST.  */
262 LONGEST
263 decimal_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
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.  */
276 void
277 decimal_from_doublest (DOUBLEST from,
278                        gdb_byte *to, int len, enum bfd_endian byte_order)
279 {
280   std::string str = string_printf ("%.30" DOUBLEST_PRINT_FORMAT, from);
281   decimal_from_string (to, len, byte_order, str);
282 }
283
284 /* Converts a decimal float of LEN bytes to a double value.  */
285 DOUBLEST
286 decimal_to_doublest (const gdb_byte *from, int len, enum bfd_endian byte_order)
287 {
288   /* This is an ugly way to do the conversion, but libdecnumber does
289      not offer a direct way to do it.  */
290   std::string str = decimal_to_string (from, len, byte_order);
291   return strtod (str.c_str (), NULL);
292 }
293
294 /* Perform operation OP with operands X and Y with sizes LEN_X and LEN_Y
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.  */
297 void
298 decimal_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)
303 {
304   decContext set;
305   decNumber number1, number2, number3;
306   gdb_byte dec1[16], dec2[16], dec3[16];
307
308   match_endianness (x, len_x, byte_order_x, dec1);
309   match_endianness (y, len_y, byte_order_y, dec2);
310
311   decimal_to_number (dec1, len_x, &number1);
312   decimal_to_number (dec2, len_y, &number2);
313
314   set_decnumber_context (&set, len_result);
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;
333      default:
334         error (_("Operation not valid for decimal floating point number."));
335         break;
336     }
337
338   /* Check for errors in the DFP operation.  */
339   decimal_check_errors (&set);
340
341   decimal_from_number (&number3, dec3, len_result);
342
343   match_endianness (dec3, len_result, byte_order_result, result);
344 }
345
346 /* Returns true if X (which is LEN bytes wide) is the number zero.  */
347 int
348 decimal_is_zero (const gdb_byte *x, int len, enum bfd_endian byte_order)
349 {
350   decNumber number;
351   gdb_byte dec[16];
352
353   match_endianness (x, len, byte_order, dec);
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.  */
362 int
363 decimal_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)
365 {
366   decNumber number1, number2, result;
367   decContext set;
368   gdb_byte dec1[16], dec2[16];
369   int len_result;
370
371   match_endianness (x, len_x, byte_order_x, dec1);
372   match_endianness (y, len_y, byte_order_y, dec2);
373
374   decimal_to_number (dec1, len_x, &number1);
375   decimal_to_number (dec2, len_y, &number2);
376
377   /* Perform the comparison in the larger of the two sizes.  */
378   len_result = len_x > len_y ? len_x : len_y;
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.  */
398 void
399 decimal_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)
402 {
403   decNumber number;
404   gdb_byte dec[16];
405
406   match_endianness (from, len_from, byte_order_from, dec);
407
408   decimal_to_number (dec, len_from, &number);
409   decimal_from_number (&number, dec, len_to);
410
411   match_endianness (dec, len_to, byte_order_to, to);
412 }