diff mbox

[1/2] lib: int_sqrt: add int64_sqrt routine

Message ID 1403516581-12560-2-git-send-email-21cnbao@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Barry Song June 23, 2014, 9:43 a.m. UTC
From: Yibo Cai <yibo.cai@csr.com>

Get square root of a 64-bit digit on 32bit platforms. CSR SiRFSoC
touchscreen driver needs it.

Signed-off-by: Yibo Cai <yibo.cai@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
 include/linux/kernel.h |  1 +
 lib/int_sqrt.c         | 27 +++++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

Comments

Peter Meerwald-Stadler June 23, 2014, 9:52 a.m. UTC | #1
> Get square root of a 64-bit digit on 32bit platforms. CSR SiRFSoC
> touchscreen driver needs it.

maybe the code could be #MACRO()'d to avoid duplication

see comment below

> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> index 4c52907..6e63081 100644
> --- a/include/linux/kernel.h
> +++ b/include/linux/kernel.h
> @@ -418,6 +418,7 @@ struct pid;
>  extern struct pid *session_of_pgrp(struct pid *pgrp);
>  
>  unsigned long int_sqrt(unsigned long);
> +unsigned long long int64_sqrt(unsigned long long);
>  
>  extern void bust_spinlocks(int yes);
>  extern int oops_in_progress;		/* If set, an oops, panic(), BUG() or die() is in progress */
> diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c
> index 1ef4cc3..2aa9fcc 100644
> --- a/lib/int_sqrt.c
> +++ b/lib/int_sqrt.c
> @@ -36,3 +36,30 @@ unsigned long int_sqrt(unsigned long x)
>  	return y;
>  }
>  EXPORT_SYMBOL(int_sqrt);
> +
> +/*
> + * Square root of a 64-bit digit.
> + * Same as int_sqrt on 64-bit platforms where "long" equals "long long"
> + */
> +unsigned long long int64_sqrt(unsigned long long x)
> +{
> +	unsigned long long m = 0, y = 0, b = 0;

initialization for b, m not needed

the original int_sqrt() code correctly skips initialization

> +
> +	if (x <= 1)
> +		return x;
> +
> +	m = 1ULL << (BITS_PER_LONG_LONG - 2);
> +	while (m != 0) {
> +		b = y + m;
> +		y >>= 1;
> +
> +		if (x >= b) {
> +			x -= b;
> +			y += m;
> +		}
> +		m >>= 2;
> +	}
> +
> +	return y;
> +}
> +EXPORT_SYMBOL(int64_sqrt);
>
Yibo Cai June 24, 2014, 4:51 a.m. UTC | #2
Hello Peter,

>> Get square root of a 64-bit digit on 32bit platforms. CSR SiRFSoC
>> touchscreen driver needs it.

> maybe the code could be #MACRO()'d to avoid duplication

Do you mean to define int64_sqrt() directly as int_sqrt() on a 64 bit platform where sizeof(long) == sizeof(long long)?

Yibo
Peter Meerwald-Stadler June 24, 2014, 6:15 a.m. UTC | #3
Hello,

> > maybe the code could be #MACRO()'d to avoid duplication
> 
> Do you mean to define int64_sqrt() directly as int_sqrt() on a 64 bit 
> platform where sizeof(long) == sizeof(long long)?

something along the lines of

#define INT_SQRT(name, type) \
   type name(type x) \ 
      type m, y = 0, b; \
...

INT_SQRT(int_sqrt, unsigned long);
INT_SQRT(int64_sqrt, unsigned long long);

not sure if it is worth it

regards, p.

