]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Math.c
ba00c8bb3d3f467923c902cb2ce2abe4bc95baac
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / EfiCommonLib / Math.c
1 /*++
2
3 Copyright (c) 2004, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 Math.c
15
16 Abstract:
17
18 Math worker functions.
19
20 --*/
21
22 #include "Tiano.h"
23
24 UINT64
25 LShiftU64 (
26 IN UINT64 Operand,
27 IN UINTN Count
28 )
29 /*++
30
31 Routine Description:
32
33 This routine allows a 64 bit value to be left shifted by 32 bits and
34 returns the shifted value.
35 Count is valid up 63. (Only Bits 0-5 is valid for Count)
36
37 Arguments:
38
39 Operand - Value to be shifted
40 Count - Number of times to shift left.
41
42 Returns:
43
44 Value shifted left identified by the Count.
45
46 --*/
47 {
48 return Operand << Count;
49 }
50
51 UINT64
52 MultU64x32 (
53 IN UINT64 Multiplicand,
54 IN UINTN Multiplier
55 )
56 /*++
57
58 Routine Description:
59
60 This routine allows a 64 bit value to be multiplied with a 32 bit
61 value returns 64bit result.
62 No checking if the result is greater than 64bits
63
64 Arguments:
65
66 Multiplicand - multiplicand
67 Multiplier - multiplier
68
69 Returns:
70
71 Multiplicand * Multiplier
72
73 --*/
74 {
75 return Multiplicand * Multiplier;
76 }
77
78 UINT64
79 RShiftU64 (
80 IN UINT64 Operand,
81 IN UINTN Count
82 )
83 /*++
84
85 Routine Description:
86
87 This routine allows a 64 bit value to be right shifted by 32 bits and returns the
88 shifted value.
89 Count is valid up 63. (Only Bits 0-5 is valid for Count)
90
91 Arguments:
92
93 Operand - Value to be shifted
94 Count - Number of times to shift right.
95
96 Returns:
97
98 Value shifted right identified by the Count.
99
100 --*/
101 {
102 return Operand >> Count;
103 }
104
105 UINT64
106 DivU64x32 (
107 IN UINT64 Dividend,
108 IN UINTN Divisor,
109 OUT UINTN *Remainder OPTIONAL
110 )
111 /*++
112
113 Routine Description:
114
115 This routine allows a 64 bit value to be divided with a 32 bit value returns
116 64bit result and the Remainder.
117
118 Arguments:
119
120 Dividend - dividend
121 Divisor - divisor
122 Remainder - buffer for remainder
123
124 Returns:
125
126 Dividend / Divisor
127 Remainder = Dividend mod Divisor
128
129 --*/
130 {
131 if (Remainder != NULL) {
132 *Remainder = Dividend % Divisor;
133 }
134
135 return Dividend / Divisor;
136 }
137
138 UINT8
139 Log2 (
140 IN UINT64 Operand
141 )
142 /*++
143
144 Routine Description:
145
146 This function computes rounded down log2 of the Operand. This is an equivalent
147 of the position of the highest bit set in the Operand treated as a mask.
148 E.g., Log2 (0x0001) == 0, Log2 (0x0002) == 1, Log2 (0x0003) == 1, Log2 (0x0005) == 2
149 Log2 (0x4000) == 14, Log2 (0x8000) == 15, Log2 (0xC000) == 15, Log2 (0xFFFF) == 15, etc.
150
151 Arguments:
152 Operand - value of which the Log2 is to be computed.
153
154 Returns:
155 Rounded down log2 of the Operand or 0xFF if zero passed in.
156
157 --*/
158 {
159 UINT8 Bitpos;
160 Bitpos = 0;
161
162 if (Operand == 0) {
163 return (0xff);
164 }
165
166 while (Operand != 0) {
167 Operand >>= 1;
168 Bitpos++;
169 }
170 return (UINT8)(Bitpos - 1);
171
172 }
173
174 UINT64
175 GetPowerOfTwo (
176 IN UINT64 Operand
177 )
178 /*++
179
180 Routine Description:
181
182 Calculates the largest integer that is both
183 a power of two and less than Input
184
185 Arguments:
186
187 Operand - value to calculate power of two
188
189 Returns:
190
191 the largest integer that is both a power of
192 two and less than Input
193
194 --*/
195 {
196 UINT8 Bitpos;
197 Bitpos = 0;
198
199 if (Operand == 0) {
200 return 0;
201 }
202
203 while (Operand != 0) {
204 Operand >>= 1;
205 Bitpos++;
206 }
207
208 Operand = 1;
209 Bitpos--;
210 while (Bitpos != 0) {
211 Operand <<= 1;
212 Bitpos--;
213 }
214
215 return Operand;
216 }