* solib-svr4.c (LM_ADDR_FROM_LINK_MAP): Use builtin types of
[deliverable/binutils-gdb.git] / gdb / dfp.c
CommitLineData
9b913628
TJB
1/* Decimal floating point support for GDB.
2
9b254dd1 3 Copyright 2007, 2008 Free Software Foundation, Inc.
9b913628
TJB
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"
4ef30785
TJB
21#include "expression.h"
22#include "gdbtypes.h"
23#include "value.h"
24#include "dfp.h"
9b913628
TJB
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. */
36static void
37match_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
4ef30785
TJB
57/* Helper function to get the appropriate libdecnumber context for each size
58 of decimal float. */
59static void
60set_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. */
79static void
80decimal_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. */
97static void
98decimal_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. */
120static void
121decimal_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
9b913628
TJB
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. */
143void
144decimal_to_string (const gdb_byte *decbytes, int len, char *s)
145{
146 gdb_byte dec[16];
147
148 match_endianness (decbytes, len, dec);
4ef30785 149
9b913628
TJB
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:
a4ae0ca1 162 error (_("Unknown decimal floating point type."));
9b913628
TJB
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. */
170int
171decimal_from_string (gdb_byte *decbytes, int len, const char *string)
172{
173 decContext set;
174 gdb_byte dec[16];
175
4ef30785
TJB
176 set_decnumber_context (&set, len);
177
9b913628
TJB
178 switch (len)
179 {
180 case 4:
9b913628
TJB
181 decimal32FromString ((decimal32 *) dec, string, &set);
182 break;
183 case 8:
9b913628
TJB
184 decimal64FromString ((decimal64 *) dec, string, &set);
185 break;
186 case 16:
9b913628
TJB
187 decimal128FromString ((decimal128 *) dec, string, &set);
188 break;
189 default:
a4ae0ca1 190 error (_("Unknown decimal floating point type."));
9b913628
TJB
191 break;
192 }
193
194 match_endianness (dec, len, decbytes);
195
4ef30785
TJB
196 /* Check for errors in the DFP operation. */
197 decimal_check_errors (&set);
198
9b913628
TJB
199 return 1;
200}
4ef30785
TJB
201
202/* Converts a value of an integral type to a decimal float of
203 specified LEN bytes. */
204void
205decimal_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. */
234void
235decimal_from_floating (struct value *from, gdb_byte *to, int len)
236{
237 char *buffer;
238 int ret;
239
689e4e2d
TJB
240 ret = asprintf (&buffer, "%.30" DOUBLEST_PRINT_FORMAT,
241 value_as_double (from));
4ef30785
TJB
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. */
251DOUBLEST
ba759613 252decimal_to_doublest (const gdb_byte *from, int len)
4ef30785
TJB
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. */
264static int
265promote_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. */
291void
292decimal_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. */
343int
344decimal_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. */
358int
359decimal_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. */
393void
394decimal_convert (const gdb_byte *from, int len_from, gdb_byte *to,
395 int len_to)
396{
397 decNumber number;
cd0b43b1
JM
398 gdb_byte dec[16];
399
400 match_endianness (from, len_from, dec);
401
402 decimal_to_number (dec, len_from, &number);
403 decimal_from_number (&number, dec, len_to);
4ef30785 404
cd0b43b1 405 match_endianness (dec, len_to, to);
4ef30785 406}
This page took 0.094263 seconds and 4 git commands to generate.