All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexandru Elisei <alexandru.elisei@arm.com>
To: Paolo Bonzini <pbonzini@redhat.com>, kvm@vger.kernel.org
Subject: Re: [PATCH kvm-unit-tests 1/2] libcflat: clean up and complete long division routines
Date: Wed, 12 May 2021 11:39:07 +0100	[thread overview]
Message-ID: <3255ae16-ee2d-861d-d7e8-9360e7eaa09c@arm.com> (raw)
In-Reply-To: <20210511174106.703235-2-pbonzini@redhat.com>

Hi Paolo,

Thanks for sending this so quickly!

On 5/11/21 6:41 PM, Paolo Bonzini wrote:
> Avoid possible uninitialized variables on machines where
> division by zero does not trap.  Add __divmoddi4, and

According to the ARM Architecture Reference Manual for ARMv7-A (ARM DDI 0406C.d),
hardware floating point support is optional (page A2-54), so initializing the
remainder to zero in the case of zero division makes sense.

> do not use 64-bit math unnecessarily in __moddi3 and __divdi3.
>
> Reported-by: Alexandru Elisei <alexandru.elisei@arm.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  lib/ldiv32.c | 28 +++++++++++++++++++++++++---
>  1 file changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/lib/ldiv32.c b/lib/ldiv32.c
> index 96f4b35..c39fccd 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,9 +39,27 @@ uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *p_rem)
>  	return quot;
>  }
>  
> +int64_t __divmoddi4(int64_t num, int64_t den, int64_t *p_rem)
> +{
> +	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 + nmask) ^ nmask;
> +	if (den < 0)
> +		den = -den;
> +
> +	/* Copy sign of num^den into quotient, sign of num into remainder.  */
> +	quot = (__divmoddi4(num, den, p_rem) + qmask) ^ qmask;

I see no early return statement in the function, it looks to me like the function
will recurse forever. Maybe you wanted to call here __*u*divmoddi4() (emphasis
added) instead?

Other than that, the function looks correct.

Thanks,

Alex

> +	if (p_rem)
> +		*p_rem = (*p_rem + nmask) ^ nmask;
> +	return quot;
> +}
> +
>  int64_t __moddi3(int64_t num, int64_t den)
>  {
> -	uint64_t mask = num < 0 ? -1 : 0;
> +	int32_t mask = num < 0 ? -1 : 0;
>  
>  	/* Compute absolute values and do an unsigned division.  */
>  	num = (num + mask) ^ mask;
> @@ -50,7 +72,7 @@ int64_t __moddi3(int64_t num, int64_t den)
>  
>  int64_t __divdi3(int64_t num, int64_t den)
>  {
> -	uint64_t mask = (num ^ den) < 0 ? -1 : 0;
> +	int32_t mask = (num ^ den) < 0 ? -1 : 0;
>  
>  	/* Compute absolute values and do an unsigned division.  */
>  	if (num < 0)

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

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

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=3255ae16-ee2d-861d-d7e8-9360e7eaa09c@arm.com \
    --to=alexandru.elisei@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    /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.