[1/8] Add many operators to gdb_mpz

Message ID 20230303211207.1053037-2-tromey@adacore.com
State New
Headers
Series Arithmetic for 128-bit types |

Commit Message

Tom Tromey March 3, 2023, 9:12 p.m. UTC
  This adds many operator overloads and other useful methods to gdb_mpz.
This is preparation for using this class for scalar arithmetic in gdb
expression evaluation.
---
 gdb/gmp-utils.h | 138 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 138 insertions(+)
  

Comments

Alexandra Petlanova Hajkova March 7, 2023, 1:38 p.m. UTC | #1
On Fri, Mar 3, 2023 at 10:12 PM Tom Tromey via Gdb-patches <
gdb-patches@sourceware.org> wrote:

> This adds many operator overloads and other useful methods to gdb_mpz.
> This is preparation for using this class for scalar arithmetic in gdb
> expression evaluation.
> ---
>
> Looks great, applies cleanly.
  

Patch

diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h
index 274c28c0ce8..d4e5015e345 100644
--- a/gdb/gmp-utils.h
+++ b/gdb/gmp-utils.h
@@ -90,6 +90,12 @@  struct gdb_mpz
     return *this;
   }
 
+  gdb_mpz &operator= (bool src)
+  {
+    mpz_set_ui (m_val, (unsigned long) src);
+    return *this;
+  }
+
   /* Initialize this value from a string and a base.  Returns true if
      the string was parsed successfully, false otherwise.  */
   bool set (const char *str, int base)
@@ -105,6 +111,14 @@  struct gdb_mpz
     return result;
   }
 
+  /* Return a new value that is this value raised to EXP.  */
+  gdb_mpz pow (unsigned long exp) const
+  {
+    gdb_mpz result;
+    mpz_pow_ui (result.m_val, m_val, exp);
+    return result;
+  }
+
   /* Convert VAL to an integer of the given type.
 
      The return type can signed or unsigned, with no size restriction.  */
@@ -137,35 +151,154 @@  struct gdb_mpz
     mpz_neg (m_val, m_val);
   }
 
+  /* Take the one's complement in place.  */
+  void complement ()
+  { mpz_com (m_val, m_val); }
+
+  /* Mask this value to N bits, in place.  */
+  void mask (unsigned n)
+  { mpz_tdiv_r_2exp (m_val, m_val, n); }
+
+  /* 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 mpz_sgn (m_val); }
+
+  explicit operator bool () const
+  { return sgn () != 0; }
+
   gdb_mpz &operator*= (long other)
   {
     mpz_mul_si (m_val, m_val, other);
     return *this;
   }
 
+  gdb_mpz operator* (const gdb_mpz &other) const
+  {
+    gdb_mpz result;
+    mpz_mul (result.m_val, m_val, other.m_val);
+    return result;
+  }
+
+  gdb_mpz operator/ (const gdb_mpz &other) const
+  {
+    gdb_mpz result;
+    mpz_tdiv_q (result.m_val, m_val, other.m_val);
+    return result;
+  }
+
+  gdb_mpz operator% (const gdb_mpz &other) const
+  {
+    gdb_mpz result;
+    mpz_tdiv_r (result.m_val, m_val, other.m_val);
+    return result;
+  }
+
   gdb_mpz &operator+= (unsigned long other)
   {
     mpz_add_ui (m_val, m_val, other);
     return *this;
   }
 
+  gdb_mpz &operator+= (const gdb_mpz &other)
+  {
+    mpz_add (m_val, m_val, other.m_val);
+    return *this;
+  }
+
+  gdb_mpz operator+ (const gdb_mpz &other) const
+  {
+    gdb_mpz result;
+    mpz_add (result.m_val, m_val, other.m_val);
+    return result;
+  }
+
   gdb_mpz &operator-= (unsigned long other)
   {
     mpz_sub_ui (m_val, m_val, other);
     return *this;
   }
 
+  gdb_mpz &operator-= (const gdb_mpz &other)
+  {
+    mpz_sub (m_val, m_val, other.m_val);
+    return *this;
+  }
+
+  gdb_mpz operator- (const gdb_mpz &other) const
+  {
+    gdb_mpz result;
+    mpz_sub (result.m_val, m_val, other.m_val);
+    return result;
+  }
+
   gdb_mpz &operator<<= (unsigned long nbits)
   {
     mpz_mul_2exp (m_val, m_val, nbits);
     return *this;
   }
 
+  gdb_mpz operator<< (unsigned long nbits) const
+  {
+    gdb_mpz result;
+    mpz_mul_2exp (result.m_val, m_val, nbits);
+    return result;
+  }
+
+  gdb_mpz operator>> (unsigned long nbits) const
+  {
+    gdb_mpz result;
+    mpz_tdiv_q_2exp (result.m_val, m_val, nbits);
+    return result;
+  }
+
+  gdb_mpz &operator>>= (unsigned long nbits)
+  {
+    mpz_tdiv_q_2exp (m_val, m_val, nbits);
+    return *this;
+  }
+
+  gdb_mpz operator& (const gdb_mpz &other) const
+  {
+    gdb_mpz result;
+    mpz_and (result.m_val, m_val, other.m_val);
+    return result;
+  }
+
+  gdb_mpz operator| (const gdb_mpz &other) const
+  {
+    gdb_mpz result;
+    mpz_ior (result.m_val, m_val, other.m_val);
+    return result;
+  }
+
+  gdb_mpz operator^ (const gdb_mpz &other) const
+  {
+    gdb_mpz result;
+    mpz_xor (result.m_val, m_val, other.m_val);
+    return result;
+  }
+
   bool operator> (const gdb_mpz &other) const
   {
     return mpz_cmp (m_val, other.m_val) > 0;
   }
 
+  bool operator>= (const gdb_mpz &other) const
+  {
+    return mpz_cmp (m_val, other.m_val) >= 0;
+  }
+
+  bool operator< (const gdb_mpz &other) const
+  {
+    return mpz_cmp (m_val, other.m_val) < 0;
+  }
+
+  bool operator<= (const gdb_mpz &other) const
+  {
+    return mpz_cmp (m_val, other.m_val) <= 0;
+  }
+
   bool operator< (int other) const
   {
     return mpz_cmp_si (m_val, other) < 0;
@@ -181,6 +314,11 @@  struct gdb_mpz
     return mpz_cmp (m_val, other.m_val) == 0;
   }
 
+  bool operator!= (const gdb_mpz &other) const
+  {
+    return mpz_cmp (m_val, other.m_val) != 0;
+  }
+
 private:
 
   /* Helper template for constructor and operator=.  */