diff options
author | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2017-11-21 18:50:59 +0100 |
---|---|---|
committer | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2017-11-21 18:50:59 +0100 |
commit | ed0f427344d0befead629d9267aecd01bfb72721 (patch) | |
tree | 28c66c138b903afe536bef7624c66ab70e8c06f2 /gdb/rs6000-tdep.c | |
parent | a25d69c6dcbabf3f6629b847246ffb4ddbc29472 (diff) | |
download | gdb-ed0f427344d0befead629d9267aecd01bfb72721.zip gdb-ed0f427344d0befead629d9267aecd01bfb72721.tar.gz gdb-ed0f427344d0befead629d9267aecd01bfb72721.tar.bz2 |
[PowerPC] Detect different long double floating-point formats
Current versions of GCC support switching the format used for "long double"
to either IBM double double or IEEE-128. The resulting binary is marked
via different setting of the Tag_GNU_Power_ABI_FP GNU attribute.
This patch checks this attribute to detect the format of the default
"long double" type and sets GDB's notion of the format accordingly.
The patch also adds support for the "__ibm128" type, which always uses
IBM double double format independent of the format used for "long double".
A new test case verifies that all three types, "long double", "__float128",
and "__ibm128" are correctly detected in all three compiler settings,
the default setting, -mabi=ieeelongdouble, and -mabi=ibmlongdouble.
gdb/ChangeLog:
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.
gdb/testsuite/ChangeLog:
2017-11-21 Ulrich Weigand <uweigand@de.ibm.com>
* gdb.arch/ppc-longdouble.exp: New file.
* gdb.arch/ppc-longdouble.c: Likewise.
Diffstat (limited to 'gdb/rs6000-tdep.c')
-rw-r--r-- | gdb/rs6000-tdep.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 6c44995..456dbcc 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -5949,6 +5949,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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, @@ -6271,7 +6272,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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; @@ -6284,6 +6285,22 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } } + 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, @@ -6365,6 +6382,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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) @@ -6387,6 +6406,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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); |