1/*
2 * Copyright (c) 1998-2012 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23#ifndef __BIGNUM128_H__
24#define __BIGNUM128_H__
25
26#include <libkern/OSTypes.h>
27#include <stdint.h>
28
29class U128
30{
31public:
32	U128(uint64_t _lo = 0) : lo(_lo), hi(0)				{ };
33	U128(uint64_t _hi, uint64_t _lo)	: lo(_lo), hi(_hi)	{ };
34	inline bool operator==( const U128 &A ) const	 	{ return ( A.hi == hi ) && ( A.lo == lo ); }
35	inline bool operator>( const U128 &A ) const		{ return ( ( A.hi > hi ) || ( ( A.hi == hi ) && ( A.lo > lo ) ) ); }
36	inline bool operator<( const U128 &A ) const 		{ return !( ( A.hi > hi ) || ( ( A.hi == hi ) && ( A.lo > lo ) ) ); }
37
38	U128 operator++( int )
39	{
40		if ( ++lo==0 )
41			hi++;
42
43		return *this;
44	}
45
46	U128 operator--( int )
47	{
48		if ( 0 == lo-- )
49		{
50			hi--;
51		}
52		return *this;
53	}
54
55	U128& operator=( const U128 &A )
56	{
57		hi = A.hi;
58		lo = A.lo;
59
60		return *this;
61	}
62
63	U128 operator+( const U128 &A ) const
64	{
65		U128	result(A.hi + hi, A.lo + lo);
66
67		if ( ( result.lo < A.lo ) || ( result.lo < lo ) )
68		{
69			result.hi++;
70		}
71
72		return result;
73	}
74
75	U128& operator+=( const U128 &A )
76	{
77		U128	result(A.hi + hi, A.lo + lo);
78
79		if ( ( result.lo < A.lo ) || ( result.lo < lo ) )
80		{
81			result.hi++;
82		}
83
84		*this = result;
85
86		return *this;
87	}
88
89	friend U128 operator-( const U128 &A, const U128 &B )		// assumes A >= B
90	{
91		U128 C = A;
92
93		C.hi -= B.hi;
94		C.lo -= B.lo;
95
96		if ( C.lo > A.lo )		 // borrow ?
97		{
98			C.hi--;
99		}
100
101		return C;
102	}
103
104
105	friend U128 operator<<( const U128& A, int n )
106	{
107		U128 res = A;
108
109		while ( n-- )
110		{
111			res.hi <<= 1;
112			res.hi |= ( ( res.lo & MSB64 ) ? 1 : 0 );
113			res.lo <<= 1;
114		}
115
116		return res;
117	}
118
119	friend U128 operator>>( const U128& A, int n )
120	{
121		U128 res = A;
122
123		while ( n-- )
124		{
125			res.lo >>= 1;
126			res.lo |= ( ( res.hi & 0x1 ) ? MSB64 : 0 );
127			res.hi >>= 1;
128		}
129
130		return res;
131	}
132
133public:
134
135#ifdef __BIG_ENDIAN__
136	uint64_t		hi;
137	uint64_t		lo;
138#else
139	uint64_t		lo;
140	uint64_t		hi;
141#endif
142
143private:
144	enum { MSB64 = 0x8000000000000000ULL };
145};
146
147extern U128 UInt64mult(const uint64_t A, const uint64_t B);
148
149#endif			//__BIGNUM128_H__
150
151
152
153
154
155