GDB (xrefs)
/tmp/gdb-7.10/gdb/dfp.c
Go to the documentation of this file.
1 /* Decimal floating point support for GDB.
2 
3  Copyright (C) 2007-2015 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, enum bfd_endian byte_order,
38  gdb_byte *to)
39 {
40  int i;
41 
42 #if WORDS_BIGENDIAN
43 #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_LITTLE
44 #else
45 #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG
46 #endif
47 
48  if (byte_order == OPPOSITE_BYTE_ORDER)
49  for (i = 0; i < len; i++)
50  to[i] = from[len - i - 1];
51  else
52  for (i = 0; i < len; i++)
53  to[i] = from[i];
54 
55  return;
56 }
57 
58 /* Helper function to get the appropriate libdecnumber context for each size
59  of decimal float. */
60 static void
61 set_decnumber_context (decContext *ctx, int len)
62 {
63  switch (len)
64  {
65  case 4:
66  decContextDefault (ctx, DEC_INIT_DECIMAL32);
67  break;
68  case 8:
69  decContextDefault (ctx, DEC_INIT_DECIMAL64);
70  break;
71  case 16:
72  decContextDefault (ctx, DEC_INIT_DECIMAL128);
73  break;
74  }
75 
76  ctx->traps = 0;
77 }
78 
79 /* Check for errors signaled in the decimal context structure. */
80 static void
81 decimal_check_errors (decContext *ctx)
82 {
83  /* An error here could be a division by zero, an overflow, an underflow or
84  an invalid operation (from the DEC_Errors constant in decContext.h).
85  Since GDB doesn't complain about division by zero, overflow or underflow
86  errors for binary floating, we won't complain about them for decimal
87  floating either. */
88  if (ctx->status & DEC_IEEE_854_Invalid_operation)
89  {
90  /* Leave only the error bits in the status flags. */
91  ctx->status &= DEC_IEEE_854_Invalid_operation;
92  error (_("Cannot perform operation: %s"),
93  decContextStatusToString (ctx));
94  }
95 }
96 
97 /* Helper function to convert from libdecnumber's appropriate representation
98  for computation to each size of decimal float. */
99 static void
100 decimal_from_number (const decNumber *from, gdb_byte *to, int len)
101 {
102  decContext set;
103 
104  set_decnumber_context (&set, len);
105 
106  switch (len)
107  {
108  case 4:
109  decimal32FromNumber ((decimal32 *) to, from, &set);
110  break;
111  case 8:
112  decimal64FromNumber ((decimal64 *) to, from, &set);
113  break;
114  case 16:
115  decimal128FromNumber ((decimal128 *) to, from, &set);
116  break;
117  }
118 }
119 
120 /* Helper function to convert each size of decimal float to libdecnumber's
121  appropriate representation for computation. */
122 static void
123 decimal_to_number (const gdb_byte *from, int len, decNumber *to)
124 {
125  switch (len)
126  {
127  case 4:
128  decimal32ToNumber ((decimal32 *) from, to);
129  break;
130  case 8:
131  decimal64ToNumber ((decimal64 *) from, to);
132  break;
133  case 16:
134  decimal128ToNumber ((decimal128 *) from, to);
135  break;
136  default:
137  error (_("Unknown decimal floating point type."));
138  break;
139  }
140 }
141 
142 /* Convert decimal type to its string representation. LEN is the length
143  of the decimal type, 4 bytes for decimal32, 8 bytes for decimal64 and
144  16 bytes for decimal128. */
145 void
146 decimal_to_string (const gdb_byte *decbytes, int len,
147  enum bfd_endian byte_order, char *s)
148 {
149  gdb_byte dec[16];
150 
151  match_endianness (decbytes, len, byte_order, dec);
152 
153  switch (len)
154  {
155  case 4:
156  decimal32ToString ((decimal32 *) dec, s);
157  break;
158  case 8:
159  decimal64ToString ((decimal64 *) dec, s);
160  break;
161  case 16:
162  decimal128ToString ((decimal128 *) dec, s);
163  break;
164  default:
165  error (_("Unknown decimal floating point type."));
166  break;
167  }
168 }
169 
170 /* Convert the string form of a decimal value to its decimal representation.
171  LEN is the length of the decimal type, 4 bytes for decimal32, 8 bytes for
172  decimal64 and 16 bytes for decimal128. */
173 int
174 decimal_from_string (gdb_byte *decbytes, int len, enum bfd_endian byte_order,
175  const char *string)
176 {
177  decContext set;
178  gdb_byte dec[16];
179 
180  set_decnumber_context (&set, len);
181 
182  switch (len)
183  {
184  case 4:
185  decimal32FromString ((decimal32 *) dec, string, &set);
186  break;
187  case 8:
188  decimal64FromString ((decimal64 *) dec, string, &set);
189  break;
190  case 16:
191  decimal128FromString ((decimal128 *) dec, string, &set);
192  break;
193  default:
194  error (_("Unknown decimal floating point type."));
195  break;
196  }
197 
198  match_endianness (dec, len, byte_order, decbytes);
199 
200  /* Check for errors in the DFP operation. */
201  decimal_check_errors (&set);
202 
203  return 1;
204 }
205 
206 /* Converts a value of an integral type to a decimal float of
207  specified LEN bytes. */
208 void
210  gdb_byte *to, int len, enum bfd_endian byte_order)
211 {
212  LONGEST l;
213  gdb_byte dec[16];
214  decNumber number;
215  struct type *type;
216 
217  type = check_typedef (value_type (from));
218 
219  if (TYPE_LENGTH (type) > 4)
220  /* libdecnumber can convert only 32-bit integers. */
221  error (_("Conversion of large integer to a "
222  "decimal floating type is not supported."));
223 
224  l = value_as_long (from);
225 
226  if (TYPE_UNSIGNED (type))
227  decNumberFromUInt32 (&number, (unsigned int) l);
228  else
229  decNumberFromInt32 (&number, (int) l);
230 
231  decimal_from_number (&number, dec, len);
232  match_endianness (dec, len, byte_order, to);
233 }
234 
235 /* Converts a value of a float type to a decimal float of
236  specified LEN bytes.
237 
238  This is an ugly way to do the conversion, but libdecnumber does
239  not offer a direct way to do it. */
240 void
242  gdb_byte *to, int len, enum bfd_endian byte_order)
243 {
244  char *buffer;
245 
246  buffer = xstrprintf ("%.30" DOUBLEST_PRINT_FORMAT, value_as_double (from));
247 
248  decimal_from_string (to, len, byte_order, buffer);
249 
250  xfree (buffer);
251 }
252 
253 /* Converts a decimal float of LEN bytes to a double value. */
254 DOUBLEST
255 decimal_to_doublest (const gdb_byte *from, int len, enum bfd_endian byte_order)
256 {
258 
259  /* This is an ugly way to do the conversion, but libdecnumber does
260  not offer a direct way to do it. */
261  decimal_to_string (from, len, byte_order, buffer);
262  return strtod (buffer, NULL);
263 }
264 
265 /* Perform operation OP with operands X and Y with sizes LEN_X and LEN_Y
266  and byte orders BYTE_ORDER_X and BYTE_ORDER_Y, and store value in
267  RESULT with size LEN_RESULT and byte order BYTE_ORDER_RESULT. */
268 void
270  const gdb_byte *x, int len_x, enum bfd_endian byte_order_x,
271  const gdb_byte *y, int len_y, enum bfd_endian byte_order_y,
272  gdb_byte *result, int len_result,
273  enum bfd_endian byte_order_result)
274 {
275  decContext set;
276  decNumber number1, number2, number3;
277  gdb_byte dec1[16], dec2[16], dec3[16];
278 
279  match_endianness (x, len_x, byte_order_x, dec1);
280  match_endianness (y, len_y, byte_order_y, dec2);
281 
282  decimal_to_number (dec1, len_x, &number1);
283  decimal_to_number (dec2, len_y, &number2);
284 
285  set_decnumber_context (&set, len_result);
286 
287  switch (op)
288  {
289  case BINOP_ADD:
290  decNumberAdd (&number3, &number1, &number2, &set);
291  break;
292  case BINOP_SUB:
293  decNumberSubtract (&number3, &number1, &number2, &set);
294  break;
295  case BINOP_MUL:
296  decNumberMultiply (&number3, &number1, &number2, &set);
297  break;
298  case BINOP_DIV:
299  decNumberDivide (&number3, &number1, &number2, &set);
300  break;
301  case BINOP_EXP:
302  decNumberPower (&number3, &number1, &number2, &set);
303  break;
304  default:
305  internal_error (__FILE__, __LINE__,
306  _("Unknown decimal floating point operation."));
307  break;
308  }
309 
310  /* Check for errors in the DFP operation. */
311  decimal_check_errors (&set);
312 
313  decimal_from_number (&number3, dec3, len_result);
314 
315  match_endianness (dec3, len_result, byte_order_result, result);
316 }
317 
318 /* Returns true if X (which is LEN bytes wide) is the number zero. */
319 int
320 decimal_is_zero (const gdb_byte *x, int len, enum bfd_endian byte_order)
321 {
322  decNumber number;
323  gdb_byte dec[16];
324 
325  match_endianness (x, len, byte_order, dec);
326  decimal_to_number (dec, len, &number);
327 
328  return decNumberIsZero (&number);
329 }
330 
331 /* Compares two numbers numerically. If X is less than Y then the return value
332  will be -1. If they are equal, then the return value will be 0. If X is
333  greater than the Y then the return value will be 1. */
334 int
335 decimal_compare (const gdb_byte *x, int len_x, enum bfd_endian byte_order_x,
336  const gdb_byte *y, int len_y, enum bfd_endian byte_order_y)
337 {
338  decNumber number1, number2, result;
339  decContext set;
340  gdb_byte dec1[16], dec2[16];
341  int len_result;
342 
343  match_endianness (x, len_x, byte_order_x, dec1);
344  match_endianness (y, len_y, byte_order_y, dec2);
345 
346  decimal_to_number (dec1, len_x, &number1);
347  decimal_to_number (dec2, len_y, &number2);
348 
349  /* Perform the comparison in the larger of the two sizes. */
350  len_result = len_x > len_y ? len_x : len_y;
351  set_decnumber_context (&set, len_result);
352 
353  decNumberCompare (&result, &number1, &number2, &set);
354 
355  /* Check for errors in the DFP operation. */
356  decimal_check_errors (&set);
357 
358  if (decNumberIsNaN (&result))
359  error (_("Comparison with an invalid number (NaN)."));
360  else if (decNumberIsZero (&result))
361  return 0;
362  else if (decNumberIsNegative (&result))
363  return -1;
364  else
365  return 1;
366 }
367 
368 /* Convert a decimal value from a decimal type with LEN_FROM bytes to a
369  decimal type with LEN_TO bytes. */
370 void
371 decimal_convert (const gdb_byte *from, int len_from,
372  enum bfd_endian byte_order_from, gdb_byte *to, int len_to,
373  enum bfd_endian byte_order_to)
374 {
375  decNumber number;
376  gdb_byte dec[16];
377 
378  match_endianness (from, len_from, byte_order_from, dec);
379 
380  decimal_to_number (dec, len_from, &number);
381  decimal_from_number (&number, dec, len_to);
382 
383  match_endianness (dec, len_to, byte_order_to, to);
384 }
int decimal_from_string(gdb_byte *decbytes, int len, enum bfd_endian byte_order, const char *string)
Definition: dfp.c:174
void xfree(void *)
Definition: common-utils.c:97
LONGEST value_as_long(struct value *val)
Definition: value.c:2654
void decimal_convert(const gdb_byte *from, int len_from, enum bfd_endian byte_order_from, gdb_byte *to, int len_to, enum bfd_endian byte_order_to)
Definition: dfp.c:371
static void match_endianness(const gdb_byte *from, int len, enum bfd_endian byte_order, gdb_byte *to)
Definition: dfp.c:37
void internal_error(const char *file, int line, const char *fmt,...)
Definition: errors.c:50
#define MAX_DECIMAL_STRING
Definition: dfp.h:30
void decimal_to_string(const gdb_byte *decbytes, int len, enum bfd_endian byte_order, char *s)
Definition: dfp.c:146
#define _(String)
Definition: gdb_locale.h:40
static void decimal_to_number(const gdb_byte *from, int len, decNumber *to)
Definition: dfp.c:123
void decimal_from_floating(struct value *from, gdb_byte *to, int len, enum bfd_endian byte_order)
Definition: dfp.c:241
int * from
Definition: varobj.h:282
struct type * check_typedef(struct type *type)
Definition: gdbtypes.c:2217
DOUBLEST decimal_to_doublest(const gdb_byte *from, int len, enum bfd_endian byte_order)
Definition: dfp.c:255
void decimal_binop(enum exp_opcode op, const gdb_byte *x, int len_x, enum bfd_endian byte_order_x, const gdb_byte *y, int len_y, enum bfd_endian byte_order_y, gdb_byte *result, int len_result, enum bfd_endian byte_order_result)
Definition: dfp.c:269
static void set_decnumber_context(decContext *ctx, int len)
Definition: dfp.c:61
double DOUBLEST
Definition: doublest.h:24
#define OPPOSITE_BYTE_ORDER
Definition: gdbtypes.h:749
int decimal_is_zero(const gdb_byte *x, int len, enum bfd_endian byte_order)
Definition: dfp.c:320
static const char * type
Definition: language.c:103
char * xstrprintf(const char *format,...)
Definition: common-utils.c:107
#define TYPE_UNSIGNED(t)
Definition: gdbtypes.h:233
Definition: value.c:172
bfd_byte gdb_byte
Definition: common-types.h:38
#define DOUBLEST_PRINT_FORMAT
Definition: doublest.h:54
int decimal_compare(const gdb_byte *x, int len_x, enum bfd_endian byte_order_x, const gdb_byte *y, int len_y, enum bfd_endian byte_order_y)
Definition: dfp.c:335
void decimal_from_integral(struct value *from, gdb_byte *to, int len, enum bfd_endian byte_order)
Definition: dfp.c:209
Definition: buffer.h:23
exp_opcode
Definition: expression.h:43
static void decimal_check_errors(decContext *ctx)
Definition: dfp.c:81
struct type * value_type(const struct value *value)
Definition: value.c:1021
#define TYPE_LENGTH(thistype)
Definition: gdbtypes.h:1237
int int * to
Definition: varobj.h:282
void error(const char *fmt,...)
Definition: errors.c:38
DOUBLEST value_as_double(struct value *val)
Definition: value.c:2664
static void decimal_from_number(const decNumber *from, gdb_byte *to, int len)
Definition: dfp.c:100
long long LONGEST
Definition: common-types.h:52
const ULONGEST const LONGEST len
Definition: target.h:309