Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/include/asm-generic/div64.h
10814 views
1
#ifndef _ASM_GENERIC_DIV64_H
2
#define _ASM_GENERIC_DIV64_H
3
/*
4
* Copyright (C) 2003 Bernardo Innocenti <[email protected]>
5
* Based on former asm-ppc/div64.h and asm-m68knommu/div64.h
6
*
7
* The semantics of do_div() are:
8
*
9
* uint32_t do_div(uint64_t *n, uint32_t base)
10
* {
11
* uint32_t remainder = *n % base;
12
* *n = *n / base;
13
* return remainder;
14
* }
15
*
16
* NOTE: macro parameter n is evaluated multiple times,
17
* beware of side effects!
18
*/
19
20
#include <linux/types.h>
21
#include <linux/compiler.h>
22
23
#if BITS_PER_LONG == 64
24
25
# define do_div(n,base) ({ \
26
uint32_t __base = (base); \
27
uint32_t __rem; \
28
__rem = ((uint64_t)(n)) % __base; \
29
(n) = ((uint64_t)(n)) / __base; \
30
__rem; \
31
})
32
33
#elif BITS_PER_LONG == 32
34
35
extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
36
37
/* The unnecessary pointer compare is there
38
* to check for type safety (n must be 64bit)
39
*/
40
# define do_div(n,base) ({ \
41
uint32_t __base = (base); \
42
uint32_t __rem; \
43
(void)(((typeof((n)) *)0) == ((uint64_t *)0)); \
44
if (likely(((n) >> 32) == 0)) { \
45
__rem = (uint32_t)(n) % __base; \
46
(n) = (uint32_t)(n) / __base; \
47
} else \
48
__rem = __div64_32(&(n), __base); \
49
__rem; \
50
})
51
52
#else /* BITS_PER_LONG == ?? */
53
54
# error do_div() does not yet support the C64
55
56
#endif /* BITS_PER_LONG */
57
58
#endif /* _ASM_GENERIC_DIV64_H */
59
60