From patchwork Fri Mar 3 21:12:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 65989 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C55E9385B511 for ; Fri, 3 Mar 2023 21:12:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C55E9385B511 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677877968; bh=2Va6z0J5/qxI3LuHf0apgC91vaVebsNLUTeZjt2aMCI=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=JtSeSiVvW3aIVt2uVwy6TsT7h12Cagnl4oAJ3edtbFSzL7O9azNZTWC7jBP7dI6zX wCik26DtKn2EgG7Bl3cS9ouJhy81/jd2hNLxhtKVZ7rIXwimuPbBU8quCTSxVxvi3i yrkHHOgN9qZVWGinWLznY7+opxymqKKuyANfhUlg= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-il1-x132.google.com (mail-il1-x132.google.com [IPv6:2607:f8b0:4864:20::132]) by sourceware.org (Postfix) with ESMTPS id 290633858D37 for ; Fri, 3 Mar 2023 21:12:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 290633858D37 Received: by mail-il1-x132.google.com with SMTP id g9so2575317ila.8 for ; Fri, 03 Mar 2023 13:12:20 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677877939; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2Va6z0J5/qxI3LuHf0apgC91vaVebsNLUTeZjt2aMCI=; b=VluA5TZnZ5OKqgpGAK+VvJuS1uoAliydPe6BHzBwhv/TZtLqiWqgTDjGfMs82naDOs l2zf2uP2hGBzIrMWSLikRZNWdiznHE8OF+WDPTFWIkFhkFIzgi5K/Huvoii70qCyxirS fhz8wbNz2g3GKDxBOKD3WzDCb2dMXtCGD3ot4tgVn2M+HfdfdUupB+Oq4t3lXXDTHmgD 5mlCsc78dfjU915rItahTItOB4nytJVFD2A0pFHuedT7Qhzi9mhRvV4xFt8CoFIRlBrX 4hI18iBhgzT8zkknKrT5+SBvhSbwatZxbRNn3rTFO+xOMv4VLBtN0OjCIQ+1DRgg563I Dy5w== X-Gm-Message-State: AO0yUKXuUebO1XlsWbOg4BOd7JgPp9s28s+X7+FjI0OHZ/1FyOi6MRYv TMAVkH3ZPd7nXmPPzhxfO2YD3IKB9/4ktWmVlI0= X-Google-Smtp-Source: AK7set876gBYMVatMCcDci4DVW+sTOURLJHA/NdIKz+H7pWDmAakH3dUtJWNOBiQ+RQVurhHjVb6vQ== X-Received: by 2002:a05:6e02:b4d:b0:314:e6f:f2d1 with SMTP id f13-20020a056e020b4d00b003140e6ff2d1mr2497706ilu.31.1677877939359; Fri, 03 Mar 2023 13:12:19 -0800 (PST) Received: from localhost.localdomain (75-166-130-93.hlrn.qwest.net. [75.166.130.93]) by smtp.gmail.com with ESMTPSA id g8-20020a925208000000b00313b281ecd2sm867988ilb.70.2023.03.03.13.12.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Mar 2023 13:12:19 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 1/8] Add many operators to gdb_mpz Date: Fri, 3 Mar 2023 14:12:00 -0700 Message-Id: <20230303211207.1053037-2-tromey@adacore.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230303211207.1053037-1-tromey@adacore.com> References: <20230303211207.1053037-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" 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(+) 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=. */ From patchwork Fri Mar 3 21:12:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 65990 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EFC5D3857C55 for ; Fri, 3 Mar 2023 21:12:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EFC5D3857C55 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677877972; bh=tGe8mtBhieYS86P7T55DZHW8fV2TWpZQ79ygP2AgI/4=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=o4ZqszzxBgnWoBDccCJ2MObWVfTSnXL2xeqO5LqoWswZNxsqW8aPGTw2NuT7DSpfI jCwklat4hUFRxGX4xwyJ87useWZTwPC7jXNswxyKgDq8HClN+zQPMWwdRfc3Y3oSr3 U2KDOxtl7Wl2u+L5gcnWeeQNQiQKmcH5p4D16sDU= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-il1-x132.google.com (mail-il1-x132.google.com [IPv6:2607:f8b0:4864:20::132]) by sourceware.org (Postfix) with ESMTPS id 9FD153858CDB for ; Fri, 3 Mar 2023 21:12:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9FD153858CDB Received: by mail-il1-x132.google.com with SMTP id k9so2061487ilu.13 for ; Fri, 03 Mar 2023 13:12:20 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677877940; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tGe8mtBhieYS86P7T55DZHW8fV2TWpZQ79ygP2AgI/4=; b=VhngNbc2idtvzZr078Qq0yBG07Dcy+P9lLPIWw0NToW+6pkRAT7pEGzGxw7qmWV7pA H1DqB55lR5wB2jQVNRo9Ntsv+zOfynbOPJVndtrESBwHnjK2opeXd6MmXVESIV83+rUA G7SsOD4dgz+GkmBoMN7ecG/4zO/zd0MF3/lLcJ+QmIrJ6gF1sHocVfmeWuXrsQlpA2L5 EFwfFttL0sg+0o767lvQgawOqJMw+g+me700qs5ONU4i/D4YjoHdFIISQZdzndjAjRps Z979+p5IlijSJBRW2ZcX0Fp2t7x9YsrZ/Tj9A+Nmpx6F2Fmqkp583sX+uwtuJ1jDn78V TsNA== X-Gm-Message-State: AO0yUKV/eBHW1BhY09dCUxQkYIVVcCHkhD3eOCTrYFBQPXwIRmE7yZ36 1bXO4+8HfmEcbaYr/sBwNx/KLtLDx1rrJHmsWKY= X-Google-Smtp-Source: AK7set/J5x5Zgjy6C2s+XrAf9tpc2AFnKj0Ux3/OXk9C/hjQbpdcbxMyx7++XLZS5wt05ZCBPhRnbg== X-Received: by 2002:a92:c546:0:b0:30f:3d9e:f80 with SMTP id a6-20020a92c546000000b0030f3d9e0f80mr2867632ilj.25.1677877939988; Fri, 03 Mar 2023 13:12:19 -0800 (PST) Received: from localhost.localdomain (75-166-130-93.hlrn.qwest.net. [75.166.130.93]) by smtp.gmail.com with ESMTPSA id g8-20020a925208000000b00313b281ecd2sm867988ilb.70.2023.03.03.13.12.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Mar 2023 13:12:19 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 2/8] Avoid a copy in gdb_mpz::safe_export Date: Fri, 3 Mar 2023 14:12:01 -0700 Message-Id: <20230303211207.1053037-3-tromey@adacore.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230303211207.1053037-1-tromey@adacore.com> References: <20230303211207.1053037-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Currently, gdb_mpz::safe_export will always make a copy of *this. However, this copy isn't always needed. This patch makes this code slightly more efficient, by avoiding the copy when possible. --- gdb/gmp-utils.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gdb/gmp-utils.c b/gdb/gmp-utils.c index d134bc32a1d..57f5f9766b9 100644 --- a/gdb/gmp-utils.c +++ b/gdb/gmp-utils.c @@ -81,7 +81,8 @@ gdb_mpz::safe_export (gdb::array_view buf, { gdb_assert (buf.size () > 0); - if (mpz_sgn (m_val) == 0) + int sign = mpz_sgn (m_val); + if (sign == 0) { /* Our value is zero, so no need to call mpz_export to do the work, especially since mpz_export's documentation explicitly says @@ -121,17 +122,16 @@ gdb_mpz::safe_export (gdb::array_view buf, lo.str ().c_str (), hi.str ().c_str ()); - gdb_mpz exported_val (m_val); - - if (mpz_cmp_ui (exported_val.m_val, 0) < 0) + const gdb_mpz *exported_val = this; + gdb_mpz un_signed; + if (sign < 0) { /* mpz_export does not handle signed values, so create a positive value whose bit representation as an unsigned of the same length would be the same as our negative value. */ - gdb_mpz neg_offset; - - mpz_ui_pow_ui (neg_offset.m_val, 2, buf.size () * HOST_CHAR_BIT); - mpz_add (exported_val.m_val, exported_val.m_val, neg_offset.m_val); + gdb_mpz neg_offset = gdb_mpz::pow (2, buf.size () * HOST_CHAR_BIT); + un_signed = *exported_val + neg_offset; + exported_val = &un_signed; } /* Do the export into a buffer allocated by GMP itself; that way, @@ -147,7 +147,7 @@ gdb_mpz::safe_export (gdb::array_view buf, size_t word_countp; gdb::unique_xmalloc_ptr exported (mpz_export (NULL, &word_countp, -1 /* order */, buf.size () /* size */, - endian, 0 /* nails */, exported_val.m_val)); + endian, 0 /* nails */, exported_val->m_val)); gdb_assert (word_countp == 1); From patchwork Fri Mar 3 21:12:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 65994 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C30FB384FB49 for ; Fri, 3 Mar 2023 21:13:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C30FB384FB49 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677878003; bh=+n4ofZB/vWJB2OJNIceOMRaVsjl6U+y3wfrGXcWS+xE=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=M+yDb03FREDRqbYdv9koQld9L3VZxdcNsfxQdYfMXDQn8YmPtP/ZEy8OnKPNBvhX9 8ueHyV5vhbDQDUgsEfDnkbSBWuYW74kUyUZyM5U6oCSObcTijgA1NHa4AFjnD7eJ2n hjs2D1pct1DdzqMZGVrIpD773UUCpeucBgFnGfG0= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-io1-xd2e.google.com (mail-io1-xd2e.google.com [IPv6:2607:f8b0:4864:20::d2e]) by sourceware.org (Postfix) with ESMTPS id A301D3858C5E for ; Fri, 3 Mar 2023 21:12:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A301D3858C5E Received: by mail-io1-xd2e.google.com with SMTP id 76so1519695iou.9 for ; Fri, 03 Mar 2023 13:12:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677877940; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+n4ofZB/vWJB2OJNIceOMRaVsjl6U+y3wfrGXcWS+xE=; b=l8Ztky9oMxe4GQcnpZaK3bQ0dLX0/L6kLkgT7fMpmgfCdYXjCvU9FWW4jW170KqBCP nXJ7AM1xvtxwCgwISypuyhE3gNLyK6p01VgLbxXngn+KYzY+TYJU+FhhoJi3a+cJJl95 ucIa1GgiN2KbY5Oti5VrV9yzlf6eKoFE2EZRUrS9fuB2i86sy9tF4GuBFoKj0CWFQ7YC 8s/GdFBN1+5zMVPQeGzPuXC45qVzHE9ZROuQDttyAFOuL/Y7EBfYtbjGxWpEuUpAoLbN 42vlehcBvyjb7Tb06lcWA9YLTSxuXXMX3zhkkf1Kzn8qnbm4skSwyEU82PaeYra1QdaK xQrA== X-Gm-Message-State: AO0yUKWpmJIE5E5qau9v52e1Bdvwd978uNJhEhfOfPCKhID80UsuV4Xy XXu24+Ea2THst7rB4kaaNEefEj3bKsqHdLwh6iA= X-Google-Smtp-Source: AK7set8wsSPixARlKrugZxcWAG8ICZRDlf8mlln4vUZPjd2oOsmi/P3GWDJH2TrIJizgOCnXarIBJw== X-Received: by 2002:a6b:600f:0:b0:704:b286:64c3 with SMTP id r15-20020a6b600f000000b00704b28664c3mr1803562iog.16.1677877940570; Fri, 03 Mar 2023 13:12:20 -0800 (PST) Received: from localhost.localdomain (75-166-130-93.hlrn.qwest.net. [75.166.130.93]) by smtp.gmail.com with ESMTPSA id g8-20020a925208000000b00313b281ecd2sm867988ilb.70.2023.03.03.13.12.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Mar 2023 13:12:20 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 3/8] Add truncation mode to gdb_mpz Date: Fri, 3 Mar 2023 14:12:02 -0700 Message-Id: <20230303211207.1053037-4-tromey@adacore.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230303211207.1053037-1-tromey@adacore.com> References: <20230303211207.1053037-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This renames gdb_mpz::safe_export to export_bits, and adds a new flag to export a truncated value. This is needed by value arithmetic. --- gdb/gmp-utils.c | 93 ++++++++++++++++++++++++++++--------------------- gdb/gmp-utils.h | 29 +++++++++++---- 2 files changed, 76 insertions(+), 46 deletions(-) diff --git a/gdb/gmp-utils.c b/gdb/gmp-utils.c index 57f5f9766b9..0afa344781b 100644 --- a/gdb/gmp-utils.c +++ b/gdb/gmp-utils.c @@ -66,18 +66,8 @@ gdb_mpz::read (gdb::array_view buf, enum bfd_endian byte_order, /* See gmp-utils.h. */ void -gdb_mpz::write (gdb::array_view buf, enum bfd_endian byte_order, - bool unsigned_p) const -{ - this->safe_export - (buf, byte_order == BFD_ENDIAN_BIG ? 1 : -1 /* endian */, unsigned_p); -} - -/* See gmp-utils.h. */ - -void -gdb_mpz::safe_export (gdb::array_view buf, - int endian, bool unsigned_p) const +gdb_mpz::export_bits (gdb::array_view buf, int endian, bool unsigned_p, + bool safe) const { gdb_assert (buf.size () > 0); @@ -92,36 +82,39 @@ gdb_mpz::safe_export (gdb::array_view buf, return; } - /* Determine the maximum range of values that our buffer can hold, - and verify that VAL is within that range. */ - - gdb_mpz lo, hi; - const size_t max_usable_bits = buf.size () * HOST_CHAR_BIT; - if (unsigned_p) - { - lo = 0; - - mpz_ui_pow_ui (hi.m_val, 2, max_usable_bits); - mpz_sub_ui (hi.m_val, hi.m_val, 1); - } - else + if (safe) { - mpz_ui_pow_ui (lo.m_val, 2, max_usable_bits - 1); - mpz_neg (lo.m_val, lo.m_val); - - mpz_ui_pow_ui (hi.m_val, 2, max_usable_bits - 1); - mpz_sub_ui (hi.m_val, hi.m_val, 1); + /* Determine the maximum range of values that our buffer can + hold, and verify that VAL is within that range. */ + + gdb_mpz lo, hi; + const size_t max_usable_bits = buf.size () * HOST_CHAR_BIT; + if (unsigned_p) + { + lo = 0; + + mpz_ui_pow_ui (hi.m_val, 2, max_usable_bits); + mpz_sub_ui (hi.m_val, hi.m_val, 1); + } + else + { + mpz_ui_pow_ui (lo.m_val, 2, max_usable_bits - 1); + mpz_neg (lo.m_val, lo.m_val); + + mpz_ui_pow_ui (hi.m_val, 2, max_usable_bits - 1); + mpz_sub_ui (hi.m_val, hi.m_val, 1); + } + + if (mpz_cmp (m_val, lo.m_val) < 0 || mpz_cmp (m_val, hi.m_val) > 0) + error (_("Cannot export value %s as %zu-bits %s integer" + " (must be between %s and %s)"), + this->str ().c_str (), + max_usable_bits, + unsigned_p ? _("unsigned") : _("signed"), + lo.str ().c_str (), + hi.str ().c_str ()); } - if (mpz_cmp (m_val, lo.m_val) < 0 || mpz_cmp (m_val, hi.m_val) > 0) - error (_("Cannot export value %s as %zu-bits %s integer" - " (must be between %s and %s)"), - this->str ().c_str (), - max_usable_bits, - unsigned_p ? _("unsigned") : _("signed"), - lo.str ().c_str (), - hi.str ().c_str ()); - const gdb_mpz *exported_val = this; gdb_mpz un_signed; if (sign < 0) @@ -134,6 +127,28 @@ gdb_mpz::safe_export (gdb::array_view buf, exported_val = &un_signed; } + /* If the value is too large, truncate it. */ + if (!safe + && mpz_sizeinbase (exported_val->m_val, 2) > buf.size () * HOST_CHAR_BIT) + { + /* If we don't already have a copy, make it now. */ + if (exported_val != &un_signed) + { + un_signed = *exported_val; + exported_val = &un_signed; + } + + un_signed.mask (buf.size () * HOST_CHAR_BIT); + } + + /* It's possible that one of the above results in zero, which has to + be handled specially. */ + if (exported_val->sgn () == 0) + { + memset (buf.data (), 0, buf.size ()); + return; + } + /* Do the export into a buffer allocated by GMP itself; that way, we can detect cases where BUF is not large enough to export our value, and thus avoid a buffer overlow. Normally, this should diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h index d4e5015e345..d378499d287 100644 --- a/gdb/gmp-utils.h +++ b/gdb/gmp-utils.h @@ -137,7 +137,20 @@ struct gdb_mpz UNSIGNED_P indicates whether the number has an unsigned type. */ void write (gdb::array_view buf, enum bfd_endian byte_order, - bool unsigned_p) const; + bool unsigned_p) const + { + export_bits (buf, byte_order == BFD_ENDIAN_BIG ? 1 : -1 /* endian */, + unsigned_p, true /* safe */); + } + + /* Like write, but truncates the value to the desired number of + bytes. */ + void truncate (gdb::array_view buf, enum bfd_endian byte_order, + bool unsigned_p) const + { + export_bits (buf, byte_order == BFD_ENDIAN_BIG ? 1 : -1 /* endian */, + unsigned_p, false /* safe */); + } /* Return a string containing VAL. */ std::string str () const { return gmp_string_printf ("%Zd", m_val); } @@ -337,10 +350,11 @@ struct gdb_mpz . -1 for least significant byte first; or . 0 for native endianness. - An error is raised if BUF is not large enough to contain the value - being exported. */ - void safe_export (gdb::array_view buf, - int endian, bool unsigned_p) const; + If SAFE is true, an error is raised if BUF is not large enough to + contain the value being exported. If SAFE is false, the value is + truncated to fit in BUF. */ + void export_bits (gdb::array_view buf, int endian, bool unsigned_p, + bool safe) const; friend struct gdb_mpq; friend struct gdb_mpf; @@ -590,9 +604,10 @@ gdb_mpz::as_integer () const { T result; - this->safe_export ({(gdb_byte *) &result, sizeof (result)}, + this->export_bits ({(gdb_byte *) &result, sizeof (result)}, 0 /* endian (0 = native) */, - !std::is_signed::value /* unsigned_p */); + !std::is_signed::value /* unsigned_p */, + true /* safe */); return result; } From patchwork Fri Mar 3 21:12:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 65991 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4ABFA3850213 for ; Fri, 3 Mar 2023 21:13:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4ABFA3850213 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677877999; bh=pIfCIpmRhMlYkZtHCS/LwU8atPRVVZhrHopXuTYHPIk=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=EkmCq5Y90/4Znj1K6gbpWRUh0AXUHBuFIlcz7y+yGgMWZ0DiY6TvyXyP/LWlEbkm3 As4hMamNa8jQ8ctVK3ItxmGgf9//RtybB96A2tDR5fe4KGqZJFoYxJ+/mvMRe+NJbm ObdgbccgIZJJm+lvxIiJ/hKu66ewiDRQRmlz1J54= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-il1-x135.google.com (mail-il1-x135.google.com [IPv6:2607:f8b0:4864:20::135]) by sourceware.org (Postfix) with ESMTPS id 11A2B3858C74 for ; Fri, 3 Mar 2023 21:12:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 11A2B3858C74 Received: by mail-il1-x135.google.com with SMTP id a1so2566045iln.9 for ; Fri, 03 Mar 2023 13:12:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677877941; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pIfCIpmRhMlYkZtHCS/LwU8atPRVVZhrHopXuTYHPIk=; b=zwx0dXS/vAlLGligsnlDzFieVQtF4h5jfLpJLR1Tap5xWeeZrWYm/Np+xfhvGobiuX 012nxEiPAgMqvWsXd/zRzN08xfROp1c4UwPu+P5mKSGHYyL5F/IiUX3TpHFYci8M6gub fimri1GfgeO7hPensduKqmApozwJSaj953bA8auY0Vfjcd4tN3qXGfIjRMat3nPYXOFu HaoDXcvkTFlweNpYJafoxOyFuAWjvQwc7cQpOB/uqLGgGPkdr+Ozgkes8HaRA+zBuVCY tL03Yn3PqHgx/hB6pj1BZBgIFWN84AvcBd/pWTUbyCWK34PhhITJ+AS0ytx7fJI+YGNS uPTw== X-Gm-Message-State: AO0yUKVGhRvmL7ekfKIIcgsoo1D2BYI2CAO3vGK1qFy4UUqFbDEY2xcZ XRXl5Zi5eXjAaAQxfF+hR1p3lIBZmPMQzqGzcw8= X-Google-Smtp-Source: AK7set/dPXHFbIm7poE0B5z429EQKPGzrHxznX0G/mcMmkOKpK11DtjKrne0lHCmjGrdWTKbDXLOXQ== X-Received: by 2002:a05:6e02:1bea:b0:316:f0d7:8cf with SMTP id y10-20020a056e021bea00b00316f0d708cfmr3013207ilv.5.1677877941210; Fri, 03 Mar 2023 13:12:21 -0800 (PST) Received: from localhost.localdomain (75-166-130-93.hlrn.qwest.net. [75.166.130.93]) by smtp.gmail.com with ESMTPSA id g8-20020a925208000000b00313b281ecd2sm867988ilb.70.2023.03.03.13.12.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Mar 2023 13:12:20 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 4/8] Add value_as_mpz and value_from_mpz Date: Fri, 3 Mar 2023 14:12:03 -0700 Message-Id: <20230303211207.1053037-5-tromey@adacore.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230303211207.1053037-1-tromey@adacore.com> References: <20230303211207.1053037-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This adds the two new functions, value_as_mpz and value_from_mpz, useful for manipulation values via gdb_mpz. --- gdb/value.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/value.h | 7 ++++ 2 files changed, 113 insertions(+) diff --git a/gdb/value.c b/gdb/value.c index e9afa89c243..19da9e1a00b 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -2551,6 +2551,76 @@ value_as_long (struct value *val) return unpack_long (val->type (), val->contents ().data ()); } +/* See value.h. */ + +gdb_mpz +value_as_mpz (struct value *val) +{ + val = coerce_array (val); + struct type *type = check_typedef (val->type ()); + + switch (type->code ()) + { + case TYPE_CODE_ENUM: + case TYPE_CODE_BOOL: + case TYPE_CODE_INT: + case TYPE_CODE_CHAR: + case TYPE_CODE_RANGE: + break; + + default: + return gdb_mpz (value_as_long (val)); + } + + gdb_mpz result; + + gdb::array_view valbytes = val->contents (); + enum bfd_endian byte_order = type_byte_order (type); + + /* Handle integers that are either not a multiple of the word size, + or that are stored at some bit offset. */ + unsigned bit_off = 0, bit_size = 0; + if (type->bit_size_differs_p ()) + { + bit_size = type->bit_size (); + if (bit_size == 0) + { + /* We can just handle this immediately. */ + return result; + } + + bit_off = type->bit_offset (); + + unsigned n_bytes = ((bit_off % 8) + bit_size + 7) / 8; + valbytes = valbytes.slice (bit_off / 8, n_bytes); + + if (byte_order == BFD_ENDIAN_BIG) + bit_off = (n_bytes * 8 - bit_off % 8 - bit_size); + else + bit_off %= 8; + } + + result.read (val->contents (), byte_order, type->is_unsigned ()); + + /* Shift off any low bits, if needed. */ + if (bit_off != 0) + result >>= bit_off; + + /* Mask off any high bits, if needed. */ + if (bit_size) + result.mask (bit_size); + + /* Now handle any range bias. */ + if (type->code () == TYPE_CODE_RANGE && type->bounds ()->bias != 0) + { + /* Unfortunately we have to box here, because LONGEST is + probably wider than long. */ + result += gdb_mpz (type->bounds ()->bias); + } + + return result; +} + /* Extract a value as a C pointer. Does not deallocate the value. Note that val's type may not actually be a pointer; value_as_long handles all the cases. */ @@ -3378,6 +3448,42 @@ value_from_ulongest (struct type *type, ULONGEST num) return val; } +/* See value.h. */ + +struct value * +value_from_mpz (struct type *type, const gdb_mpz &v) +{ + struct type *real_type = check_typedef (type); + + const gdb_mpz *val = &v; + gdb_mpz storage; + if (real_type->code () == TYPE_CODE_RANGE && type->bounds ()->bias != 0) + { + storage = *val; + val = &storage; + storage -= type->bounds ()->bias; + } + + if (type->bit_size_differs_p ()) + { + unsigned bit_off = type->bit_offset (); + unsigned bit_size = type->bit_size (); + + if (val != &storage) + { + storage = *val; + val = &storage; + } + + storage.mask ((ULONGEST) 1 << bit_size); + storage <<= bit_off; + } + + struct value *result = value::allocate (type); + val->truncate (result->contents_raw (), type_byte_order (type), + type->is_unsigned ()); + return result; +} /* Create a value representing a pointer of type TYPE to the address ADDR. */ diff --git a/gdb/value.h b/gdb/value.h index d83c4ab3674..1b4eff22f37 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -1029,6 +1029,11 @@ extern bool is_floating_value (struct value *val); extern LONGEST value_as_long (struct value *val); extern CORE_ADDR value_as_address (struct value *val); +/* Extract the value from VAL as a MPZ. This coerces arrays and + handles various integer-like types as well. */ + +extern gdb_mpz value_as_mpz (struct value *val); + extern LONGEST unpack_long (struct type *type, const gdb_byte *valaddr); extern CORE_ADDR unpack_pointer (struct type *type, const gdb_byte *valaddr); @@ -1075,6 +1080,8 @@ extern struct value *value_from_history_ref (const char *, const char **); extern struct value *value_from_component (struct value *, struct type *, LONGEST); +/* Convert the value V into a newly allocated value. */ +extern struct value *value_from_mpz (struct type *type, const gdb_mpz &v); extern struct value *value_at (struct type *type, CORE_ADDR addr); extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr); From patchwork Fri Mar 3 21:12:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 65992 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D1FFE3850873 for ; Fri, 3 Mar 2023 21:13:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D1FFE3850873 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677878000; bh=hdPdKIKHtW/e1I4kOgHdw3MhhJlkJd6t3vKTze3TPZY=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=tvdwOw4C6hE/1si4KddspU1sSxI04OSYjFNDsyQG8g3qFbuIm7RzSQMcKQmXCXDQN PyM8Z101Vo3sT1tL63ead3HBQhirckMW5l5CzDnlQmbpmiVjRAILY6jfgQo9NwaV19 7MeiFSu3cw6TTOYCtSkQAJOzMoA7LeeI2V675Lik= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-il1-x12a.google.com (mail-il1-x12a.google.com [IPv6:2607:f8b0:4864:20::12a]) by sourceware.org (Postfix) with ESMTPS id 933713858C33 for ; Fri, 3 Mar 2023 21:12:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 933713858C33 Received: by mail-il1-x12a.google.com with SMTP id i4so2594320ils.1 for ; Fri, 03 Mar 2023 13:12:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677877942; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hdPdKIKHtW/e1I4kOgHdw3MhhJlkJd6t3vKTze3TPZY=; b=3lwaeth0RSLDS7+UfBZ0JX31/z9rg2ITieg4EUARl+HRkyi2ICxM8W3QrHUqMonuY0 Pqq07a8KUeoP55C9M41e4Z9ylniQMNymONRex8ecwYHbVibWlJOHuwrUNIugZxEogmA6 Qt/bWTPLN/CIwqQGUiHZLUW7XIw8qVjj6Etv9+g2OckdEeGUC1mKJHVLjPwOcXaFFPAW RPcZyyy1+BvhrgDOGX27qoyKi0T+CMRtwk7GOy87GymLdMAc8b9qn4B9a+VSgRDtQNqh mP3CiaRy4WRKtYS10NEBYBK0yC+7ijk7yrcHIsld4x9iOhYY4ExQAAPCRzh4pr6LhYQz /t7Q== X-Gm-Message-State: AO0yUKWE5tNbVBk1uUrXRxsVyqS+lnBRQ5+rHGNpexSM/exAH1kQw6Rs QfuUIMC5QzVmBfPNUB0W/HNiLdjm+h66DH8MtJI= X-Google-Smtp-Source: AK7set84bMIzwmK9ZDNtxHohZ4vRWvUJxT8kbQECn5YSDNRlWb2eEFwaL7iCCg0NpmTqxQEB5r+2pw== X-Received: by 2002:a05:6e02:1b09:b0:315:34b8:4c6d with SMTP id i9-20020a056e021b0900b0031534b84c6dmr2684327ilv.17.1677877941852; Fri, 03 Mar 2023 13:12:21 -0800 (PST) Received: from localhost.localdomain (75-166-130-93.hlrn.qwest.net. [75.166.130.93]) by smtp.gmail.com with ESMTPSA id g8-20020a925208000000b00313b281ecd2sm867988ilb.70.2023.03.03.13.12.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Mar 2023 13:12:21 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 5/8] Simplify binop_promote Date: Fri, 3 Mar 2023 14:12:04 -0700 Message-Id: <20230303211207.1053037-6-tromey@adacore.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230303211207.1053037-1-tromey@adacore.com> References: <20230303211207.1053037-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" binop_promote currently only handles integer sizes up to builtin_long_long. However, this may not handle 128-bit types. Simplify this code, unify the C and non-C (but not OpenCL, as I don't know how to test this) cases, and handle 128-bit integers as well. This still doesn't exactly follow C or C++ rules. This could be implemented, but if so, I think it makes more sense as a C-specific expression node. --- gdb/eval.c | 55 +++++++++++++++++++----------------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/gdb/eval.c b/gdb/eval.c index f8bbb9ef766..6b362f46424 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -371,29 +371,6 @@ binop_promote (const struct language_defn *language, struct gdbarch *gdbarch, switch (language->la_language) { - case language_c: - case language_cplus: - case language_asm: - case language_objc: - if (result_len <= builtin->builtin_int->length ()) - { - promoted_type = (unsigned_operation - ? builtin->builtin_unsigned_int - : builtin->builtin_int); - } - else if (result_len <= builtin->builtin_long->length ()) - { - promoted_type = (unsigned_operation - ? builtin->builtin_unsigned_long - : builtin->builtin_long); - } - else - { - promoted_type = (unsigned_operation - ? builtin->builtin_unsigned_long_long - : builtin->builtin_long_long); - } - break; case language_opencl: if (result_len <= lookup_signed_typename (language, "int")->length()) @@ -413,23 +390,29 @@ binop_promote (const struct language_defn *language, struct gdbarch *gdbarch, } break; default: - /* For other languages the result type is unchanged from gdb - version 6.7 for backward compatibility. - If either arg was long long, make sure that value is also long - long. Otherwise use long. */ - if (unsigned_operation) + if (result_len <= builtin->builtin_int->length ()) { - if (result_len > gdbarch_long_bit (gdbarch) / HOST_CHAR_BIT) - promoted_type = builtin->builtin_unsigned_long_long; - else - promoted_type = builtin->builtin_unsigned_long; + promoted_type = (unsigned_operation + ? builtin->builtin_unsigned_int + : builtin->builtin_int); + } + else if (result_len <= builtin->builtin_long->length ()) + { + promoted_type = (unsigned_operation + ? builtin->builtin_unsigned_long + : builtin->builtin_long); + } + else if (result_len <= builtin->builtin_long_long->length ()) + { + promoted_type = (unsigned_operation + ? builtin->builtin_unsigned_long_long + : builtin->builtin_long_long); } else { - if (result_len > gdbarch_long_bit (gdbarch) / HOST_CHAR_BIT) - promoted_type = builtin->builtin_long_long; - else - promoted_type = builtin->builtin_long; + promoted_type = (unsigned_operation + ? builtin->builtin_uint128 + : builtin->builtin_int128); } break; } From patchwork Fri Mar 3 21:12:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 65996 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 427233857352 for ; Fri, 3 Mar 2023 21:13:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 427233857352 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677878033; bh=VJXWarPVQ4tHlAKNy5KeABWFRbptDOc272is+FrJb60=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=nn3zRV21lAZvcL06qSAHmgVUcALWlVl2tU0+yXezkW/9hNEHV8P7W3O/XAtwY3/pZ Zsr0By5vAmsBCyQYIsRDEsPwWHPOT6bUahVxPhK9TKf9GPLxvB/kbi6QhVCZ9gmtoj 1YG9R7Yf2KxrhCAC/sH/iHEID4mQ2KMP3KkOh9VI= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-io1-xd33.google.com (mail-io1-xd33.google.com [IPv6:2607:f8b0:4864:20::d33]) by sourceware.org (Postfix) with ESMTPS id 3AF5C3858408 for ; Fri, 3 Mar 2023 21:12:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3AF5C3858408 Received: by mail-io1-xd33.google.com with SMTP id bf15so1524086iob.7 for ; Fri, 03 Mar 2023 13:12:23 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677877942; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VJXWarPVQ4tHlAKNy5KeABWFRbptDOc272is+FrJb60=; b=4Cwe9/rKep/vFbEkM6Soxvs/W7TOp2Rz9Fdev79xrn8CzMdEw9jjhHM+TZ0QZpalXr 7tJcnb2qWiUlZk8NfCX9T8kY7VH9kBCGj6sMN3VQDWuvv6oQbumooVCsQWlYvX1Sh4Vv y6LhXgX9+Fs+dtW2xV0X4GNFII5UREyruZP9WBqWNVCgUp/LnHW6vXYQ1Vw4+LRk4vmG CWFx5nX4Jw4j4NfqRLYg39obWOsMEqIumiQktjbZ70Fm86L3AzCxUp7TOt9dTsQtDxlu k9q/iVJCiOj0/R30HRUb0L4c9EnjuHvWwDWLYLDSThEABi7mKF7EcYTQ8GmR3FgBBJ5i zoIA== X-Gm-Message-State: AO0yUKWpKhGAdcm7D7mzS6ulGXkqrMXn7m6QikL673zi329VdFzH2Gil Xb7a7UPRLTtLTSYHdmB/Jf2w7bECP1Z9P/X25cs= X-Google-Smtp-Source: AK7set8Y+xHYmZsNZ7Dc1kFt9Bw70liUyM+gbC3z4seiS7hIB7GGhIoo6eSF25ApUkuvB8aR9RujMQ== X-Received: by 2002:a05:6602:22c3:b0:74c:8013:867b with SMTP id e3-20020a05660222c300b0074c8013867bmr1961091ioe.15.1677877942437; Fri, 03 Mar 2023 13:12:22 -0800 (PST) Received: from localhost.localdomain (75-166-130-93.hlrn.qwest.net. [75.166.130.93]) by smtp.gmail.com with ESMTPSA id g8-20020a925208000000b00313b281ecd2sm867988ilb.70.2023.03.03.13.12.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Mar 2023 13:12:22 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 6/8] Use value_true in value_equal and value_less Date: Fri, 3 Mar 2023 14:12:05 -0700 Message-Id: <20230303211207.1053037-7-tromey@adacore.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230303211207.1053037-1-tromey@adacore.com> References: <20230303211207.1053037-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Both value_equal and value_less use value_as_long to check a presumably boolean result of calling value_binop. However, value_binop in this case actually returns an int as wide as its arguments, and this approach can then fail for integers wider than LONGEST. Instead, rewrite this in a form that works for any size integer. --- gdb/valarith.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gdb/valarith.c b/gdb/valarith.c index 9d681dc9d97..99597bef695 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -1761,8 +1761,7 @@ value_equal (struct value *arg1, struct value *arg2) is_int2 = is_integral_type (type2); if (is_int1 && is_int2) - return longest_to_int (value_as_long (value_binop (arg1, arg2, - BINOP_EQUAL))); + return value_true (value_binop (arg1, arg2, BINOP_EQUAL)); else if ((is_floating_value (arg1) || is_int1) && (is_floating_value (arg2) || is_int2)) { @@ -1849,8 +1848,7 @@ value_less (struct value *arg1, struct value *arg2) if ((is_int1 && is_int2) || (is_fixed_point_type (type1) && is_fixed_point_type (type2))) - return longest_to_int (value_as_long (value_binop (arg1, arg2, - BINOP_LESS))); + return value_true (value_binop (arg1, arg2, BINOP_LESS)); else if ((is_floating_value (arg1) || is_int1) && (is_floating_value (arg2) || is_int2)) { From patchwork Fri Mar 3 21:12:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 65993 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 216E9385022B for ; Fri, 3 Mar 2023 21:13:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 216E9385022B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677878002; bh=+WBDTYiyJHcKpDYkgTxVQQhRAYR81QKXYzBS5+5Yrvg=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=AcjkbIBLDf5AbXMwG3rAbn/uE7V1I2gUlu4/tfpns7575XONhWjIT87URAIC1DtEu 26618HwNngFDB0+Y5dhrFX5Xq6/sY2KfNpebSyFYJgQSD3MYyiX3Zm0by2gfb2WuNv PakSB6v4ah5vrfvmH9XZua/FLvKd6QA2mnvxEK8c= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-il1-x12e.google.com (mail-il1-x12e.google.com [IPv6:2607:f8b0:4864:20::12e]) by sourceware.org (Postfix) with ESMTPS id 35DCC3858288 for ; Fri, 3 Mar 2023 21:12:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 35DCC3858288 Received: by mail-il1-x12e.google.com with SMTP id z5so2622919ilq.0 for ; Fri, 03 Mar 2023 13:12:24 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677877943; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+WBDTYiyJHcKpDYkgTxVQQhRAYR81QKXYzBS5+5Yrvg=; b=wvGP0XWv88geCVnQyMk7kgni49TLq/irO1y4HlWWIKVj+X49StTzew1Eqvr8H2oZIu QdzSQot5lyTEZ52K8xXXZvzFF1NjCgHS8BxxpX8xuYZ/MRULjW9fsXc+pcgHeSZKwnId Bw3cgiru2UYrs785VIk8SdJuzhMozh4kGS108edxvMj5+HWE1OY3RoSoaZWHwy1dbkEh 8cl2fGO8jKBhYyPtqcOYrzcJRUgponPG742UevtIQV1HsxCoW3VdFgihjrfqvnv5m3Pn sALGNzSnUbWeAwqb5bmCQHRtL0EnsvSfO+tih1xtaysh24MCvYdehPFmg9HDXpsILToy vFWg== X-Gm-Message-State: AO0yUKXqe7Y5KHyDXJpICt//d6JELzovKBAb9hqKeHgfuVPDxDTyCtd+ sRHAipL5O0+VNBclMcK3udDk/kH7JIrdaaXbzYo= X-Google-Smtp-Source: AK7set/Nij1GUQJOKSzGv5u+EkAiLY+LZsltpQxkumJeCzphuzuLtYC0dlIzsQVlcPpi7XV5FpqPzw== X-Received: by 2002:a05:6e02:2193:b0:316:e033:86ba with SMTP id j19-20020a056e02219300b00316e03386bamr2940072ila.31.1677877943093; Fri, 03 Mar 2023 13:12:23 -0800 (PST) Received: from localhost.localdomain (75-166-130-93.hlrn.qwest.net. [75.166.130.93]) by smtp.gmail.com with ESMTPSA id g8-20020a925208000000b00313b281ecd2sm867988ilb.70.2023.03.03.13.12.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Mar 2023 13:12:22 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 7/8] Use gdb_gmp for scalar arithmetic Date: Fri, 3 Mar 2023 14:12:06 -0700 Message-Id: <20230303211207.1053037-8-tromey@adacore.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230303211207.1053037-1-tromey@adacore.com> References: <20230303211207.1053037-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_LOTSOFHASH, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This changes gdb to use scalar arithmetic for expression evaluation. I suspect this patch is not truly complete, as there may be code paths that still don't correctly handle 128-bit integers. However, many things do work now. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30190 --- gdb/testsuite/gdb.rust/onetwoeight.exp | 65 ++++ gdb/testsuite/gdb.rust/onetwoeight.rs | 31 ++ gdb/utils.c | 30 -- gdb/utils.h | 7 - gdb/valarith.c | 489 ++++++++----------------- gdb/valops.c | 14 +- 6 files changed, 253 insertions(+), 383 deletions(-) create mode 100644 gdb/testsuite/gdb.rust/onetwoeight.exp create mode 100644 gdb/testsuite/gdb.rust/onetwoeight.rs diff --git a/gdb/testsuite/gdb.rust/onetwoeight.exp b/gdb/testsuite/gdb.rust/onetwoeight.exp new file mode 100644 index 00000000000..317c848a899 --- /dev/null +++ b/gdb/testsuite/gdb.rust/onetwoeight.exp @@ -0,0 +1,65 @@ +# Copyright (C) 2023 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Test expression parsing and evaluation that requires Rust compiler. + +load_lib rust-support.exp +require allow_rust_tests + +set v [split [rust_compiler_version] .] +if {[lindex $v 0] == 1 && [lindex $v 1] < 43} { + untested "128-bit ints require rust 1.43 or greater" + return -1 +} + +standard_testfile .rs +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug rust}]} { + return -1 +} + +set line [gdb_get_line_number "BREAK"] +if {![runto ${srcfile}:$line]} { + untested "could not run to breakpoint" + return -1 +} + +gdb_test "print x" " = 340282366920938463463374607431768211455" +gdb_test "print y" " = 170141183460469231731687303715884105727" + +gdb_test "print x / 2" " = 170141183460469231731687303715884105727" +gdb_test "print sm * 2" " = 170141183460469231731687303715884105726" +gdb_test "print sm + sm" " = 170141183460469231731687303715884105726" +gdb_test "print x - y" " = 170141183460469231731687303715884105728" +gdb_test "print -y" " = -170141183460469231731687303715884105727" +gdb_test "print +y" " = 170141183460469231731687303715884105727" + +gdb_test "print/x x" " = 0xffffffffffffffffffffffffffffffff" +gdb_test "print x % 4" " = 3" +gdb_test "print !x" " = 0" + +gdb_test "print x < 0" " = false" +gdb_test "print -y < 0" " = true" +gdb_test "print x > y" " = true" +gdb_test "print y >= y" " = true" +gdb_test "print y <= y" " = true" +gdb_test "print y == y" " = true" +gdb_test "print x != y" " = true" + +gdb_test "print sm << 2" "= 340282366920938463463374607431768211452" +gdb_test "print x >> 2" "= 85070591730234615865843651857942052863" + +gdb_test "print/x x & mask" " = 0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0" +gdb_test "print/x x ^ mask" " = 0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f" +gdb_test "print/x mask | (mask >> 4)" " = 0xffffffffffffffffffffffffffffffff" diff --git a/gdb/testsuite/gdb.rust/onetwoeight.rs b/gdb/testsuite/gdb.rust/onetwoeight.rs new file mode 100644 index 00000000000..aa8cb1cf7b1 --- /dev/null +++ b/gdb/testsuite/gdb.rust/onetwoeight.rs @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Free Software Foundation, Inc. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_assignments)] + + +fn empty() { +} + +fn main () { + let x : u128 = 340_282_366_920_938_463_463_374_607_431_768_211_455; + let sm : u128 = x /4; + let y : i128 = 170_141_183_460_469_231_731_687_303_715_884_105_727; + let mask : u128 = 0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0; + + empty(); // BREAK +} diff --git a/gdb/utils.c b/gdb/utils.c index 0138c8e9fb6..9ca83246b24 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -723,36 +723,6 @@ myread (int desc, char *addr, int len) return orglen; } -/* See utils.h. */ - -ULONGEST -uinteger_pow (ULONGEST v1, LONGEST v2) -{ - if (v2 < 0) - { - if (v1 == 0) - error (_("Attempt to raise 0 to negative power.")); - else - return 0; - } - else - { - /* The Russian Peasant's Algorithm. */ - ULONGEST v; - - v = 1; - for (;;) - { - if (v2 & 1L) - v *= v1; - v2 >>= 1; - if (v2 == 0) - return v; - v1 *= v1; - } - } -} - /* An RAII class that sets up to handle input and then tears down diff --git a/gdb/utils.h b/gdb/utils.h index 6e240deccbf..a383036bcfe 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -303,13 +303,6 @@ extern pid_t wait_to_die_with_timeout (pid_t pid, int *status, int timeout); extern int myread (int, char *, int); -/* Integer exponentiation: Return V1**V2, where both arguments - are integers. - - Requires V1 != 0 if V2 < 0. - Returns 1 for 0 ** 0. */ -extern ULONGEST uinteger_pow (ULONGEST v1, LONGEST v2); - /* Resource limits used by getrlimit and setrlimit. */ enum resource_limit_kind diff --git a/gdb/valarith.c b/gdb/valarith.c index 99597bef695..a8ae17e1730 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -34,13 +34,6 @@ static struct value *value_subscripted_rvalue (struct value *array, LONGEST index, LONGEST lowerbound); -/* Define whether or not the C operator '/' truncates towards zero for - differently signed operands (truncation direction is undefined in C). */ - -#ifndef TRUNCATION_TOWARDS_ZERO -#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2) -#endif - /* Given a pointer, return the size of its target. If the pointer type is void *, then return 1. If the target type is incomplete, then error out. @@ -726,36 +719,6 @@ value_concat (struct value *arg1, struct value *arg2) return result; } -/* Integer exponentiation: V1**V2, where both arguments are - integers. Requires V1 != 0 if V2 < 0. Returns 1 for 0 ** 0. */ - -static LONGEST -integer_pow (LONGEST v1, LONGEST v2) -{ - if (v2 < 0) - { - if (v1 == 0) - error (_("Attempt to raise 0 to negative power.")); - else - return 0; - } - else - { - /* The Russian Peasant's Algorithm. */ - LONGEST v; - - v = 1; - for (;;) - { - if (v2 & 1L) - v *= v1; - v2 >>= 1; - if (v2 == 0) - return v; - v1 *= v1; - } - } -} /* Obtain argument values for binary operation, converting from other types if one of them is not floating point. */ @@ -1099,33 +1062,39 @@ type_length_bits (type *type) both negative and too-large shift amounts, which are undefined, and would crash a GDB built with UBSan. Depending on the current language, if the shift is not valid, this either warns and returns - false, or errors out. Returns true if valid. */ + false, or errors out. Returns true and sets NBITS if valid. */ static bool check_valid_shift_count (enum exp_opcode op, type *result_type, - type *shift_count_type, ULONGEST shift_count) + type *shift_count_type, const gdb_mpz &shift_count, + unsigned long &nbits) { - if (!shift_count_type->is_unsigned () && (LONGEST) shift_count < 0) + if (!shift_count_type->is_unsigned ()) { - auto error_or_warning = [] (const char *msg) - { - /* Shifts by a negative amount are always an error in Go. Other - languages are more permissive and their compilers just warn or - have modes to disable the errors. */ - if (current_language->la_language == language_go) - error (("%s"), msg); - else - warning (("%s"), msg); - }; + LONGEST count = shift_count.as_integer (); + if (count < 0) + { + auto error_or_warning = [] (const char *msg) + { + /* Shifts by a negative amount are always an error in Go. Other + languages are more permissive and their compilers just warn or + have modes to disable the errors. */ + if (current_language->la_language == language_go) + error (("%s"), msg); + else + warning (("%s"), msg); + }; - if (op == BINOP_RSH) - error_or_warning (_("right shift count is negative")); - else - error_or_warning (_("left shift count is negative")); - return false; + if (op == BINOP_RSH) + error_or_warning (_("right shift count is negative")); + else + error_or_warning (_("left shift count is negative")); + return false; + } } - if (shift_count >= type_length_bits (result_type)) + nbits = shift_count.as_integer (); + if (nbits >= type_length_bits (result_type)) { /* In Go, shifting by large amounts is defined. Be silent and still return false, as the caller's error path does the right @@ -1249,299 +1218,135 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) else result_type = promotion_type (type1, type2); - if (result_type->is_unsigned ()) + gdb_mpz v1 = value_as_mpz (arg1); + gdb_mpz v2 = value_as_mpz (arg2); + gdb_mpz v; + + switch (op) { - LONGEST v2_signed = value_as_long (arg2); - ULONGEST v1, v2, v = 0; + case BINOP_ADD: + v = v1 + v2; + break; - v1 = (ULONGEST) value_as_long (arg1); - v2 = (ULONGEST) v2_signed; + case BINOP_SUB: + v = v1 - v2; + break; - switch (op) - { - case BINOP_ADD: - v = v1 + v2; - break; - - case BINOP_SUB: - v = v1 - v2; - break; - - case BINOP_MUL: - v = v1 * v2; - break; - - case BINOP_DIV: - case BINOP_INTDIV: - if (v2 != 0) - v = v1 / v2; - else - error (_("Division by zero")); - break; - - case BINOP_EXP: - v = uinteger_pow (v1, v2_signed); - break; - - case BINOP_REM: - if (v2 != 0) - v = v1 % v2; - else - error (_("Division by zero")); - break; - - case BINOP_MOD: - /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, - v1 mod 0 has a defined value, v1. */ - if (v2 == 0) - { - v = v1; - } - else - { - v = v1 / v2; - /* Note floor(v1/v2) == v1/v2 for unsigned. */ - v = v1 - (v2 * v); - } - break; - - case BINOP_LSH: - if (!check_valid_shift_count (op, result_type, type2, v2)) - v = 0; - else - v = v1 << v2; - break; - - case BINOP_RSH: - if (!check_valid_shift_count (op, result_type, type2, v2)) - v = 0; - else - v = v1 >> v2; - break; - - case BINOP_BITWISE_AND: - v = v1 & v2; - break; - - case BINOP_BITWISE_IOR: - v = v1 | v2; - break; - - case BINOP_BITWISE_XOR: - v = v1 ^ v2; - break; - - case BINOP_LOGICAL_AND: - v = v1 && v2; - break; - - case BINOP_LOGICAL_OR: - v = v1 || v2; - break; - - case BINOP_MIN: - v = v1 < v2 ? v1 : v2; - break; - - case BINOP_MAX: - v = v1 > v2 ? v1 : v2; - break; - - case BINOP_EQUAL: - v = v1 == v2; - break; - - case BINOP_NOTEQUAL: - v = v1 != v2; - break; - - case BINOP_LESS: - v = v1 < v2; - break; - - case BINOP_GTR: - v = v1 > v2; - break; - - case BINOP_LEQ: - v = v1 <= v2; - break; - - case BINOP_GEQ: - v = v1 >= v2; - break; - - default: - error (_("Invalid binary operation on numbers.")); - } + case BINOP_MUL: + v = v1 * v2; + break; - val = value::allocate (result_type); - store_unsigned_integer (val->contents_raw ().data (), - val->type ()->length (), - type_byte_order (result_type), - v); - } - else - { - LONGEST v1, v2, v = 0; + case BINOP_DIV: + case BINOP_INTDIV: + if (v2.sgn () != 0) + v = v1 / v2; + else + error (_("Division by zero")); + break; - v1 = value_as_long (arg1); - v2 = value_as_long (arg2); + case BINOP_EXP: + v = v1.pow (v2.as_integer ()); + break; + + case BINOP_REM: + if (v2.sgn () != 0) + v = v1 % v2; + else + error (_("Division by zero")); + break; - switch (op) + case BINOP_MOD: + /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, + v1 mod 0 has a defined value, v1. */ + if (v2.sgn () == 0) + { + v = v1; + } + else { - case BINOP_ADD: - v = v1 + v2; - break; - - case BINOP_SUB: - /* Avoid runtime error: signed integer overflow: \ - 0 - -9223372036854775808 cannot be represented in type - 'long int'. */ - v = (ULONGEST)v1 - (ULONGEST)v2; - break; - - case BINOP_MUL: - v = v1 * v2; - break; - - case BINOP_DIV: - case BINOP_INTDIV: - if (v2 != 0) - v = v1 / v2; - else - error (_("Division by zero")); - break; - - case BINOP_EXP: - v = integer_pow (v1, v2); - break; - - case BINOP_REM: - if (v2 != 0) - v = v1 % v2; - else - error (_("Division by zero")); - break; - - case BINOP_MOD: - /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, - X mod 0 has a defined value, X. */ - if (v2 == 0) - { - v = v1; - } - else - { - v = v1 / v2; - /* Compute floor. */ - if (TRUNCATION_TOWARDS_ZERO && (v < 0) && ((v1 % v2) != 0)) - { - v--; - } - v = v1 - (v2 * v); - } - break; - - case BINOP_LSH: - if (!check_valid_shift_count (op, result_type, type2, v2)) - v = 0; - else - { - /* Cast to unsigned to avoid undefined behavior on - signed shift overflow (unless C++20 or later), - which would crash GDB when built with UBSan. - Note we don't warn on left signed shift overflow, - because starting with C++20, that is actually - defined behavior. Also, note GDB assumes 2's - complement throughout. */ - v = (ULONGEST) v1 << v2; - } - break; - - case BINOP_RSH: - if (!check_valid_shift_count (op, result_type, type2, v2)) - { - /* Pretend the too-large shift was decomposed in a - number of smaller shifts. An arithmetic signed - right shift of a negative number always yields -1 - with such semantics. This is the right thing to - do for Go, and we might as well do it for - languages where it is undefined. Also, pretend a - shift by a negative number was a shift by the - negative number cast to unsigned, which is the - same as shifting by a too-large number. */ - if (v1 < 0) - v = -1; - else - v = 0; - } - else - v = v1 >> v2; - break; - - case BINOP_BITWISE_AND: - v = v1 & v2; - break; - - case BINOP_BITWISE_IOR: - v = v1 | v2; - break; - - case BINOP_BITWISE_XOR: - v = v1 ^ v2; - break; - - case BINOP_LOGICAL_AND: - v = v1 && v2; - break; - - case BINOP_LOGICAL_OR: - v = v1 || v2; - break; - - case BINOP_MIN: - v = v1 < v2 ? v1 : v2; - break; - - case BINOP_MAX: - v = v1 > v2 ? v1 : v2; - break; - - case BINOP_EQUAL: - v = v1 == v2; - break; - - case BINOP_NOTEQUAL: - v = v1 != v2; - break; - - case BINOP_LESS: - v = v1 < v2; - break; - - case BINOP_GTR: - v = v1 > v2; - break; - - case BINOP_LEQ: - v = v1 <= v2; - break; - - case BINOP_GEQ: - v = v1 >= v2; - break; - - default: - error (_("Invalid binary operation on numbers.")); + v = v1 / v2; + /* Note floor(v1/v2) == v1/v2 for unsigned. */ + v = v1 - (v2 * v); } + break; - val = value::allocate (result_type); - store_signed_integer (val->contents_raw ().data (), - val->type ()->length (), - type_byte_order (result_type), - v); + case BINOP_LSH: + { + unsigned long nbits; + if (!check_valid_shift_count (op, result_type, type2, v2, nbits)) + v = 0; + else + v = v1 << nbits; + } + break; + + case BINOP_RSH: + { + unsigned long nbits; + if (!check_valid_shift_count (op, result_type, type2, v2, nbits)) + v = 0; + else + v = v1 >> nbits; + } + break; + + case BINOP_BITWISE_AND: + v = v1 & v2; + break; + + case BINOP_BITWISE_IOR: + v = v1 | v2; + break; + + case BINOP_BITWISE_XOR: + v = v1 ^ v2; + break; + + case BINOP_LOGICAL_AND: + v = v1 && v2; + break; + + case BINOP_LOGICAL_OR: + v = v1 || v2; + break; + + case BINOP_MIN: + v = v1 < v2 ? v1 : v2; + break; + + case BINOP_MAX: + v = v1 > v2 ? v1 : v2; + break; + + case BINOP_EQUAL: + v = v1 == v2; + break; + + case BINOP_NOTEQUAL: + v = v1 != v2; + break; + + case BINOP_LESS: + v = v1 < v2; + break; + + case BINOP_GTR: + v = v1 > v2; + break; + + case BINOP_LEQ: + v = v1 <= v2; + break; + + case BINOP_GEQ: + v = v1 >= v2; + break; + + default: + error (_("Invalid binary operation on numbers.")); } + + val = value_from_mpz (result_type, v); } return val; @@ -1960,7 +1765,11 @@ value_complement (struct value *arg1) type = check_typedef (arg1->type ()); if (is_integral_type (type)) - val = value_from_longest (type, ~value_as_long (arg1)); + { + gdb_mpz num = value_as_mpz (arg1); + num.complement (); + val = value_from_mpz (type, num); + } else if (type->code () == TYPE_CODE_ARRAY && type->is_vector ()) { struct type *eltype = check_typedef (type->target_type ()); diff --git a/gdb/valops.c b/gdb/valops.c index 2cef24fc4c5..f06969e92e6 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -569,7 +569,7 @@ value_cast (struct type *type, struct value *arg2) && (scalar || code2 == TYPE_CODE_PTR || code2 == TYPE_CODE_MEMBERPTR)) { - LONGEST longest; + gdb_mpz longest; /* When we cast pointers to integers, we mustn't use gdbarch_pointer_to_address to find the address the pointer @@ -578,12 +578,14 @@ value_cast (struct type *type, struct value *arg2) sees a cast as a simple reinterpretation of the pointer's bits. */ if (code2 == TYPE_CODE_PTR) - longest = extract_unsigned_integer - (arg2->contents (), type_byte_order (type2)); + longest = extract_unsigned_integer (arg2->contents (), + type_byte_order (type2)); else - longest = value_as_long (arg2); - return value_from_longest (to_type, convert_to_boolean ? - (LONGEST) (longest ? 1 : 0) : longest); + longest = value_as_mpz (arg2); + if (convert_to_boolean) + longest = bool (longest); + + return value_from_mpz (to_type, longest); } else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_ENUM From patchwork Fri Mar 3 21:12:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 65995 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 579FE3850209 for ; Fri, 3 Mar 2023 21:13:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 579FE3850209 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677878031; bh=vL+T5FWqkcH25sIygTO+71lGG6uEEhxg7B5ls2Dbu/c=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=TQMc43nY3TqDNqYUbG9nXvbxRKrymm95gl+MfAXYY4SZQgZiIMNtcbcl9wkQOyjaM jsBgynPElv/IFmzNTAox4sFmb6YLpUM1OWzARYy+ZAc7+8j5Gqxtg7gDQ0MuQSlb06 o5pVI7rs9DNjIo09Bm8JZ/NMjhHbWE8Ujs0lM3ls= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-il1-x12f.google.com (mail-il1-x12f.google.com [IPv6:2607:f8b0:4864:20::12f]) by sourceware.org (Postfix) with ESMTPS id 95DD938582A1 for ; Fri, 3 Mar 2023 21:12:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 95DD938582A1 Received: by mail-il1-x12f.google.com with SMTP id z5so2622926ilq.0 for ; Fri, 03 Mar 2023 13:12:24 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677877944; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vL+T5FWqkcH25sIygTO+71lGG6uEEhxg7B5ls2Dbu/c=; b=Slb8Nih4Q7AKOBA5z/NtZpf+3o+f1QF7T60bm/82pP+wxOv+J1mCw2oOjGorpK503V BxdAr2FdFQJIF/2cWOuDH05wdQIsmaoN0gT1BwUxHrMmrGDNmjn8ps0IFqfybr3KHgRf 0f3poHinYNHIw6IO5wIUaXDCFcXvOVkeo2kYd63vJw/aBNpmEHNeSn6eY8AKzWM+IXtN o//sWBcLXMaM8jBXWUjHZQxneq0XIRZUfvcQqasfj/hTTAdJndRe8pKoqAyoqgY5LHBe UEBhO1Mx2XVqyaqoQofCwnRz/JdK4J9P5MIWc2Ew1Ic5BWiV2vTjl8eOgQzXAFW15Gnz jV9Q== X-Gm-Message-State: AO0yUKV5XN9YzH6S9UEVCgHozq5XLf+K9knvsIeUJC3DfMDiSPrMFfdY Q+xzXgmSwhK/vs6Z/KFxPvmjV4lwq2kxlzbwuhU= X-Google-Smtp-Source: AK7set8oWBuzHtjE/mVN68Ib9SI4RFWd6Q/Fi9a+IP1YvBU5Q0RrvVhx8JZgUogITODimUs433+P/g== X-Received: by 2002:a05:6e02:12cf:b0:317:c80f:b405 with SMTP id i15-20020a056e0212cf00b00317c80fb405mr2758272ilm.15.1677877943742; Fri, 03 Mar 2023 13:12:23 -0800 (PST) Received: from localhost.localdomain (75-166-130-93.hlrn.qwest.net. [75.166.130.93]) by smtp.gmail.com with ESMTPSA id g8-20020a925208000000b00313b281ecd2sm867988ilb.70.2023.03.03.13.12.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Mar 2023 13:12:23 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 8/8] Fix 128-bit integer bug in Ada Date: Fri, 3 Mar 2023 14:12:07 -0700 Message-Id: <20230303211207.1053037-9-tromey@adacore.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230303211207.1053037-1-tromey@adacore.com> References: <20230303211207.1053037-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" While working on 128-bit integer support, I found one spot in Ada that needed a fix as well. --- gdb/ada-lang.c | 27 ++++-------------- gdb/testsuite/gdb.ada/verylong.exp | 37 +++++++++++++++++++++++++ gdb/testsuite/gdb.ada/verylong/prog.adb | 20 +++++++++++++ 3 files changed, 63 insertions(+), 21 deletions(-) create mode 100644 gdb/testsuite/gdb.ada/verylong.exp create mode 100644 gdb/testsuite/gdb.ada/verylong/prog.adb diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 7b07c4f9473..d1afb1a27b1 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -62,14 +62,6 @@ #include "charset.h" #include "ax-gdb.h" -/* Define whether or not the C operator '/' truncates towards zero for - differently signed operands (truncation direction is undefined in C). - Copied from valarith.c. */ - -#ifndef TRUNCATION_TOWARDS_ZERO -#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2) -#endif - static struct type *desc_base_type (struct type *); static struct type *desc_bounds_type (struct type *); @@ -9351,9 +9343,7 @@ coerce_for_assign (struct type *type, struct value *val) static struct value * ada_value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) { - struct value *val; struct type *type1, *type2; - LONGEST v, v1, v2; arg1 = coerce_ref (arg1); arg2 = coerce_ref (arg2); @@ -9374,8 +9364,8 @@ ada_value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) return value_binop (arg1, arg2, op); } - v2 = value_as_long (arg2); - if (v2 == 0) + gdb_mpz v2 = value_as_mpz (arg2); + if (v2.sgn () == 0) { const char *name; if (op == BINOP_MOD) @@ -9394,13 +9384,12 @@ ada_value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) if (type1->is_unsigned () || op == BINOP_MOD) return value_binop (arg1, arg2, op); - v1 = value_as_long (arg1); + gdb_mpz v1 = value_as_mpz (arg1); + gdb_mpz v; switch (op) { case BINOP_DIV: v = v1 / v2; - if (!TRUNCATION_TOWARDS_ZERO && v1 * (v1 % v2) < 0) - v += v > 0 ? -1 : 1; break; case BINOP_REM: v = v1 % v2; @@ -9409,14 +9398,10 @@ ada_value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) break; default: /* Should not reach this point. */ - v = 0; + gdb_assert_not_reached ("invalid operator"); } - val = value::allocate (type1); - store_unsigned_integer (val->contents_raw ().data (), - val->type ()->length (), - type_byte_order (type1), v); - return val; + return value_from_mpz (type1, v); } static int diff --git a/gdb/testsuite/gdb.ada/verylong.exp b/gdb/testsuite/gdb.ada/verylong.exp new file mode 100644 index 00000000000..93df785862b --- /dev/null +++ b/gdb/testsuite/gdb.ada/verylong.exp @@ -0,0 +1,37 @@ +# Copyright 2023 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile prog + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} { + return -1 +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "START" ${testdir}/prog.adb] +runto "prog.adb:$bp_location" + +gdb_test "print x" " = 170141183460469231731687303715884105727" +gdb_test "print x / 2" " = 85070591730234615865843651857942052863" +gdb_test "print (x / 4) * 2" " = 85070591730234615865843651857942052862" +gdb_test "print x - x" " = 0" +gdb_test "print x - 99 + 1" " = 170141183460469231731687303715884105629" +gdb_test "print -x" " = -170141183460469231731687303715884105727" +gdb_test "print +x" " = 170141183460469231731687303715884105727" diff --git a/gdb/testsuite/gdb.ada/verylong/prog.adb b/gdb/testsuite/gdb.ada/verylong/prog.adb new file mode 100644 index 00000000000..766419d0a4f --- /dev/null +++ b/gdb/testsuite/gdb.ada/verylong/prog.adb @@ -0,0 +1,20 @@ +-- Copyright 2023 Free Software Foundation, Inc. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +procedure Main is + X : Long_Long_Long_Integer := Long_Long_Long_Integer'Last; +begin + null; -- START +end Main;