All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-core] [patch] factoring arithmetic routines.
@ 2006-01-13 15:22 Gilles Chanteperdrix
  2006-01-13 15:35 ` Gilles Chanteperdrix
  2006-01-13 16:22 ` Philippe Gerum
  0 siblings, 2 replies; 4+ messages in thread
From: Gilles Chanteperdrix @ 2006-01-13 15:22 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: message body and .signature --]
[-- Type: text/plain, Size: 485 bytes --]


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...

-- 


					    Gilles Chanteperdrix.

[-- Attachment #2: xeno-arith.diff --]
[-- Type: text/plain, Size: 18852 bytes --]

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)));

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Xenomai-core] [patch] factoring arithmetic routines.
  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
  1 sibling, 1 reply; 4+ messages in thread
From: Gilles Chanteperdrix @ 2006-01-13 15:35 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: message body and .signature --]
[-- Type: text/plain, Size: 214 bytes --]

Gilles Chanteperdrix wrote:
 > 
 > Hi,
 > 
 > For your review, here is an attempt to factor arithmetic routines in
 > asm-generic/hal.h.

And with the blackfin architecture...

-- 


					    Gilles Chanteperdrix.

[-- Attachment #2: xeno-arith.diff --]
[-- Type: application/octet-stream, Size: 21723 bytes --]

Index: include/asm-arm/hal.h
===================================================================
--- include/asm-arm/hal.h	(revision 453)
+++ include/asm-arm/hal.h	(working copy)
@@ -30,92 +30,10 @@
 #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 */
-#define endianstruct struct { u_long _l; u_long _h; } _s
-#endif
-
-#define __rthal_u64tou32(ull, h, l) ({          \
-    union { unsigned long long _ull;            \
-    endianstruct;                               \
-    } _u;                                       \
-    _u._ull = (ull);                            \
-    (h) = _u._s._h;                             \
-    (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;                                    \
-})
-
-static inline unsigned long long rthal_ullmul(const unsigned long m0,
-                                              const unsigned long m1)
-{
-    return (unsigned long long) m0 * m1;
-}
-
-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-blackfin/hal.h
===================================================================
--- include/asm-blackfin/hal.h	(revision 453)
+++ include/asm-blackfin/hal.h	(working copy)
@@ -31,76 +31,6 @@
 
 typedef unsigned long long rthal_time_t;
 
-#define __rthal_u64tou32(ull, h, l) ({                  \
-        union { unsigned long long _ull;                \
-            struct { u_long _l; u_long _h; } _s; } _u;  \
-        _u._ull = (ull);                                \
-        (h) = _u._s._h;                                 \
-        (l) = _u._s._l;                                 \
-        })
-
-#define __rthal_u64fromu32(h, l) ({                     \
-        union { unsigned long long _ull;                \
-            struct { u_long _l; u_long _h; } _s; } _u;  \
-        _u._s._h = (h);                                 \
-        _u._s._l = (l);                                 \
-        _u._ull;                                        \
-        })
-
-static inline unsigned long long rthal_ullmul(const unsigned long m0, 
-					      const unsigned long m1)
-{
-    return (unsigned long long) m0 * m1;
-}
-
-static inline unsigned long long rthal_ulldiv (unsigned long long ull,
-					       const unsigned long uld,
-					       unsigned long *const rp)
-{
-    const unsigned long r = __div64_32(&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);
-}
-
 static inline __attribute_const__ unsigned long ffnz (unsigned long ul)
 {
     return ffs(ul) - 1;
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 l,
+                           const unsigned 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)));

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Xenomai-core] [patch] factoring arithmetic routines.
  2006-01-13 15:22 [Xenomai-core] [patch] factoring arithmetic routines Gilles Chanteperdrix
  2006-01-13 15:35 ` Gilles Chanteperdrix
@ 2006-01-13 16:22 ` Philippe Gerum
  1 sibling, 0 replies; 4+ messages in thread
From: Philippe Gerum @ 2006-01-13 16:22 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai

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.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Xenomai-core] [patch] factoring arithmetic routines.
  2006-01-13 15:35 ` Gilles Chanteperdrix
@ 2006-01-31 13:10   ` Philippe Gerum
  0 siblings, 0 replies; 4+ messages in thread
From: Philippe Gerum @ 2006-01-31 13:10 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai

Gilles Chanteperdrix wrote:
> Gilles Chanteperdrix wrote:
>  > 
>  > Hi,
>  > 
>  > For your review, here is an attempt to factor arithmetic routines in
>  > asm-generic/hal.h.
> 
> And with the blackfin architecture...
>

Applied, thanks.


> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Xenomai-core mailing list
> Xenomai-core@domain.hid
> https://mail.gna.org/listinfo/xenomai-core


-- 

Philippe.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-01-31 13:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 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.