1/*
2 * @APPLE_LICENSE_HEADER_START@
3 *
4 * Copyright (c) 1999-2010 Apple Computer, Inc.  All Rights Reserved.
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#ifndef _IOFIXED64_H
25#define _IOFIXED64_H
26
27#include <IOKit/IOTypes.h>
28#include <machine/limits.h>
29
30#ifndef INT_MAX
31#define	INT_MAX	2147483647L	/* max signed int */
32#endif
33
34#ifndef INT_MIN
35#define	INT_MIN	(-2147483647L-1) /* min signed int */
36#endif
37
38//===========================================================================
39class IOFixed64 {
40public:
41    IOFixed64() {
42        value = 0;
43    }
44
45    SInt64 as64() const {
46        return value / 65536LL;
47    }
48
49    SInt64 asFixed64() const {
50        return value;
51    }
52
53    SInt32 asFixed24x8() const {
54        return value / 256LL;
55    }
56
57    UInt16 fraction() const {
58        UInt64 result;
59        if( value < 0LL )
60            result = value | ~0xffffLL;
61        else
62            result = value & 0xffffLL;
63        return result;
64    }
65
66    SInt32 as32() const {
67        SInt64 result = as64();
68
69        if (result > INT_MAX)
70            return INT_MAX;
71
72        if (result < INT_MIN)
73            return INT_MIN;
74
75        return (SInt32)result;
76    }
77
78    IOFixed asFixed() const {
79        if (value > INT_MAX)
80            return INT_MAX;
81
82        if (value < INT_MIN)
83            return INT_MIN;
84
85        return IOFixed(value);
86    }
87
88    IOFixed64& fromIntFloor(SInt64 x) {
89        value = (x * 65536LL);
90        return *this;
91    }
92
93    static IOFixed64 withIntFloor(SInt64 x) {
94        IOFixed64 result;
95        return result.fromIntFloor(x);
96    }
97
98    IOFixed64& fromIntCeiling(SInt64 x) {
99        value = (x * 65536LL) + 65535LL;
100        return *this;
101    }
102
103    IOFixed64& fromFixed(IOFixed x) {
104        value = x;
105        return *this;
106    }
107
108    static IOFixed64 withFixed(IOFixed x) {
109        IOFixed64 result;
110        return result.fromFixed(x);
111    }
112
113    IOFixed64& fromFixed64(SInt64 x) {
114        value = x;
115        return *this;
116    }
117
118    IOFixed64& fromFixed24x8(SInt32 x) {
119        value = x * 256LL;
120        return *this;
121    }
122
123    IOFixed64& operator+=(IOFixed64 x) {
124        value += x.value;
125        return *this;
126    }
127
128    IOFixed64& operator-=(IOFixed64 x) {
129        value -= x.value;
130        return *this;
131    }
132
133    IOFixed64& operator*=(IOFixed64 x) {
134        value *= x.value;
135        value /= 65536LL;
136        return *this;
137    }
138
139    IOFixed64& operator/=(IOFixed64 x) {
140        value *= 65536LL;
141        value /= x.value;
142        return *this;
143    }
144
145    IOFixed64& operator+=(SInt64 x) {
146        value += x * 65536LL;
147        return *this;
148    }
149
150    IOFixed64& operator-=(SInt64 x) {
151        value -= x * 65536LL;
152        return *this;
153    }
154
155    IOFixed64& operator*=(SInt64 x) {
156        value *= x;
157        return *this;
158    }
159
160    IOFixed64& operator/=(SInt64 x) {
161        value /= x;
162        return *this;
163    }
164
165    operator const bool() {
166        return (value != 0);
167    }
168
169#define BOOL_OPERATOR(X) \
170bool operator X (const IOFixed64 b) const { return value X b.value; }; \
171bool operator X (const SInt64 b) const { return value X (b * 65536LL); };
172
173    BOOL_OPERATOR(>)
174    BOOL_OPERATOR(>=)
175    BOOL_OPERATOR(<)
176    BOOL_OPERATOR(<=)
177    BOOL_OPERATOR(==)
178    BOOL_OPERATOR(!=)
179
180#undef BOOL_OPERATOR
181
182private:
183    SInt64 value;
184};
185
186//===========================================================================
187IOFixed64 operator* (const IOFixed64 a, const IOFixed64 b);
188IOFixed64 operator* (const IOFixed64 b, const SInt64 a);
189IOFixed64 operator/ (const IOFixed64 a, const IOFixed64 b);
190IOFixed64 operator/ (const IOFixed64 a, const SInt64 b);
191IOFixed64 operator+ (const IOFixed64 a, const IOFixed64 b);
192IOFixed64 operator+ (const IOFixed64 a, const SInt64 b);
193IOFixed64 operator- (const IOFixed64 a, const IOFixed64 b);
194IOFixed64 operator- (const IOFixed64 a, const SInt64 b);
195IOFixed64 exponent(const IOFixed64 original, const UInt8 power);
196UInt32 llsqrt(UInt64 x);
197UInt16 lsqrt(UInt32 x);
198IOFixed64 IOQuarticFunction( const IOFixed64 x, const IOFixed64 *gains );
199IOFixed64 IOQuarticDerivative( const IOFixed64 x, const IOFixed64 *gains );
200
201//===========================================================================
202#endif // _IOFIXED64_H
203