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