148 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			148 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /****************************************************************************
 | ||
|  | 
 | ||
|  | Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. | ||
|  | 
 | ||
|  | This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT | ||
|  | be copied by any method or incorporated into another program without | ||
|  | the express written consent of Aerospace C.Power. This Information or any portion | ||
|  | thereof remains the property of Aerospace C.Power. The Information contained herein | ||
|  | is believed to be accurate and Aerospace C.Power assumes no responsibility or | ||
|  | liability for its use in any way and conveys no license or title under | ||
|  | any patent or copyright and makes no representation or warranty that this | ||
|  | Information is free from patent or copyright infringement. | ||
|  | 
 | ||
|  | ****************************************************************************/ | ||
|  | 
 | ||
|  | /* os shim includes */ | ||
|  | #include "os_types.h"
 | ||
|  | 
 | ||
|  | /* common includes */ | ||
|  | #include "iot_bitops.h"
 | ||
|  | 
 | ||
|  | /* table used for ffs and ffz operation */ | ||
|  | const IRAM_ATTR uint8_t iot_bitops_ffs_tab[IOT_BITOPS_TAB_SIZE] = { | ||
|  | 0, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 6, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 7, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 6, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 8, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 6, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 7, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 6, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, | ||
|  | 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1 }; | ||
|  | 
 | ||
|  | /* table used for fls and ffz operation */ | ||
|  | const IRAM_ATTR uint8_t iot_bitops_fls_tab[IOT_BITOPS_TAB_SIZE] = { | ||
|  | 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, | ||
|  | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | ||
|  | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | ||
|  | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | ||
|  | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
|  | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
|  | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
|  | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
|  | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | ||
|  | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | ||
|  | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | ||
|  | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | ||
|  | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | ||
|  | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | ||
|  | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | ||
|  | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; | ||
|  | 
 | ||
|  | /* table used for cbs and cbz operation */ | ||
|  | const uint8_t iot_bitops_cbs_tab[IOT_BITOPS_TAB_SIZE] = { | ||
|  | 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, | ||
|  | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, | ||
|  | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, | ||
|  | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, | ||
|  | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, | ||
|  | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, | ||
|  | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, | ||
|  | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, | ||
|  | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, | ||
|  | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, | ||
|  | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, | ||
|  | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, | ||
|  | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, | ||
|  | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, | ||
|  | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, | ||
|  | 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; | ||
|  | 
 | ||
|  | /* find the first bit set to 1 for non-zero byte */ | ||
|  | static inline uint8_t __iot_bitops_ffs(uint8_t tmp) | ||
|  | { | ||
|  |     uint8_t b = 1; | ||
|  | 
 | ||
|  |     if (!(tmp & 0x0F)) { | ||
|  |         tmp >>= 4; | ||
|  |         b += 4; | ||
|  |     } | ||
|  |     if (!(tmp & 0x03)) { | ||
|  |         tmp >>= 2; | ||
|  |         b += 2; | ||
|  |     } | ||
|  |     if (!(tmp & 0x01)) { | ||
|  |         b += 1; | ||
|  |     } | ||
|  | 
 | ||
|  |     return b; | ||
|  | } | ||
|  | 
 | ||
|  | /* find the last bit set to 1 for non-zero byte */ | ||
|  | static inline uint8_t __iot_bitops_fls(uint8_t tmp) | ||
|  | { | ||
|  |     uint8_t b = 8; | ||
|  | 
 | ||
|  |     if (!(tmp & 0xF0)) { | ||
|  |         tmp <<= 4; | ||
|  |         b -= 4; | ||
|  |     } | ||
|  |     if (!(tmp & 0xC0)) { | ||
|  |         tmp <<= 2; | ||
|  |         b -= 2; | ||
|  |     } | ||
|  |     if (!(tmp & 0x80)) { | ||
|  |         b -= 1; | ||
|  |     } | ||
|  | 
 | ||
|  |     return b; | ||
|  | } | ||
|  | 
 | ||
|  | /* find number of bits set to 1 for one byte */ | ||
|  | static inline uint8_t __iot_bitops_cbs(uint8_t tmp) | ||
|  | { | ||
|  |     uint8_t b = 0; | ||
|  | 
 | ||
|  |     for (b = 0; tmp; b++) { | ||
|  |         /* clear the least significant bit set */ | ||
|  |         tmp &= tmp - 1; | ||
|  |     } | ||
|  | 
 | ||
|  |     return b; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_bitops_init() | ||
|  | { | ||
|  |     uint32_t i; | ||
|  | 
 | ||
|  |     for (i = 1; i < IOT_BITOPS_TAB_SIZE; i++) { | ||
|  |         if (iot_bitops_ffs_tab[i] != __iot_bitops_ffs((uint8_t)i)) | ||
|  |             IOT_ASSERT(0); | ||
|  |     } | ||
|  |     for (i = 1; i < IOT_BITOPS_TAB_SIZE; i++) { | ||
|  |         if (iot_bitops_fls_tab[i] != __iot_bitops_fls((uint8_t)i)) | ||
|  |             IOT_ASSERT(0); | ||
|  |     } | ||
|  |     for (i = 1; i < IOT_BITOPS_TAB_SIZE; i++) { | ||
|  |         if (iot_bitops_cbs_tab[i] != __iot_bitops_cbs((uint8_t)i)) | ||
|  |             IOT_ASSERT(0); | ||
|  |     } | ||
|  | } |