diff options
author | gm281@boulderdash.cl.cam.ac.uk <gm281@boulderdash.cl.cam.ac.uk> | 2004-08-04 16:19:59 +0000 |
---|---|---|
committer | gm281@boulderdash.cl.cam.ac.uk <gm281@boulderdash.cl.cam.ac.uk> | 2004-08-04 16:19:59 +0000 |
commit | 4e7ebaddbb5072689dbd08f4f3384131569e367c (patch) | |
tree | 157a46edcf12bc0916e76d04dc554e21a4e3c785 /xen/common/lib.c | |
parent | f8c0a4a63356942a67dbd3105e98f90d4d90545e (diff) | |
download | xen-4e7ebaddbb5072689dbd08f4f3384131569e367c.tar.gz xen-4e7ebaddbb5072689dbd08f4f3384131569e367c.tar.bz2 xen-4e7ebaddbb5072689dbd08f4f3384131569e367c.zip |
bitkeeper revision 1.1144.1.1 (41110cafHhGko2QnIa3NEGARA_3f3Q)
Addition of libc functions which allow to do 64 bit mod operations.
Diffstat (limited to 'xen/common/lib.c')
-rw-r--r-- | xen/common/lib.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/xen/common/lib.c b/xen/common/lib.c index 256ec34294..b01d5a1727 100644 --- a/xen/common/lib.c +++ b/xen/common/lib.c @@ -354,10 +354,10 @@ __qdivrem(uq, vq, arq) return (tmp.q); } - /* * Divide two signed quads. * ??? if -1/2 should produce -1 on this machine, this code is wrong + * (Grzegorz Milos) Note for the above: -1/2 is 0. And so it should. */ s64 __divdi3(s64 a, s64 b) @@ -377,6 +377,7 @@ __divdi3(s64 a, s64 b) return (neg ? -uq : uq); } + /* * Divide two unsigned quads. */ @@ -388,4 +389,55 @@ __udivdi3(a, b) return (__qdivrem(a, b, (u64 *)0)); } +/* + * Remainder of unsigned quad division + */ +u64 __umoddi3(u64 a, u64 b) +{ + u64 rem; + __qdivrem(a, b, &rem); + return rem; +} + +/* + * Remainder of signed quad division. + * The result of mod is not always equal to division + * remainder. The following example shows the result for all + * four possible cases: + * 11 % 5 = 1 + * -11 % 5 = 4 + * 11 % -5 = -4 + * -11 % -5 = -1 + */ +s64 __moddi3(s64 a, s64 b) +{ + u64 ua, ub, urem; + int neg1, neg2; + + if (a < 0) + ua = -(u64)a, neg1 = 1; + else + ua = a, neg1 = 0; + + if (b < 0) + ub = -(u64)b, neg2 = 1; + else + ub = b, neg2 = 0; + __qdivrem(ua, ub, &urem); + + /* There 4 different cases: */ + if(neg1) + { + if(neg2) + return -urem; + else + return ub - urem; + } + else + if(neg2) + return -ub + urem; + else + return urem; +} + #endif /* BITS_PER_LONG == 32 */ |