All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoffer Dall <christoffer.dall@linaro.org>
To: Andrew Jones <drjones@redhat.com>
Cc: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, gleb@redhat.com
Subject: Re: [PATCH 7/9] arm: replace arbitrary divisions
Date: Wed, 16 Oct 2013 18:06:29 -0700	[thread overview]
Message-ID: <20131017010629.GJ24837@cbox> (raw)
In-Reply-To: <1381767815-12510-8-git-send-email-drjones@redhat.com>

On Mon, Oct 14, 2013 at 06:23:33PM +0200, Andrew Jones wrote:
> arm can't do arbitrary divisions without software support. Usually
> libgcc would jump in here, but depending on the toolchain used that may
> or may not work. Luckily, we only care about two types of divisions.
> Divide by 10 and divide by 16. Divide by 16 is already covered by gcc
> since it's a power of two. Divide by 10 can be hacked up using a
> multiplication and shift.

Isn't this just a matter of supplying a few libc implementations to
handle div_by_0 and that sort?  I'm pretty sure we had that working in
the kvm-selftest for ARM thingy that allowed you to use the standard '/'
operator in C code.... I suspect there will be more users of this
eventually.

Or wait, do you mean 'long long' operations by arbitrary? In that case,
I'm less sure...  A library implementation to support the operator would
still be preferred IMHO.

> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
>  lib/divmod.h | 20 ++++++++++++++++++++
>  lib/printf.c | 27 ++++++++++++++-------------
>  2 files changed, 34 insertions(+), 13 deletions(-)
>  create mode 100644 lib/divmod.h
> 
> diff --git a/lib/divmod.h b/lib/divmod.h
> new file mode 100644
> index 0000000000000..c0f04d7d8386d
> --- /dev/null
> +++ b/lib/divmod.h
> @@ -0,0 +1,20 @@
> +#ifndef _DIVMOD_H_
> +#define _DIVMOD_H_
> +#ifdef __arm__
> +static inline long long div10(long long n)
> +{
> +    /*
> +     * multiply n by 2^32/10 and the result of n/10
> +     * will be in the upper word
> +     */
> +    return (n * 0x1999999aU) >> 32;
> +}
> +static inline int mod10(long long n)
> +{
> +    return n - div10(n) * 10;
> +}
> +#else
> +#define div10(n) ((n) / 10)
> +#define mod10(n) ((n) % 10)
> +#endif
> +#endif
> diff --git a/lib/printf.c b/lib/printf.c
> index 867eb1926f742..9fb8133868c7a 100644
> --- a/lib/printf.c
> +++ b/lib/printf.c
> @@ -1,4 +1,5 @@
>  #include "libcflat.h"
> +#include "divmod.h"
>  
>  typedef struct pstream {
>      char *buffer;
> @@ -23,7 +24,7 @@ void print_str(pstream_t *p, const char *s)
>  
>  static char digits[16] = "0123456789abcdef";
>  
> -void print_int(pstream_t *ps, long long n, int base)
> +void print_int(pstream_t *ps, long long n)
>  {
>      char buf[sizeof(long) * 3 + 2], *p = buf;
>      int s = 0, i;
> @@ -34,8 +35,8 @@ void print_int(pstream_t *ps, long long n, int base)
>      }
>  
>      while (n) {
> -	*p++ = digits[n % base];
> -	n /= base;
> +	*p++ = digits[mod10(n)];
> +	n = div10(n);
>      }
>  
>      if (s)
> @@ -57,14 +58,14 @@ void print_int(pstream_t *ps, long long n, int base)
>      print_str(ps, buf);
>  }
>  
> -void print_unsigned(pstream_t *ps, unsigned long long n, int base)
> +void print_unsigned(pstream_t *ps, unsigned long long n)
>  {
>      char buf[sizeof(long) * 3 + 1], *p = buf;
>      int i;
>  
>      while (n) {
> -	*p++ = digits[n % base];
> -	n /= base;
> +	*p++ = digits[n % 16];
> +	n /= 16;
>      }
>  
>      if (p == buf)
> @@ -116,32 +117,32 @@ int vsnprintf(char *buf, int size, const char *fmt, va_list va)
>  	case 'd':
>  	    switch (nlong) {
>  	    case 0:
> -		print_int(&s, va_arg(va, int), 10);
> +		print_int(&s, va_arg(va, int));
>  		break;
>  	    case 1:
> -		print_int(&s, va_arg(va, long), 10);
> +		print_int(&s, va_arg(va, long));
>  		break;
>  	    default:
> -		print_int(&s, va_arg(va, long long), 10);
> +		print_int(&s, va_arg(va, long long));
>  		break;
>  	    }
>  	    break;
>  	case 'x':
>  	    switch (nlong) {
>  	    case 0:
> -		print_unsigned(&s, va_arg(va, unsigned), 16);
> +		print_unsigned(&s, va_arg(va, unsigned));
>  		break;
>  	    case 1:
> -		print_unsigned(&s, va_arg(va, unsigned long), 16);
> +		print_unsigned(&s, va_arg(va, unsigned long));
>  		break;
>  	    default:
> -		print_unsigned(&s, va_arg(va, unsigned long long), 16);
> +		print_unsigned(&s, va_arg(va, unsigned long long));
>  		break;
>  	    }
>  	    break;
>  	case 'p':
>  	    print_str(&s, "0x");
> -	    print_unsigned(&s, (unsigned long)va_arg(va, void *), 16);
> +	    print_unsigned(&s, (unsigned long)va_arg(va, void *));
>  	    break;
>  	case 's':
>  	    print_str(&s, va_arg(va, const char *));
> -- 
> 1.8.1.4
> 

  reply	other threads:[~2013-10-17  1:05 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
2013-10-14 16:23 ` [PATCH 1/9] remove unused files Andrew Jones
2013-10-16 12:52   ` Gleb Natapov
2013-10-16 13:13     ` Alexander Graf
2013-10-16 13:13       ` Alexander Graf
2013-10-16 13:18     ` Andrew Jones
2013-10-14 16:23 ` [PATCH 2/9] makefile and run_tests tweaks Andrew Jones
2013-10-14 16:23 ` [PATCH 3/9] clean root dir of all x86-ness Andrew Jones
2013-10-17  1:06   ` Christoffer Dall
2013-10-17  9:35     ` Andrew Jones
2013-10-17 19:01       ` Christoffer Dall
2013-10-20 16:37         ` Andrew Jones
2013-10-14 16:23 ` [PATCH 4/9] Introduce a simple iomap structure Andrew Jones
2013-10-14 16:23 ` [PATCH 5/9] Add halt() and some error codes Andrew Jones
2013-10-14 16:23 ` [PATCH 6/9] Introduce virtio-testdev Andrew Jones
2013-10-15  8:39   ` Andrew Jones
2013-10-17  1:06   ` Christoffer Dall
2013-10-17  9:51     ` Andrew Jones
2013-10-17 19:01       ` Christoffer Dall
2013-10-17  1:06   ` Christoffer Dall
2013-10-14 16:23 ` [PATCH 7/9] arm: replace arbitrary divisions Andrew Jones
2013-10-17  1:06   ` Christoffer Dall [this message]
2013-10-17 10:03     ` Andrew Jones
2013-10-17 18:59       ` Christoffer Dall
2013-10-14 16:23 ` [PATCH 8/9] arm: initial drop Andrew Jones
2013-10-17  1:06   ` Christoffer Dall
2013-10-17 10:16     ` Andrew Jones
2013-10-17 13:28       ` Andrew Jones
2013-10-17 18:39         ` Christoffer Dall
2013-10-14 16:23 ` [PATCH 9/9] arm: add vectors support Andrew Jones
2013-10-17  1:06   ` Christoffer Dall
2013-10-17 10:38     ` Andrew Jones
2013-10-17 18:58       ` Christoffer Dall
2013-10-20 16:35         ` Andrew Jones
2013-10-21  9:59           ` Christoffer Dall
2013-11-20 23:06 ` [PATCH 0/9] kvm-unit-tests/arm: initial drop María Soler Heredia
2013-11-26 17:23   ` Andrew Jones
2013-12-29  9:24 ` Christoffer Dall
2014-01-02 18:56   ` Andrew Jones

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=20131017010629.GJ24837@cbox \
    --to=christoffer.dall@linaro.org \
    --cc=drjones@redhat.com \
    --cc=gleb@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    /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.