/* * do_div() is NOT a C function. It wants to return * two values (the quotient and the remainder), but * since that doesn't work very well in C, what it * does is: * * - modifies the 64-bit dividend _in_place_ * - returns the 32-bit remainder * * This ends up being the most efficient "calling * convention" on x86.
*/ #define do_div(n, base) \
({ \ unsignedlong __upper, __low, __high, __mod, __base; \
__base = (base); \ if (__builtin_constant_p(__base) && is_power_of_2(__base)) { \
__mod = n & (__base - 1); \
n >>= ilog2(__base); \
} else { \ asm("" : "=a" (__low), "=d" (__high) : "A" (n));\
__upper = __high; \ if (__high) { \
__upper = __high % (__base); \
__high = __high / (__base); \
} \ asm("divl %2" : "=a" (__low), "=d" (__mod) \
: "rm" (__base), "0" (__low), "1" (__upper)); \ asm("" : "=A" (n) : "a" (__low), "d" (__high)); \
} \
__mod; \
})
/* * __div64_32() is never called on x86, so prevent the * generic definition from getting built.
*/ #define __div64_32
#else # include <asm-generic/div64.h>
/* * Will generate an #DE when the result doesn't fit u64, could fix with an * __ex_table[] entry when it becomes an issue.
*/ staticinline u64 mul_u64_u64_div_u64(u64 a, u64 mul, u64 div)
{
u64 q;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.