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);
 | |
|     }
 | |
| } |