144 lines
2.9 KiB
C
Vendored
144 lines
2.9 KiB
C
Vendored
/*
|
|
* cam_os_util.h- Sigmastar
|
|
*
|
|
* Copyright (c) [2019~2020] SigmaStar Technology.
|
|
*
|
|
*
|
|
* This software is licensed under the terms of the GNU General Public
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
* may be copied, distributed, and modified under those terms.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License version 2 for more details.
|
|
*
|
|
*/
|
|
|
|
|
|
#ifndef __CAM_OS_UTIL_H__
|
|
#define __CAM_OS_UTIL_H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif /* __cplusplus */
|
|
|
|
#define FORCE_INLINE __attribute__((always_inline)) inline
|
|
|
|
#ifndef offsetof
|
|
#ifdef __compiler_offsetof
|
|
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
|
|
#else
|
|
#ifdef size_t
|
|
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
|
#else
|
|
#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#define CAM_OS_CONTAINER_OF(ptr, type, member) ({ \
|
|
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
|
(type *)( (char *)__mptr - offsetof(type,member) );})
|
|
|
|
#ifndef likely
|
|
#define CAM_OS_LIKELY(x) __builtin_expect(!!(x), 1)
|
|
#else
|
|
#define CAM_OS_LIKELY(x) likely(x)
|
|
#endif
|
|
|
|
#ifndef unlikely
|
|
#define CAM_OS_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
|
#else
|
|
#define CAM_OS_UNLIKELY(x) unlikely(x)
|
|
#endif
|
|
|
|
static FORCE_INLINE s32 CAM_OS_FLS(s32 x)
|
|
{
|
|
int r = 32;
|
|
|
|
if (!x)
|
|
return 0;
|
|
if (!(x & 0xffff0000u)) {
|
|
x <<= 16;
|
|
r -= 16;
|
|
}
|
|
if (!(x & 0xff000000u)) {
|
|
x <<= 8;
|
|
r -= 8;
|
|
}
|
|
if (!(x & 0xf0000000u)) {
|
|
x <<= 4;
|
|
r -= 4;
|
|
}
|
|
if (!(x & 0xc0000000u)) {
|
|
x <<= 2;
|
|
r -= 2;
|
|
}
|
|
if (!(x & 0x80000000u)) {
|
|
x <<= 1;
|
|
r -= 1;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
#if CAM_OS_BITS_PER_LONG == 32
|
|
static FORCE_INLINE s32 CAM_OS_FLS64(u64 x)
|
|
{
|
|
u32 h = x >> 32;
|
|
if (h)
|
|
return CAM_OS_FLS(h) + 32;
|
|
return CAM_OS_FLS(x);
|
|
}
|
|
#elif CAM_OS_BITS_PER_LONG == 64
|
|
static FORCE_INLINE s32 _CAM_OS_FLS(u64 word)
|
|
{
|
|
s32 num = CAM_OS_BITS_PER_LONG - 1;
|
|
|
|
//#if CAM_OS_BITS_PER_LONG == 64
|
|
if (!(word & (~0ul << 32))) {
|
|
num -= 32;
|
|
word <<= 32;
|
|
}
|
|
//#endif
|
|
if (!(word & (~0ul << (CAM_OS_BITS_PER_LONG-16)))) {
|
|
num -= 16;
|
|
word <<= 16;
|
|
}
|
|
if (!(word & (~0ul << (CAM_OS_BITS_PER_LONG-8)))) {
|
|
num -= 8;
|
|
word <<= 8;
|
|
}
|
|
if (!(word & (~0ul << (CAM_OS_BITS_PER_LONG-4)))) {
|
|
num -= 4;
|
|
word <<= 4;
|
|
}
|
|
if (!(word & (~0ul << (CAM_OS_BITS_PER_LONG-2)))) {
|
|
num -= 2;
|
|
word <<= 2;
|
|
}
|
|
if (!(word & (~0ul << (CAM_OS_BITS_PER_LONG-1))))
|
|
num -= 1;
|
|
return num;
|
|
}
|
|
|
|
static FORCE_INLINE s32 CAM_OS_FLS64(u64 x)
|
|
{
|
|
if (x == 0)
|
|
return 0;
|
|
return _CAM_OS_FLS(x) + 1;
|
|
}
|
|
#else
|
|
#error CAM_OS_BITS_PER_LONG not 32 or 64
|
|
#endif
|
|
|
|
#define CAM_OS_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif /* __cplusplus */
|
|
|
|
#define CAM_OS_MIN(a,b) (((a)<(b))?(a):(b))
|
|
#define CAM_OS_MAX(a,b) (((a)>(b))?(a):(b))
|
|
|
|
#endif //__CAM_OS_UTIL_H__
|