All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: kvm@vger.kernel.org
Cc: Alexandru Elisei <alexandru.elisei@arm.com>
Subject: [PATCH v2 kvm-unit-tests 1/2] libcflat: clean up and complete long division routines
Date: Wed, 12 May 2021 12:54:39 +0200	[thread overview]
Message-ID: <20210512105440.748153-2-pbonzini@redhat.com> (raw)
In-Reply-To: <20210512105440.748153-1-pbonzini@redhat.com>

Avoid possible uninitialized variables on machines where
division by zero does not trap.  Add __divmoddi4, and
use it in __moddi3 and __divdi3.

Reported-by: Alexandru Elisei <alexandru.elisei@arm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 lib/ldiv32.c | 40 ++++++++++++++++++++++++----------------
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/lib/ldiv32.c b/lib/ldiv32.c
index 96f4b35..897a4b9 100644
--- a/lib/ldiv32.c
+++ b/lib/ldiv32.c
@@ -1,6 +1,7 @@
 #include <stdint.h>
 
 extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *p_rem);
+extern int64_t __divmoddi4(int64_t num, int64_t den, int64_t *p_rem);
 extern int64_t __moddi3(int64_t num, int64_t den);
 extern int64_t __divdi3(int64_t num, int64_t den);
 extern uint64_t __udivdi3(uint64_t num, uint64_t den);
@@ -11,8 +12,11 @@ uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *p_rem)
 	uint64_t quot = 0;
 
 	/* Trigger a division by zero at run time (trick taken from iPXE).  */
-	if (den == 0)
+	if (den == 0) {
+		if (p_rem)
+			*p_rem = 0;
 		return 1/((unsigned)den);
+	}
 
 	if (num >= den) {
 		/* Align den to num to avoid wasting time on leftmost zero bits.  */
@@ -35,31 +39,35 @@ uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *p_rem)
 	return quot;
 }
 
-int64_t __moddi3(int64_t num, int64_t den)
+int64_t __divmoddi4(int64_t num, int64_t den, int64_t *p_rem)
 {
-	uint64_t mask = num < 0 ? -1 : 0;
+	int32_t nmask = num < 0 ? -1 : 0;
+	int32_t qmask = (num ^ den) < 0 ? -1 : 0;
+	uint64_t quot;
 
 	/* Compute absolute values and do an unsigned division.  */
-	num = (num + mask) ^ mask;
+	num = (num + nmask) ^ nmask;
 	if (den < 0)
 		den = -den;
 
-	/* Copy sign of num into result.  */
-	return (__umoddi3(num, den) + mask) ^ mask;
+	/* Copy sign of num^den into quotient, sign of num into remainder.  */
+	quot = (__udivmoddi4(num, den, (uint64_t *)p_rem) + qmask) ^ qmask;
+	if (p_rem)
+		*p_rem = (*p_rem + nmask) ^ nmask;
+	return quot;
 }
 
-int64_t __divdi3(int64_t num, int64_t den)
+int64_t __moddi3(int64_t num, int64_t den)
 {
-	uint64_t mask = (num ^ den) < 0 ? -1 : 0;
-
-	/* Compute absolute values and do an unsigned division.  */
-	if (num < 0)
-		num = -num;
-	if (den < 0)
-		den = -den;
+	int64_t rem;
+	__divmoddi4(num, den, &rem);
+	return rem;
+}
 
-	/* Copy sign of num^den into result.  */
-	return (__udivdi3(num, den) + mask) ^ mask;
+int64_t __divdi3(int64_t num, int64_t den)
+{
+	int64_t rem;
+	return __divmoddi4(num, den, &rem);
 }
 
 uint64_t __udivdi3(uint64_t num, uint64_t den)
-- 
2.31.1



  reply	other threads:[~2021-05-12 10:54 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-12 10:54 [PATCH v2 kvm-unit-tests 0/2] fix long division routines for ARM eabi Paolo Bonzini
2021-05-12 10:54 ` Paolo Bonzini [this message]
2021-05-12 13:44   ` [PATCH v2 kvm-unit-tests 1/2] libcflat: clean up and complete long division routines Alexandru Elisei
2021-05-12 10:54 ` [PATCH v2 kvm-unit-tests 2/2] arm: add eabi version of 64-bit division functions Paolo Bonzini
2021-05-12 13:44   ` Alexandru Elisei
2021-05-12 13:51     ` Paolo Bonzini
2021-05-12 14:04       ` Alexandru Elisei
2021-05-12 14:04 ` [PATCH v2 kvm-unit-tests 0/2] fix long division routines for ARM eabi Alexandru Elisei

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210512105440.748153-2-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=alexandru.elisei@arm.com \
    --cc=kvm@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.