OSDN Git Service

* varobj.c (varobj_set_display_format): Use xfree.
[pf3gnuchains/pf3gnuchains3x.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
239   buffer = xstrprintf ("%.30" DOUBLEST_PRINT_FORMAT, value_as_double (from));
240
241   decimal_from_string (to, len, buffer);
242
243   xfree (buffer);
244 }
245
246 /* Converts a decimal float of LEN bytes to a double value.  */
247 DOUBLEST
248 decimal_to_doublest (const gdb_byte *from, int len)
249 {
250   char buffer[MAX_DECIMAL_STRING];
251
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);
256 }
257
258 /* Check if operands have the same size and convert them to the
259    biggest of the two if necessary.  */
260 static int
261 promote_decimal (gdb_byte *x, int len_x, gdb_byte *y, int len_y)
262 {
263   int len_result;
264   decNumber number;
265
266   if (len_x < len_y)
267     {
268       decimal_to_number (x, len_x, &number);
269       decimal_from_number (&number, x, len_y);
270       len_result = len_y;
271     }
272   else if (len_x > len_y)
273     {
274       decimal_to_number (y, len_y, &number);
275       decimal_from_number (&number, y, len_x);
276       len_result = len_x;
277     }
278   else
279     len_result = len_x;
280
281   return len_result;
282 }
283
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.  */
287 void
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)
290 {
291   decContext set;
292   decNumber number1, number2, number3;
293   gdb_byte dec1[16], dec2[16], dec3[16];
294
295   match_endianness (x, len_x, dec1);
296   match_endianness (y, len_y, dec2);
297
298   *len_result = promote_decimal (dec1, len_x, dec2, len_y);
299
300   /* Both operands are of size *len_result from now on.  */
301
302   decimal_to_number (dec1, *len_result, &number1);
303   decimal_to_number (dec2, *len_result, &number2);
304
305   set_decnumber_context (&set, *len_result);
306
307   switch (op)
308     {
309       case BINOP_ADD:
310         decNumberAdd (&number3, &number1, &number2, &set);
311         break;
312       case BINOP_SUB:
313         decNumberSubtract (&number3, &number1, &number2, &set);
314         break;
315       case BINOP_MUL:
316         decNumberMultiply (&number3, &number1, &number2, &set);
317         break;
318       case BINOP_DIV:
319         decNumberDivide (&number3, &number1, &number2, &set);
320         break;
321       case BINOP_EXP:
322         decNumberPower (&number3, &number1, &number2, &set);
323         break;
324       default:
325         internal_error (__FILE__, __LINE__,
326                         _("Unknown decimal floating point operation."));
327         break;
328     }
329
330   /* Check for errors in the DFP operation.  */
331   decimal_check_errors (&set);
332
333   decimal_from_number (&number3, dec3, *len_result);
334
335   match_endianness (dec3, *len_result, result);
336 }
337
338 /* Returns true if X (which is LEN bytes wide) is the number zero.  */
339 int
340 decimal_is_zero (const gdb_byte *x, int len)
341 {
342   decNumber number;
343   gdb_byte dec[16];
344
345   match_endianness (x, len, dec);
346   decimal_to_number (dec, len, &number);
347
348   return decNumberIsZero (&number);
349 }
350
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.  */
354 int
355 decimal_compare (const gdb_byte *x, int len_x, const gdb_byte *y, int len_y)
356 {
357   decNumber number1, number2, result;
358   decContext set;
359   gdb_byte dec1[16], dec2[16];
360   int len_result;
361
362   match_endianness (x, len_x, dec1);
363   match_endianness (y, len_y, dec2);
364
365   len_result = promote_decimal (dec1, len_x, dec2, len_y);
366
367   decimal_to_number (dec1, len_result, &number1);
368   decimal_to_number (dec2, len_result, &number2);
369
370   set_decnumber_context (&set, len_result);
371
372   decNumberCompare (&result, &number1, &number2, &set);
373
374   /* Check for errors in the DFP operation.  */
375   decimal_check_errors (&set);
376
377   if (decNumberIsNaN (&result))
378     error (_("Comparison with an invalid number (NaN)."));
379   else if (decNumberIsZero (&result))
380     return 0;
381   else if (decNumberIsNegative (&result))
382     return -1;
383   else
384     return 1;
385 }
386
387 /* Convert a decimal value from a decimal type with LEN_FROM bytes to a
388    decimal type with LEN_TO bytes.  */
389 void
390 decimal_convert (const gdb_byte *from, int len_from, gdb_byte *to,
391                  int len_to)
392 {
393   decNumber number;
394   gdb_byte dec[16];
395
396   match_endianness (from, len_from, dec);
397
398   decimal_to_number (dec, len_from, &number);
399   decimal_from_number (&number, dec, len_to);
400
401   match_endianness (dec, len_to, to);
402 }