]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/Math64.c
MdePkg/BaseLib: Add bit field population calculating methods
[mirror_edk2.git] / MdePkg / Library / BaseLib / Math64.c
1 /** @file
2 Leaf math worker functions that require 64-bit arithmetic support from the
3 compiler.
4
5 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "BaseLibInternals.h"
17
18 /**
19 Shifts a 64-bit integer left between 0 and 63 bits. The low bits
20 are filled with zeros. The shifted value is returned.
21
22 This function shifts the 64-bit value Operand to the left by Count bits. The
23 low Count bits are set to zero. The shifted value is returned.
24
25 @param Operand The 64-bit operand to shift left.
26 @param Count The number of bits to shift left.
27
28 @return Operand << Count.
29
30 **/
31 UINT64
32 EFIAPI
33 InternalMathLShiftU64 (
34 IN UINT64 Operand,
35 IN UINTN Count
36 )
37 {
38 return Operand << Count;
39 }
40
41 /**
42 Shifts a 64-bit integer right between 0 and 63 bits. This high bits
43 are filled with zeros. The shifted value is returned.
44
45 This function shifts the 64-bit value Operand to the right by Count bits. The
46 high Count bits are set to zero. The shifted value is returned.
47
48 @param Operand The 64-bit operand to shift right.
49 @param Count The number of bits to shift right.
50
51 @return Operand >> Count.
52
53 **/
54 UINT64
55 EFIAPI
56 InternalMathRShiftU64 (
57 IN UINT64 Operand,
58 IN UINTN Count
59 )
60 {
61 return Operand >> Count;
62 }
63
64 /**
65 Shifts a 64-bit integer right between 0 and 63 bits. The high bits
66 are filled with original integer's bit 63. The shifted value is returned.
67
68 This function shifts the 64-bit value Operand to the right by Count bits. The
69 high Count bits are set to bit 63 of Operand. The shifted value is returned.
70
71 @param Operand The 64-bit operand to shift right.
72 @param Count The number of bits to shift right.
73
74 @return Operand arithmetically shifted right by Count.
75
76 **/
77 UINT64
78 EFIAPI
79 InternalMathARShiftU64 (
80 IN UINT64 Operand,
81 IN UINTN Count
82 )
83 {
84 INTN TestValue;
85
86 //
87 // Test if this compiler supports arithmetic shift
88 //
89 TestValue = (INTN)((INT64)(1ULL << 63) >> 63);
90 if (TestValue == -1) {
91 //
92 // Arithmetic shift is supported
93 //
94 return (UINT64)((INT64)Operand >> Count);
95 }
96
97 //
98 // Arithmetic is not supported
99 //
100 return (Operand >> Count) |
101 ((INTN)Operand < 0 ? ~((UINTN)-1 >> Count) : 0);
102 }
103
104
105 /**
106 Rotates a 64-bit integer left between 0 and 63 bits, filling
107 the low bits with the high bits that were rotated.
108
109 This function rotates the 64-bit value Operand to the left by Count bits. The
110 low Count bits are fill with the high Count bits of Operand. The rotated
111 value is returned.
112
113 @param Operand The 64-bit operand to rotate left.
114 @param Count The number of bits to rotate left.
115
116 @return Operand <<< Count.
117
118 **/
119 UINT64
120 EFIAPI
121 InternalMathLRotU64 (
122 IN UINT64 Operand,
123 IN UINTN Count
124 )
125 {
126 return (Operand << Count) | (Operand >> (64 - Count));
127 }
128
129 /**
130 Rotates a 64-bit integer right between 0 and 63 bits, filling
131 the high bits with the high low bits that were rotated.
132
133 This function rotates the 64-bit value Operand to the right by Count bits.
134 The high Count bits are fill with the low Count bits of Operand. The rotated
135 value is returned.
136
137 @param Operand The 64-bit operand to rotate right.
138 @param Count The number of bits to rotate right.
139
140 @return Operand >>> Count.
141
142 **/
143 UINT64
144 EFIAPI
145 InternalMathRRotU64 (
146 IN UINT64 Operand,
147 IN UINTN Count
148 )
149 {
150 return (Operand >> Count) | (Operand << (64 - Count));
151 }
152
153 /**
154 Switches the endianess of a 64-bit integer.
155
156 This function swaps the bytes in a 64-bit unsigned value to switch the value
157 from little endian to big endian or vice versa. The byte swapped value is
158 returned.
159
160 @param Operand A 64-bit unsigned value.
161
162 @return The byte swapped Operand.
163
164 **/
165 UINT64
166 EFIAPI
167 InternalMathSwapBytes64 (
168 IN UINT64 Operand
169 )
170 {
171 UINT64 LowerBytes;
172 UINT64 HigherBytes;
173
174 LowerBytes = (UINT64) SwapBytes32 ((UINT32) Operand);
175 HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32));
176
177 return (LowerBytes << 32 | HigherBytes);
178 }
179
180 /**
181 Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer
182 and generates a 64-bit unsigned result.
183
184 This function multiplies the 64-bit unsigned value Multiplicand by the 32-bit
185 unsigned value Multiplier and generates a 64-bit unsigned result. This 64-
186 bit unsigned result is returned.
187
188 @param Multiplicand A 64-bit unsigned value.
189 @param Multiplier A 32-bit unsigned value.
190
191 @return Multiplicand * Multiplier
192
193 **/
194 UINT64
195 EFIAPI
196 InternalMathMultU64x32 (
197 IN UINT64 Multiplicand,
198 IN UINT32 Multiplier
199 )
200 {
201 return Multiplicand * Multiplier;
202 }
203
204
205 /**
206 Multiplies a 64-bit unsigned integer by a 64-bit unsigned integer
207 and generates a 64-bit unsigned result.
208
209 This function multiplies the 64-bit unsigned value Multiplicand by the 64-bit
210 unsigned value Multiplier and generates a 64-bit unsigned result. This 64-
211 bit unsigned result is returned.
212
213 @param Multiplicand A 64-bit unsigned value.
214 @param Multiplier A 64-bit unsigned value.
215
216 @return Multiplicand * Multiplier.
217
218 **/
219 UINT64
220 EFIAPI
221 InternalMathMultU64x64 (
222 IN UINT64 Multiplicand,
223 IN UINT64 Multiplier
224 )
225 {
226 return Multiplicand * Multiplier;
227 }
228
229 /**
230 Divides a 64-bit unsigned integer by a 32-bit unsigned integer and
231 generates a 64-bit unsigned result.
232
233 This function divides the 64-bit unsigned value Dividend by the 32-bit
234 unsigned value Divisor and generates a 64-bit unsigned quotient. This
235 function returns the 64-bit unsigned quotient.
236
237 @param Dividend A 64-bit unsigned value.
238 @param Divisor A 32-bit unsigned value.
239
240 @return Dividend / Divisor.
241
242 **/
243 UINT64
244 EFIAPI
245 InternalMathDivU64x32 (
246 IN UINT64 Dividend,
247 IN UINT32 Divisor
248 )
249 {
250 return Dividend / Divisor;
251 }
252
253 /**
254 Divides a 64-bit unsigned integer by a 32-bit unsigned integer and
255 generates a 32-bit unsigned remainder.
256
257 This function divides the 64-bit unsigned value Dividend by the 32-bit
258 unsigned value Divisor and generates a 32-bit remainder. This function
259 returns the 32-bit unsigned remainder.
260
261 @param Dividend A 64-bit unsigned value.
262 @param Divisor A 32-bit unsigned value.
263
264 @return Dividend % Divisor.
265
266 **/
267 UINT32
268 EFIAPI
269 InternalMathModU64x32 (
270 IN UINT64 Dividend,
271 IN UINT32 Divisor
272 )
273 {
274 return (UINT32)(Dividend % Divisor);
275 }
276
277 /**
278 Divides a 64-bit unsigned integer by a 32-bit unsigned integer and
279 generates a 64-bit unsigned result and an optional 32-bit unsigned remainder.
280
281 This function divides the 64-bit unsigned value Dividend by the 32-bit
282 unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder
283 is not NULL, then the 32-bit unsigned remainder is returned in Remainder.
284 This function returns the 64-bit unsigned quotient.
285
286 @param Dividend A 64-bit unsigned value.
287 @param Divisor A 32-bit unsigned value.
288 @param Remainder A pointer to a 32-bit unsigned value. This parameter is
289 optional and may be NULL.
290
291 @return Dividend / Divisor.
292
293 **/
294 UINT64
295 EFIAPI
296 InternalMathDivRemU64x32 (
297 IN UINT64 Dividend,
298 IN UINT32 Divisor,
299 OUT UINT32 *Remainder OPTIONAL
300 )
301 {
302 if (Remainder != NULL) {
303 *Remainder = (UINT32)(Dividend % Divisor);
304 }
305 return Dividend / Divisor;
306 }
307
308 /**
309 Divides a 64-bit unsigned integer by a 64-bit unsigned integer and
310 generates a 64-bit unsigned result and an optional 64-bit unsigned remainder.
311
312 This function divides the 64-bit unsigned value Dividend by the 64-bit
313 unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder
314 is not NULL, then the 64-bit unsigned remainder is returned in Remainder.
315 This function returns the 64-bit unsigned quotient.
316
317 @param Dividend A 64-bit unsigned value.
318 @param Divisor A 64-bit unsigned value.
319 @param Remainder A pointer to a 64-bit unsigned value. This parameter is
320 optional and may be NULL.
321
322 @return Dividend / Divisor
323
324 **/
325 UINT64
326 EFIAPI
327 InternalMathDivRemU64x64 (
328 IN UINT64 Dividend,
329 IN UINT64 Divisor,
330 OUT UINT64 *Remainder OPTIONAL
331 )
332 {
333 if (Remainder != NULL) {
334 *Remainder = Dividend % Divisor;
335 }
336 return Dividend / Divisor;
337 }
338
339 /**
340 Divides a 64-bit signed integer by a 64-bit signed integer and
341 generates a 64-bit signed result and an optional 64-bit signed remainder.
342
343 This function divides the 64-bit signed value Dividend by the 64-bit
344 signed value Divisor and generates a 64-bit signed quotient. If Remainder
345 is not NULL, then the 64-bit signed remainder is returned in Remainder.
346 This function returns the 64-bit signed quotient.
347
348 @param Dividend A 64-bit signed value.
349 @param Divisor A 64-bit signed value.
350 @param Remainder A pointer to a 64-bit signed value. This parameter is
351 optional and may be NULL.
352
353 @return Dividend / Divisor.
354
355 **/
356 INT64
357 EFIAPI
358 InternalMathDivRemS64x64 (
359 IN INT64 Dividend,
360 IN INT64 Divisor,
361 OUT INT64 *Remainder OPTIONAL
362 )
363 {
364 if (Remainder != NULL) {
365 *Remainder = Dividend % Divisor;
366 }
367 return Dividend / Divisor;
368 }