> ________________________________________
> From: Peter Meerwald [pmeerw@pmeerw.net]
> Sent: Monday, June 23, 2014 5:52 PM
> To: Barry Song
> Cc: dmitry.torokhov@gmail.com; dtor@mail.ru; akpm@linux-foundation.org; linux-input@vger.kernel.org; DL-SHA-WorkGroupLinux; Yibo Cai; Barry Song
> Subject: Re: [PATCH 1/2] lib: int_sqrt: add int64_sqrt routine
> 
> > Get square root of a 64-bit digit on 32bit platforms. CSR SiRFSoC
> > touchscreen driver needs it.
> 
> maybe the code could be #MACRO()'d to avoid duplication
> 
> see comment below
> 
> > diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> > index 4c52907..6e63081 100644
> > --- a/include/linux/kernel.h
> > +++ b/include/linux/kernel.h
> > @@ -418,6 +418,7 @@ struct pid;
> >  extern struct pid *session_of_pgrp(struct pid *pgrp);
> >
> >  unsigned long int_sqrt(unsigned long);
> > +unsigned long long int64_sqrt(unsigned long long);
> >
> >  extern void bust_spinlocks(int yes);
> >  extern int oops_in_progress;         /* If set, an oops, panic(), BUG() or die() is in progress */
> > diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c
> > index 1ef4cc3..2aa9fcc 100644
> > --- a/lib/int_sqrt.c
> > +++ b/lib/int_sqrt.c
> > @@ -36,3 +36,30 @@ unsigned long int_sqrt(unsigned long x)
> >       return y;
> >  }
> >  EXPORT_SYMBOL(int_sqrt);
> > +
> > +/*
> > + * Square root of a 64-bit digit.
> > + * Same as int_sqrt on 64-bit platforms where "long" equals "long long"
> > + */
> > +unsigned long long int64_sqrt(unsigned long long x)
> > +{
> > +     unsigned long long m = 0, y = 0, b = 0;
> 
> initialization for b, m not needed
> 
> the original int_sqrt() code correctly skips initialization
> 
> > +
> > +     if (x <= 1)
> > +             return x;
> > +
> > +     m = 1ULL << (BITS_PER_LONG_LONG - 2);
> > +     while (m != 0) {
> > +             b = y + m;
> > +             y >>= 1;
> > +
> > +             if (x >= b) {
> > +                     x -= b;
> > +                     y += m;
> > +             }
> > +             m >>= 2;
> > +     }
> > +
> > +     return y;
> > +}
> > +EXPORT_SYMBOL(int64_sqrt);
> >
> 
> --
> 
> Peter Meerwald
> +43-664-2444418 (mobile)
> 
> 
>  To report this email as spam click https://www.mailcontrol.com/sr/MZbqvYs5QwJvpeaetUwhCQ== .
> 
> 
> Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
> More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
> New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.
>
Elias Vanderstuyft June 24, 2014, 1:43 p.m. UTC | #4
On Mon, Jun 23, 2014 at 11:43 AM, Barry Song <21cnbao@gmail.com> wrote:
> From: Yibo Cai <yibo.cai@csr.com>
>
> Get square root of a 64-bit digit on 32bit platforms. CSR SiRFSoC
> touchscreen driver needs it.
>
> Signed-off-by: Yibo Cai <yibo.cai@csr.com>
> Signed-off-by: Barry Song <Baohua.Song@csr.com>
> ---
>  include/linux/kernel.h |  1 +
>  lib/int_sqrt.c         | 27 +++++++++++++++++++++++++++
>  2 files changed, 28 insertions(+)
>
> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> index 4c52907..6e63081 100644
> --- a/include/linux/kernel.h
> +++ b/include/linux/kernel.h
> @@ -418,6 +418,7 @@ struct pid;
>  extern struct pid *session_of_pgrp(struct pid *pgrp);
>
>  unsigned long int_sqrt(unsigned long);
> +unsigned long long int64_sqrt(unsigned long long);
>
>  extern void bust_spinlocks(int yes);
>  extern int oops_in_progress;           /* If set, an oops, panic(), BUG() or die() is in progress */
> diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c
> index 1ef4cc3..2aa9fcc 100644
> --- a/lib/int_sqrt.c
> +++ b/lib/int_sqrt.c
> @@ -36,3 +36,30 @@ unsigned long int_sqrt(unsigned long x)
>         return y;
>  }
>  EXPORT_SYMBOL(int_sqrt);
> +
> +/*
> + * Square root of a 64-bit digit.
> + * Same as int_sqrt on 64-bit platforms where "long" equals "long long"
> + */
> +unsigned long long int64_sqrt(unsigned long long x)
> +{
> +       unsigned long long m = 0, y = 0, b = 0;
> +
> +       if (x <= 1)
> +               return x;
> +
> +       m = 1ULL << (BITS_PER_LONG_LONG - 2);
> +       while (m != 0) {
> +               b = y + m;
> +               y >>= 1;
> +
> +               if (x >= b) {
> +                       x -= b;
> +                       y += m;
> +               }
> +               m >>= 2;
> +       }
> +
> +       return y;
> +}
> +EXPORT_SYMBOL(int64_sqrt);
>

