OSDN Git Service

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