]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/BitField.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / BaseLib / BitField.c
CommitLineData
e1f414b6 1/** @file\r
2 Bit field functions of BaseLib.\r
3\r
9095d37b 4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
9344f092 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
e1f414b6 6\r
e1f414b6 7**/\r
8\r
e1f414b6 9#include "BaseLibInternals.h"\r
10\r
11/**\r
2fc60b70 12 Worker function that returns a bit field from Operand.\r
e1f414b6 13\r
14 Returns the bitfield specified by the StartBit and the EndBit from Operand.\r
15\r
16 @param Operand Operand on which to perform the bitfield operation.\r
17 @param StartBit The ordinal of the least significant bit in the bit field.\r
18 @param EndBit The ordinal of the most significant bit in the bit field.\r
19\r
20 @return The bit field read.\r
21\r
22**/\r
28ca72bc 23UINTN\r
38bbd3d9 24EFIAPI\r
80151e53 25InternalBaseLibBitFieldReadUint (\r
28ca72bc 26 IN UINTN Operand,\r
e1f414b6 27 IN UINTN StartBit,\r
28 IN UINTN EndBit\r
29 )\r
30{\r
31 //\r
28ca72bc 32 // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]\r
e1f414b6 33 // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.\r
34 //\r
28ca72bc 35 return (Operand & ~((UINTN)-2 << EndBit)) >> StartBit;\r
e1f414b6 36}\r
37\r
38/**\r
2fc60b70 39 Worker function that reads a bit field from Operand, performs a bitwise OR,\r
e1f414b6 40 and returns the result.\r
41\r
42 Performs a bitwise OR between the bit field specified by StartBit and EndBit\r
43 in Operand and the value specified by AndData. All other bits in Operand are\r
44 preserved. The new value is returned.\r
45\r
94952554
LG
46 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
47\r
e1f414b6 48 @param Operand Operand on which to perform the bitfield operation.\r
49 @param StartBit The ordinal of the least significant bit in the bit field.\r
50 @param EndBit The ordinal of the most significant bit in the bit field.\r
127010dd 51 @param OrData The value to OR with the read value from the value.\r
e1f414b6 52\r
53 @return The new value.\r
54\r
55**/\r
28ca72bc 56UINTN\r
38bbd3d9 57EFIAPI\r
80151e53 58InternalBaseLibBitFieldOrUint (\r
28ca72bc 59 IN UINTN Operand,\r
e1f414b6 60 IN UINTN StartBit,\r
61 IN UINTN EndBit,\r
28ca72bc 62 IN UINTN OrData\r
e1f414b6 63 )\r
64{\r
94952554 65 //\r
9095d37b 66 // Higher bits in OrData those are not used must be zero.\r
94952554 67 //\r
77518065
LG
68 // EndBit - StartBit + 1 might be 32 while the result right shifting 32 on a 32bit integer is undefined,\r
69 // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.\r
499ceb8e
LG
70 //\r
71 ASSERT ((OrData >> (EndBit - StartBit)) == ((OrData >> (EndBit - StartBit)) & 1));\r
9095d37b 72\r
e1f414b6 73 //\r
28ca72bc 74 // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]\r
e1f414b6 75 // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.\r
76 //\r
28ca72bc 77 return Operand | ((OrData << StartBit) & ~((UINTN) -2 << EndBit));\r
e1f414b6 78}\r
79\r
80/**\r
2fc60b70 81 Worker function that reads a bit field from Operand, performs a bitwise AND,\r
e1f414b6 82 and returns the result.\r
83\r
84 Performs a bitwise AND between the bit field specified by StartBit and EndBit\r
85 in Operand and the value specified by AndData. All other bits in Operand are\r
86 preserved. The new value is returned.\r
87\r
94952554
LG
88 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
89\r
e1f414b6 90 @param Operand Operand on which to perform the bitfield operation.\r
91 @param StartBit The ordinal of the least significant bit in the bit field.\r
92 @param EndBit The ordinal of the most significant bit in the bit field.\r
127010dd 93 @param AndData The value to And with the read value from the value.\r
e1f414b6 94\r
95 @return The new value.\r
96\r
97**/\r
28ca72bc 98UINTN\r
38bbd3d9 99EFIAPI\r
80151e53 100InternalBaseLibBitFieldAndUint (\r
28ca72bc 101 IN UINTN Operand,\r
e1f414b6 102 IN UINTN StartBit,\r
103 IN UINTN EndBit,\r
28ca72bc 104 IN UINTN AndData\r
e1f414b6 105 )\r
106{\r
94952554 107 //\r
9095d37b 108 // Higher bits in AndData those are not used must be zero.\r
94952554 109 //\r
77518065
LG
110 // EndBit - StartBit + 1 might be 32 while the result right shifting 32 on a 32bit integer is undefined,\r
111 // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.\r
499ceb8e
LG
112 //\r
113 ASSERT ((AndData >> (EndBit - StartBit)) == ((AndData >> (EndBit - StartBit)) & 1));\r
94952554 114\r
e1f414b6 115 //\r
28ca72bc 116 // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]\r
e1f414b6 117 // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.\r
118 //\r
28ca72bc 119 return Operand & ~((~AndData << StartBit) & ~((UINTN)-2 << EndBit));\r
e1f414b6 120}\r
121\r
122/**\r
123 Returns a bit field from an 8-bit value.\r
124\r
125 Returns the bitfield specified by the StartBit and the EndBit from Operand.\r
126\r
127 If 8-bit operations are not supported, then ASSERT().\r
128 If StartBit is greater than 7, then ASSERT().\r
129 If EndBit is greater than 7, then ASSERT().\r
130 If EndBit is less than StartBit, then ASSERT().\r
131\r
132 @param Operand Operand on which to perform the bitfield operation.\r
133 @param StartBit The ordinal of the least significant bit in the bit field.\r
134 Range 0..7.\r
135 @param EndBit The ordinal of the most significant bit in the bit field.\r
136 Range 0..7.\r
137\r
138 @return The bit field read.\r
139\r
140**/\r
141UINT8\r
142EFIAPI\r
143BitFieldRead8 (\r
144 IN UINT8 Operand,\r
145 IN UINTN StartBit,\r
146 IN UINTN EndBit\r
147 )\r
148{\r
5385a579 149 ASSERT (EndBit < 8);\r
e1f414b6 150 ASSERT (StartBit <= EndBit);\r
80151e53 151 return (UINT8)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit);\r
e1f414b6 152}\r
153\r
154/**\r
155 Writes a bit field to an 8-bit value, and returns the result.\r
156\r
157 Writes Value to the bit field specified by the StartBit and the EndBit in\r
158 Operand. All other bits in Operand are preserved. The new 8-bit value is\r
159 returned.\r
160\r
161 If 8-bit operations are not supported, then ASSERT().\r
162 If StartBit is greater than 7, then ASSERT().\r
163 If EndBit is greater than 7, then ASSERT().\r
164 If EndBit is less than StartBit, then ASSERT().\r
94952554 165 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 166\r
167 @param Operand Operand on which to perform the bitfield operation.\r
168 @param StartBit The ordinal of the least significant bit in the bit field.\r
169 Range 0..7.\r
170 @param EndBit The ordinal of the most significant bit in the bit field.\r
171 Range 0..7.\r
2fc59a00 172 @param Value The new value of the bit field.\r
e1f414b6 173\r
174 @return The new 8-bit value.\r
175\r
176**/\r
177UINT8\r
178EFIAPI\r
179BitFieldWrite8 (\r
180 IN UINT8 Operand,\r
181 IN UINTN StartBit,\r
182 IN UINTN EndBit,\r
183 IN UINT8 Value\r
184 )\r
185{\r
5385a579 186 ASSERT (EndBit < 8);\r
e1f414b6 187 ASSERT (StartBit <= EndBit);\r
188 return BitFieldAndThenOr8 (Operand, StartBit, EndBit, 0, Value);\r
189}\r
190\r
191/**\r
192 Reads a bit field from an 8-bit value, performs a bitwise OR, and returns the\r
193 result.\r
194\r
62991af2 195 Performs a bitwise OR between the bit field specified by StartBit\r
e1f414b6 196 and EndBit in Operand and the value specified by OrData. All other bits in\r
197 Operand are preserved. The new 8-bit value is returned.\r
198\r
199 If 8-bit operations are not supported, then ASSERT().\r
200 If StartBit is greater than 7, then ASSERT().\r
201 If EndBit is greater than 7, then ASSERT().\r
202 If EndBit is less than StartBit, then ASSERT().\r
94952554 203 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 204\r
205 @param Operand Operand on which to perform the bitfield operation.\r
206 @param StartBit The ordinal of the least significant bit in the bit field.\r
207 Range 0..7.\r
208 @param EndBit The ordinal of the most significant bit in the bit field.\r
209 Range 0..7.\r
127010dd 210 @param OrData The value to OR with the read value from the value.\r
e1f414b6 211\r
212 @return The new 8-bit value.\r
213\r
214**/\r
215UINT8\r
216EFIAPI\r
217BitFieldOr8 (\r
218 IN UINT8 Operand,\r
219 IN UINTN StartBit,\r
220 IN UINTN EndBit,\r
221 IN UINT8 OrData\r
222 )\r
223{\r
5385a579 224 ASSERT (EndBit < 8);\r
e1f414b6 225 ASSERT (StartBit <= EndBit);\r
80151e53 226 return (UINT8)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData);\r
e1f414b6 227}\r
228\r
229/**\r
230 Reads a bit field from an 8-bit value, performs a bitwise AND, and returns\r
231 the result.\r
232\r
233 Performs a bitwise AND between the bit field specified by StartBit and EndBit\r
234 in Operand and the value specified by AndData. All other bits in Operand are\r
235 preserved. The new 8-bit value is returned.\r
236\r
237 If 8-bit operations are not supported, then ASSERT().\r
238 If StartBit is greater than 7, then ASSERT().\r
239 If EndBit is greater than 7, then ASSERT().\r
240 If EndBit is less than StartBit, then ASSERT().\r
94952554 241 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 242\r
243 @param Operand Operand on which to perform the bitfield operation.\r
244 @param StartBit The ordinal of the least significant bit in the bit field.\r
245 Range 0..7.\r
246 @param EndBit The ordinal of the most significant bit in the bit field.\r
247 Range 0..7.\r
248 @param AndData The value to AND with the read value from the value.\r
249\r
250 @return The new 8-bit value.\r
251\r
252**/\r
253UINT8\r
254EFIAPI\r
255BitFieldAnd8 (\r
256 IN UINT8 Operand,\r
257 IN UINTN StartBit,\r
258 IN UINTN EndBit,\r
259 IN UINT8 AndData\r
260 )\r
261{\r
5385a579 262 ASSERT (EndBit < 8);\r
e1f414b6 263 ASSERT (StartBit <= EndBit);\r
80151e53 264 return (UINT8)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData);\r
e1f414b6 265}\r
266\r
267/**\r
268 Reads a bit field from an 8-bit value, performs a bitwise AND followed by a\r
269 bitwise OR, and returns the result.\r
270\r
271 Performs a bitwise AND between the bit field specified by StartBit and EndBit\r
9095d37b 272 in Operand and the value specified by AndData, followed by a bitwise\r
62991af2 273 OR with value specified by OrData. All other bits in Operand are\r
e1f414b6 274 preserved. The new 8-bit value is returned.\r
275\r
276 If 8-bit operations are not supported, then ASSERT().\r
277 If StartBit is greater than 7, then ASSERT().\r
278 If EndBit is greater than 7, then ASSERT().\r
279 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
280 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
281 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 282\r
283 @param Operand Operand on which to perform the bitfield operation.\r
284 @param StartBit The ordinal of the least significant bit in the bit field.\r
285 Range 0..7.\r
286 @param EndBit The ordinal of the most significant bit in the bit field.\r
287 Range 0..7.\r
288 @param AndData The value to AND with the read value from the value.\r
289 @param OrData The value to OR with the result of the AND operation.\r
290\r
291 @return The new 8-bit value.\r
292\r
293**/\r
294UINT8\r
295EFIAPI\r
296BitFieldAndThenOr8 (\r
297 IN UINT8 Operand,\r
298 IN UINTN StartBit,\r
299 IN UINTN EndBit,\r
300 IN UINT8 AndData,\r
301 IN UINT8 OrData\r
302 )\r
303{\r
5385a579 304 ASSERT (EndBit < 8);\r
e1f414b6 305 ASSERT (StartBit <= EndBit);\r
306 return BitFieldOr8 (\r
307 BitFieldAnd8 (Operand, StartBit, EndBit, AndData),\r
308 StartBit,\r
309 EndBit,\r
310 OrData\r
311 );\r
312}\r
313\r
314/**\r
315 Returns a bit field from a 16-bit value.\r
316\r
317 Returns the bitfield specified by the StartBit and the EndBit from Operand.\r
318\r
319 If 16-bit operations are not supported, then ASSERT().\r
320 If StartBit is greater than 15, then ASSERT().\r
321 If EndBit is greater than 15, then ASSERT().\r
322 If EndBit is less than StartBit, then ASSERT().\r
323\r
324 @param Operand Operand on which to perform the bitfield operation.\r
325 @param StartBit The ordinal of the least significant bit in the bit field.\r
326 Range 0..15.\r
327 @param EndBit The ordinal of the most significant bit in the bit field.\r
328 Range 0..15.\r
329\r
330 @return The bit field read.\r
331\r
332**/\r
333UINT16\r
334EFIAPI\r
335BitFieldRead16 (\r
336 IN UINT16 Operand,\r
337 IN UINTN StartBit,\r
338 IN UINTN EndBit\r
339 )\r
340{\r
5385a579 341 ASSERT (EndBit < 16);\r
e1f414b6 342 ASSERT (StartBit <= EndBit);\r
80151e53 343 return (UINT16)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit);\r
e1f414b6 344}\r
345\r
346/**\r
347 Writes a bit field to a 16-bit value, and returns the result.\r
348\r
349 Writes Value to the bit field specified by the StartBit and the EndBit in\r
350 Operand. All other bits in Operand are preserved. The new 16-bit value is\r
351 returned.\r
352\r
353 If 16-bit operations are not supported, then ASSERT().\r
354 If StartBit is greater than 15, then ASSERT().\r
355 If EndBit is greater than 15, then ASSERT().\r
356 If EndBit is less than StartBit, then ASSERT().\r
94952554 357 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 358\r
359 @param Operand Operand on which to perform the bitfield operation.\r
360 @param StartBit The ordinal of the least significant bit in the bit field.\r
361 Range 0..15.\r
362 @param EndBit The ordinal of the most significant bit in the bit field.\r
363 Range 0..15.\r
2fc59a00 364 @param Value The new value of the bit field.\r
e1f414b6 365\r
366 @return The new 16-bit value.\r
367\r
368**/\r
369UINT16\r
370EFIAPI\r
371BitFieldWrite16 (\r
372 IN UINT16 Operand,\r
373 IN UINTN StartBit,\r
374 IN UINTN EndBit,\r
375 IN UINT16 Value\r
376 )\r
377{\r
5385a579 378 ASSERT (EndBit < 16);\r
e1f414b6 379 ASSERT (StartBit <= EndBit);\r
380 return BitFieldAndThenOr16 (Operand, StartBit, EndBit, 0, Value);\r
381}\r
382\r
383/**\r
384 Reads a bit field from a 16-bit value, performs a bitwise OR, and returns the\r
385 result.\r
386\r
62991af2 387 Performs a bitwise OR between the bit field specified by StartBit\r
e1f414b6 388 and EndBit in Operand and the value specified by OrData. All other bits in\r
389 Operand are preserved. The new 16-bit value is returned.\r
390\r
391 If 16-bit operations are not supported, then ASSERT().\r
392 If StartBit is greater than 15, then ASSERT().\r
393 If EndBit is greater than 15, then ASSERT().\r
394 If EndBit is less than StartBit, then ASSERT().\r
94952554 395 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 396\r
397 @param Operand Operand on which to perform the bitfield operation.\r
398 @param StartBit The ordinal of the least significant bit in the bit field.\r
399 Range 0..15.\r
400 @param EndBit The ordinal of the most significant bit in the bit field.\r
401 Range 0..15.\r
127010dd 402 @param OrData The value to OR with the read value from the value.\r
e1f414b6 403\r
404 @return The new 16-bit value.\r
405\r
406**/\r
407UINT16\r
408EFIAPI\r
409BitFieldOr16 (\r
410 IN UINT16 Operand,\r
411 IN UINTN StartBit,\r
412 IN UINTN EndBit,\r
413 IN UINT16 OrData\r
414 )\r
415{\r
5385a579 416 ASSERT (EndBit < 16);\r
e1f414b6 417 ASSERT (StartBit <= EndBit);\r
80151e53 418 return (UINT16)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData);\r
e1f414b6 419}\r
420\r
421/**\r
422 Reads a bit field from a 16-bit value, performs a bitwise AND, and returns\r
423 the result.\r
424\r
425 Performs a bitwise AND between the bit field specified by StartBit and EndBit\r
426 in Operand and the value specified by AndData. All other bits in Operand are\r
427 preserved. The new 16-bit value is returned.\r
428\r
429 If 16-bit operations are not supported, then ASSERT().\r
430 If StartBit is greater than 15, then ASSERT().\r
431 If EndBit is greater than 15, then ASSERT().\r
432 If EndBit is less than StartBit, then ASSERT().\r
94952554 433 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 434\r
435 @param Operand Operand on which to perform the bitfield operation.\r
436 @param StartBit The ordinal of the least significant bit in the bit field.\r
437 Range 0..15.\r
438 @param EndBit The ordinal of the most significant bit in the bit field.\r
439 Range 0..15.\r
127010dd 440 @param AndData The value to AND with the read value from the value.\r
e1f414b6 441\r
442 @return The new 16-bit value.\r
443\r
444**/\r
445UINT16\r
446EFIAPI\r
447BitFieldAnd16 (\r
448 IN UINT16 Operand,\r
449 IN UINTN StartBit,\r
450 IN UINTN EndBit,\r
451 IN UINT16 AndData\r
452 )\r
453{\r
5385a579 454 ASSERT (EndBit < 16);\r
e1f414b6 455 ASSERT (StartBit <= EndBit);\r
80151e53 456 return (UINT16)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData);\r
e1f414b6 457}\r
458\r
459/**\r
460 Reads a bit field from a 16-bit value, performs a bitwise AND followed by a\r
461 bitwise OR, and returns the result.\r
462\r
463 Performs a bitwise AND between the bit field specified by StartBit and EndBit\r
9095d37b 464 in Operand and the value specified by AndData, followed by a bitwise\r
62991af2 465 OR with value specified by OrData. All other bits in Operand are\r
e1f414b6 466 preserved. The new 16-bit value is returned.\r
467\r
468 If 16-bit operations are not supported, then ASSERT().\r
469 If StartBit is greater than 15, then ASSERT().\r
470 If EndBit is greater than 15, then ASSERT().\r
471 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
472 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
473 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 474\r
475 @param Operand Operand on which to perform the bitfield operation.\r
476 @param StartBit The ordinal of the least significant bit in the bit field.\r
477 Range 0..15.\r
478 @param EndBit The ordinal of the most significant bit in the bit field.\r
479 Range 0..15.\r
480 @param AndData The value to AND with the read value from the value.\r
481 @param OrData The value to OR with the result of the AND operation.\r
482\r
483 @return The new 16-bit value.\r
484\r
485**/\r
486UINT16\r
487EFIAPI\r
488BitFieldAndThenOr16 (\r
489 IN UINT16 Operand,\r
490 IN UINTN StartBit,\r
491 IN UINTN EndBit,\r
492 IN UINT16 AndData,\r
493 IN UINT16 OrData\r
494 )\r
495{\r
5385a579 496 ASSERT (EndBit < 16);\r
e1f414b6 497 ASSERT (StartBit <= EndBit);\r
498 return BitFieldOr16 (\r
499 BitFieldAnd16 (Operand, StartBit, EndBit, AndData),\r
500 StartBit,\r
501 EndBit,\r
502 OrData\r
503 );\r
504}\r
505\r
506/**\r
507 Returns a bit field from a 32-bit value.\r
508\r
509 Returns the bitfield specified by the StartBit and the EndBit from Operand.\r
510\r
511 If 32-bit operations are not supported, then ASSERT().\r
512 If StartBit is greater than 31, then ASSERT().\r
513 If EndBit is greater than 31, then ASSERT().\r
514 If EndBit is less than StartBit, then ASSERT().\r
515\r
516 @param Operand Operand on which to perform the bitfield operation.\r
517 @param StartBit The ordinal of the least significant bit in the bit field.\r
518 Range 0..31.\r
519 @param EndBit The ordinal of the most significant bit in the bit field.\r
520 Range 0..31.\r
521\r
522 @return The bit field read.\r
523\r
524**/\r
525UINT32\r
526EFIAPI\r
527BitFieldRead32 (\r
528 IN UINT32 Operand,\r
529 IN UINTN StartBit,\r
530 IN UINTN EndBit\r
531 )\r
532{\r
5385a579 533 ASSERT (EndBit < 32);\r
e1f414b6 534 ASSERT (StartBit <= EndBit);\r
80151e53 535 return (UINT32)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit);\r
e1f414b6 536}\r
537\r
538/**\r
539 Writes a bit field to a 32-bit value, and returns the result.\r
540\r
541 Writes Value to the bit field specified by the StartBit and the EndBit in\r
542 Operand. All other bits in Operand are preserved. The new 32-bit value is\r
543 returned.\r
544\r
545 If 32-bit operations are not supported, then ASSERT().\r
546 If StartBit is greater than 31, then ASSERT().\r
547 If EndBit is greater than 31, then ASSERT().\r
548 If EndBit is less than StartBit, then ASSERT().\r
94952554 549 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 550\r
551 @param Operand Operand on which to perform the bitfield operation.\r
552 @param StartBit The ordinal of the least significant bit in the bit field.\r
553 Range 0..31.\r
554 @param EndBit The ordinal of the most significant bit in the bit field.\r
555 Range 0..31.\r
2fc59a00 556 @param Value The new value of the bit field.\r
e1f414b6 557\r
558 @return The new 32-bit value.\r
559\r
560**/\r
561UINT32\r
562EFIAPI\r
563BitFieldWrite32 (\r
564 IN UINT32 Operand,\r
565 IN UINTN StartBit,\r
566 IN UINTN EndBit,\r
567 IN UINT32 Value\r
568 )\r
569{\r
5385a579 570 ASSERT (EndBit < 32);\r
e1f414b6 571 ASSERT (StartBit <= EndBit);\r
572 return BitFieldAndThenOr32 (Operand, StartBit, EndBit, 0, Value);\r
573}\r
574\r
575/**\r
576 Reads a bit field from a 32-bit value, performs a bitwise OR, and returns the\r
577 result.\r
578\r
62991af2 579 Performs a bitwise OR between the bit field specified by StartBit\r
e1f414b6 580 and EndBit in Operand and the value specified by OrData. All other bits in\r
581 Operand are preserved. The new 32-bit value is returned.\r
582\r
583 If 32-bit operations are not supported, then ASSERT().\r
584 If StartBit is greater than 31, then ASSERT().\r
585 If EndBit is greater than 31, then ASSERT().\r
586 If EndBit is less than StartBit, then ASSERT().\r
94952554 587 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 588\r
589 @param Operand Operand on which to perform the bitfield operation.\r
590 @param StartBit The ordinal of the least significant bit in the bit field.\r
591 Range 0..31.\r
592 @param EndBit The ordinal of the most significant bit in the bit field.\r
593 Range 0..31.\r
127010dd 594 @param OrData The value to OR with the read value from the value.\r
e1f414b6 595\r
596 @return The new 32-bit value.\r
597\r
598**/\r
599UINT32\r
600EFIAPI\r
601BitFieldOr32 (\r
602 IN UINT32 Operand,\r
603 IN UINTN StartBit,\r
604 IN UINTN EndBit,\r
605 IN UINT32 OrData\r
606 )\r
607{\r
5385a579 608 ASSERT (EndBit < 32);\r
e1f414b6 609 ASSERT (StartBit <= EndBit);\r
80151e53 610 return (UINT32)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData);\r
e1f414b6 611}\r
612\r
613/**\r
614 Reads a bit field from a 32-bit value, performs a bitwise AND, and returns\r
615 the result.\r
616\r
617 Performs a bitwise AND between the bit field specified by StartBit and EndBit\r
618 in Operand and the value specified by AndData. All other bits in Operand are\r
619 preserved. The new 32-bit value is returned.\r
620\r
621 If 32-bit operations are not supported, then ASSERT().\r
622 If StartBit is greater than 31, then ASSERT().\r
623 If EndBit is greater than 31, then ASSERT().\r
624 If EndBit is less than StartBit, then ASSERT().\r
94952554 625 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 626\r
627 @param Operand Operand on which to perform the bitfield operation.\r
628 @param StartBit The ordinal of the least significant bit in the bit field.\r
629 Range 0..31.\r
630 @param EndBit The ordinal of the most significant bit in the bit field.\r
631 Range 0..31.\r
127010dd 632 @param AndData The value to AND with the read value from the value.\r
e1f414b6 633\r
634 @return The new 32-bit value.\r
635\r
636**/\r
637UINT32\r
638EFIAPI\r
639BitFieldAnd32 (\r
640 IN UINT32 Operand,\r
641 IN UINTN StartBit,\r
642 IN UINTN EndBit,\r
643 IN UINT32 AndData\r
644 )\r
645{\r
5385a579 646 ASSERT (EndBit < 32);\r
e1f414b6 647 ASSERT (StartBit <= EndBit);\r
80151e53 648 return (UINT32)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData);\r
e1f414b6 649}\r
650\r
651/**\r
652 Reads a bit field from a 32-bit value, performs a bitwise AND followed by a\r
653 bitwise OR, and returns the result.\r
654\r
655 Performs a bitwise AND between the bit field specified by StartBit and EndBit\r
9095d37b 656 in Operand and the value specified by AndData, followed by a bitwise\r
62991af2 657 OR with value specified by OrData. All other bits in Operand are\r
e1f414b6 658 preserved. The new 32-bit value is returned.\r
659\r
660 If 32-bit operations are not supported, then ASSERT().\r
661 If StartBit is greater than 31, then ASSERT().\r
662 If EndBit is greater than 31, then ASSERT().\r
663 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
664 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
665 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 666\r
667 @param Operand Operand on which to perform the bitfield operation.\r
668 @param StartBit The ordinal of the least significant bit in the bit field.\r
669 Range 0..31.\r
670 @param EndBit The ordinal of the most significant bit in the bit field.\r
671 Range 0..31.\r
672 @param AndData The value to AND with the read value from the value.\r
673 @param OrData The value to OR with the result of the AND operation.\r
674\r
675 @return The new 32-bit value.\r
676\r
677**/\r
678UINT32\r
679EFIAPI\r
680BitFieldAndThenOr32 (\r
681 IN UINT32 Operand,\r
682 IN UINTN StartBit,\r
683 IN UINTN EndBit,\r
684 IN UINT32 AndData,\r
685 IN UINT32 OrData\r
686 )\r
687{\r
5385a579 688 ASSERT (EndBit < 32);\r
e1f414b6 689 ASSERT (StartBit <= EndBit);\r
690 return BitFieldOr32 (\r
691 BitFieldAnd32 (Operand, StartBit, EndBit, AndData),\r
692 StartBit,\r
693 EndBit,\r
694 OrData\r
695 );\r
696}\r
697\r
698/**\r
699 Returns a bit field from a 64-bit value.\r
700\r
701 Returns the bitfield specified by the StartBit and the EndBit from Operand.\r
702\r
703 If 64-bit operations are not supported, then ASSERT().\r
704 If StartBit is greater than 63, then ASSERT().\r
705 If EndBit is greater than 63, then ASSERT().\r
706 If EndBit is less than StartBit, then ASSERT().\r
707\r
708 @param Operand Operand on which to perform the bitfield operation.\r
709 @param StartBit The ordinal of the least significant bit in the bit field.\r
710 Range 0..63.\r
711 @param EndBit The ordinal of the most significant bit in the bit field.\r
712 Range 0..63.\r
713\r
714 @return The bit field read.\r
715\r
716**/\r
717UINT64\r
718EFIAPI\r
719BitFieldRead64 (\r
720 IN UINT64 Operand,\r
721 IN UINTN StartBit,\r
722 IN UINTN EndBit\r
723 )\r
724{\r
5385a579 725 ASSERT (EndBit < 64);\r
e1f414b6 726 ASSERT (StartBit <= EndBit);\r
727 return RShiftU64 (Operand & ~LShiftU64 ((UINT64)-2, EndBit), StartBit);\r
728}\r
729\r
730/**\r
731 Writes a bit field to a 64-bit value, and returns the result.\r
732\r
733 Writes Value to the bit field specified by the StartBit and the EndBit in\r
734 Operand. All other bits in Operand are preserved. The new 64-bit value is\r
735 returned.\r
736\r
737 If 64-bit operations are not supported, then ASSERT().\r
738 If StartBit is greater than 63, then ASSERT().\r
739 If EndBit is greater than 63, then ASSERT().\r
740 If EndBit is less than StartBit, then ASSERT().\r
94952554 741 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 742\r
743 @param Operand Operand on which to perform the bitfield operation.\r
744 @param StartBit The ordinal of the least significant bit in the bit field.\r
745 Range 0..63.\r
746 @param EndBit The ordinal of the most significant bit in the bit field.\r
747 Range 0..63.\r
2fc59a00 748 @param Value The new value of the bit field.\r
e1f414b6 749\r
750 @return The new 64-bit value.\r
751\r
752**/\r
753UINT64\r
754EFIAPI\r
755BitFieldWrite64 (\r
756 IN UINT64 Operand,\r
757 IN UINTN StartBit,\r
758 IN UINTN EndBit,\r
759 IN UINT64 Value\r
760 )\r
761{\r
5385a579 762 ASSERT (EndBit < 64);\r
e1f414b6 763 ASSERT (StartBit <= EndBit);\r
764 return BitFieldAndThenOr64 (Operand, StartBit, EndBit, 0, Value);\r
765}\r
766\r
767/**\r
768 Reads a bit field from a 64-bit value, performs a bitwise OR, and returns the\r
769 result.\r
770\r
62991af2 771 Performs a bitwise OR between the bit field specified by StartBit\r
e1f414b6 772 and EndBit in Operand and the value specified by OrData. All other bits in\r
773 Operand are preserved. The new 64-bit value is returned.\r
774\r
775 If 64-bit operations are not supported, then ASSERT().\r
776 If StartBit is greater than 63, then ASSERT().\r
777 If EndBit is greater than 63, then ASSERT().\r
778 If EndBit is less than StartBit, then ASSERT().\r
94952554 779 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 780\r
781 @param Operand Operand on which to perform the bitfield operation.\r
782 @param StartBit The ordinal of the least significant bit in the bit field.\r
783 Range 0..63.\r
784 @param EndBit The ordinal of the most significant bit in the bit field.\r
785 Range 0..63.\r
786 @param OrData The value to OR with the read value from the value\r
787\r
788 @return The new 64-bit value.\r
789\r
790**/\r
791UINT64\r
792EFIAPI\r
793BitFieldOr64 (\r
794 IN UINT64 Operand,\r
795 IN UINTN StartBit,\r
796 IN UINTN EndBit,\r
797 IN UINT64 OrData\r
798 )\r
799{\r
800 UINT64 Value1;\r
801 UINT64 Value2;\r
802\r
5385a579 803 ASSERT (EndBit < 64);\r
e1f414b6 804 ASSERT (StartBit <= EndBit);\r
499ceb8e 805 //\r
9095d37b 806 // Higher bits in OrData those are not used must be zero.\r
499ceb8e 807 //\r
77518065
LG
808 // EndBit - StartBit + 1 might be 64 while the result right shifting 64 on RShiftU64() API is invalid,\r
809 // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.\r
499ceb8e
LG
810 //\r
811 ASSERT (RShiftU64 (OrData, EndBit - StartBit) == (RShiftU64 (OrData, EndBit - StartBit) & 1));\r
e1f414b6 812\r
813 Value1 = LShiftU64 (OrData, StartBit);\r
814 Value2 = LShiftU64 ((UINT64) - 2, EndBit);\r
815\r
816 return Operand | (Value1 & ~Value2);\r
817}\r
818\r
819/**\r
820 Reads a bit field from a 64-bit value, performs a bitwise AND, and returns\r
821 the result.\r
822\r
823 Performs a bitwise AND between the bit field specified by StartBit and EndBit\r
824 in Operand and the value specified by AndData. All other bits in Operand are\r
825 preserved. The new 64-bit value is returned.\r
826\r
827 If 64-bit operations are not supported, then ASSERT().\r
828 If StartBit is greater than 63, then ASSERT().\r
829 If EndBit is greater than 63, then ASSERT().\r
830 If EndBit is less than StartBit, then ASSERT().\r
94952554 831 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 832\r
833 @param Operand Operand on which to perform the bitfield operation.\r
834 @param StartBit The ordinal of the least significant bit in the bit field.\r
835 Range 0..63.\r
836 @param EndBit The ordinal of the most significant bit in the bit field.\r
837 Range 0..63.\r
127010dd 838 @param AndData The value to AND with the read value from the value.\r
e1f414b6 839\r
840 @return The new 64-bit value.\r
841\r
842**/\r
843UINT64\r
844EFIAPI\r
845BitFieldAnd64 (\r
846 IN UINT64 Operand,\r
847 IN UINTN StartBit,\r
848 IN UINTN EndBit,\r
849 IN UINT64 AndData\r
850 )\r
851{\r
852 UINT64 Value1;\r
853 UINT64 Value2;\r
9095d37b 854\r
5385a579 855 ASSERT (EndBit < 64);\r
e1f414b6 856 ASSERT (StartBit <= EndBit);\r
499ceb8e 857 //\r
9095d37b 858 // Higher bits in AndData those are not used must be zero.\r
499ceb8e 859 //\r
77518065
LG
860 // EndBit - StartBit + 1 might be 64 while the right shifting 64 on RShiftU64() API is invalid,\r
861 // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.\r
499ceb8e
LG
862 //\r
863 ASSERT (RShiftU64 (AndData, EndBit - StartBit) == (RShiftU64 (AndData, EndBit - StartBit) & 1));\r
e1f414b6 864\r
865 Value1 = LShiftU64 (~AndData, StartBit);\r
866 Value2 = LShiftU64 ((UINT64)-2, EndBit);\r
867\r
868 return Operand & ~(Value1 & ~Value2);\r
869}\r
870\r
871/**\r
872 Reads a bit field from a 64-bit value, performs a bitwise AND followed by a\r
873 bitwise OR, and returns the result.\r
874\r
875 Performs a bitwise AND between the bit field specified by StartBit and EndBit\r
9095d37b 876 in Operand and the value specified by AndData, followed by a bitwise\r
62991af2 877 OR with value specified by OrData. All other bits in Operand are\r
e1f414b6 878 preserved. The new 64-bit value is returned.\r
879\r
880 If 64-bit operations are not supported, then ASSERT().\r
881 If StartBit is greater than 63, then ASSERT().\r
882 If EndBit is greater than 63, then ASSERT().\r
883 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
884 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
885 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 886\r
887 @param Operand Operand on which to perform the bitfield operation.\r
888 @param StartBit The ordinal of the least significant bit in the bit field.\r
889 Range 0..63.\r
890 @param EndBit The ordinal of the most significant bit in the bit field.\r
891 Range 0..63.\r
892 @param AndData The value to AND with the read value from the value.\r
893 @param OrData The value to OR with the result of the AND operation.\r
894\r
895 @return The new 64-bit value.\r
896\r
897**/\r
898UINT64\r
899EFIAPI\r
900BitFieldAndThenOr64 (\r
901 IN UINT64 Operand,\r
902 IN UINTN StartBit,\r
903 IN UINTN EndBit,\r
904 IN UINT64 AndData,\r
905 IN UINT64 OrData\r
906 )\r
907{\r
5385a579 908 ASSERT (EndBit < 64);\r
e1f414b6 909 ASSERT (StartBit <= EndBit);\r
910 return BitFieldOr64 (\r
911 BitFieldAnd64 (Operand, StartBit, EndBit, AndData),\r
912 StartBit,\r
913 EndBit,\r
914 OrData\r
915 );\r
916}\r
d7634dc0
TP
917\r
918/**\r
919 Reads a bit field from a 32-bit value, counts and returns\r
920 the number of set bits.\r
921\r
922 Counts the number of set bits in the bit field specified by\r
923 StartBit and EndBit in Operand. The count is returned.\r
924\r
925 If StartBit is greater than 31, then ASSERT().\r
926 If EndBit is greater than 31, then ASSERT().\r
927 If EndBit is less than StartBit, then ASSERT().\r
928\r
929 @param Operand Operand on which to perform the bitfield operation.\r
930 @param StartBit The ordinal of the least significant bit in the bit field.\r
931 Range 0..31.\r
932 @param EndBit The ordinal of the most significant bit in the bit field.\r
933 Range 0..31.\r
934\r
935 @return The number of bits set between StartBit and EndBit.\r
936\r
937**/\r
938UINT8\r
939EFIAPI\r
940BitFieldCountOnes32 (\r
941 IN UINT32 Operand,\r
942 IN UINTN StartBit,\r
943 IN UINTN EndBit\r
944 )\r
945{\r
946 UINT32 Count;\r
947\r
948 ASSERT (EndBit < 32);\r
949 ASSERT (StartBit <= EndBit);\r
950\r
951 Count = BitFieldRead32 (Operand, StartBit, EndBit);\r
952 Count -= ((Count >> 1) & 0x55555555);\r
953 Count = (Count & 0x33333333) + ((Count >> 2) & 0x33333333);\r
954 Count += Count >> 4;\r
955 Count &= 0x0F0F0F0F;\r
956 Count += Count >> 8;\r
957 Count += Count >> 16;\r
958\r
959 return (UINT8) Count & 0x3F;\r
960}\r
961\r
962/**\r
963 Reads a bit field from a 64-bit value, counts and returns\r
964 the number of set bits.\r
965\r
966 Counts the number of set bits in the bit field specified by\r
967 StartBit and EndBit in Operand. The count is returned.\r
968\r
969 If StartBit is greater than 63, then ASSERT().\r
970 If EndBit is greater than 63, then ASSERT().\r
971 If EndBit is less than StartBit, then ASSERT().\r
972\r
973 @param Operand Operand on which to perform the bitfield operation.\r
974 @param StartBit The ordinal of the least significant bit in the bit field.\r
975 Range 0..63.\r
976 @param EndBit The ordinal of the most significant bit in the bit field.\r
977 Range 0..63.\r
978\r
979 @return The number of bits set between StartBit and EndBit.\r
980\r
981**/\r
982UINT8\r
983EFIAPI\r
984BitFieldCountOnes64 (\r
985 IN UINT64 Operand,\r
986 IN UINTN StartBit,\r
987 IN UINTN EndBit\r
988 )\r
989{\r
990 UINT64 BitField;\r
991 UINT8 Count;\r
992\r
993 ASSERT (EndBit < 64);\r
994 ASSERT (StartBit <= EndBit);\r
995\r
996 BitField = BitFieldRead64 (Operand, StartBit, EndBit);\r
997 Count = BitFieldCountOnes32 ((UINT32) BitField, 0, 31);\r
998 Count += BitFieldCountOnes32 ((UINT32) RShiftU64(BitField, 32), 0, 31);\r
999\r
1000 return Count;\r
1001}\r
1002\r