From: Tom Tromey Date: Thu, 23 Feb 2023 17:34:22 +0000 (-0700) Subject: Add operators and methods to gdb_mpq X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7607de943130608a0798a550581b15331d140825;p=binutils-gdb.git 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. --- diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h index 3f43f5f835b..381ea9dbc72 100644 --- a/gdb/gmp-utils.h +++ b/gdb/gmp-utils.h @@ -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 " / ". */ 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. diff --git a/gdb/unittests/gmp-utils-selftests.c b/gdb/unittests/gmp-utils-selftests.c index 8e028fec88c..384ca2df212 100644 --- a/gdb/unittests/gmp-utils-selftests.c +++ b/gdb/unittests/gmp-utils-selftests.c @@ -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; diff --git a/gdb/valarith.c b/gdb/valarith.c index e0a3461aaa2..b3321e4ff75 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -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: diff --git a/gdb/valops.c b/gdb/valops.c index e0936d45cb3..2cef24fc4c5 100644 --- a/gdb/valops.c +++ b/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; }