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