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