]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/kern/arithmetic_128.h
2 * Copyright (c) 1999, 2003, 2006, 2007, 2010 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 * Code duplicated from Libc/gen/nanosleep.c
27 #ifndef _ARITHMETIC_128_H_
28 #define _ARITHMETIC_128_H_
34 static __inline
uint64_t
35 multi_overflow(uint64_t a
, uint64_t b
)
38 prod
= (__uint128_t
)a
* (__uint128_t
)b
;
39 return (uint64_t) (prod
>> 64);
49 /* 128-bit addition: acc += add */
51 add128_128(uint128_data_t
*acc
, uint128_data_t
*add
)
53 acc
->high
+= add
->high
;
55 if (acc
->low
< add
->low
) {
60 /* 64x64 -> 128 bit multiplication */
62 mul64x64(uint64_t x
, uint64_t y
, uint128_data_t
*prod
)
66 * Split the two 64-bit multiplicands into 32-bit parts:
70 uint32_t x1
= (uint32_t)(x
>> 32);
71 uint32_t x2
= (uint32_t)x
;
72 uint32_t y1
= (uint32_t)(y
>> 32);
73 uint32_t y2
= (uint32_t)y
;
75 * direct multiplication:
76 * x * y => 2^64 * (x1 * y1) + 2^32 (x1 * y2 + x2 * y1) + (x2 * y2)
77 * The first and last terms are direct assignmenet into the uint128_t
78 * structure. Then we add the middle two terms separately, to avoid
79 * 64-bit overflow. (We could use the Karatsuba algorithm to save
80 * one multiply, but it is harder to deal with 64-bit overflows.)
82 prod
->high
= (uint64_t)x1
* (uint64_t)y1
;
83 prod
->low
= (uint64_t)x2
* (uint64_t)y2
;
84 add
.low
= (uint64_t)x1
* (uint64_t)y2
;
85 add
.high
= (add
.low
>> 32);
87 add128_128(prod
, &add
);
88 add
.low
= (uint64_t)x2
* (uint64_t)y1
;
89 add
.high
= (add
.low
>> 32);
91 add128_128(prod
, &add
);
94 static __inline
uint64_t
95 multi_overflow(uint64_t a
, uint64_t b
)
98 mul64x64(a
, b
, &prod
);
102 #endif /* __LP64__ */
103 #endif /* _ARITHMETIC_128_H_ */