* Makefile.in (dfp.o): Depend on expression.h, gdbtypes.h and value.h.
[platform/upstream/binutils.git] / gdb / dfp.c
1 /* Decimal floating point support for GDB.
2
3    Copyright 2007, 2008 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 "gdbtypes.h"
23 #include "value.h"
24 #include "dfp.h"
25
26 /* The order of the following headers is important for making sure
27    decNumber structure is large enough to hold decimal128 digits.  */
28
29 #include "dpd/decimal128.h"
30 #include "dpd/decimal64.h"
31 #include "dpd/decimal32.h"
32
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.  */
36 static void
37 match_endianness (const gdb_byte *from, int len, gdb_byte *to)
38 {
39   int i;
40
41 #if WORDS_BIGENDIAN
42 #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_LITTLE
43 #else
44 #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG
45 #endif
46
47   if (gdbarch_byte_order (current_gdbarch) == OPPOSITE_BYTE_ORDER)
48     for (i = 0; i < len; i++)
49       to[i] = from[len - i - 1];
50   else
51     for (i = 0; i < len; i++)
52       to[i] = from[i];
53
54   return;
55 }
56
57 /* Helper function to get the appropriate libdecnumber context for each size
58    of decimal float.  */
59 static void
60 set_decnumber_context (decContext *ctx, int len)
61 {
62   switch (len)
63     {
64       case 4:
65         decContextDefault (ctx, DEC_INIT_DECIMAL32);
66         break;
67       case 8:
68         decContextDefault (ctx, DEC_INIT_DECIMAL64);
69         break;
70       case 16:
71         decContextDefault (ctx, DEC_INIT_DECIMAL128);
72         break;
73     }
74
75   ctx->traps = 0;
76 }
77
78 /* Check for errors signaled in the decimal context structure.  */
79 static void
80 decimal_check_errors (decContext *ctx)
81 {
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
86      floating either.  */
87   if (ctx->status & DEC_IEEE_854_Invalid_operation)
88     {
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));
92     }
93 }
94
95 /* Helper function to convert from libdecnumber's appropriate representation
96    for computation to each size of decimal float.  */
97 static void
98 decimal_from_number (const decNumber *from, gdb_byte *to, int len)
99 {
100   decContext set;
101
102   set_decnumber_context (&set, len);
103
104   switch (len)
105     {
106       case 4:
107         decimal32FromNumber ((decimal32 *) to, from, &set);
108         break;
109       case 8:
110         decimal64FromNumber ((decimal64 *) to, from, &set);
111         break;
112       case 16:
113         decimal128FromNumber ((decimal128 *) to, from, &set);
114         break;
115     }
116 }
117
118 /* Helper function to convert each size of decimal float to libdecnumber's
119    appropriate representation for computation.  */
120 static void
121 decimal_to_number (const gdb_byte *from, int len, decNumber *to)
122 {
123   switch (len)
124     {
125       case 4:
126         decimal32ToNumber ((decimal32 *) from, to);
127         break;
128       case 8:
129         decimal64ToNumber ((decimal64 *) from, to);
130         break;
131       case 16:
132         decimal128ToNumber ((decimal128 *) from, to);
133         break;
134       default:
135         error (_("Unknown decimal floating point type.\n"));
136         break;
137     }
138 }
139
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.  */
143 void
144 decimal_to_string (const gdb_byte *decbytes, int len, char *s)
145 {
146   gdb_byte dec[16];
147
148   match_endianness (decbytes, len, dec);
149
150   switch (len)
151     {
152       case 4:
153         decimal32ToString ((decimal32 *) dec, s);
154         break;
155       case 8:
156         decimal64ToString ((decimal64 *) dec, s);
157         break;
158       case 16:
159         decimal128ToString ((decimal128 *) dec, s);
160         break;
161       default:
162         error (_("Unknown decimal floating point type."));
163         break;
164     }
165 }
166
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.  */
170 int
171 decimal_from_string (gdb_byte *decbytes, int len, const char *string)
172 {
173   decContext set;
174   gdb_byte dec[16];
175
176   set_decnumber_context (&set, len);
177
178   switch (len)
179     {
180       case 4:
181         decimal32FromString ((decimal32 *) dec, string, &set);
182         break;
183       case 8:
184         decimal64FromString ((decimal64 *) dec, string, &set);
185         break;
186       case 16:
187         decimal128FromString ((decimal128 *) dec, string, &set);
188         break;
189       default:
190         error (_("Unknown decimal floating point type."));
191         break;
192     }
193
194   match_endianness (dec, len, decbytes);
195
196   /* Check for errors in the DFP operation.  */
197   decimal_check_errors (&set);
198
199   return 1;
200 }
201
202 /* Converts a value of an integral type to a decimal float of
203    specified LEN bytes.  */
204 void
205 decimal_from_integral (struct value *from, gdb_byte *to, int len)
206 {
207   LONGEST l;
208   gdb_byte dec[16];
209   decNumber number;
210   struct type *type;
211
212   type = check_typedef (value_type (from));
213
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."));
217
218   l = value_as_long (from);
219
220   if (TYPE_UNSIGNED (type))
221     decNumberFromUInt32 (&number, (unsigned int) l);
222   else
223     decNumberFromInt32 (&number, (int) l);
224
225   decimal_from_number (&number, dec, len);
226   match_endianness (dec, len, to);
227 }
228
229 /* Converts a value of a float type to a decimal float of
230    specified LEN bytes.
231
232    This is an ugly way to do the conversion, but libdecnumber does
233    not offer a direct way to do it.  */
234 void
235 decimal_from_floating (struct value *from, gdb_byte *to, int len)
236 {
237   char *buffer;
238   int ret;
239
240   ret = asprintf (&buffer, "%.30Lg", value_as_double (from));
241   if (ret < 0)
242     error (_("Error in memory allocation for conversion to decimal float."));
243
244   decimal_from_string (to, len, buffer);
245
246   free (buffer);
247 }
248
249 /* Converts a decimal float of LEN bytes to a double value.  */
250 DOUBLEST
251 decimal_to_double (const gdb_byte *from, int len)
252 {
253   char buffer[MAX_DECIMAL_STRING];
254
255   /* This is an ugly way to do the conversion, but libdecnumber does
256      not offer a direct way to do it.  */
257   decimal_to_string (from, len, buffer);
258   return strtod (buffer, NULL);
259 }
260
261 /* Check if operands have the same size and convert them to the
262    biggest of the two if necessary.  */
263 static int
264 promote_decimal (gdb_byte *x, int len_x, gdb_byte *y, int len_y)
265 {
266   int len_result;
267   decNumber number;
268
269   if (len_x < len_y)
270     {
271       decimal_to_number (x, len_x, &number);
272       decimal_from_number (&number, x, len_y);
273       len_result = len_y;
274     }
275   else if (len_x > len_y)
276     {
277       decimal_to_number (y, len_y, &number);
278       decimal_from_number (&number, y, len_x);
279       len_result = len_x;
280     }
281   else
282     len_result = len_x;
283
284   return len_result;
285 }
286
287 /* Perform operation OP with operands X and Y and store value in RESULT.
288    If LEN_X and LEN_Y are not equal, RESULT will have the size of the biggest
289    of the two, and LEN_RESULT will be set accordingly.  */
290 void
291 decimal_binop (enum exp_opcode op, const gdb_byte *x, int len_x,
292                const gdb_byte *y, int len_y, gdb_byte *result, int *len_result)
293 {
294   decContext set;
295   decNumber number1, number2, number3;
296   gdb_byte dec1[16], dec2[16], dec3[16];
297
298   match_endianness (x, len_x, dec1);
299   match_endianness (y, len_y, dec2);
300
301   *len_result = promote_decimal (dec1, len_x, dec2, len_y);
302
303   /* Both operands are of size *len_result from now on.  */
304
305   decimal_to_number (dec1, *len_result, &number1);
306   decimal_to_number (dec2, *len_result, &number2);
307
308   set_decnumber_context (&set, *len_result);
309
310   switch (op)
311     {
312       case BINOP_ADD:
313         decNumberAdd (&number3, &number1, &number2, &set);
314         break;
315       case BINOP_SUB:
316         decNumberSubtract (&number3, &number1, &number2, &set);
317         break;
318       case BINOP_MUL:
319         decNumberMultiply (&number3, &number1, &number2, &set);
320         break;
321       case BINOP_DIV:
322         decNumberDivide (&number3, &number1, &number2, &set);
323         break;
324       case BINOP_EXP:
325         decNumberPower (&number3, &number1, &number2, &set);
326         break;
327       default:
328         internal_error (__FILE__, __LINE__,
329                         _("Unknown decimal floating point operation."));
330         break;
331     }
332
333   /* Check for errors in the DFP operation.  */
334   decimal_check_errors (&set);
335
336   decimal_from_number (&number3, dec3, *len_result);
337
338   match_endianness (dec3, *len_result, result);
339 }
340
341 /* Returns true if X (which is LEN bytes wide) is the number zero.  */
342 int
343 decimal_is_zero (const gdb_byte *x, int len)
344 {
345   decNumber number;
346   gdb_byte dec[16];
347
348   match_endianness (x, len, dec);
349   decimal_to_number (dec, len, &number);
350
351   return decNumberIsZero (&number);
352 }
353
354 /* Compares two numbers numerically.  If X is less than Y then the return value
355    will be -1.  If they are equal, then the return value will be 0.  If X is
356    greater than the Y then the return value will be 1.  */
357 int
358 decimal_compare (const gdb_byte *x, int len_x, const gdb_byte *y, int len_y)
359 {
360   decNumber number1, number2, result;
361   decContext set;
362   gdb_byte dec1[16], dec2[16];
363   int len_result;
364
365   match_endianness (x, len_x, dec1);
366   match_endianness (y, len_y, dec2);
367
368   len_result = promote_decimal (dec1, len_x, dec2, len_y);
369
370   decimal_to_number (dec1, len_result, &number1);
371   decimal_to_number (dec2, len_result, &number2);
372
373   set_decnumber_context (&set, len_result);
374
375   decNumberCompare (&result, &number1, &number2, &set);
376
377   /* Check for errors in the DFP operation.  */
378   decimal_check_errors (&set);
379
380   if (decNumberIsNaN (&result))
381     error (_("Comparison with an invalid number (NaN)."));
382   else if (decNumberIsZero (&result))
383     return 0;
384   else if (decNumberIsNegative (&result))
385     return -1;
386   else
387     return 1;
388 }
389
390 /* Convert a decimal value from a decimal type with LEN_FROM bytes to a
391    decimal type with LEN_TO bytes.  */
392 void
393 decimal_convert (const gdb_byte *from, int len_from, gdb_byte *to,
394                  int len_to)
395 {
396   decNumber number;
397
398   decimal_to_number (from, len_from, &number);
399   decimal_from_number (&number, to, len_to);
400 }