1/* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * This software may be distributed and modified according to the terms of 5 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 6 * See "LICENSE_GPLv2.txt" for details. 7 * 8 * @TAG(GD_GPL) 9 */ 10 11#ifndef __UTIL_H 12#define __UTIL_H 13 14#define MASK(n) (BIT(n)-1ul) 15#define IS_ALIGNED(n, b) (!((n) & MASK(b))) 16#define ROUND_DOWN(n, b) (((n) >> (b)) << (b)) 17#define ROUND_UP(n, b) (((((n) - 1ul) >> (b)) + 1ul) << (b)) 18#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) 19#define MIN(a, b) ((a) < (b) ? (a) : (b)) 20#define MAX(a,b) (((a)>(b))?(a):(b)) 21#define PASTE(a, b) a ## b 22#define _STRINGIFY(a) #a 23#define STRINGIFY(a) _STRINGIFY(a) 24 25/* time constants */ 26#define MS_IN_S 1000llu 27#define US_IN_MS 1000llu 28#define HZ_IN_KHZ 1000llu 29#define KHZ_IN_MHZ 1000llu 30#define HZ_IN_MHZ 1000000llu 31 32#ifndef __ASSEMBLER__ 33 34#define NULL ((void *)0) 35#define BIT(n) (1ul << (n)) 36#define UL_CONST(x) PASTE(x, ul) 37 38#define PACKED __attribute__((packed)) 39#define NORETURN __attribute__((__noreturn__)) 40#define CONST __attribute__((__const__)) 41#define PURE __attribute__((__pure__)) 42#define ALIGN(n) __attribute__((__aligned__(n))) 43#define FASTCALL __attribute__((fastcall)) 44#ifdef __clang__ 45#define VISIBLE /* nothing */ 46#else 47#define VISIBLE __attribute__((externally_visible)) 48#endif 49#define NO_INLINE __attribute__((noinline)) 50#define FORCE_INLINE __attribute__((always_inline)) 51#define SECTION(sec) __attribute__((__section__(sec))) 52#define UNUSED __attribute__((unused)) 53#define USED __attribute__((used)) 54#define FASTCALL __attribute__((fastcall)) 55#define FORCE_O2 __attribute__((optimize("O2"))) 56/** MODIFIES: */ 57void __builtin_unreachable(void); 58#define UNREACHABLE() __builtin_unreachable() 59#define MAY_ALIAS __attribute__((may_alias)) 60 61#define OFFSETOF(type, member) \ 62 __builtin_offsetof(type, member) 63 64#ifdef __GNUC__ 65/* Borrowed from linux/include/linux/compiler.h */ 66#define likely(x) __builtin_expect(!!(x), 1) 67#define unlikely(x) __builtin_expect(!!(x), 0) 68#else 69#define likely(x) (!!(x)) 70#define unlikely(x) (!!(x)) 71#endif 72 73/* need that for compiling with c99 instead of gnu99 */ 74#define asm __asm__ 75 76/* Evaluate a Kconfig-provided configuration setting at compile-time. */ 77#define config_set(macro) _is_set_(macro) 78#define _macrotest_1 , 79#define _is_set_(value) _is_set__(_macrotest_##value) 80#define _is_set__(comma) _is_set___(comma 1, 0) 81#define _is_set___(_, v, ...) v 82 83/* Check the existence of a configuration setting, returning one value if it 84 * exists and a different one if it does not */ 85#define config_ternary(macro, true, false) _config_ternary(macro, true, false) 86#define _config_ternary(value, true, false) _config_ternary_(_macrotest_##value, true, false) 87#define _config_ternary_(comma, true, false) _config_ternary__(comma true, false) 88#define _config_ternary__(_, v, ...) v 89 90/** MODIFIES: 91 FNSPEC 92 halt_spec: "\<Gamma> \<turnstile> {} Call halt_'proc {}" 93*/ 94void halt(void) NORETURN; 95void memzero(void *s, unsigned long n); 96void *memset(void *s, unsigned long c, unsigned long n) VISIBLE; 97void *memcpy(void* ptr_dst, const void* ptr_src, unsigned long n) VISIBLE; 98int PURE strncmp(const char *s1, const char *s2, int n); 99long CONST char_to_long(char c); 100long PURE str_to_long(const char* str); 101 102 103int __builtin_clzl (unsigned long x); 104int __builtin_ctzl (unsigned long x); 105 106#ifdef CONFIG_ARCH_RISCV 107uint32_t __clzsi2(uint32_t x); 108uint32_t __ctzsi2(uint32_t x); 109uint32_t __clzdi2(uint64_t x); 110uint32_t __ctzdi2(uint64_t x); 111#endif 112/** MODIFIES: */ 113/** DONT_TRANSLATE */ 114/** FNSPEC clzl_spec: 115 "\<forall>s. \<Gamma> \<turnstile> 116 {\<sigma>. s = \<sigma> \<and> x_' s \<noteq> 0 } 117 \<acute>ret__long :== PROC clzl(\<acute>x) 118 \<lbrace> \<acute>ret__long = of_nat (word_clz (x_' s)) \<rbrace>" 119*/ 120static inline long 121CONST clzl(unsigned long x) 122{ 123 return __builtin_clzl(x); 124} 125 126/** MODIFIES: */ 127/** DONT_TRANSLATE */ 128/** FNSPEC ctzl_spec: 129 "\<forall>s. \<Gamma> \<turnstile> 130 {\<sigma>. s = \<sigma> \<and> x_' s \<noteq> 0 } 131 \<acute>ret__long :== PROC ctzl(\<acute>x) 132 \<lbrace> \<acute>ret__long = of_nat (word_ctz (x_' s)) \<rbrace>" 133*/ 134static inline long 135CONST ctzl(unsigned long x) 136{ 137 return __builtin_ctzl(x); 138} 139 140#define CTZL(x) __builtin_ctzl(x) 141 142/** DONT_TRANSLATE */ 143/** FNSPEC clzl_spec: 144 "\<forall>s. \<Gamma> \<turnstile> 145 {\<sigma>. s = \<sigma> \<and> x_' s \<noteq> 0 } 146 \<acute>ret__long :== PROC clzl(\<acute>x) 147 \<lbrace> \<acute>ret__long = of_nat (word_clz (x_' s)) \<rbrace>" 148*/ 149static inline long long 150CONST clzll(unsigned long long x) 151{ 152 return __builtin_clzll(x); 153} 154 155int __builtin_popcountl (unsigned long x); 156 157/** DONT_TRANSLATE */ 158static inline long 159CONST popcountl(unsigned long mask) 160{ 161#ifndef __POPCNT__ 162 unsigned int count; // c accumulates the total bits set in v 163 for (count = 0; mask; count++) { 164 mask &= mask - 1; // clear the least significant bit set 165 } 166 167 return count; 168#else 169 return __builtin_popcountl(mask); 170#endif 171} 172 173#define POPCOUNTL(x) popcountl(x) 174 175/* Can be used to insert padding to the next L1 cache line boundary */ 176#define PAD_TO_NEXT_CACHE_LN(used) char padding[L1_CACHE_LINE_SIZE - ((used) % L1_CACHE_LINE_SIZE)] 177 178#else /* __ASSEMBLER__ */ 179 180/* Some assemblers don't recognise ul (unsigned long) suffix */ 181#define BIT(n) (1 << (n)) 182#define UL_CONST(x) x 183 184#endif /* !__ASSEMBLER__ */ 185#endif /* __UTIL_H */ 186