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