Commit | Line | Data |
---|---|---|
9b913628 TJB |
1 | /* Decimal floating point support for GDB. |
2 | ||
3 | Copyright 2007 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 | ||
22 | /* The order of the following headers is important for making sure | |
23 | decNumber structure is large enough to hold decimal128 digits. */ | |
24 | ||
25 | #include "dpd/decimal128.h" | |
26 | #include "dpd/decimal64.h" | |
27 | #include "dpd/decimal32.h" | |
28 | ||
29 | /* In GDB, we are using an array of gdb_byte to represent decimal values. | |
30 | They are stored in host byte order. This routine does the conversion if | |
31 | the target byte order is different. */ | |
32 | static void | |
33 | match_endianness (const gdb_byte *from, int len, gdb_byte *to) | |
34 | { | |
35 | int i; | |
36 | ||
37 | #if WORDS_BIGENDIAN | |
38 | #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_LITTLE | |
39 | #else | |
40 | #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG | |
41 | #endif | |
42 | ||
43 | if (gdbarch_byte_order (current_gdbarch) == OPPOSITE_BYTE_ORDER) | |
44 | for (i = 0; i < len; i++) | |
45 | to[i] = from[len - i - 1]; | |
46 | else | |
47 | for (i = 0; i < len; i++) | |
48 | to[i] = from[i]; | |
49 | ||
50 | return; | |
51 | } | |
52 | ||
53 | /* Convert decimal type to its string representation. LEN is the length | |
54 | of the decimal type, 4 bytes for decimal32, 8 bytes for decimal64 and | |
55 | 16 bytes for decimal128. */ | |
56 | void | |
57 | decimal_to_string (const gdb_byte *decbytes, int len, char *s) | |
58 | { | |
59 | gdb_byte dec[16]; | |
60 | ||
61 | match_endianness (decbytes, len, dec); | |
62 | switch (len) | |
63 | { | |
64 | case 4: | |
65 | decimal32ToString ((decimal32 *) dec, s); | |
66 | break; | |
67 | case 8: | |
68 | decimal64ToString ((decimal64 *) dec, s); | |
69 | break; | |
70 | case 16: | |
71 | decimal128ToString ((decimal128 *) dec, s); | |
72 | break; | |
73 | default: | |
a4ae0ca1 | 74 | error (_("Unknown decimal floating point type.")); |
9b913628 TJB |
75 | break; |
76 | } | |
77 | } | |
78 | ||
79 | /* Convert the string form of a decimal value to its decimal representation. | |
80 | LEN is the length of the decimal type, 4 bytes for decimal32, 8 bytes for | |
81 | decimal64 and 16 bytes for decimal128. */ | |
82 | int | |
83 | decimal_from_string (gdb_byte *decbytes, int len, const char *string) | |
84 | { | |
85 | decContext set; | |
86 | gdb_byte dec[16]; | |
87 | ||
88 | switch (len) | |
89 | { | |
90 | case 4: | |
91 | decContextDefault (&set, DEC_INIT_DECIMAL32); | |
92 | set.traps = 0; | |
93 | decimal32FromString ((decimal32 *) dec, string, &set); | |
94 | break; | |
95 | case 8: | |
96 | decContextDefault (&set, DEC_INIT_DECIMAL64); | |
97 | set.traps = 0; | |
98 | decimal64FromString ((decimal64 *) dec, string, &set); | |
99 | break; | |
100 | case 16: | |
101 | decContextDefault (&set, DEC_INIT_DECIMAL128); | |
102 | set.traps = 0; | |
103 | decimal128FromString ((decimal128 *) dec, string, &set); | |
104 | break; | |
105 | default: | |
a4ae0ca1 | 106 | error (_("Unknown decimal floating point type.")); |
9b913628 TJB |
107 | break; |
108 | } | |
109 | ||
110 | match_endianness (dec, len, decbytes); | |
111 | ||
112 | return 1; | |
113 | } |