Maybe it's a stupid question (I'm new to kernel programming),
but why don't you use a for-loop instead of a while-loop?
(apart from following the already-existing code of int_sqrt.c)

E.g.:
    for (m = 1ULL << (BITS_PER_LONG_LONG - 2); m != 0; m >>= 2) {
        b = y + m;
        y >>= 1;

        if (x >= b) {
            x -= b;
            y += m;
        }
    }

Instead of:
    m = 1ULL << (BITS_PER_LONG_LONG - 2);
    while (m != 0) {
        b = y + m;
        y >>= 1;

        if (x >= b) {
            x -= b;
            y += m;
        }
        m >>= 2;
    }

Thanks,
Elias
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andrew Morton June 24, 2014, 8:25 p.m. UTC | #5
On Tue, 24 Jun 2014 08:15:55 +0200 (CEST) Peter Meerwald <pmeerw@pmeerw.net> wrote:

> > > maybe the code could be #MACRO()'d to avoid duplication
> > 
> > Do you mean to define int64_sqrt() directly as int_sqrt() on a 64 bit 
> > platform where sizeof(long) == sizeof(long long)?
> 
> something along the lines of
> 
> #define INT_SQRT(name, type) \
>    type name(type x) \ 
>       type m, y = 0, b; \
> ...
> 
> INT_SQRT(int_sqrt, unsigned long);
> INT_SQRT(int64_sqrt, unsigned long long);
> 
> not sure if it is worth it

We have made smaller optimisations in the past ;)

But not a macro, please:

#ifdef CONFIG_64BIT
static inline unsigned long long int64_sqrt(unsigned long long x)
{
	return int_sqrt(x);
}
#else
unsigned long long int64_sqrt(unsigned long long x);
#endif


--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 4c52907..6e63081 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -418,6 +418,7 @@  struct pid;
 extern struct pid *session_of_pgrp(struct pid *pgrp);
 
 unsigned long int_sqrt(unsigned long);
+unsigned long long int64_sqrt(unsigned long long);
 
 extern void bust_spinlocks(int yes);
 extern int oops_in_progress;		/* If set, an oops, panic(), BUG() or die() is in progress */
diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c
index 1ef4cc3..2aa9fcc 100644
--- a/lib/int_sqrt.c
+++ b/lib/int_sqrt.c
@@ -36,3 +36,30 @@  unsigned long int_sqrt(unsigned long x)
 	return y;
 }
 EXPORT_SYMBOL(int_sqrt);
+
+/*
+ * Square root of a 64-bit digit.
+ * Same as int_sqrt on 64-bit platforms where "long" equals "long long"
+ */
+unsigned long long int64_sqrt(unsigned long long x)
+{
+	unsigned long long m = 0, y = 0, b = 0;
+
+	if (x <= 1)
+		return x;
+
+	m = 1ULL << (BITS_PER_LONG_LONG - 2);
+	while (m != 0) {
+		b = y + m;
+		y >>= 1;
+
+		if (x >= b) {
+			x -= b;
+			y += m;
+		}
+		m >>= 2;
+	}
+
+	return y;
+}
+EXPORT_SYMBOL(int64_sqrt);