Changeset 87193 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Jan 7, 2021 8:59:58 PM (4 years ago)
- Location:
- trunk/src/VBox/Runtime/common/asm
- Files:
-
- 2 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/asm/ASMBitFirstClear-generic.cpp
r87192 r87193 39 39 const volatile size_t RT_FAR *pu = (const volatile size_t RT_FAR *)pvBitmap; 40 40 Assert(!(cBits & 31)); 41 Assert(!((uintptr_t)pvBitmap & 3)); 41 42 43 #if ARCH_BITS > 32 44 /* Deal with misaligned bitmaps (happens all the time via ASMBitNextClear()). */ 45 if (!((uintptr_t)pvBitmap & 7) && cBits >= 32) 46 { 47 uint32_t u32 = *(const volatile uint32_t RT_FAR *)pu; 48 if (u32 != UINT32_MAX) 49 { 50 size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8; 51 return iBaseBit + ASMBitFirstSetU32(~RT_LE2H_U32(u32)) - 1; 52 } 53 pu = (const volatile size_t RT_FAR *)((uintptr_t)pu + sizeof(uint32_t)); 54 cBits -= 32; 55 } 56 #endif 57 58 /* Main search loop: */ 42 59 while (cBits >= sizeof(size_t) * 8) 43 60 { … … 53 70 return iBaseBit + ASMBitFirstSetU64(~RT_LE2H_U64(u)) - 1; 54 71 #else 55 # error "ARCH_BITS or RT_BIG_ENDIAN/RT_LITTLE_ENDIAN is not supported" /** @todo figure out bitmaps on bigendian systems! */72 # error "ARCH_BITS is not supported" 56 73 #endif 57 74 } … … 62 79 63 80 #if ARCH_BITS > 32 64 if (cBits >= 32) 81 /* Final 32-bit item (unlikely)? */ 82 if (cBits < 32) 83 { } 84 else 65 85 { 66 86 uint32_t u32 = *(const volatile uint32_t RT_FAR *)pu; -
trunk/src/VBox/Runtime/common/asm/ASMBitFirstSet-generic.cpp
r87192 r87193 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - ASMBitFirst Clear- generic C implementation.3 * IPRT - ASMBitFirstSet - generic C implementation. 4 4 */ 5 5 … … 35 35 36 36 37 DECLASM(int32_t) ASMBitFirst Clear(const volatile void RT_FAR *pvBitmap, uint32_t cBits) RT_NOTHROW_DEF37 DECLASM(int32_t) ASMBitFirstSet(const volatile void RT_FAR *pvBitmap, uint32_t cBits) RT_NOTHROW_DEF 38 38 { 39 39 const volatile size_t RT_FAR *pu = (const volatile size_t RT_FAR *)pvBitmap; 40 40 Assert(!(cBits & 31)); 41 Assert(!((uintptr_t)pvBitmap & 3)); 41 42 43 #if ARCH_BITS > 32 44 /* Deal with misaligned bitmaps (happens all the time via ASMBitNextClear()). */ 45 if (!((uintptr_t)pvBitmap & 7) && cBits >= 32) 46 { 47 uint32_t u32 = *(const volatile uint32_t RT_FAR *)pu; 48 if (u32 != UINT32_MAX) 49 { 50 size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8; 51 return iBaseBit + ASMBitFirstSetU32(RT_LE2H_U32(u32)) - 1; 52 } 53 pu = (const volatile size_t RT_FAR *)((uintptr_t)pu + sizeof(uint32_t)); 54 cBits -= 32; 55 } 56 #endif 57 58 /* Main search loop: */ 42 59 while (cBits >= sizeof(size_t) * 8) 43 60 { 44 61 size_t u = *pu; 45 if (u == ~(size_t)0)62 if (u == 0) 46 63 { } 47 64 else … … 49 66 size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8; 50 67 #if ARCH_BITS == 32 51 return iBaseBit + ASMBitFirstSetU32( ~RT_LE2H_U32(u)) - 1;68 return iBaseBit + ASMBitFirstSetU32(RT_LE2H_U32(u)) - 1; 52 69 #elif ARCH_BITS == 64 53 return iBaseBit + ASMBitFirstSetU64( ~RT_LE2H_U64(u)) - 1;70 return iBaseBit + ASMBitFirstSetU64(RT_LE2H_U64(u)) - 1; 54 71 #else 55 # error "ARCH_BITS or RT_BIG_ENDIAN/RT_LITTLE_ENDIAN is not supported" /** @todo figure out bitmaps on bigendian systems! */72 # error "ARCH_BITS is not supported" 56 73 #endif 57 74 } … … 62 79 63 80 #if ARCH_BITS > 32 64 if (cBits >= 32) 81 /* Final 32-bit item (unlikely)? */ 82 if (cBits < 32) 83 { } 84 else 65 85 { 66 86 uint32_t u32 = *(const volatile uint32_t RT_FAR *)pu; … … 68 88 { 69 89 size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8; 70 return iBaseBit + ASMBitFirstSetU32( ~RT_LE2H_U32(u32)) - 1;90 return iBaseBit + ASMBitFirstSetU32(RT_LE2H_U32(u32)) - 1; 71 91 } 72 92 } -
trunk/src/VBox/Runtime/common/asm/ASMBitNextClear-generic.cpp
r87192 r87193 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - ASMBit FirstClear - generic C implementation.3 * IPRT - ASMBitNextClear - generic C implementation. 4 4 */ 5 5 … … 35 35 36 36 37 DECLASM(int 32_t) ASMBitFirstClear(const volatile void RT_FAR *pvBitmap, uint32_t cBits) RT_NOTHROW_DEF37 DECLASM(int) ASMBitNextClear(const volatile void RT_FAR *pvBitmap, uint32_t cBits, uint32_t iBitPrev) RT_NOTHROW_DEF 38 38 { 39 const volatile size_t RT_FAR *pu = (const volatile size_t RT_FAR *)pvBitmap; 39 const volatile uint32_t RT_FAR *pau32Bitmap = (const volatile uint32_t RT_FAR *)pvBitmap; 40 int iBit = ++iBitPrev & 31; 40 41 Assert(!(cBits & 31)); 42 Assert(!((uintptr_t)pvBitmap & 3)); 43 if (iBit) 44 { 45 /* 46 * Inspect the 32-bit word containing the unaligned bit. 47 */ 48 uint32_t u32 = ~RT_LE2H_U32(pau32Bitmap[iBitPrev / 32]) >> iBit; 49 if (u32) 50 return iBitPrev + ASMBitFirstSetU32(u32) - 1; 41 51 42 while (cBits >= sizeof(size_t) * 8) 43 { 44 size_t u = *pu; 45 if (u == ~(size_t)0) 46 { } 47 else 48 { 49 size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8; 50 #if ARCH_BITS == 32 51 return iBaseBit + ASMBitFirstSetU32(~RT_LE2H_U32(u)) - 1; 52 #elif ARCH_BITS == 64 53 return iBaseBit + ASMBitFirstSetU64(~RT_LE2H_U64(u)) - 1; 54 #else 55 # error "ARCH_BITS or RT_BIG_ENDIAN/RT_LITTLE_ENDIAN is not supported" /** @todo figure out bitmaps on bigendian systems! */ 56 #endif 57 } 58 59 pu++; 60 cBits -= sizeof(size_t) * 8; 52 /* 53 * Skip ahead and see if there is anything left to search. 54 */ 55 iBitPrev |= 31; 56 iBitPrev++; 57 if (cBits <= (uint32_t)iBitPrev) 58 return -1; 61 59 } 62 60 63 #if ARCH_BITS > 32 64 if (cBits >= 32) 65 { 66 uint32_t u32 = *(const volatile uint32_t RT_FAR *)pu; 67 if (u32 != UINT32_MAX) 68 { 69 size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8; 70 return iBaseBit + ASMBitFirstSetU32(~RT_LE2H_U32(u32)) - 1; 71 } 72 } 73 #endif 74 75 return -1; 61 /* 62 * 32-bit aligned search, let ASMBitFirstClear do the dirty work. 63 */ 64 iBit = ASMBitFirstClear(&pau32Bitmap[iBitPrev / 32], cBits - iBitPrev); 65 if (iBit >= 0) 66 iBit += iBitPrev; 67 return iBit; 76 68 } 77 69 -
trunk/src/VBox/Runtime/common/asm/asm-fake.cpp
r87192 r87193 297 297 } 298 298 299 RTDECL(int) ASMBitNextClear(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev)300 {301 const volatile uint8_t *pau8Bitmap = (const volatile uint8_t *)pvBitmap;302 int iBit = ++iBitPrev & 7;303 if (iBit)304 {305 /*306 * Inspect the byte containing the unaligned bit.307 */308 uint8_t u8 = ~pau8Bitmap[iBitPrev / 8] >> iBit;309 if (u8)310 {311 iBit = 0;312 while (!(u8 & 1))313 {314 u8 >>= 1;315 iBit++;316 }317 return iBitPrev + iBit;318 }319 320 /*321 * Skip ahead and see if there is anything left to search.322 */323 iBitPrev |= 7;324 iBitPrev++;325 if (cBits <= iBitPrev)326 return -1;327 }328 329 /*330 * Byte search, let ASMBitFirstClear do the dirty work.331 */332 iBit = ASMBitFirstClear(&pau8Bitmap[iBitPrev / 8], cBits - iBitPrev);333 if (iBit >= 0)334 iBit += iBitPrev;335 return iBit;336 }337 338 RTDECL(int) ASMBitFirstSet(const volatile void *pvBitmap, uint32_t cBits)339 {340 uint32_t iBit = 0;341 uint8_t volatile *pu8 = (uint8_t volatile *)pvBitmap;342 while (iBit < cBits)343 {344 uint8_t u8 = *pu8;345 if (u8 != 0)346 {347 while (!(u8 & 1))348 {349 u8 >>= 1;350 iBit++;351 }352 if (iBit >= cBits)353 return -1;354 return iBit;355 }356 357 iBit += 8;358 pu8++;359 }360 return -1;361 }362 363 299 RTDECL(int) ASMBitNextSet(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev) 364 300 {
Note:
See TracChangeset
for help on using the changeset viewer.