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