Target FP: Add conversion routines to target-float.{c,h}

This patch adds the following conversion routines:
 - target_float_to_longest
 - target_float_from_longest
 - target_float_from_ulongest
 - target_float_convert
which call the equivalent decimal_ routines to handle decimal FP,
and call helper routines that currently still go via DOUBLEST to
handle binary FP.

The target_float_convert routine not only handles BFP<->BFP and
DFP<->DFP conversions, but also BFP<->DFP, which are implemented
by converting to a string and back.

These helpers are used in particular to implement conversion
from and to FP in value_cast, without going through DOUBLEST there.
In order to implement this for the FP<-integer case, the
pack_long / pack_unsigned_long routines are extended to support
floating-point values as output (thereby allowing use of
value_from_[u]longest with a floating-point target type).

This latter change also allows simplification of value_one.

gdb/ChangeLog:
2017-11-06  Ulrich Weigand  <uweigand@de.ibm.com>

	* target-float.c (floatformat_to_longest): New function.
	(floatformat_from_longest, floatformat_from_ulongest): Likewise.
	(floatformat_convert): Likewise.
	(target_float_to_longest): Likewise.
	(target_float_from_longest, target_float_from_ulongest): Likewise.
	(target_float_convert): Likewise.
	* target-float.h (target_float_to_longest): Add prototype.
	(target_float_from_longest, target_float_from_ulongest): Likewise.
	(target_float_convert): Likewise.

	* value.c (unpack_long): Use target_float_to_longest.
	(pack_long): Allow FP types.  Use target_float_from_longest.
	(pack_unsigned_long): Likewise using target_float_from_ulongest.
	* valops.c: Include "target-float.h".  Do not include "dfp.h".
	(value_cast): Handle conversions to FP using target_float_convert,
	value_from_ulongest, and value_from_longest.
	(value_one): Use value_from_longest for FP types as well.
This commit is contained in:
Ulrich Weigand
2017-11-06 15:57:31 +01:00
parent f69fdf9bca
commit 50637b26f8
4 changed files with 205 additions and 36 deletions

View File

@@ -34,7 +34,7 @@
#include "infcall.h"
#include "dictionary.h"
#include "cp-support.h"
#include "dfp.h"
#include "target-float.h"
#include "tracepoint.h"
#include "observer.h"
#include "objfiles.h"
@@ -462,29 +462,21 @@ value_cast (struct type *type, struct value *arg2)
return v;
}
if (code1 == TYPE_CODE_FLT && scalar)
return value_from_double (to_type, value_as_double (arg2));
else if (code1 == TYPE_CODE_DECFLOAT && scalar)
if (is_floating_type (type) && scalar)
{
enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
int dec_len = TYPE_LENGTH (type);
gdb_byte dec[16];
if (is_floating_value (arg2))
{
struct value *v = allocate_value (to_type);
target_float_convert (value_contents (arg2), type2,
value_contents_raw (v), type);
return v;
}
if (code2 == TYPE_CODE_FLT)
decimal_from_doublest (value_as_double (arg2),
dec, dec_len, byte_order);
else if (code2 == TYPE_CODE_DECFLOAT)
decimal_convert (value_contents (arg2), TYPE_LENGTH (type2),
byte_order, dec, dec_len, byte_order);
/* The only option left is an integral type. */
else if (TYPE_UNSIGNED (type2))
decimal_from_ulongest (value_as_long (arg2),
dec, dec_len, byte_order);
if (TYPE_UNSIGNED (type2))
return value_from_ulongest (to_type, value_as_long (arg2));
else
decimal_from_longest (value_as_long (arg2),
dec, dec_len, byte_order);
return value_from_decfloat (to_type, dec);
return value_from_longest (to_type, value_as_long (arg2));
}
else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM
|| code1 == TYPE_CODE_RANGE)
@@ -868,19 +860,7 @@ value_one (struct type *type)
struct type *type1 = check_typedef (type);
struct value *val;
if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT)
{
enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
gdb_byte v[16];
decimal_from_string (v, TYPE_LENGTH (type), byte_order, "1");
val = value_from_decfloat (type, v);
}
else if (TYPE_CODE (type1) == TYPE_CODE_FLT)
{
val = value_from_double (type, (DOUBLEST) 1);
}
else if (is_integral_type (type1))
if (is_integral_type (type1) || is_floating_type (type1))
{
val = value_from_longest (type, (LONGEST) 1);
}