~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/x86/include/asm/div64.h

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef _ASM_X86_DIV64_H
 
2
#define _ASM_X86_DIV64_H
 
3
 
 
4
#ifdef CONFIG_X86_32
 
5
 
 
6
#include <linux/types.h>
 
7
 
 
8
/*
 
9
 * do_div() is NOT a C function. It wants to return
 
10
 * two values (the quotient and the remainder), but
 
11
 * since that doesn't work very well in C, what it
 
12
 * does is:
 
13
 *
 
14
 * - modifies the 64-bit dividend _in_place_
 
15
 * - returns the 32-bit remainder
 
16
 *
 
17
 * This ends up being the most efficient "calling
 
18
 * convention" on x86.
 
19
 */
 
20
#define do_div(n, base)                                         \
 
21
({                                                              \
 
22
        unsigned long __upper, __low, __high, __mod, __base;    \
 
23
        __base = (base);                                        \
 
24
        asm("":"=a" (__low), "=d" (__high) : "A" (n));          \
 
25
        __upper = __high;                                       \
 
26
        if (__high) {                                           \
 
27
                __upper = __high % (__base);                    \
 
28
                __high = __high / (__base);                     \
 
29
        }                                                       \
 
30
        asm("divl %2":"=a" (__low), "=d" (__mod)                \
 
31
            : "rm" (__base), "0" (__low), "1" (__upper));       \
 
32
        asm("":"=A" (n) : "a" (__low), "d" (__high));           \
 
33
        __mod;                                                  \
 
34
})
 
35
 
 
36
static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
 
37
{
 
38
        union {
 
39
                u64 v64;
 
40
                u32 v32[2];
 
41
        } d = { dividend };
 
42
        u32 upper;
 
43
 
 
44
        upper = d.v32[1];
 
45
        d.v32[1] = 0;
 
46
        if (upper >= divisor) {
 
47
                d.v32[1] = upper / divisor;
 
48
                upper %= divisor;
 
49
        }
 
50
        asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) :
 
51
                "rm" (divisor), "0" (d.v32[0]), "1" (upper));
 
52
        return d.v64;
 
53
}
 
54
#define div_u64_rem     div_u64_rem
 
55
 
 
56
#else
 
57
# include <asm-generic/div64.h>
 
58
#endif /* CONFIG_X86_32 */
 
59
 
 
60
#endif /* _ASM_X86_DIV64_H */