2026-05-19 11:49:22 +08:00
|
|
|
#include "cpu_clz.h"
|
|
|
|
|
#include "os_config.h"
|
2026-05-27 23:30:31 +08:00
|
|
|
#include "cpu.h"
|
2026-05-19 11:49:22 +08:00
|
|
|
|
|
|
|
|
#if !defined(OS_CFG_CPU_CLZ_ASM_PRESENT) || (!OS_CFG_CPU_CLZ_ASM_PRESENT)
|
|
|
|
|
// 如果配置中没有提供汇编版本的clz函数,则使用C语言实现
|
|
|
|
|
|
|
|
|
|
static const uint8_t clz_table[256] = {/* 索引 */
|
|
|
|
|
8u,7u,6u,6u,5u,5u,5u,5u,4u,4u,4u,4u,4u,4u,4u,4u, /* 0x00 to 0x0F */
|
|
|
|
|
3u,3u,3u,3u,3u,3u,3u,3u,3u,3u,3u,3u,3u,3u,3u,3u, /* 0x10 to 0x1F */
|
|
|
|
|
2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u, /* 0x20 to 0x2F */
|
|
|
|
|
2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u, /* 0x30 to 0x3F */
|
|
|
|
|
1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u, /* 0x40 to 0x4F */
|
|
|
|
|
1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u, /* 0x50 to 0x5F */
|
|
|
|
|
1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u, /* 0x60 to 0x6F */
|
|
|
|
|
1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u, /* 0x70 to 0x7F */
|
|
|
|
|
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0x80 to 0x8F */
|
|
|
|
|
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0x90 to 0x9F */
|
|
|
|
|
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0xA0 to 0xAF */
|
|
|
|
|
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0xB0 to 0xBF */
|
|
|
|
|
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0xC0 to 0xCF */
|
|
|
|
|
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0xD0 to 0xDF */
|
|
|
|
|
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0xE0 to 0xEF */
|
|
|
|
|
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u /* 0xF0 to 0xFF */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
os_uint_t cpu_clz(os_uint_t value){
|
|
|
|
|
os_uint_t result = 0;
|
|
|
|
|
uint8_t idx;
|
|
|
|
|
|
|
|
|
|
// 检查高 16 bits
|
|
|
|
|
if(value > 0x0000FFFFu){
|
|
|
|
|
// 检查 bits[24:31]
|
|
|
|
|
if(value > 0x00FFFFFFu){
|
|
|
|
|
idx = (value >> 24u) & 0xFFu; // 获取 bits[24:31] 的值
|
|
|
|
|
result = clz_table[idx]; // 查表获取 bits[24:31] 中前导零的数量
|
|
|
|
|
}else{
|
|
|
|
|
idx = (value >> 16u) & 0xFFu; // 获取 bits[16:23] 的值
|
|
|
|
|
result = clz_table[idx] + 8u; // 查表获取 bits[16:23] 中前导零的数量,并加上8,表示 bits[24:31] 中的0
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
// 检查 bits[0:15]
|
|
|
|
|
if(value > 0x000000FFu){
|
|
|
|
|
idx = (value >> 8u) & 0xFFu; // 获取 bits[8:15] 的值
|
|
|
|
|
result = clz_table[idx] + 16u; // 查表获取 bits[8:15] 中前导零的数量,并加上16,表示 bits[16:31] 中的0
|
|
|
|
|
}else{
|
|
|
|
|
idx = value & 0xFFu; // 获取 bits[0:7] 的值
|
|
|
|
|
result = clz_table[idx] + 24u; // 查表获取 bits[0:7] 中前导零的数量,并加上24,表示 bits[8:31] 中的0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endif /* OS_CFG_CLZ_ASM_PRESENT */
|