+2017-11-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * ppc-tdep.h (enum powerpc_long_double_abi): New data type.
+ (struct gdbarch_tdep): New member long_double_abi.
+ * rs6000-tdep.c (rs6000_gdbarch_init): Initialize long_double_abi
+ member of tdep struct based on Tag_GNU_Power_ABI_FP attribute.
+ * ppc-linux-tdep.c (ppc_linux_init_abi): Install long double data
+ format depending on long_double_abi tdep member.
+ (ppc_floatformat_for_type): Handle __ibm128 type.
+
2017-11-20 Simon Marchi <simon.marchi@polymtl.ca>
* darwin-nat.c (set_enable_mach_exceptions): Constify parameter.
const char *name, int len)
{
if (len == 128 && name)
- if (strcmp (name, "__float128") == 0
- || strcmp (name, "_Float128") == 0
- || strcmp (name, "_Float64x") == 0
- || strcmp (name, "complex _Float128") == 0
- || strcmp (name, "complex _Float64x") == 0)
- return floatformats_ia64_quad;
+ {
+ if (strcmp (name, "__float128") == 0
+ || strcmp (name, "_Float128") == 0
+ || strcmp (name, "_Float64x") == 0
+ || strcmp (name, "complex _Float128") == 0
+ || strcmp (name, "complex _Float64x") == 0)
+ return floatformats_ia64_quad;
+
+ if (strcmp (name, "__ibm128") == 0)
+ return floatformats_ibm_long_double;
+ }
return default_floatformat_for_type (gdbarch, name, len);
}
linux_init_abi (info, gdbarch);
/* PPC GNU/Linux uses either 64-bit or 128-bit long doubles; where
- 128-bit, they are IBM long double, not IEEE quad long double as
- in the System V ABI PowerPC Processor Supplement. We can safely
- let them default to 128-bit, since the debug info will give the
- size of type actually used in each case. */
+ 128-bit, they can be either IBM long double or IEEE quad long double.
+ The 64-bit long double case will be detected automatically using
+ the size specified in debug info. We use a .gnu.attribute flag
+ to distinguish between the IBM long double and IEEE quad cases. */
set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);
- set_gdbarch_long_double_format (gdbarch, floatformats_ibm_long_double);
+ if (tdep->long_double_abi == POWERPC_LONG_DOUBLE_IEEE128)
+ set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad);
+ else
+ set_gdbarch_long_double_format (gdbarch, floatformats_ibm_long_double);
/* Support for floating-point data type variants. */
set_gdbarch_floatformat_for_type (gdbarch, ppc_floatformat_for_type);
POWERPC_VEC_LAST
};
+/* long double ABI version used by the inferior. */
+enum powerpc_long_double_abi
+{
+ POWERPC_LONG_DOUBLE_AUTO,
+ POWERPC_LONG_DOUBLE_IBM128,
+ POWERPC_LONG_DOUBLE_IEEE128,
+ POWERPC_LONG_DOUBLE_LAST
+};
+
struct gdbarch_tdep
{
int wordsize; /* Size in bytes of fixed-point word. */
enum powerpc_elf_abi elf_abi; /* ELF ABI version. */
+ /* Format to use for the "long double" data type. */
+ enum powerpc_long_double_abi long_double_abi;
+
/* How to pass vector arguments. Never set to AUTO or LAST. */
enum powerpc_vector_abi vector_abi;
bfd abfd;
enum auto_boolean soft_float_flag = powerpc_soft_float_global;
int soft_float;
+ enum powerpc_long_double_abi long_double_abi = POWERPC_LONG_DOUBLE_AUTO;
enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global;
enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO;
int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0,
if (soft_float_flag == AUTO_BOOLEAN_AUTO && from_elf_exec)
{
switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
- Tag_GNU_Power_ABI_FP))
+ Tag_GNU_Power_ABI_FP) & 3)
{
case 1:
soft_float_flag = AUTO_BOOLEAN_FALSE;
}
}
+ if (long_double_abi == POWERPC_LONG_DOUBLE_AUTO && from_elf_exec)
+ {
+ switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
+ Tag_GNU_Power_ABI_FP) >> 2)
+ {
+ case 1:
+ long_double_abi = POWERPC_LONG_DOUBLE_IBM128;
+ break;
+ case 3:
+ long_double_abi = POWERPC_LONG_DOUBLE_IEEE128;
+ break;
+ default:
+ break;
+ }
+ }
+
if (vector_abi == POWERPC_VEC_AUTO && from_elf_exec)
{
switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
continue;
if (tdep && tdep->soft_float != soft_float)
continue;
+ if (tdep && tdep->long_double_abi != long_double_abi)
+ continue;
if (tdep && tdep->vector_abi != vector_abi)
continue;
if (tdep && tdep->wordsize == wordsize)
tdep->wordsize = wordsize;
tdep->elf_abi = elf_abi;
tdep->soft_float = soft_float;
+ tdep->long_double_abi = long_double_abi;
tdep->vector_abi = vector_abi;
gdbarch = gdbarch_alloc (&info, tdep);
+2017-11-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * gdb.arch/ppc-longdouble.exp: New file.
+ * gdb.arch/ppc-longdouble.c: Likewise.
+
2017-11-21 Pedro Alves <palves@redhat.com>
* gdb.ada/minsyms.exp: Accept any address for 'some_minsym'.
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2017 Free Software Foundation, Inc.
+
+ 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 <stdio.h>
+#include <stdlib.h>
+
+long double ld;
+__float128 float128;
+__ibm128 ibm128;
+
+/* FIXME: GCC will only emit a .gnu.attribute section specifying the
+ long double ABI if long double is used in a function prototype. */
+void test (long double x)
+{
+}
+
+int main()
+{
+ ld = 1.375l;
+ float128 = 2.375l;
+ ibm128 = 3.375l;
+
+ return 0;
+}
--- /dev/null
+# Copyright 2016-2017 Free Software Foundation, Inc.
+
+# 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/>.
+
+if ![istarget "powerpc*"] then {
+ verbose "Skipping powerpc long-double floating point tests."
+ return
+}
+
+standard_testfile
+
+proc do_test { name {opts {}} } {
+ global srcdir subdir srcfile binfile
+ set ccopts {debug quiet}
+ foreach opt $opts {lappend ccopts "additional_flags=$opt"}
+ set lines [gdb_compile "${srcdir}/${subdir}/${srcfile}" "$binfile.$name" executable $ccopts]
+ # We get this warning even with the nowarnings option ...
+ regsub -all "(^|\n)\[^\n\]*using \[^\n\]* extended precision long double" $lines "" lines
+ if { $lines != "" } then {
+ return
+ }
+
+ clean_restart ${binfile}.${name}
+
+ if ![runto_main] then {
+ return
+ }
+
+ # Run to the breakpoint at return.
+ gdb_breakpoint [gdb_get_line_number "return"]
+ gdb_continue_to_breakpoint "return"
+
+ # Print the value of ld
+ gdb_test "print ld" ".* = 1\\.375.*" "the value of ld is 1.375 ($name)"
+ # Print the value of float128
+ gdb_test "print float128" ".* = 2\\.375.*" "the value of float128 is 2.375 ($name)"
+ # Print the value of ibm128
+ gdb_test "print ibm128" ".* = 3\\.375.*" "the value of ibm128 is 3.375 ($name)"
+}
+
+# Verify that we correctly detect the floating-point format used for
+# long double. Re-run the test with -mabi=ieeelongdouble and mabi=ibmlongdouble
+
+do_test default { -mfloat128 }
+do_test ieee128 { -mfloat128 -mabi=ieeelongdouble }
+do_test ibm128 { -mfloat128 -mabi=ibmlongdouble }
+