mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-15 04:31:49 +08:00
7a26362d36
Prepare for using MPFR to implement floating-point arithmetic by refactoring the way host floating-point arithmetic is currently used. In particular, fix the following two problems that cause different (and incorrect) results due to using host arithmetic: - Current processing always uses host "long double", and then converts back to the actual target format. This may introduce rounding errors. - Conversion of FP values to LONGEST simply does a host C++ type cast. However the result of such a cast is undefined if the source value is outside the representable range. MPFR always has defined behavior here (returns the minimum or maximum representable value). To fix the first issue, I've now created not just one set of routines using host FP arithmetic (on long double), but instead three different sets of routines, one each for host float, double, and long double. Operations can then be performed in the desired type directly, avoiding the extra rounding step. Using C++ templates, the three sets can all share the same source code without duplication. To fix the second issue, I'm simply enforcing the same conversion rule (which makes sense anyway) when converting out-of-range values from FP to LONGEST. To contain the code complexity with the variety of options now possible, I've created a new class "target_float_ops". There are a total of five separate implementations of this: host_float_ops<float> Implemented via host FP in given type host_float_ops<double> host_float_ops<long double> mpfr_float_ops Implemented via MPFR if available decimal_float_ops Implemented via libdecnumber Note instead of using the DOUBLEST define, this always just uses the "long double" data type. But since we now require C++11 anyway, this type must in any case be avaialble unconditionally. Most target floating-point operations simply dispatch to a (virtual) member routine of this class. Which implementation to choose is determined from the target types involved, and whether they match some host type or not. E.g. any operation on a single type that matches a host type is performed in that type. Operations involving two types that both match host types are performed in the larger one (according to C/C++ implicit conversion rules). Operations that involve any type that does not match a host type are performed using MPFR. (And of course operations involving decimal FP are performed using libdecnumber.) This first patch implements the refactoring of target-float.c as described above, introduing the host_float_ops and decimal_float_ops classes, and using them. Use of MPFR is introduced in the second patch. A bit of special-case handling code is moved around to as to avoid code duplication between host_float_ops and mpfr_float_ops. Note that due to the changes mentioned above, I've had to update (fix) the floating-point register values tested in the gdb.arch/vsx-regs.exp test case. (The new values now work both with host arithmetic and MPFR.) gdb/ChangeLog: 2017-11-22 Ulrich Weigand <uweigand@de.ibm.com> * target-float.c: Do not include <math.h>. Include <cmath> and <limits>. (DOUBLEST): Do not define. (class target_float_ops): New type. (class host_float_ops): New templated type. (class decimal_float_ops): New type. (floatformat_to_doublest): Rename to ... (host_float_ops<T>::from_target): ... this. Use template type T instead of DOUBLEST. Use C++ math routines. Update recursive calls. (host_float_ops<T>::from_target): New overload using a type argument. (floatformat_from_doublest): Rename to ... (host_float_ops<T>::to_target): ... this. Use template type T instead of DOUBLEST. Use C++ math routines. Update recursive calls. (host_float_ops<T>::to_target): New overload using a type argument. (floatformat_printf_format): New function. (struct printf_length_modifier): New templated type. (floatformat_to_string): Rename to ... (host_float_ops<T>::to_string): ... this. Use type instead of floatformat argument. Use floatformat_printf_format and printf_length_modifier. Remove special handling of invalid numbers, infinities and NaN (moved to target_float_to_string). (struct scanf_length_modifier): New templated type. (floatformat_from_string): Rename to ... (host_float_ops<T>::from_string): ... this. Use type instead of floatformat argument. Use scanf_length_modifier. (floatformat_to_longest): Rename to ... (host_float_ops<T>::to_longest): ... this. Use type instead of floatformat argument. Handle out-of-range values deterministically. (floatformat_from_longest): Rename to ... (host_float_ops<T>::from_longest): ... this. Use type instead of floatformat argument. (floatformat_from_ulongest): Rename to ... (host_float_ops<T>::from_ulongest): ... this. Use type instead of floatformat argument. (floatformat_to_host_double): Rename to ... (host_float_ops<T>::to_host_double): ... this. Use type instead of floatformat argument. (floatformat_from_host_double): Rename to ... (host_float_ops<T>::from_host_double): ... this. Use type instead of floatformat argument. (floatformat_convert): Rename to ... (host_float_ops<T>::convert): ... this. Use type instead of floatformat arguments. Remove handling of no-op conversions. (floatformat_binop): Rename to ... (host_float_ops<T>::binop): ... this. Use type instead of floatformat arguments. (floatformat_compare): Rename to ... (host_float_ops<T>::compare): ... this. Use type instead of floatformat arguments. (match_endianness): Use type instead of length/byte_order arguments. (set_decnumber_context): Likewise. (decimal_from_number): Likewise. Update calls. (decimal_to_number): Likewise. (decimal_is_zero): Likewise. Update calls. Move to earlier in file. (decimal_float_ops::to_host_double): New dummy function. (decimal_float_ops::from_host_double): Likewise. (decimal_to_string): Rename to ... (decimal_float_ops::to_string): ... this. Use type instead of length/byte_order arguments. Update calls. (decimal_from_string): Rename to ... (decimal_float_ops::from_string): ... this. Use type instead of length/byte_order arguments. Update calls. (decimal_from_longest): Rename to ... (decimal_float_ops::from_longest): ... this. Use type instead of length/byte_order arguments. Update calls. (decimal_from_ulongest): Rename to ... (decimal_float_ops::from_ulongest): ... this. Use type instead of length/byte_order arguments. Update calls. (decimal_to_longest): Rename to ... (decimal_float_ops::to_longest): ... this. Use type instead of length/byte_order arguments. Update calls. (decimal_binop): Rename to ... (decimal_float_ops::binop): ... this. Use type instead of length/byte_order arguments. Update calls. (decimal_compare): Rename to ... (decimal_float_ops::compare): ... this. Use type instead of length/byte_order arguments. Update calls. (decimal_convert): Rename to ... (decimal_float_ops::convert): ... this. Use type instead of length/byte_order arguments. Update calls. (target_float_same_category_p): New function. (target_float_same_format_p): Likewise. (target_float_format_length): Likewise. (enum target_float_ops_kind): New type. (get_target_float_ops_kind): New function. (get_target_float_ops): Three new overloaded functions. (target_float_is_zero): Update call. (target_float_to_string): Add special handling of invalid numbers, infinities and NaN (moved from floatformat_to_string). Use target_float_ops callback. (target_float_from_string): Use target_float_ops callback. (target_float_to_longest): Likewise. (target_float_from_longest): Likewise. (target_float_from_ulongest): Likewise. (target_float_to_host_double): Likewise. (target_float_from_host_double): Likewise. (target_float_convert): Add special case for no-op conversions. Use target_float_ops callback. (target_float_binop): Use target_float_ops callback. (target_float_compare): Likewise. gdb/testsuite/ChangeLog: 2017-11-22 Ulrich Weigand <uweigand@de.ibm.com> * gdb.arch/vsx-regs.exp: Update register content checks. |
||
---|---|---|
bfd | ||
binutils | ||
config | ||
cpu | ||
elfcpp | ||
etc | ||
gas | ||
gdb | ||
gold | ||
gprof | ||
include | ||
intl | ||
ld | ||
libdecnumber | ||
libiberty | ||
opcodes | ||
readline | ||
sim | ||
texinfo | ||
zlib | ||
.cvsignore | ||
.gitattributes | ||
.gitignore | ||
ChangeLog | ||
compile | ||
config-ml.in | ||
config.guess | ||
config.rpath | ||
config.sub | ||
configure | ||
configure.ac | ||
COPYING | ||
COPYING3 | ||
COPYING3.LIB | ||
COPYING.LIB | ||
COPYING.LIBGLOSS | ||
COPYING.NEWLIB | ||
depcomp | ||
djunpack.bat | ||
install-sh | ||
libtool.m4 | ||
lt~obsolete.m4 | ||
ltgcc.m4 | ||
ltmain.sh | ||
ltoptions.m4 | ||
ltsugar.m4 | ||
ltversion.m4 | ||
MAINTAINERS | ||
Makefile.def | ||
Makefile.in | ||
Makefile.tpl | ||
makefile.vms | ||
missing | ||
mkdep | ||
mkinstalldirs | ||
move-if-change | ||
README | ||
README-maintainer-mode | ||
setup.com | ||
src-release.sh | ||
symlink-tree | ||
ylwrap |
README for GNU development tools This directory contains various GNU compilers, assemblers, linkers, debuggers, etc., plus their support routines, definitions, and documentation. If you are receiving this as part of a GDB release, see the file gdb/README. If with a binutils release, see binutils/README; if with a libg++ release, see libg++/README, etc. That'll give you info about this package -- supported targets, how to use it, how to report bugs, etc. It is now possible to automatically configure and build a variety of tools with one command. To build all of the tools contained herein, run the ``configure'' script here, e.g.: ./configure make To install them (by default in /usr/local/bin, /usr/local/lib, etc), then do: make install (If the configure script can't determine your type of computer, give it the name as an argument, for instance ``./configure sun4''. You can use the script ``config.sub'' to test whether a name is recognized; if it is, config.sub translates it to a triplet specifying CPU, vendor, and OS.) If you have more than one compiler on your system, it is often best to explicitly set CC in the environment before running configure, and to also set CC when running make. For example (assuming sh/bash/ksh): CC=gcc ./configure make A similar example using csh: setenv CC gcc ./configure make Much of the code and documentation enclosed is copyright by the Free Software Foundation, Inc. See the file COPYING or COPYING.LIB in the various directories, for a description of the GNU General Public License terms under which you can copy the files. REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info on where and how to report problems.