aboutsummaryrefslogtreecommitdiff
path: root/gdb/dfp.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dfp.c')
-rw-r--r--gdb/dfp.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/gdb/dfp.c b/gdb/dfp.c
new file mode 100644
index 0000000..67cee13
--- /dev/null
+++ b/gdb/dfp.c
@@ -0,0 +1,113 @@
+/* Decimal floating point support for GDB.
+
+ Copyright 2007 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+
+/* The order of the following headers is important for making sure
+ decNumber structure is large enough to hold decimal128 digits. */
+
+#include "dpd/decimal128.h"
+#include "dpd/decimal64.h"
+#include "dpd/decimal32.h"
+
+/* In GDB, we are using an array of gdb_byte to represent decimal values.
+ They are stored in host byte order. This routine does the conversion if
+ the target byte order is different. */
+static void
+match_endianness (const gdb_byte *from, int len, gdb_byte *to)
+{
+ int i;
+
+#if WORDS_BIGENDIAN
+#define OPPOSITE_BYTE_ORDER BFD_ENDIAN_LITTLE
+#else
+#define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG
+#endif
+
+ if (gdbarch_byte_order (current_gdbarch) == OPPOSITE_BYTE_ORDER)
+ for (i = 0; i < len; i++)
+ to[i] = from[len - i - 1];
+ else
+ for (i = 0; i < len; i++)
+ to[i] = from[i];
+
+ return;
+}
+
+/* Convert decimal type to its string representation. LEN is the length
+ of the decimal type, 4 bytes for decimal32, 8 bytes for decimal64 and
+ 16 bytes for decimal128. */
+void
+decimal_to_string (const gdb_byte *decbytes, int len, char *s)
+{
+ gdb_byte dec[16];
+
+ match_endianness (decbytes, len, dec);
+ switch (len)
+ {
+ case 4:
+ decimal32ToString ((decimal32 *) dec, s);
+ break;
+ case 8:
+ decimal64ToString ((decimal64 *) dec, s);
+ break;
+ case 16:
+ decimal128ToString ((decimal128 *) dec, s);
+ break;
+ default:
+ error (_("Unknown decimal floating point type.\n"));
+ break;
+ }
+}
+
+/* Convert the string form of a decimal value to its decimal representation.
+ LEN is the length of the decimal type, 4 bytes for decimal32, 8 bytes for
+ decimal64 and 16 bytes for decimal128. */
+int
+decimal_from_string (gdb_byte *decbytes, int len, const char *string)
+{
+ decContext set;
+ gdb_byte dec[16];
+
+ switch (len)
+ {
+ case 4:
+ decContextDefault (&set, DEC_INIT_DECIMAL32);
+ set.traps = 0;
+ decimal32FromString ((decimal32 *) dec, string, &set);
+ break;
+ case 8:
+ decContextDefault (&set, DEC_INIT_DECIMAL64);
+ set.traps = 0;
+ decimal64FromString ((decimal64 *) dec, string, &set);
+ break;
+ case 16:
+ decContextDefault (&set, DEC_INIT_DECIMAL128);
+ set.traps = 0;
+ decimal128FromString ((decimal128 *) dec, string, &set);
+ break;
+ default:
+ error (_("Unknown decimal floating point type.\n"));
+ break;
+ }
+
+ match_endianness (dec, len, decbytes);
+
+ return 1;
+}