Add operators and methods to gdb_mpq
This adds some operators and methods to gdb_mpq, in preparation for making its implementation private. This only adds the operators currently needed by gdb. More could be added as necessary.
This commit is contained in:
parent
7aeae94f88
commit
7607de9431
@ -245,6 +245,13 @@ struct gdb_mpq
|
||||
mpq_canonicalize (val);
|
||||
}
|
||||
|
||||
gdb_mpq (long num, long denom)
|
||||
{
|
||||
mpq_init (val);
|
||||
mpq_set_si (val, num, denom);
|
||||
mpq_canonicalize (val);
|
||||
}
|
||||
|
||||
/* Copy assignment operator. */
|
||||
gdb_mpq &operator= (const gdb_mpq &from)
|
||||
{
|
||||
@ -264,6 +271,67 @@ struct gdb_mpq
|
||||
return *this;
|
||||
}
|
||||
|
||||
gdb_mpq &operator= (double d)
|
||||
{
|
||||
mpq_set_d (val, d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Return the sign of this value. This returns -1 for a negative
|
||||
value, 0 if the value is 0, and 1 for a positive value. */
|
||||
int sgn () const
|
||||
{ return mpq_sgn (val); }
|
||||
|
||||
gdb_mpq operator+ (const gdb_mpq &other) const
|
||||
{
|
||||
gdb_mpq result;
|
||||
mpq_add (result.val, val, other.val);
|
||||
return result;
|
||||
}
|
||||
|
||||
gdb_mpq operator- (const gdb_mpq &other) const
|
||||
{
|
||||
gdb_mpq result;
|
||||
mpq_sub (result.val, val, other.val);
|
||||
return result;
|
||||
}
|
||||
|
||||
gdb_mpq operator* (const gdb_mpq &other) const
|
||||
{
|
||||
gdb_mpq result;
|
||||
mpq_mul (result.val, val, other.val);
|
||||
return result;
|
||||
}
|
||||
|
||||
gdb_mpq operator/ (const gdb_mpq &other) const
|
||||
{
|
||||
gdb_mpq result;
|
||||
mpq_div (result.val, val, other.val);
|
||||
return result;
|
||||
}
|
||||
|
||||
gdb_mpq &operator*= (const gdb_mpq &other)
|
||||
{
|
||||
mpq_mul (val, val, other.val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
gdb_mpq &operator/= (const gdb_mpq &other)
|
||||
{
|
||||
mpq_div (val, val, other.val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator== (const gdb_mpq &other) const
|
||||
{
|
||||
return mpq_cmp (val, other.val) == 0;
|
||||
}
|
||||
|
||||
bool operator< (const gdb_mpq &other) const
|
||||
{
|
||||
return mpq_cmp (val, other.val) < 0;
|
||||
}
|
||||
|
||||
/* Return a string representing VAL as "<numerator> / <denominator>". */
|
||||
std::string str () const { return gmp_string_printf ("%Qd", val); }
|
||||
|
||||
@ -278,6 +346,10 @@ struct gdb_mpq
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return this value converted to a host double. */
|
||||
double as_double () const
|
||||
{ return mpq_get_d (val); }
|
||||
|
||||
/* Set VAL from the contents of the given byte array (BUF), which
|
||||
contains the unscaled value of a fixed point type object.
|
||||
The byte size of the data is the size of BUF.
|
||||
|
@ -399,8 +399,8 @@ read_fp_test (int unscaled, const gdb_mpq &scaling_factor,
|
||||
|
||||
actual.read_fixed_point ({buf, len}, byte_order, 0, scaling_factor);
|
||||
|
||||
mpq_set_si (expected.val, unscaled, 1);
|
||||
mpq_mul (expected.val, expected.val, scaling_factor.val);
|
||||
expected = gdb_mpq (unscaled, 1);
|
||||
expected *= scaling_factor;
|
||||
}
|
||||
|
||||
/* Perform various tests of the gdb_mpq::read_fixed_point method. */
|
||||
@ -409,38 +409,37 @@ static void
|
||||
gdb_mpq_read_fixed_point ()
|
||||
{
|
||||
gdb_mpq expected, actual;
|
||||
gdb_mpq scaling_factor;
|
||||
|
||||
/* Pick an arbitrary scaling_factor; this operation is trivial enough
|
||||
thanks to GMP that the value we use isn't really important. */
|
||||
mpq_set_ui (scaling_factor.val, 3, 5);
|
||||
gdb_mpq scaling_factor (3, 5);
|
||||
|
||||
/* Try a few values, both negative and positive... */
|
||||
|
||||
read_fp_test (-256, scaling_factor, BFD_ENDIAN_BIG, expected, actual);
|
||||
SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
|
||||
SELF_CHECK (actual == expected);
|
||||
read_fp_test (-256, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual);
|
||||
SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
|
||||
SELF_CHECK (actual == expected);
|
||||
|
||||
read_fp_test (-1, scaling_factor, BFD_ENDIAN_BIG, expected, actual);
|
||||
SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
|
||||
SELF_CHECK (actual == expected);
|
||||
read_fp_test (-1, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual);
|
||||
SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
|
||||
SELF_CHECK (actual == expected);
|
||||
|
||||
read_fp_test (0, scaling_factor, BFD_ENDIAN_BIG, expected, actual);
|
||||
SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
|
||||
SELF_CHECK (actual == expected);
|
||||
read_fp_test (0, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual);
|
||||
SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
|
||||
SELF_CHECK (actual == expected);
|
||||
|
||||
read_fp_test (1, scaling_factor, BFD_ENDIAN_BIG, expected, actual);
|
||||
SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
|
||||
SELF_CHECK (actual == expected);
|
||||
read_fp_test (1, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual);
|
||||
SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
|
||||
SELF_CHECK (actual == expected);
|
||||
|
||||
read_fp_test (1025, scaling_factor, BFD_ENDIAN_BIG, expected, actual);
|
||||
SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
|
||||
SELF_CHECK (actual == expected);
|
||||
read_fp_test (1025, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual);
|
||||
SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
|
||||
SELF_CHECK (actual == expected);
|
||||
}
|
||||
|
||||
/* A helper function which builds a gdb_mpq object from the given
|
||||
@ -463,9 +462,7 @@ write_fp_test (int numerator, unsigned int denominator,
|
||||
gdb_byte buf[len];
|
||||
memset (buf, 0, len);
|
||||
|
||||
gdb_mpq v;
|
||||
mpq_set_si (v.val, numerator, denominator);
|
||||
mpq_canonicalize (v.val);
|
||||
gdb_mpq v (numerator, denominator);
|
||||
v.write_fixed_point ({buf, len}, byte_order, 0, scaling_factor);
|
||||
|
||||
return extract_unsigned_integer (buf, len, byte_order);
|
||||
@ -479,8 +476,7 @@ gdb_mpq_write_fixed_point ()
|
||||
/* Pick an arbitrary factor; this operations is sufficiently trivial
|
||||
with the use of GMP that the value of this factor is not really
|
||||
all that important. */
|
||||
gdb_mpq scaling_factor;
|
||||
mpq_set_ui (scaling_factor.val, 1, 3);
|
||||
gdb_mpq scaling_factor (1, 3);
|
||||
|
||||
gdb_mpq vq;
|
||||
|
||||
|
@ -883,43 +883,43 @@ fixed_point_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
|
||||
switch (op)
|
||||
{
|
||||
case BINOP_ADD:
|
||||
mpq_add (res.val, v1.val, v2.val);
|
||||
res = v1 + v2;
|
||||
val = fixed_point_to_value (res);
|
||||
break;
|
||||
|
||||
case BINOP_SUB:
|
||||
mpq_sub (res.val, v1.val, v2.val);
|
||||
res = v1 - v2;
|
||||
val = fixed_point_to_value (res);
|
||||
break;
|
||||
|
||||
case BINOP_MIN:
|
||||
val = fixed_point_to_value (mpq_cmp (v1.val, v2.val) < 0 ? v1 : v2);
|
||||
val = fixed_point_to_value (std::min (v1, v2));
|
||||
break;
|
||||
|
||||
case BINOP_MAX:
|
||||
val = fixed_point_to_value (mpq_cmp (v1.val, v2.val) > 0 ? v1 : v2);
|
||||
val = fixed_point_to_value (std::max (v1, v2));
|
||||
break;
|
||||
|
||||
case BINOP_MUL:
|
||||
mpq_mul (res.val, v1.val, v2.val);
|
||||
res = v1 * v2;
|
||||
val = fixed_point_to_value (res);
|
||||
break;
|
||||
|
||||
case BINOP_DIV:
|
||||
if (mpq_sgn (v2.val) == 0)
|
||||
if (v2.sgn () == 0)
|
||||
error (_("Division by zero"));
|
||||
mpq_div (res.val, v1.val, v2.val);
|
||||
res = v1 / v2;
|
||||
val = fixed_point_to_value (res);
|
||||
break;
|
||||
|
||||
case BINOP_EQUAL:
|
||||
val = value_from_ulongest (language_bool_type (language, gdbarch),
|
||||
mpq_cmp (v1.val, v2.val) == 0 ? 1 : 0);
|
||||
v1 == v2 ? 1 : 0);
|
||||
break;
|
||||
|
||||
case BINOP_LESS:
|
||||
val = value_from_ulongest (language_bool_type (language, gdbarch),
|
||||
mpq_cmp (v1.val, v2.val) < 0 ? 1 : 0);
|
||||
v1 < v2 ? 1 : 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
13
gdb/valops.c
13
gdb/valops.c
@ -341,11 +341,7 @@ value_to_gdb_mpq (struct value *value)
|
||||
|
||||
gdb_mpq result;
|
||||
if (is_floating_type (type))
|
||||
{
|
||||
double d = target_float_to_host_double (value->contents ().data (),
|
||||
type);
|
||||
mpq_set_d (result.val, d);
|
||||
}
|
||||
result = target_float_to_host_double (value->contents ().data (), type);
|
||||
else
|
||||
{
|
||||
gdb_assert (is_integral_type (type)
|
||||
@ -357,8 +353,7 @@ value_to_gdb_mpq (struct value *value)
|
||||
result = vz;
|
||||
|
||||
if (is_fixed_point_type (type))
|
||||
mpq_mul (result.val, result.val,
|
||||
type->fixed_point_scaling_factor ().val);
|
||||
result *= type->fixed_point_scaling_factor ();
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -386,7 +381,7 @@ value_cast_to_fixed_point (struct type *to_type, struct value *from_val)
|
||||
/* Divide that value by the scaling factor to obtain the unscaled
|
||||
value, first in rational form, and then in integer form. */
|
||||
|
||||
mpq_div (vq.val, vq.val, to_type->fixed_point_scaling_factor ().val);
|
||||
vq /= to_type->fixed_point_scaling_factor ();
|
||||
gdb_mpz unscaled = vq.get_rounded ();
|
||||
|
||||
/* Finally, create the result value, and pack the unscaled value
|
||||
@ -559,7 +554,7 @@ value_cast (struct type *type, struct value *arg2)
|
||||
|
||||
struct value *v = value::allocate (to_type);
|
||||
target_float_from_host_double (v->contents_raw ().data (),
|
||||
to_type, mpq_get_d (fp_val.val));
|
||||
to_type, fp_val.as_double ());
|
||||
return v;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user