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