All of lore.kernel.org
 help / color / mirror / Atom feed
From: Philippe Gerum <rpm@xenomai.org>
To: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
Cc: xenomai@xenomai.org
Subject: Re: [Xenomai-core] [patch] factoring arithmetic routines.
Date: Fri, 13 Jan 2006 17:22:20 +0100	[thread overview]
Message-ID: <43C7D3BC.7090604@domain.hid> (raw)
In-Reply-To: <17351.50625.229758.938503@domain.hid>

Gilles Chanteperdrix wrote:
> Hi,
> 
> For your review, here is an attempt to factor arithmetic routines in
> asm-generic/hal.h.
> 
> I am not sure the way I did it is the best one.
> Maybe defining some HAVE_ARCH symbols, would have been better.
> Maybe moving the definitions in asm-generic/system.h would have been
> better than the #defines before #include for side effects.
> I am not to pleased with the double definition of div96by32 either.
> 
> Please feel free to comment, insult, etc...
> 

Queued for -rc3, froggie, etc...

> 
> 
> ------------------------------------------------------------------------
> 
> Index: include/asm-arm/hal.h
> ===================================================================
> --- include/asm-arm/hal.h	(revision 453)
> +++ include/asm-arm/hal.h	(working copy)
> @@ -29,12 +29,6 @@
>  #ifndef _XENO_ASM_ARM_HAL_H
>  #define _XENO_ASM_ARM_HAL_H
>  
> -#include <asm-generic/xenomai/hal.h>	/* Read the generic bits. */
> -#include <asm/div64.h>
> -#include <asm/byteorder.h>
> -
> -typedef unsigned long long rthal_time_t;
> -
>  #ifdef __BIG_ENDIAN
>  #define endianstruct struct { u_long _h; u_long _l; } _s
>  #else /* __LITTLE_ENDIAN */
> @@ -50,72 +44,12 @@
>      (l) = _u._s._l;                             \
>  })
>  
> -#define __rthal_u64fromu32(h, l) ({             \
> -    union { unsigned long long _ull;            \
> -    endianstruct;                               \
> -    } _u;                                       \
> -    _u._s._h = (h);                             \
> -    _u._s._l = (l);                             \
> -    _u._ull;                                    \
> -})
> +#include <asm-generic/xenomai/hal.h>	/* Read the generic bits. */
> +#include <asm/div64.h>
> +#include <asm/byteorder.h>
>  
> -static inline unsigned long long rthal_ullmul(const unsigned long m0,
> -                                              const unsigned long m1)
> -{
> -    return (unsigned long long) m0 * m1;
> -}
> +typedef unsigned long long rthal_time_t;
>  
> -static inline unsigned long long rthal_ulldiv (unsigned long long ull,
> -                                               const unsigned long uld,
> -                                               unsigned long *const rp)
> -{
> -    unsigned long r = do_div(ull, uld);
> -
> -    if (rp)
> -    	*rp = r;
> -
> -    return ull;
> -}
> -
> -#define rthal_uldivrem(ull,ul,rp) ((u_long) rthal_ulldiv((ull),(ul),(rp)))
> -
> -static inline int rthal_imuldiv (int i, int mult, int div) {
> -
> -    /* Returns (int)i = (unsigned long long)i*(u_long)(mult)/(u_long)div. */
> -    const unsigned long long ull = rthal_ullmul(i, mult);
> -    return rthal_uldivrem(ull, div, NULL);
> -}
> -
> -static inline __attribute_const__
> -unsigned long long __rthal_ullimd (const unsigned long long op,
> -                                   const unsigned long m,
> -                                   const unsigned long d)
> -{
> -    u_long oph, opl, tlh, tll, qh, rh, ql;
> -    unsigned long long th, tl;
> -
> -    __rthal_u64tou32(op, oph, opl);
> -    tl = rthal_ullmul(opl, m);
> -    __rthal_u64tou32(tl, tlh, tll);
> -    th = rthal_ullmul(oph, m);
> -    th += tlh;
> -
> -    qh = rthal_uldivrem(th, d, &rh);
> -    th = __rthal_u64fromu32(rh, tll);
> -    ql = rthal_uldivrem(th, d, NULL);
> -    return __rthal_u64fromu32(qh, ql);
> -}
> -
> -static inline long long rthal_llimd (long long op,
> -                                     unsigned long m,
> -                                     unsigned long d)
> -{
> -
> -    if(op < 0LL)
> -        return -__rthal_ullimd(-op, m, d);
> -    return __rthal_ullimd(op, m, d);
> -}
> -
>  #if __LINUX_ARM_ARCH__ < 5
>  static inline __attribute_const__ unsigned long ffnz (unsigned long x) {
>  	int r = 0;
> Index: include/asm-generic/hal.h
> ===================================================================
> --- include/asm-generic/hal.h	(revision 453)
> +++ include/asm-generic/hal.h	(working copy)
> @@ -38,6 +38,8 @@
>  #include <linux/interrupt.h>
>  #include <linux/kallsyms.h>
>  #include <linux/init.h>
> +#include <asm/byteorder.h>
> +#include <asm/div64.h>
>  #include <asm/xenomai/wrappers.h>
>  
>  #define RTHAL_DOMAIN_ID		0x58454e4f
> @@ -278,6 +280,124 @@
>  
>  #define rthal_printk	printk
>  
> +#ifdef __BIG_ENDIAN
> +#define endianstruct struct { u_long _h; u_long _l; } _s
> +#else /* __LITTLE_ENDIAN */
> +#define endianstruct struct { u_long _l; u_long _h; } _s
> +#endif
> +
> +#ifndef __rthal_u64tou32
> +#define __rthal_u64tou32(ull, h, l) ({          \
> +    union { unsigned long long _ull;            \
> +    endianstruct;                               \
> +    } _u;                                       \
> +    _u._ull = (ull);                            \
> +    (h) = _u._s._h;                             \
> +    (l) = _u._s._l;                             \
> +})
> +#endif /* !__rthal_u64tou32 */
> +
> +#ifndef __rthal_u64fromu32
> +#define __rthal_u64fromu32(h, l) ({             \
> +    union { unsigned long long _ull;            \
> +    endianstruct;                               \
> +    } _u;                                       \
> +    _u._s._h = (h);                             \
> +    _u._s._l = (l);                             \
> +    _u._ull;                                    \
> +})
> +#endif /* !__rthal_u64fromu32 */
> +
> +#ifndef rthal_ullmul
> +static inline __attribute_const__ unsigned long long
> +__rthal_generic_ullmul(const unsigned m0, const unsigned m1)
> +{
> +    return (unsigned long long) m0 * m1;
> +}
> +#define rthal_ullmul(m0,m1) __rthal_generic_ullmul((m0),(m1))
> +#endif /* !rthal_ullmul */
> +
> +#ifndef rthal_ulldiv
> +static inline unsigned long long __rthal_generic_ulldiv (unsigned long long ull,
> +                                                         const unsigned uld,
> +                                                         unsigned long *const rp)
> +{
> +    const unsigned long r = do_div(ull, uld);
> +
> +    if (rp)
> +        *rp = r;
> +
> +    return ull;
> +}
> +#define rthal_ulldiv(ull,uld,rp) __rthal_generic_ulldiv((ull),(uld),(rp))
> +#endif /* !rthal_ulldiv */
> +
> +/* Another implementation of ulldiv, used to be defined on x86. */
> +#define rthal_u64div32c(ull,uld,rp) rthal_ulldiv((ull),(uld),(rp))
> +
> +#ifndef rthal_uldivrem
> +#define rthal_uldivrem(ull,ul,rp) ((unsigned) rthal_ulldiv((ull),(ul),(rp)))
> +#endif /* !rthal_uldivrem */
> +
> +#ifndef rthal_imuldiv
> +static inline __attribute_const__ int __rthal_generic_imuldiv (int i,
> +                                                               int mult,
> +                                                               int div)
> +{
> +    /* Returns (int)i = (unsigned long long)i*(unsigned)(mult)/(unsigned)div. */
> +    const unsigned long long ull = rthal_ullmul(i, mult);
> +    return rthal_uldivrem(ull, div, NULL);
> +}
> +#define rthal_imuldiv(i,m,d) __rthal_generic_imuldiv((i),(m),(d))
> +#endif /* !rthal_imuldiv */
> +
> +#ifndef rthal_llimd
> +/* Division of an unsigned 96 bits ((h << 32) + l) by an unsigned 32 bits. 
> +   Building block for llimd. Without const qualifiers, gcc reload registers
> +   after each call to uldivrem. */
> +static inline unsigned long long
> +__rthal_generic_div96by32 (const unsigned long long h,
> +                           const unsigned long l,
> +                           const unsigned long d,
> +                           unsigned long *const rp)
> +{
> +    unsigned long rh;
> +    const unsigned qh = rthal_uldivrem(h, d, &rh);
> +    const unsigned long long t = __rthal_u64fromu32(rh, l);
> +    const unsigned ql = rthal_uldivrem(t, d, rp);
> +
> +    return __rthal_u64fromu32(qh, ql);
> +}
> +
> +static inline __attribute_const__
> +unsigned long long __rthal_generic_ullimd (const unsigned long long op,
> +                                           const unsigned m,
> +                                           const unsigned d)
> +{
> +    unsigned oph, opl, tlh, tll;
> +    unsigned long long th, tl;
> +
> +    __rthal_u64tou32(op, oph, opl);
> +    tl = rthal_ullmul(opl, m);
> +    __rthal_u64tou32(tl, tlh, tll);
> +    th = rthal_ullmul(oph, m);
> +    th += tlh;
> +
> +    return __rthal_generic_div96by32(th, tll, d, NULL);
> +}
> +
> +static inline __attribute_const__ long long __rthal_generic_llimd (long long op,
> +                                                                   unsigned m,
> +                                                                   unsigned d)
> +{
> +
> +    if(op < 0LL)
> +        return -__rthal_generic_ullimd(-op, m, d);
> +    return __rthal_generic_ullimd(op, m, d);
> +}
> +#define rthal_llimd(ll,m,d) __rthal_generic_llimd((ll),(m),(d))
> +#endif /* !rthal_llimd */
> +
>  typedef ipipe_irq_handler_t rthal_irq_handler_t;
>  typedef ipipe_irq_ackfn_t   rthal_irq_ackfn_t;
>  
> Index: include/asm-i386/hal.h
> ===================================================================
> --- include/asm-i386/hal.h	(revision 453)
> +++ include/asm-i386/hal.h	(working copy)
> @@ -37,14 +37,6 @@
>  #ifndef _XENO_ASM_I386_HAL_H
>  #define _XENO_ASM_I386_HAL_H
>  
> -#include <asm-generic/xenomai/hal.h>    /* Read the generic bits. */
> -
> -#ifndef CONFIG_X86_WP_WORKS_OK
> -#error "Xenomai has to rely on the WP bit, CONFIG_M486 or better required"
> -#endif /* CONFIG_X86_WP_WORKS_OK */
> -
> -typedef unsigned long long rthal_time_t;
> -
>  #define __rthal_u64tou32(ull, h, l) ({          \
>      unsigned long long _ull = (ull);            \
>      (l) = _ull & 0xffffffff;                    \
> @@ -57,13 +49,6 @@
>      _ull;                                       \
>  })
>  
> -/* Fast longs multiplication. */
> -static inline __attribute_const__ unsigned long long
> -rthal_ullmul(unsigned long m1, unsigned long m2) {
> -    /* Gcc (at least for versions 2.95 and higher) optimises correctly here. */
> -    return (unsigned long long) m1 * m2;
> -}
> -
>  /* const helper for rthal_uldivrem, so that the compiler will eliminate
>     multiple calls with same arguments, at no additionnal cost. */
>  static inline __attribute_const__ unsigned long long
> @@ -75,23 +60,12 @@
>      return ret;
>  }
>  
> -static inline __attribute_const__ int rthal_imuldiv (const int i,
> -                                                     const int mult,
> -                                                     const int div) {
>  
> -    /* Returns (unsigned)i =
> -               (unsigned long long)i*(unsigned)(mult)/(unsigned)div. */
> -    const unsigned long ui = (const unsigned long) i;
> -    const unsigned long um = (const unsigned long) mult;
> -    return __rthal_uldivrem((const unsigned long long) ui * um, div);
> -}
> +/* Fast long long division: when the quotient and remainder fit on 32 bits. */
> +static inline unsigned long __rthal_i386_uldivrem(unsigned long long ull,
> +                                                  const unsigned d,
> +                                                  unsigned long *const rp) {
>  
> -/* Fast long long division: when the quotient and remainder fit on 32 bits.
> -   Recent compilers remove redundant calls to this function. */
> -static inline unsigned long rthal_uldivrem(unsigned long long ull,
> -                                           const unsigned long d,
> -                                           unsigned long *const rp) {
> -
>      unsigned long q, r;
>      ull = __rthal_uldivrem(ull, d);
>      __asm__ ( "": "=d"(r), "=a"(q) : "A"(ull));
> @@ -99,10 +73,10 @@
>          *rp = r;
>      return q;
>  }
> +#define rthal_uldivrem(ull, d, rp) __rthal_i386_uldivrem((ull),(d),(rp))
>  
> -
>  /* Division of an unsigned 96 bits ((h << 32) + l) by an unsigned 32 bits.
> -   Common building block for ulldiv and llimd. */
> +   Building block for ulldiv. */
>  static inline unsigned long long __rthal_div96by32 (const unsigned long long h,
>                                                      const unsigned long l,
>                                                      const unsigned long d,
> @@ -116,53 +90,27 @@
>      return __rthal_u64fromu32(qh, ql);
>  }
>  
> -
>  /* Slow long long division. Uses rthal_uldivrem, hence has the same property:
>     the compiler removes redundant calls. */
> -static inline unsigned long long rthal_ulldiv (const unsigned long long ull,
> -                                               const unsigned long d,
> -                                               unsigned long *const rp) {
> +static inline unsigned long long
> +__rthal_i386_ulldiv (const unsigned long long ull,
> +                     const unsigned d,
> +                     unsigned long *const rp) {
>  
>      unsigned long h, l;
>      __rthal_u64tou32(ull, h, l);
>      return __rthal_div96by32(h, l, d, rp);
>  }
> +#define rthal_ulldiv(ull,d,rp) __rthal_i386_ulldiv((ull),(d),(rp))
>  
> -/* Replaced the helper with rthal_ulldiv. */
> -#define rthal_u64div32c rthal_ulldiv
> +#include <asm-generic/xenomai/hal.h>    /* Read the generic bits. */
>  
> -static inline __attribute_const__
> -unsigned long long __rthal_ullimd (const unsigned long long op,
> -                                   const unsigned long m,
> -                                   const unsigned long d) {
> +#ifndef CONFIG_X86_WP_WORKS_OK
> +#error "Xenomai has to rely on the WP bit, CONFIG_M486 or better required"
> +#endif /* CONFIG_X86_WP_WORKS_OK */
>  
> -    unsigned long long th, tl;
> -    u_long oph, opl, tlh, tll;
> +typedef unsigned long long rthal_time_t;
>  
> -    __rthal_u64tou32(op, oph, opl);
> -    tl = (unsigned long long) opl * m;
> -    __rthal_u64tou32(tl, tlh, tll);
> -    th = (unsigned long long) oph * m;
> -    /* op * m == ((th + tlh) << 32) + tll */
> -
> -    __asm__ (  "addl %1, %%eax\n\t"
> -               "adcl $0, %%edx"
> -               : "=A,A"(th)
> -               : "r,?m"(tlh), "A,A"(th) );
> -    /* op * m == (th << 32) + tll */
> -
> -    return __rthal_div96by32(th, tll, d, NULL);
> -}
> -
> -static inline __attribute_const__ long long rthal_llimd (const long long op,
> -                                                         const unsigned long m,
> -                                                         const unsigned long d) {
> -
> -    if(op < 0LL)
> -        return -__rthal_ullimd(-op, m, d);
> -    return __rthal_ullimd(op, m, d);
> -}
> -
>  static inline __attribute_const__ unsigned long ffnz (unsigned long ul) {
>      /* Derived from bitops.h's ffs() */
>      __asm__("bsfl %1, %0"
> Index: include/asm-ia64/hal.h
> ===================================================================
> --- include/asm-ia64/hal.h	(revision 453)
> +++ include/asm-ia64/hal.h	(working copy)
> @@ -31,76 +31,6 @@
>  
>  typedef unsigned long long rthal_time_t;
>  
> -#define __rthal_u64tou32(ull, h, l) ({          \
> -    unsigned long long _ull = (ull);            \
> -    (l) = _ull & 0xffffffff;                    \
> -    (h) = _ull >> 32;                           \
> -})
> -
> -#define __rthal_u64fromu32(h, l) ({             \
> -    (((unsigned long long) (h)) << 32) + (l);   \
> -})
> -
> -static inline unsigned long long rthal_ullmul(const unsigned m0, 
> -                                              const unsigned m1)
> -{
> -    return (unsigned long long) m0 * m1;
> -}
> -
> -static inline unsigned long long rthal_ulldiv (unsigned long long ull,
> -                                               const unsigned uld,
> -                                               unsigned long *const rp)
> -{
> -    const unsigned long long result = ull / uld;
> -
> -    if (rp)
> -        *rp = ull % uld;
> -
> -    return result;
> -}
> -
> -#define rthal_uldivrem(ull,ul,rp) ((u_long) rthal_ulldiv((ull),(ul),(rp)))
> -
> -static inline __attribute_const__ int rthal_imuldiv (const int i,
> -                                                     const int mult,
> -                                                     const int div) {
> -
> -    /* Returns (int)i = (unsigned long long)i*(u_long)(mult)/(u_long)div. */
> -    const unsigned long long ull = rthal_ullmul(i, mult);
> -    return rthal_uldivrem(ull, div, NULL);
> -}
> -
> -static inline __attribute_const__
> -unsigned long long __rthal_ullimd (const unsigned long long op,
> -                                   const unsigned m,
> -                                   const unsigned d)
> -{
> -    unsigned oph, opl, tlh, tll, qh, ql;
> -    unsigned long long th, tl;
> -    unsigned long rh;
> -
> -    __rthal_u64tou32(op, oph, opl);
> -    tl = rthal_ullmul(opl, m);
> -    __rthal_u64tou32(tl, tlh, tll);
> -    th = rthal_ullmul(oph, m);
> -    th += tlh;
> -
> -    qh = rthal_uldivrem(th, d, &rh);
> -    th = __rthal_u64fromu32(rh, tll);
> -    ql = rthal_uldivrem(th, d, NULL);
> -    return __rthal_u64fromu32(qh, ql);
> -}
> -
> -static inline long long rthal_llimd (long long op,
> -                                     unsigned m,
> -                                     unsigned d)
> -{
> -
> -    if(op < 0LL)
> -        return -__rthal_ullimd(-op, m, d);
> -    return __rthal_ullimd(op, m, d);
> -}
> -
>  static inline __attribute_const__ unsigned long ffnz (unsigned long ul)
>  {
>      unsigned long r;
> Index: include/asm-powerpc/hal.h
> ===================================================================
> --- include/asm-powerpc/hal.h	(revision 453)
> +++ include/asm-powerpc/hal.h	(working copy)
> @@ -30,89 +30,9 @@
>  #define _XENO_ASM_POWERPC_HAL_H
>  
>  #include <asm-generic/xenomai/hal.h>	/* Read the generic bits. */
> -#include <asm/div64.h>
>  
>  typedef unsigned long long rthal_time_t;
>  
> -#define __rthal_u64tou32(ull, h, l) ({                          \
> -        union { unsigned long long _ull;                        \
> -            struct { unsigned _h; unsigned _l; } _s; } _u;      \
> -        _u._ull = (ull);                                        \
> -        (h) = _u._s._h;                                         \
> -        (l) = _u._s._l;                                         \
> -        })
> -
> -#define __rthal_u64fromu32(h, l) ({                             \
> -        union { unsigned long long _ull;                        \
> -            struct { unsigned _h; unsigned _l; } _s; } _u;      \
> -        _u._s._h = (h);                                         \
> -        _u._s._l = (l);                                         \
> -        _u._ull;                                                \
> -        })
> -
> -static inline unsigned long long rthal_ullmul(const unsigned m0, 
> -					      const unsigned m1)
> -{
> -    return (unsigned long long) m0 * m1;
> -}
> -
> -static inline unsigned long long rthal_ulldiv (unsigned long long ull,
> -					       const unsigned uld,
> -					       unsigned long *const rp)
> -{
> -#if BITS_PER_LONG == 32
> -    const unsigned long r = __div64_32(&ull, uld);
> -#else /* BITS_PER_LONG == 64 */
> -    const unsigned long r = ull % uld;
> -    ull /= uld;
> -#endif
> -
> -    if (rp)
> -	*rp = r;
> -
> -    return ull;
> -}
> -
> -#define rthal_uldivrem(ull,ul,rp) ((u_long) rthal_ulldiv((ull),(ul),(rp)))
> -
> -static inline __attribute_const__ int rthal_imuldiv (int i, int mult, int div) {
> -
> -    /* Returns (int)i = (unsigned long long)i*(u_long)(mult)/(u_long)div. */
> -    const unsigned long long ull = rthal_ullmul(i, mult);
> -    return rthal_uldivrem(ull, div, NULL);
> -}
> -
> -static inline __attribute_const__
> -unsigned long long __rthal_ullimd (const unsigned long long op,
> -                                   const unsigned m,
> -                                   const unsigned d)
> -{
> -    unsigned oph, opl, tlh, tll, qh, ql;
> -    unsigned long long th, tl;
> -    unsigned long rh;
> -
> -    __rthal_u64tou32(op, oph, opl);
> -    tl = rthal_ullmul(opl, m);
> -    __rthal_u64tou32(tl, tlh, tll);
> -    th = rthal_ullmul(oph, m);
> -    th += tlh;
> -
> -    qh = rthal_uldivrem(th, d, &rh);
> -    th = __rthal_u64fromu32(rh, tll);
> -    ql = rthal_uldivrem(th, d, NULL);
> -    return __rthal_u64fromu32(qh, ql);
> -}
> -
> -static inline long long rthal_llimd (long long op,
> -                                     unsigned m,
> -                                     unsigned d)
> -{
> -
> -    if(op < 0LL)
> -        return -__rthal_ullimd(-op, m, d);
> -    return __rthal_ullimd(op, m, d);
> -}
> -
>  static inline __attribute_const__ unsigned long ffnz (unsigned long ul) {
>  #ifdef CONFIG_PPC64
>      __asm__ ("cntlzd %0, %1" : "=r" (ul) : "r" (ul & (-ul)));
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Xenomai-core mailing list
> Xenomai-core@domain.hid
> https://mail.gna.org/listinfo/xenomai-core


-- 

Philippe.


      parent reply	other threads:[~2006-01-13 16:22 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-01-13 15:22 [Xenomai-core] [patch] factoring arithmetic routines Gilles Chanteperdrix
2006-01-13 15:35 ` Gilles Chanteperdrix
2006-01-31 13:10   ` Philippe Gerum
2006-01-13 16:22 ` Philippe Gerum [this message]

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=43C7D3BC.7090604@domain.hid \
    --to=rpm@xenomai.org \
    --cc=gilles.chanteperdrix@xenomai.org \
    --cc=xenomai@xenomai.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.